inorder cpu: add missing DPRINTF argument
[gem5.git] / src / cpu / ozone / cpu.hh
1 /*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Kevin Lim
29 */
30
31 #ifndef __CPU_OZONE_CPU_HH__
32 #define __CPU_OZONE_CPU_HH__
33
34 #include <set>
35
36 #include "arch/alpha/tlb.hh"
37 #include "base/statistics.hh"
38 #include "config/the_isa.hh"
39 #include "cpu/ozone/rename_table.hh"
40 #include "cpu/ozone/thread_state.hh"
41 #include "cpu/base.hh"
42 #include "cpu/inst_seq.hh"
43 #include "cpu/pc_event.hh"
44 #include "cpu/static_inst.hh"
45 #include "cpu/thread_context.hh"
46 #include "cpu/timebuf.hh"
47 #include "mem/page_table.hh"
48 #include "sim/eventq.hh"
49
50 // forward declarations
51
52 namespace TheISA {
53 namespace Kernel {
54 class Statistics;
55 };
56 class TLB;
57 };
58
59 class Checkpoint;
60 class EndQuiesceEvent;
61 class MemoryController;
62 class MemObject;
63 class Process;
64 class Request;
65
66 namespace Trace {
67 class InstRecord;
68 }
69
70 template <class>
71 class Checker;
72
73 /**
74 * Light weight out of order CPU model that approximates an out of
75 * order CPU. It is separated into a front end and a back end, with
76 * the template parameter Impl describing the classes used for each.
77 * The goal is to be able to specify through the Impl the class to use
78 * for the front end and back end, with different classes used to
79 * model different levels of detail.
80 */
81 template <class Impl>
82 class OzoneCPU : public BaseCPU
83 {
84 private:
85 typedef typename Impl::FrontEnd FrontEnd;
86 typedef typename Impl::BackEnd BackEnd;
87 typedef typename Impl::DynInst DynInst;
88 typedef typename Impl::DynInstPtr DynInstPtr;
89
90 typedef TheISA::FloatReg FloatReg;
91 typedef TheISA::FloatRegBits FloatRegBits;
92 typedef TheISA::MiscReg MiscReg;
93
94 public:
95 class OzoneTC : public ThreadContext {
96 public:
97 OzoneCPU<Impl> *cpu;
98
99 OzoneThreadState<Impl> *thread;
100
101 BaseCPU *getCpuPtr();
102
103 TheISA::TLB *getITBPtr() { return cpu->itb; }
104
105 TheISA::TLB * getDTBPtr() { return cpu->dtb; }
106
107 System *getSystemPtr() { return cpu->system; }
108
109 TheISA::Kernel::Statistics *getKernelStats()
110 { return thread->getKernelStats(); }
111
112 Process *getProcessPtr() { return thread->getProcessPtr(); }
113
114 PortProxy &getPhysProxy() { return thread->getPhysProxy(); }
115
116 FSTranslatingPortProxy &getVirtProxy()
117 { return thread->getVirtProxy(); }
118
119 SETranslatingPortProxy &getMemProxy() { return thread->getMemProxy(); }
120
121 Status status() const { return thread->status(); }
122
123 void setStatus(Status new_status);
124
125 /// Set the status to Active. Optional delay indicates number of
126 /// cycles to wait before beginning execution.
127 void activate(int delay = 1);
128
129 /// Set the status to Suspended.
130 void suspend();
131
132 /// Set the status to Halted.
133 void halt();
134
135 void dumpFuncProfile();
136
137 void takeOverFrom(ThreadContext *old_context);
138
139 void regStats(const std::string &name);
140
141 void serialize(std::ostream &os);
142 void unserialize(Checkpoint *cp, const std::string &section);
143
144 EndQuiesceEvent *getQuiesceEvent();
145
146 Tick readLastActivate();
147 Tick readLastSuspend();
148
149 void profileClear();
150 void profileSample();
151
152 int threadId();
153
154 void copyArchRegs(ThreadContext *tc);
155
156 void clearArchRegs();
157
158 uint64_t readIntReg(int reg_idx);
159
160 FloatReg readFloatReg(int reg_idx);
161
162 FloatRegBits readFloatRegBits(int reg_idx);
163
164 void setIntReg(int reg_idx, uint64_t val);
165
166 void setFloatReg(int reg_idx, FloatReg val);
167
168 void setFloatRegBits(int reg_idx, FloatRegBits val);
169
170 uint64_t readPC() { return thread->PC; }
171 void setPC(Addr val);
172
173 uint64_t readNextPC() { return thread->nextPC; }
174 void setNextPC(Addr val);
175
176 uint64_t readNextNPC()
177 {
178 #if ISA_HAS_DELAY_SLOT
179 panic("Ozone needs to support nextNPC");
180 #else
181 return thread->nextPC + sizeof(TheISA::MachInst);
182 #endif
183 }
184
185 void setNextNPC(uint64_t val)
186 {
187 #if ISA_HAS_DELAY_SLOT
188 panic("Ozone needs to support nextNPC");
189 #endif
190 }
191
192 public:
193 // ISA stuff:
194 MiscReg readMiscRegNoEffect(int misc_reg);
195
196 MiscReg readMiscReg(int misc_reg);
197
198 void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
199
200 void setMiscReg(int misc_reg, const MiscReg &val);
201
202 unsigned readStCondFailures()
203 { return thread->storeCondFailures; }
204
205 void setStCondFailures(unsigned sc_failures)
206 { thread->storeCondFailures = sc_failures; }
207
208 bool misspeculating() { return false; }
209
210 Counter readFuncExeInst() { return thread->funcExeInst; }
211
212 void setFuncExeInst(Counter new_val)
213 { thread->funcExeInst = new_val; }
214 };
215
216 // Ozone specific thread context
217 OzoneTC ozoneTC;
218 // Thread context to be used
219 ThreadContext *tc;
220 // Checker thread context; will wrap the OzoneTC if a checker is
221 // being used.
222 ThreadContext *checkerTC;
223
224 typedef OzoneThreadState<Impl> ImplState;
225
226 private:
227 // Committed thread state for the OzoneCPU.
228 OzoneThreadState<Impl> thread;
229
230 public:
231 // main simulation loop (one cycle)
232 void tick();
233
234 #ifndef NDEBUG
235 /** Count of total number of dynamic instructions in flight. */
236 int instcount;
237 #endif
238
239 std::set<InstSeqNum> snList;
240 std::set<Addr> lockAddrList;
241 private:
242 struct TickEvent : public Event
243 {
244 OzoneCPU *cpu;
245 int width;
246
247 TickEvent(OzoneCPU *c, int w);
248 void process();
249 const char *description() const;
250 };
251
252 TickEvent tickEvent;
253
254 /// Schedule tick event, regardless of its current state.
255 void scheduleTickEvent(int delay)
256 {
257 if (tickEvent.squashed())
258 tickEvent.reschedule(curTick() + ticks(delay));
259 else if (!tickEvent.scheduled())
260 tickEvent.schedule(curTick() + ticks(delay));
261 }
262
263 /// Unschedule tick event, regardless of its current state.
264 void unscheduleTickEvent()
265 {
266 if (tickEvent.scheduled())
267 tickEvent.squash();
268 }
269
270 public:
271 enum Status {
272 Running,
273 Idle,
274 SwitchedOut
275 };
276
277 Status _status;
278
279 public:
280 void wakeup();
281
282 void zero_fill_64(Addr addr) {
283 static int warned = 0;
284 if (!warned) {
285 warn ("WH64 is not implemented");
286 warned = 1;
287 }
288 };
289
290 typedef typename Impl::Params Params;
291
292 OzoneCPU(Params *params);
293
294 virtual ~OzoneCPU();
295
296 void init();
297
298 public:
299 BaseCPU *getCpuPtr() { return this; }
300
301 void switchOut();
302 void signalSwitched();
303 void takeOverFrom(BaseCPU *oldCPU);
304
305 int switchCount;
306
307 Addr dbg_vtophys(Addr addr);
308
309 bool interval_stats;
310
311 TheISA::TLB *itb;
312 TheISA::TLB *dtb;
313 System *system;
314
315 FrontEnd *frontEnd;
316
317 BackEnd *backEnd;
318
319 private:
320 Status status() const { return _status; }
321 void setStatus(Status new_status) { _status = new_status; }
322
323 virtual void activateContext(int thread_num, int delay);
324 virtual void suspendContext(int thread_num);
325 virtual void deallocateContext(int thread_num, int delay);
326 virtual void haltContext(int thread_num);
327
328 // statistics
329 virtual void regStats();
330 virtual void resetStats();
331
332 // number of simulated instructions
333 public:
334 Counter numInst;
335 Counter startNumInst;
336
337 virtual Counter totalInstructions() const
338 {
339 return numInst - startNumInst;
340 }
341
342 private:
343 // number of simulated loads
344 Counter numLoad;
345 Counter startNumLoad;
346
347 // number of idle cycles
348 Stats::Average notIdleFraction;
349 Stats::Formula idleFraction;
350
351 public:
352 virtual void serialize(std::ostream &os);
353 virtual void unserialize(Checkpoint *cp, const std::string &section);
354
355 void demapPage(Addr vaddr, uint64_t asn)
356 {
357 cpu->itb->demap(vaddr, asn);
358 cpu->dtb->demap(vaddr, asn);
359 }
360
361 void demapInstPage(Addr vaddr, uint64_t asn)
362 {
363 cpu->itb->demap(vaddr, asn);
364 }
365
366 void demapDataPage(Addr vaddr, uint64_t asn)
367 {
368 cpu->dtb->demap(vaddr, asn);
369 }
370
371 /** CPU read function, forwards read to LSQ. */
372 template <class T>
373 Fault read(Request *req, T &data, int load_idx)
374 {
375 return backEnd->read(req, data, load_idx);
376 }
377
378 /** CPU write function, forwards write to LSQ. */
379 template <class T>
380 Fault write(Request *req, T &data, int store_idx)
381 {
382 return backEnd->write(req, data, store_idx);
383 }
384
385 public:
386 void squashFromTC();
387
388 void dumpInsts() { frontEnd->dumpInsts(); }
389
390 Fault hwrei();
391 bool simPalCheck(int palFunc);
392 void processInterrupts();
393 void syscall(uint64_t &callnum);
394
395 ThreadContext *tcBase() { return tc; }
396
397 struct CommStruct {
398 InstSeqNum doneSeqNum;
399 InstSeqNum nonSpecSeqNum;
400 bool uncached;
401 unsigned lqIdx;
402
403 bool stall;
404 };
405
406 InstSeqNum globalSeqNum;
407
408 TimeBuffer<CommStruct> comm;
409
410 bool decoupledFrontEnd;
411
412 bool lockFlag;
413
414 Stats::Scalar quiesceCycles;
415
416 Checker<DynInstPtr> *checker;
417 };
418
419 #endif // __CPU_OZONE_CPU_HH__