Deleted Added
sdiff udiff text old ( 7445:dfd04ffc1773 ) new ( 7597:063f160e8b50 )
full compact
1/*
2 * Copyright (c) 2002-2005 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: Steve Reinhardt
29 * Dave Greene
30 * Nathan Binkert
31 */
32
33#ifndef __CPU_SIMPLE_BASE_HH__
34#define __CPU_SIMPLE_BASE_HH__
35
36#include "arch/predecoder.hh"
37#include "base/statistics.hh"
38#include "config/full_system.hh"
39#include "config/the_isa.hh"
40#include "cpu/base.hh"
41#include "cpu/simple_thread.hh"
42#include "cpu/pc_event.hh"
43#include "cpu/static_inst.hh"
44#include "mem/packet.hh"
45#include "mem/port.hh"
46#include "mem/request.hh"
47#include "sim/eventq.hh"
48#include "sim/system.hh"
49
50// forward declarations
51#if FULL_SYSTEM
52class Processor;
53namespace TheISA
54{
55 class ITB;
56 class DTB;
57}
58class MemObject;
59
60#else
61
62class Process;
63
64#endif // FULL_SYSTEM
65
66namespace TheISA
67{
68 class Predecoder;
69}
70class ThreadContext;
71class Checkpoint;
72
73namespace Trace {
74 class InstRecord;
75}
76
77class BaseSimpleCPUParams;
78
79
80class BaseSimpleCPU : public BaseCPU
81{
82 protected:
83 typedef TheISA::MiscReg MiscReg;
84 typedef TheISA::FloatReg FloatReg;
85 typedef TheISA::FloatRegBits FloatRegBits;
86
87 protected:
88 Trace::InstRecord *traceData;
89
90 inline void checkPcEventQueue() {
91 Addr oldpc;
92 do {
93 oldpc = thread->readPC();
94 system->pcEventQueue.service(tc);
95 } while (oldpc != thread->readPC());
96 }
97
98 public:
99 void wakeup();
100
101 void zero_fill_64(Addr addr) {
102 static int warned = 0;
103 if (!warned) {
104 warn ("WH64 is not implemented");
105 warned = 1;
106 }
107 };
108
109 public:
110 BaseSimpleCPU(BaseSimpleCPUParams *params);
111 virtual ~BaseSimpleCPU();
112
113 public:
114 /** SimpleThread object, provides all the architectural state. */
115 SimpleThread *thread;
116
117 /** ThreadContext object, provides an interface for external
118 * objects to modify this thread's state.
119 */
120 ThreadContext *tc;
121 protected:
122
123 enum Status {
124 Idle,
125 Running,
126 ITBWaitResponse,
127 IcacheRetry,
128 IcacheWaitResponse,
129 IcacheWaitSwitch,
130 DTBWaitResponse,
131 DcacheRetry,
132 DcacheWaitResponse,
133 DcacheWaitSwitch,
134 SwitchedOut
135 };
136
137 Status _status;
138
139 public:
140
141#if FULL_SYSTEM
142 Addr dbg_vtophys(Addr addr);
143
144 bool interval_stats;
145#endif
146
147 // current instruction
148 TheISA::MachInst inst;
149
150 // The predecoder
151 TheISA::Predecoder predecoder;
152
153 StaticInstPtr curStaticInst;
154 StaticInstPtr curMacroStaticInst;
155
156 //This is the offset from the current pc that fetch should be performed at
157 Addr fetchOffset;
158 //This flag says to stay at the current pc. This is useful for
159 //instructions which go beyond MachInst boundaries.
160 bool stayAtPC;
161
162 void checkForInterrupts();
163 void setupFetchRequest(Request *req);
164 void preExecute();
165 void postExecute();
166 void advancePC(Fault fault);
167
168 virtual void deallocateContext(int thread_num);
169 virtual void haltContext(int thread_num);
170
171 // statistics
172 virtual void regStats();
173 virtual void resetStats();
174
175 // number of simulated instructions
176 Counter numInst;
177 Counter startNumInst;
178 Stats::Scalar numInsts;
179
180 void countInst()
181 {
182 numInst++;
183 numInsts++;
184
185 thread->funcExeInst++;
186 }
187
188 virtual Counter totalInstructions() const
189 {
190 return numInst - startNumInst;
191 }
192
193 // Mask to align PCs to MachInst sized boundaries
194 static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1);
195
196 // number of simulated memory references
197 Stats::Scalar numMemRefs;
198
199 // number of simulated loads
200 Counter numLoad;
201 Counter startNumLoad;
202
203 // number of idle cycles
204 Stats::Average notIdleFraction;
205 Stats::Formula idleFraction;
206
207 // number of cycles stalled for I-cache responses
208 Stats::Scalar icacheStallCycles;
209 Counter lastIcacheStall;
210
211 // number of cycles stalled for I-cache retries
212 Stats::Scalar icacheRetryCycles;
213 Counter lastIcacheRetry;
214
215 // number of cycles stalled for D-cache responses
216 Stats::Scalar dcacheStallCycles;
217 Counter lastDcacheStall;
218
219 // number of cycles stalled for D-cache retries
220 Stats::Scalar dcacheRetryCycles;
221 Counter lastDcacheRetry;
222
223 virtual void serialize(std::ostream &os);
224 virtual void unserialize(Checkpoint *cp, const std::string &section);
225
226 // These functions are only used in CPU models that split
227 // effective address computation from the actual memory access.
228 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
229 Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n");
230 M5_DUMMY_RETURN}
231
232 void prefetch(Addr addr, unsigned flags);
233 void writeHint(Addr addr, int size, unsigned flags);
234
235 Fault copySrcTranslate(Addr src);
236
237 Fault copy(Addr dest);
238
239 // The register accessor methods provide the index of the
240 // instruction's operand (e.g., 0 or 1), not the architectural
241 // register index, to simplify the implementation of register
242 // renaming. We find the architectural register index by indexing
243 // into the instruction's own operand index table. Note that a
244 // raw pointer to the StaticInst is provided instead of a
245 // ref-counted StaticInstPtr to redice overhead. This is fine as
246 // long as these methods don't copy the pointer into any long-term
247 // storage (which is pretty hard to imagine they would have reason
248 // to do).
249
250 uint64_t readIntRegOperand(const StaticInst *si, int idx)
251 {
252 return thread->readIntReg(si->srcRegIdx(idx));
253 }
254
255 FloatReg readFloatRegOperand(const StaticInst *si, int idx)
256 {
257 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
258 return thread->readFloatReg(reg_idx);
259 }
260
261 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
262 {
263 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
264 return thread->readFloatRegBits(reg_idx);
265 }
266
267 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
268 {
269 thread->setIntReg(si->destRegIdx(idx), val);
270 }
271
272 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
273 {
274 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
275 thread->setFloatReg(reg_idx, val);
276 }
277
278 void setFloatRegOperandBits(const StaticInst *si, int idx,
279 FloatRegBits val)
280 {
281 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
282 thread->setFloatRegBits(reg_idx, val);
283 }
284
285 uint64_t readPC() { return thread->readPC(); }
286 uint64_t readMicroPC() { return thread->readMicroPC(); }
287 uint64_t readNextPC() { return thread->readNextPC(); }
288 uint64_t readNextMicroPC() { return thread->readNextMicroPC(); }
289 uint64_t readNextNPC() { return thread->readNextNPC(); }
290 bool readPredicate() { return thread->readPredicate(); }
291
292 void setPC(uint64_t val) { thread->setPC(val); }
293 void setMicroPC(uint64_t val) { thread->setMicroPC(val); }
294 void setNextPC(uint64_t val) { thread->setNextPC(val); }
295 void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); }
296 void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
297 void setPredicate(bool val)
298 { return thread->setPredicate(val); }
299
300 MiscReg readMiscRegNoEffect(int misc_reg)
301 {
302 return thread->readMiscRegNoEffect(misc_reg);
303 }
304
305 MiscReg readMiscReg(int misc_reg)
306 {
307 return thread->readMiscReg(misc_reg);
308 }
309
310 void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
311 {
312 return thread->setMiscRegNoEffect(misc_reg, val);
313 }
314
315 void setMiscReg(int misc_reg, const MiscReg &val)
316 {
317 return thread->setMiscReg(misc_reg, val);
318 }
319
320 MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
321 {
322 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
323 return thread->readMiscRegNoEffect(reg_idx);
324 }
325
326 MiscReg readMiscRegOperand(const StaticInst *si, int idx)
327 {
328 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
329 return thread->readMiscReg(reg_idx);
330 }
331
332 void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val)
333 {
334 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
335 return thread->setMiscRegNoEffect(reg_idx, val);
336 }
337
338 void setMiscRegOperand(
339 const StaticInst *si, int idx, const MiscReg &val)
340 {
341 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
342 return thread->setMiscReg(reg_idx, val);
343 }
344
345 void demapPage(Addr vaddr, uint64_t asn)
346 {
347 thread->demapPage(vaddr, asn);
348 }
349
350 void demapInstPage(Addr vaddr, uint64_t asn)
351 {
352 thread->demapInstPage(vaddr, asn);
353 }
354
355 void demapDataPage(Addr vaddr, uint64_t asn)
356 {
357 thread->demapDataPage(vaddr, asn);
358 }
359
360 unsigned readStCondFailures() {
361 return thread->readStCondFailures();
362 }
363
364 void setStCondFailures(unsigned sc_failures) {
365 thread->setStCondFailures(sc_failures);
366 }
367
368 MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
369 {
370 panic("Simple CPU models do not support multithreaded "
371 "register access.\n");
372 }
373
374 void setRegOtherThread(int regIdx, const MiscReg &val,
375 ThreadID tid = InvalidThreadID)
376 {
377 panic("Simple CPU models do not support multithreaded "
378 "register access.\n");
379 }
380
381 //Fault CacheOp(uint8_t Op, Addr EA);
382
383#if FULL_SYSTEM
384 Fault hwrei() { return thread->hwrei(); }
385 void ev5_trap(Fault fault) { fault->invoke(tc); }
386 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
387#else
388 void syscall(int64_t callnum) { thread->syscall(callnum); }
389#endif
390
391 bool misspeculating() { return thread->misspeculating(); }
392 ThreadContext *tcBase() { return tc; }
393};
394
395#endif // __CPU_SIMPLE_BASE_HH__