pwr: Adds logic to enter power gating for the cpu model
[gem5.git] / src / cpu / simple / exec_context.hh
1 /*
2 * Copyright (c) 2014-2016 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: Kevin Lim
41 * Andreas Sandberg
42 * Mitch Hayenga
43 */
44
45 #ifndef __CPU_SIMPLE_EXEC_CONTEXT_HH__
46 #define __CPU_SIMPLE_EXEC_CONTEXT_HH__
47
48 #include "arch/registers.hh"
49 #include "base/types.hh"
50 #include "config/the_isa.hh"
51 #include "cpu/base.hh"
52 #include "cpu/exec_context.hh"
53 #include "cpu/reg_class.hh"
54 #include "cpu/simple/base.hh"
55 #include "cpu/static_inst_fwd.hh"
56 #include "cpu/translation.hh"
57 #include "mem/request.hh"
58
59 class BaseSimpleCPU;
60
61 class SimpleExecContext : public ExecContext {
62 protected:
63 typedef TheISA::MiscReg MiscReg;
64 typedef TheISA::FloatReg FloatReg;
65 typedef TheISA::FloatRegBits FloatRegBits;
66 typedef TheISA::CCReg CCReg;
67 using VecRegContainer = TheISA::VecRegContainer;
68 using VecElem = TheISA::VecElem;
69
70 public:
71 BaseSimpleCPU *cpu;
72 SimpleThread* thread;
73
74 // This is the offset from the current pc that fetch should be performed
75 Addr fetchOffset;
76 // This flag says to stay at the current pc. This is useful for
77 // instructions which go beyond MachInst boundaries.
78 bool stayAtPC;
79
80 // Branch prediction
81 TheISA::PCState predPC;
82
83 /** PER-THREAD STATS */
84
85 // Number of simulated instructions
86 Counter numInst;
87 Stats::Scalar numInsts;
88 Counter numOp;
89 Stats::Scalar numOps;
90
91 // Number of integer alu accesses
92 Stats::Scalar numIntAluAccesses;
93
94 // Number of float alu accesses
95 Stats::Scalar numFpAluAccesses;
96
97 // Number of vector alu accesses
98 Stats::Scalar numVecAluAccesses;
99
100 // Number of function calls/returns
101 Stats::Scalar numCallsReturns;
102
103 // Conditional control instructions;
104 Stats::Scalar numCondCtrlInsts;
105
106 // Number of int instructions
107 Stats::Scalar numIntInsts;
108
109 // Number of float instructions
110 Stats::Scalar numFpInsts;
111
112 // Number of vector instructions
113 Stats::Scalar numVecInsts;
114
115 // Number of integer register file accesses
116 Stats::Scalar numIntRegReads;
117 Stats::Scalar numIntRegWrites;
118
119 // Number of float register file accesses
120 Stats::Scalar numFpRegReads;
121 Stats::Scalar numFpRegWrites;
122
123 // Number of vector register file accesses
124 mutable Stats::Scalar numVecRegReads;
125 Stats::Scalar numVecRegWrites;
126
127 // Number of condition code register file accesses
128 Stats::Scalar numCCRegReads;
129 Stats::Scalar numCCRegWrites;
130
131 // Number of simulated memory references
132 Stats::Scalar numMemRefs;
133 Stats::Scalar numLoadInsts;
134 Stats::Scalar numStoreInsts;
135
136 // Number of idle cycles
137 Stats::Formula numIdleCycles;
138
139 // Number of busy cycles
140 Stats::Formula numBusyCycles;
141
142 // Number of simulated loads
143 Counter numLoad;
144
145 // Number of idle cycles
146 Stats::Average notIdleFraction;
147 Stats::Formula idleFraction;
148
149 // Number of cycles stalled for I-cache responses
150 Stats::Scalar icacheStallCycles;
151 Counter lastIcacheStall;
152
153 // Number of cycles stalled for D-cache responses
154 Stats::Scalar dcacheStallCycles;
155 Counter lastDcacheStall;
156
157 /// @{
158 /// Total number of branches fetched
159 Stats::Scalar numBranches;
160 /// Number of branches predicted as taken
161 Stats::Scalar numPredictedBranches;
162 /// Number of misprediced branches
163 Stats::Scalar numBranchMispred;
164 /// @}
165
166 // Instruction mix histogram by OpClass
167 Stats::Vector statExecutedInstType;
168
169 public:
170 /** Constructor */
171 SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
172 : cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
173 numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
174 { }
175
176 /** Reads an integer register. */
177 IntReg readIntRegOperand(const StaticInst *si, int idx) override
178 {
179 numIntRegReads++;
180 const RegId& reg = si->srcRegIdx(idx);
181 assert(reg.isIntReg());
182 return thread->readIntReg(reg.index());
183 }
184
185 /** Sets an integer register to a value. */
186 void setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
187 {
188 numIntRegWrites++;
189 const RegId& reg = si->destRegIdx(idx);
190 assert(reg.isIntReg());
191 thread->setIntReg(reg.index(), val);
192 }
193
194 /** Reads a floating point register of single register width. */
195 FloatReg readFloatRegOperand(const StaticInst *si, int idx) override
196 {
197 numFpRegReads++;
198 const RegId& reg = si->srcRegIdx(idx);
199 assert(reg.isFloatReg());
200 return thread->readFloatReg(reg.index());
201 }
202
203 /** Reads a floating point register in its binary format, instead
204 * of by value. */
205 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) override
206 {
207 numFpRegReads++;
208 const RegId& reg = si->srcRegIdx(idx);
209 assert(reg.isFloatReg());
210 return thread->readFloatRegBits(reg.index());
211 }
212
213 /** Sets a floating point register of single width to a value. */
214 void setFloatRegOperand(const StaticInst *si, int idx,
215 FloatReg val) override
216 {
217 numFpRegWrites++;
218 const RegId& reg = si->destRegIdx(idx);
219 assert(reg.isFloatReg());
220 thread->setFloatReg(reg.index(), val);
221 }
222
223 /** Sets the bits of a floating point register of single width
224 * to a binary value. */
225 void setFloatRegOperandBits(const StaticInst *si, int idx,
226 FloatRegBits val) override
227 {
228 numFpRegWrites++;
229 const RegId& reg = si->destRegIdx(idx);
230 assert(reg.isFloatReg());
231 thread->setFloatRegBits(reg.index(), val);
232 }
233
234 /** Reads a vector register. */
235 const VecRegContainer&
236 readVecRegOperand(const StaticInst *si, int idx) const override
237 {
238 numVecRegReads++;
239 const RegId& reg = si->srcRegIdx(idx);
240 assert(reg.isVecReg());
241 return thread->readVecReg(reg);
242 }
243
244 /** Reads a vector register for modification. */
245 VecRegContainer&
246 getWritableVecRegOperand(const StaticInst *si, int idx) override
247 {
248 numVecRegWrites++;
249 const RegId& reg = si->destRegIdx(idx);
250 assert(reg.isVecReg());
251 return thread->getWritableVecReg(reg);
252 }
253
254 /** Sets a vector register to a value. */
255 void setVecRegOperand(const StaticInst *si, int idx,
256 const VecRegContainer& val) override
257 {
258 numVecRegWrites++;
259 const RegId& reg = si->destRegIdx(idx);
260 assert(reg.isVecReg());
261 thread->setVecReg(reg, val);
262 }
263
264 /** Vector Register Lane Interfaces. */
265 /** @{ */
266 /** Reads source vector lane. */
267 template <typename VecElem>
268 VecLaneT<VecElem, true>
269 readVecLaneOperand(const StaticInst *si, int idx) const
270 {
271 numVecRegReads++;
272 const RegId& reg = si->srcRegIdx(idx);
273 assert(reg.isVecReg());
274 return thread->readVecLane<VecElem>(reg);
275 }
276 /** Reads source vector 8bit operand. */
277 virtual ConstVecLane8
278 readVec8BitLaneOperand(const StaticInst *si, int idx) const
279 override
280 { return readVecLaneOperand<uint8_t>(si, idx); }
281
282 /** Reads source vector 16bit operand. */
283 virtual ConstVecLane16
284 readVec16BitLaneOperand(const StaticInst *si, int idx) const
285 override
286 { return readVecLaneOperand<uint16_t>(si, idx); }
287
288 /** Reads source vector 32bit operand. */
289 virtual ConstVecLane32
290 readVec32BitLaneOperand(const StaticInst *si, int idx) const
291 override
292 { return readVecLaneOperand<uint32_t>(si, idx); }
293
294 /** Reads source vector 64bit operand. */
295 virtual ConstVecLane64
296 readVec64BitLaneOperand(const StaticInst *si, int idx) const
297 override
298 { return readVecLaneOperand<uint64_t>(si, idx); }
299
300 /** Write a lane of the destination vector operand. */
301 template <typename LD>
302 void
303 setVecLaneOperandT(const StaticInst *si, int idx,
304 const LD& val)
305 {
306 numVecRegWrites++;
307 const RegId& reg = si->destRegIdx(idx);
308 assert(reg.isVecReg());
309 return thread->setVecLane(reg, val);
310 }
311 /** Write a lane of the destination vector operand. */
312 virtual void
313 setVecLaneOperand(const StaticInst *si, int idx,
314 const LaneData<LaneSize::Byte>& val) override
315 { return setVecLaneOperandT(si, idx, val); }
316 /** Write a lane of the destination vector operand. */
317 virtual void
318 setVecLaneOperand(const StaticInst *si, int idx,
319 const LaneData<LaneSize::TwoByte>& val) override
320 { return setVecLaneOperandT(si, idx, val); }
321 /** Write a lane of the destination vector operand. */
322 virtual void
323 setVecLaneOperand(const StaticInst *si, int idx,
324 const LaneData<LaneSize::FourByte>& val) override
325 { return setVecLaneOperandT(si, idx, val); }
326 /** Write a lane of the destination vector operand. */
327 virtual void
328 setVecLaneOperand(const StaticInst *si, int idx,
329 const LaneData<LaneSize::EightByte>& val) override
330 { return setVecLaneOperandT(si, idx, val); }
331 /** @} */
332
333 /** Reads an element of a vector register. */
334 VecElem readVecElemOperand(const StaticInst *si, int idx) const override
335 {
336 numVecRegReads++;
337 const RegId& reg = si->destRegIdx(idx);
338 assert(reg.isVecElem());
339 return thread->readVecElem(reg);
340 }
341
342 /** Sets an element of a vector register to a value. */
343 void setVecElemOperand(const StaticInst *si, int idx,
344 const VecElem val) override
345 {
346 numVecRegWrites++;
347 const RegId& reg = si->destRegIdx(idx);
348 assert(reg.isVecElem());
349 thread->setVecElem(reg, val);
350 }
351
352 CCReg readCCRegOperand(const StaticInst *si, int idx) override
353 {
354 numCCRegReads++;
355 const RegId& reg = si->srcRegIdx(idx);
356 assert(reg.isCCReg());
357 return thread->readCCReg(reg.index());
358 }
359
360 void setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
361 {
362 numCCRegWrites++;
363 const RegId& reg = si->destRegIdx(idx);
364 assert(reg.isCCReg());
365 thread->setCCReg(reg.index(), val);
366 }
367
368 MiscReg readMiscRegOperand(const StaticInst *si, int idx) override
369 {
370 numIntRegReads++;
371 const RegId& reg = si->srcRegIdx(idx);
372 assert(reg.isMiscReg());
373 return thread->readMiscReg(reg.index());
374 }
375
376 void setMiscRegOperand(const StaticInst *si, int idx,
377 const MiscReg &val) override
378 {
379 numIntRegWrites++;
380 const RegId& reg = si->destRegIdx(idx);
381 assert(reg.isMiscReg());
382 thread->setMiscReg(reg.index(), val);
383 }
384
385 /**
386 * Reads a miscellaneous register, handling any architectural
387 * side effects due to reading that register.
388 */
389 MiscReg readMiscReg(int misc_reg) override
390 {
391 numIntRegReads++;
392 return thread->readMiscReg(misc_reg);
393 }
394
395 /**
396 * Sets a miscellaneous register, handling any architectural
397 * side effects due to writing that register.
398 */
399 void setMiscReg(int misc_reg, const MiscReg &val) override
400 {
401 numIntRegWrites++;
402 thread->setMiscReg(misc_reg, val);
403 }
404
405 PCState pcState() const override
406 {
407 return thread->pcState();
408 }
409
410 void pcState(const PCState &val) override
411 {
412 thread->pcState(val);
413 }
414
415
416 /**
417 * Record the effective address of the instruction.
418 *
419 * @note Only valid for memory ops.
420 */
421 void setEA(Addr EA) override
422 { panic("BaseSimpleCPU::setEA() not implemented\n"); }
423
424 /**
425 * Get the effective address of the instruction.
426 *
427 * @note Only valid for memory ops.
428 */
429 Addr getEA() const override
430 { panic("BaseSimpleCPU::getEA() not implemented\n"); }
431
432 Fault readMem(Addr addr, uint8_t *data, unsigned int size,
433 Request::Flags flags) override
434 {
435 return cpu->readMem(addr, data, size, flags);
436 }
437
438 Fault initiateMemRead(Addr addr, unsigned int size,
439 Request::Flags flags) override
440 {
441 return cpu->initiateMemRead(addr, size, flags);
442 }
443
444 Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
445 Request::Flags flags, uint64_t *res) override
446 {
447 return cpu->writeMem(data, size, addr, flags, res);
448 }
449
450 /**
451 * Sets the number of consecutive store conditional failures.
452 */
453 void setStCondFailures(unsigned int sc_failures) override
454 {
455 thread->setStCondFailures(sc_failures);
456 }
457
458 /**
459 * Returns the number of consecutive store conditional failures.
460 */
461 unsigned int readStCondFailures() const override
462 {
463 return thread->readStCondFailures();
464 }
465
466 /**
467 * Executes a syscall specified by the callnum.
468 */
469 void syscall(int64_t callnum, Fault *fault) override
470 {
471 if (FullSystem)
472 panic("Syscall emulation isn't available in FS mode.");
473
474 thread->syscall(callnum, fault);
475 }
476
477 /** Returns a pointer to the ThreadContext. */
478 ThreadContext *tcBase() override
479 {
480 return thread->getTC();
481 }
482
483 /**
484 * Somewhat Alpha-specific function that handles returning from an
485 * error or interrupt.
486 */
487 Fault hwrei() override
488 {
489 return thread->hwrei();
490 }
491
492 /**
493 * Check for special simulator handling of specific PAL calls. If
494 * return value is false, actual PAL call will be suppressed.
495 */
496 bool simPalCheck(int palFunc) override
497 {
498 return thread->simPalCheck(palFunc);
499 }
500
501 bool readPredicate() override
502 {
503 return thread->readPredicate();
504 }
505
506 void setPredicate(bool val) override
507 {
508 thread->setPredicate(val);
509
510 if (cpu->traceData) {
511 cpu->traceData->setPredicate(val);
512 }
513 }
514
515 /**
516 * Invalidate a page in the DTLB <i>and</i> ITLB.
517 */
518 void demapPage(Addr vaddr, uint64_t asn) override
519 {
520 thread->demapPage(vaddr, asn);
521 }
522
523 void armMonitor(Addr address) override
524 {
525 cpu->armMonitor(thread->threadId(), address);
526 }
527
528 bool mwait(PacketPtr pkt) override
529 {
530 return cpu->mwait(thread->threadId(), pkt);
531 }
532
533 void mwaitAtomic(ThreadContext *tc) override
534 {
535 cpu->mwaitAtomic(thread->threadId(), tc, thread->dtb);
536 }
537
538 AddressMonitor *getAddrMonitor() override
539 {
540 return cpu->getCpuAddrMonitor(thread->threadId());
541 }
542
543 #if THE_ISA == MIPS_ISA
544 MiscReg readRegOtherThread(const RegId& reg,
545 ThreadID tid = InvalidThreadID)
546 override
547 {
548 panic("Simple CPU models do not support multithreaded "
549 "register access.");
550 }
551
552 void setRegOtherThread(const RegId& reg, MiscReg val,
553 ThreadID tid = InvalidThreadID) override
554 {
555 panic("Simple CPU models do not support multithreaded "
556 "register access.");
557 }
558
559 #endif
560
561 };
562
563 #endif // __CPU_EXEC_CONTEXT_HH__