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