Deleted Added
sdiff udiff text old ( 8850:ed91b534ed04 ) new ( 8887:20ea02da9c53 )
full compact
1/*
2 * Copyright (c) 2011 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Steve Reinhardt
41 * Dave Greene
42 * Nathan Binkert
43 */
44
45#ifndef __CPU_SIMPLE_BASE_HH__
46#define __CPU_SIMPLE_BASE_HH__
47
48#include "arch/predecoder.hh"
49#include "base/statistics.hh"
50#include "config/the_isa.hh"
51#include "config/use_checker.hh"
52#include "cpu/base.hh"
53#include "cpu/decode.hh"
54#include "cpu/pc_event.hh"
55#include "cpu/simple_thread.hh"
56#include "cpu/static_inst.hh"
57#include "mem/packet.hh"
58#include "mem/port.hh"
59#include "mem/request.hh"
60#include "sim/eventq.hh"
61#include "sim/full_system.hh"
62#include "sim/system.hh"
63
64#if USE_CHECKER
65#include "cpu/checker/cpu.hh"
66#endif
67
68// forward declarations
69class Checkpoint;
70class Process;
71class Processor;
72class ThreadContext;
73
74namespace TheISA
75{
76 class DTB;
77 class ITB;
78 class Predecoder;
79}
80
81namespace Trace {
82 class InstRecord;
83}
84
85struct BaseSimpleCPUParams;
86
87
88class BaseSimpleCPU : public BaseCPU
89{
90 protected:
91 typedef TheISA::MiscReg MiscReg;
92 typedef TheISA::FloatReg FloatReg;
93 typedef TheISA::FloatRegBits FloatRegBits;
94
95 protected:
96 Trace::InstRecord *traceData;
97
98 inline void checkPcEventQueue() {
99 Addr oldpc, pc = thread->instAddr();
100 do {
101 oldpc = pc;
102 system->pcEventQueue.service(tc);
103 pc = thread->instAddr();
104 } while (oldpc != pc);
105 }
106
107 public:
108 void wakeup();
109
110 void zero_fill_64(Addr addr) {
111 static int warned = 0;
112 if (!warned) {
113 warn ("WH64 is not implemented");
114 warned = 1;
115 }
116 };
117
118 public:
119 BaseSimpleCPU(BaseSimpleCPUParams *params);
120 virtual ~BaseSimpleCPU();
121
122 public:
123 /** SimpleThread object, provides all the architectural state. */
124 SimpleThread *thread;
125
126 /** ThreadContext object, provides an interface for external
127 * objects to modify this thread's state.
128 */
129 ThreadContext *tc;
130
131#if USE_CHECKER
132 CheckerCPU *checker;
133#endif
134 protected:
135
136 enum Status {
137 Idle,
138 Running,
139 Faulting,
140 ITBWaitResponse,
141 IcacheRetry,
142 IcacheWaitResponse,
143 IcacheWaitSwitch,
144 DTBWaitResponse,
145 DcacheRetry,
146 DcacheWaitResponse,
147 DcacheWaitSwitch,
148 SwitchedOut
149 };
150
151 Status _status;
152
153 public:
154
155 Addr dbg_vtophys(Addr addr);
156
157 bool interval_stats;
158
159 // current instruction
160 TheISA::MachInst inst;
161
162 // The predecoder
163 TheISA::Predecoder predecoder;
164
165 StaticInstPtr curStaticInst;
166 StaticInstPtr curMacroStaticInst;
167
168 //This is the offset from the current pc that fetch should be performed at
169 Addr fetchOffset;
170 //This flag says to stay at the current pc. This is useful for
171 //instructions which go beyond MachInst boundaries.
172 bool stayAtPC;
173
174 void checkForInterrupts();
175 void setupFetchRequest(Request *req);
176 void preExecute();
177 void postExecute();
178 void advancePC(Fault fault);
179
180 virtual void deallocateContext(ThreadID thread_num);
181 virtual void haltContext(ThreadID thread_num);
182
183 // statistics
184 virtual void regStats();
185 virtual void resetStats();
186
187 // number of simulated instructions
188 Counter numInst;
189 Counter startNumInst;
190 Stats::Scalar numInsts;
191 Counter numOp;
192 Counter startNumOp;
193 Stats::Scalar numOps;
194
195 void countInst()
196 {
197 if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
198 numInst++;
199 numInsts++;
200 }
201 numOp++;
202 numOps++;
203
204 system->totalNumInsts++;
205 thread->funcExeInst++;
206 }
207
208 virtual Counter totalInsts() const
209 {
210 return numInst - startNumInst;
211 }
212
213 virtual Counter totalOps() const
214 {
215 return numOp - startNumOp;
216 }
217
218 //number of integer alu accesses
219 Stats::Scalar numIntAluAccesses;
220
221 //number of float alu accesses
222 Stats::Scalar numFpAluAccesses;
223
224 //number of function calls/returns
225 Stats::Scalar numCallsReturns;
226
227 //conditional control instructions;
228 Stats::Scalar numCondCtrlInsts;
229
230 //number of int instructions
231 Stats::Scalar numIntInsts;
232
233 //number of float instructions
234 Stats::Scalar numFpInsts;
235
236 //number of integer register file accesses
237 Stats::Scalar numIntRegReads;
238 Stats::Scalar numIntRegWrites;
239
240 //number of float register file accesses
241 Stats::Scalar numFpRegReads;
242 Stats::Scalar numFpRegWrites;
243
244 // number of simulated memory references
245 Stats::Scalar numMemRefs;
246 Stats::Scalar numLoadInsts;
247 Stats::Scalar numStoreInsts;
248
249 // number of idle cycles
250 Stats::Formula numIdleCycles;
251
252 // number of busy cycles
253 Stats::Formula numBusyCycles;
254
255 // number of simulated loads
256 Counter numLoad;
257 Counter startNumLoad;
258
259 // number of idle cycles
260 Stats::Average notIdleFraction;
261 Stats::Formula idleFraction;
262
263 // number of cycles stalled for I-cache responses
264 Stats::Scalar icacheStallCycles;
265 Counter lastIcacheStall;
266
267 // number of cycles stalled for I-cache retries
268 Stats::Scalar icacheRetryCycles;
269 Counter lastIcacheRetry;
270
271 // number of cycles stalled for D-cache responses
272 Stats::Scalar dcacheStallCycles;
273 Counter lastDcacheStall;
274
275 // number of cycles stalled for D-cache retries
276 Stats::Scalar dcacheRetryCycles;
277 Counter lastDcacheRetry;
278
279 virtual void serialize(std::ostream &os);
280 virtual void unserialize(Checkpoint *cp, const std::string &section);
281
282 // These functions are only used in CPU models that split
283 // effective address computation from the actual memory access.
284 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
285 Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n");
286 M5_DUMMY_RETURN}
287
288 // The register accessor methods provide the index of the
289 // instruction's operand (e.g., 0 or 1), not the architectural
290 // register index, to simplify the implementation of register
291 // renaming. We find the architectural register index by indexing
292 // into the instruction's own operand index table. Note that a
293 // raw pointer to the StaticInst is provided instead of a
294 // ref-counted StaticInstPtr to redice overhead. This is fine as
295 // long as these methods don't copy the pointer into any long-term
296 // storage (which is pretty hard to imagine they would have reason
297 // to do).
298
299 uint64_t readIntRegOperand(const StaticInst *si, int idx)
300 {
301 numIntRegReads++;
302 return thread->readIntReg(si->srcRegIdx(idx));
303 }
304
305 FloatReg readFloatRegOperand(const StaticInst *si, int idx)
306 {
307 numFpRegReads++;
308 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
309 return thread->readFloatReg(reg_idx);
310 }
311
312 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
313 {
314 numFpRegReads++;
315 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
316 return thread->readFloatRegBits(reg_idx);
317 }
318
319 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
320 {
321 numIntRegWrites++;
322 thread->setIntReg(si->destRegIdx(idx), val);
323 }
324
325 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
326 {
327 numFpRegWrites++;
328 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
329 thread->setFloatReg(reg_idx, val);
330 }
331
332 void setFloatRegOperandBits(const StaticInst *si, int idx,
333 FloatRegBits val)
334 {
335 numFpRegWrites++;
336 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
337 thread->setFloatRegBits(reg_idx, val);
338 }
339
340 bool readPredicate() { return thread->readPredicate(); }
341 void setPredicate(bool val)
342 {
343 thread->setPredicate(val);
344 if (traceData) {
345 traceData->setPredicate(val);
346 }
347 }
348 TheISA::PCState pcState() { return thread->pcState(); }
349 void pcState(const TheISA::PCState &val) { thread->pcState(val); }
350 Addr instAddr() { return thread->instAddr(); }
351 Addr nextInstAddr() { return thread->nextInstAddr(); }
352 MicroPC microPC() { return thread->microPC(); }
353
354 MiscReg readMiscRegNoEffect(int misc_reg)
355 {
356 return thread->readMiscRegNoEffect(misc_reg);
357 }
358
359 MiscReg readMiscReg(int misc_reg)
360 {
361 numIntRegReads++;
362 return thread->readMiscReg(misc_reg);
363 }
364
365 void setMiscReg(int misc_reg, const MiscReg &val)
366 {
367 numIntRegWrites++;
368 return thread->setMiscReg(misc_reg, val);
369 }
370
371 MiscReg readMiscRegOperand(const StaticInst *si, int idx)
372 {
373 numIntRegReads++;
374 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
375 return thread->readMiscReg(reg_idx);
376 }
377
378 void setMiscRegOperand(
379 const StaticInst *si, int idx, const MiscReg &val)
380 {
381 numIntRegWrites++;
382 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
383 return thread->setMiscReg(reg_idx, val);
384 }
385
386 void demapPage(Addr vaddr, uint64_t asn)
387 {
388 thread->demapPage(vaddr, asn);
389 }
390
391 void demapInstPage(Addr vaddr, uint64_t asn)
392 {
393 thread->demapInstPage(vaddr, asn);
394 }
395
396 void demapDataPage(Addr vaddr, uint64_t asn)
397 {
398 thread->demapDataPage(vaddr, asn);
399 }
400
401 unsigned readStCondFailures() {
402 return thread->readStCondFailures();
403 }
404
405 void setStCondFailures(unsigned sc_failures) {
406 thread->setStCondFailures(sc_failures);
407 }
408
409 MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
410 {
411 panic("Simple CPU models do not support multithreaded "
412 "register access.\n");
413 }
414
415 void setRegOtherThread(int regIdx, const MiscReg &val,
416 ThreadID tid = InvalidThreadID)
417 {
418 panic("Simple CPU models do not support multithreaded "
419 "register access.\n");
420 }
421
422 //Fault CacheOp(uint8_t Op, Addr EA);
423
424 Fault hwrei() { return thread->hwrei(); }
425 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
426
427 void
428 syscall(int64_t callnum)
429 {
430 if (FullSystem)
431 panic("Syscall emulation isn't available in FS mode.\n");
432
433 thread->syscall(callnum);
434 }
435
436 bool misspeculating() { return thread->misspeculating(); }
437 ThreadContext *tcBase() { return tc; }
438};
439
440#endif // __CPU_SIMPLE_BASE_HH__