CPU: Get rid of the now unnecessary getInst/setInst family of functions.
[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 "base/statistics.hh"
37 #include "base/timebuf.hh"
38 #include "config/full_system.hh"
39 #include "config/the_isa.hh"
40 #include "cpu/base.hh"
41 #include "cpu/thread_context.hh"
42 #include "cpu/inst_seq.hh"
43 #include "cpu/ozone/rename_table.hh"
44 #include "cpu/ozone/thread_state.hh"
45 #include "cpu/pc_event.hh"
46 #include "cpu/static_inst.hh"
47 #include "mem/page_table.hh"
48 #include "sim/eventq.hh"
49
50 // forward declarations
51 #if FULL_SYSTEM
52 #include "arch/alpha/tlb.hh"
53
54 namespace TheISA
55 {
56 class TLB;
57 }
58 class PhysicalMemory;
59 class MemoryController;
60
61 namespace TheISA {
62 namespace Kernel {
63 class Statistics;
64 };
65 };
66
67 #else
68
69 class Process;
70
71 #endif // FULL_SYSTEM
72
73 class Checkpoint;
74 class EndQuiesceEvent;
75 class MemObject;
76 class Request;
77
78 namespace Trace {
79 class InstRecord;
80 }
81
82 template <class>
83 class Checker;
84
85 /**
86 * Light weight out of order CPU model that approximates an out of
87 * order CPU. It is separated into a front end and a back end, with
88 * the template parameter Impl describing the classes used for each.
89 * The goal is to be able to specify through the Impl the class to use
90 * for the front end and back end, with different classes used to
91 * model different levels of detail.
92 */
93 template <class Impl>
94 class OzoneCPU : public BaseCPU
95 {
96 private:
97 typedef typename Impl::FrontEnd FrontEnd;
98 typedef typename Impl::BackEnd BackEnd;
99 typedef typename Impl::DynInst DynInst;
100 typedef typename Impl::DynInstPtr DynInstPtr;
101
102 typedef TheISA::FloatReg FloatReg;
103 typedef TheISA::FloatRegBits FloatRegBits;
104 typedef TheISA::MiscReg MiscReg;
105
106 public:
107 class OzoneTC : public ThreadContext {
108 public:
109 OzoneCPU<Impl> *cpu;
110
111 OzoneThreadState<Impl> *thread;
112
113 BaseCPU *getCpuPtr();
114
115 TheISA::TLB *getITBPtr() { return cpu->itb; }
116
117 TheISA::TLB * getDTBPtr() { return cpu->dtb; }
118
119 #if FULL_SYSTEM
120 System *getSystemPtr() { return cpu->system; }
121
122 PhysicalMemory *getPhysMemPtr() { return cpu->physmem; }
123
124 TheISA::Kernel::Statistics *getKernelStats()
125 { return thread->getKernelStats(); }
126
127 FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
128
129 VirtualPort *getVirtPort()
130 { return thread->getVirtPort(); }
131 #else
132 TranslatingPort *getMemPort() { return thread->getMemPort(); }
133
134 Process *getProcessPtr() { return thread->getProcessPtr(); }
135 #endif
136
137 Status status() const { return thread->status(); }
138
139 void setStatus(Status new_status);
140
141 /// Set the status to Active. Optional delay indicates number of
142 /// cycles to wait before beginning execution.
143 void activate(int delay = 1);
144
145 /// Set the status to Suspended.
146 void suspend();
147
148 /// Set the status to Halted.
149 void halt();
150
151 #if FULL_SYSTEM
152 void dumpFuncProfile();
153 #endif
154
155 void takeOverFrom(ThreadContext *old_context);
156
157 void regStats(const std::string &name);
158
159 void serialize(std::ostream &os);
160 void unserialize(Checkpoint *cp, const std::string &section);
161
162 #if FULL_SYSTEM
163 EndQuiesceEvent *getQuiesceEvent();
164
165 Tick readLastActivate();
166 Tick readLastSuspend();
167
168 void profileClear();
169 void profileSample();
170 #endif
171
172 int threadId();
173
174 void copyArchRegs(ThreadContext *tc);
175
176 void clearArchRegs();
177
178 uint64_t readIntReg(int reg_idx);
179
180 FloatReg readFloatReg(int reg_idx);
181
182 FloatRegBits readFloatRegBits(int reg_idx);
183
184 void setIntReg(int reg_idx, uint64_t val);
185
186 void setFloatReg(int reg_idx, FloatReg val);
187
188 void setFloatRegBits(int reg_idx, FloatRegBits val);
189
190 uint64_t readPC() { return thread->PC; }
191 void setPC(Addr val);
192
193 uint64_t readNextPC() { return thread->nextPC; }
194 void setNextPC(Addr val);
195
196 uint64_t readNextNPC()
197 {
198 #if ISA_HAS_DELAY_SLOT
199 panic("Ozone needs to support nextNPC");
200 #else
201 return thread->nextPC + sizeof(TheISA::MachInst);
202 #endif
203 }
204
205 void setNextNPC(uint64_t val)
206 {
207 #if ISA_HAS_DELAY_SLOT
208 panic("Ozone needs to support nextNPC");
209 #endif
210 }
211
212 public:
213 // ISA stuff:
214 MiscReg readMiscRegNoEffect(int misc_reg);
215
216 MiscReg readMiscReg(int misc_reg);
217
218 void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
219
220 void setMiscReg(int misc_reg, const MiscReg &val);
221
222 unsigned readStCondFailures()
223 { return thread->storeCondFailures; }
224
225 void setStCondFailures(unsigned sc_failures)
226 { thread->storeCondFailures = sc_failures; }
227
228 bool misspeculating() { return false; }
229
230 #if !FULL_SYSTEM
231 Counter readFuncExeInst() { return thread->funcExeInst; }
232
233 void setFuncExeInst(Counter new_val)
234 { thread->funcExeInst = new_val; }
235 #endif
236 };
237
238 // Ozone specific thread context
239 OzoneTC ozoneTC;
240 // Thread context to be used
241 ThreadContext *tc;
242 // Checker thread context; will wrap the OzoneTC if a checker is
243 // being used.
244 ThreadContext *checkerTC;
245
246 typedef OzoneThreadState<Impl> ImplState;
247
248 private:
249 // Committed thread state for the OzoneCPU.
250 OzoneThreadState<Impl> thread;
251
252 public:
253 // main simulation loop (one cycle)
254 void tick();
255
256 #ifndef NDEBUG
257 /** Count of total number of dynamic instructions in flight. */
258 int instcount;
259 #endif
260
261 std::set<InstSeqNum> snList;
262 std::set<Addr> lockAddrList;
263 private:
264 struct TickEvent : public Event
265 {
266 OzoneCPU *cpu;
267 int width;
268
269 TickEvent(OzoneCPU *c, int w);
270 void process();
271 const char *description() const;
272 };
273
274 TickEvent tickEvent;
275
276 /// Schedule tick event, regardless of its current state.
277 void scheduleTickEvent(int delay)
278 {
279 if (tickEvent.squashed())
280 tickEvent.reschedule(curTick + ticks(delay));
281 else if (!tickEvent.scheduled())
282 tickEvent.schedule(curTick + ticks(delay));
283 }
284
285 /// Unschedule tick event, regardless of its current state.
286 void unscheduleTickEvent()
287 {
288 if (tickEvent.scheduled())
289 tickEvent.squash();
290 }
291
292 public:
293 enum Status {
294 Running,
295 Idle,
296 SwitchedOut
297 };
298
299 Status _status;
300
301 public:
302 void wakeup();
303
304 void zero_fill_64(Addr addr) {
305 static int warned = 0;
306 if (!warned) {
307 warn ("WH64 is not implemented");
308 warned = 1;
309 }
310 };
311
312 typedef typename Impl::Params Params;
313
314 OzoneCPU(Params *params);
315
316 virtual ~OzoneCPU();
317
318 void init();
319
320 public:
321 BaseCPU *getCpuPtr() { return this; }
322
323 void switchOut();
324 void signalSwitched();
325 void takeOverFrom(BaseCPU *oldCPU);
326
327 int switchCount;
328
329 #if FULL_SYSTEM
330 Addr dbg_vtophys(Addr addr);
331
332 bool interval_stats;
333
334 TheISA::TLB *itb;
335 TheISA::TLB *dtb;
336 System *system;
337 PhysicalMemory *physmem;
338 #endif
339
340 virtual Port *getPort(const std::string &name, int idx);
341
342 FrontEnd *frontEnd;
343
344 BackEnd *backEnd;
345
346 private:
347 Status status() const { return _status; }
348 void setStatus(Status new_status) { _status = new_status; }
349
350 virtual void activateContext(int thread_num, int delay);
351 virtual void suspendContext(int thread_num);
352 virtual void deallocateContext(int thread_num, int delay);
353 virtual void haltContext(int thread_num);
354
355 // statistics
356 virtual void regStats();
357 virtual void resetStats();
358
359 // number of simulated instructions
360 public:
361 Counter numInst;
362 Counter startNumInst;
363
364 virtual Counter totalInstructions() const
365 {
366 return numInst - startNumInst;
367 }
368
369 private:
370 // number of simulated loads
371 Counter numLoad;
372 Counter startNumLoad;
373
374 // number of idle cycles
375 Stats::Average notIdleFraction;
376 Stats::Formula idleFraction;
377
378 public:
379 virtual void serialize(std::ostream &os);
380 virtual void unserialize(Checkpoint *cp, const std::string &section);
381
382 void demapPage(Addr vaddr, uint64_t asn)
383 {
384 cpu->itb->demap(vaddr, asn);
385 cpu->dtb->demap(vaddr, asn);
386 }
387
388 void demapInstPage(Addr vaddr, uint64_t asn)
389 {
390 cpu->itb->demap(vaddr, asn);
391 }
392
393 void demapDataPage(Addr vaddr, uint64_t asn)
394 {
395 cpu->dtb->demap(vaddr, asn);
396 }
397
398 /** CPU read function, forwards read to LSQ. */
399 template <class T>
400 Fault read(Request *req, T &data, int load_idx)
401 {
402 return backEnd->read(req, data, load_idx);
403 }
404
405 /** CPU write function, forwards write to LSQ. */
406 template <class T>
407 Fault write(Request *req, T &data, int store_idx)
408 {
409 return backEnd->write(req, data, store_idx);
410 }
411
412 void prefetch(Addr addr, unsigned flags)
413 {
414 // need to do this...
415 }
416
417 void writeHint(Addr addr, int size, unsigned flags)
418 {
419 // need to do this...
420 }
421
422 Fault copySrcTranslate(Addr src);
423
424 Fault copy(Addr dest);
425
426 public:
427 void squashFromTC();
428
429 void dumpInsts() { frontEnd->dumpInsts(); }
430
431 #if FULL_SYSTEM
432 Fault hwrei();
433 bool simPalCheck(int palFunc);
434 void processInterrupts();
435 #else
436 void syscall(uint64_t &callnum);
437 #endif
438
439 ThreadContext *tcBase() { return tc; }
440
441 struct CommStruct {
442 InstSeqNum doneSeqNum;
443 InstSeqNum nonSpecSeqNum;
444 bool uncached;
445 unsigned lqIdx;
446
447 bool stall;
448 };
449
450 InstSeqNum globalSeqNum;
451
452 TimeBuffer<CommStruct> comm;
453
454 bool decoupledFrontEnd;
455
456 bool lockFlag;
457
458 Stats::Scalar quiesceCycles;
459
460 Checker<DynInstPtr> *checker;
461 };
462
463 #endif // __CPU_OZONE_CPU_HH__