fastmodel,cpu,sim: Eliminate EndQuiesceEvent and plumbing.
[gem5.git] / src / cpu / simple_thread.hh
1 /*
2 * Copyright (c) 2011-2012, 2016-2018 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) 2001-2006 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
42 #ifndef __CPU_SIMPLE_THREAD_HH__
43 #define __CPU_SIMPLE_THREAD_HH__
44
45 #include <array>
46
47 #include "arch/decoder.hh"
48 #include "arch/generic/tlb.hh"
49 #include "arch/isa.hh"
50 #include "arch/isa_traits.hh"
51 #include "arch/registers.hh"
52 #include "arch/types.hh"
53 #include "base/types.hh"
54 #include "config/the_isa.hh"
55 #include "cpu/thread_context.hh"
56 #include "cpu/thread_state.hh"
57 #include "debug/CCRegs.hh"
58 #include "debug/FloatRegs.hh"
59 #include "debug/IntRegs.hh"
60 #include "debug/VecPredRegs.hh"
61 #include "debug/VecRegs.hh"
62 #include "mem/page_table.hh"
63 #include "mem/request.hh"
64 #include "sim/byteswap.hh"
65 #include "sim/eventq.hh"
66 #include "sim/full_system.hh"
67 #include "sim/process.hh"
68 #include "sim/serialize.hh"
69 #include "sim/system.hh"
70
71 class BaseCPU;
72 class CheckerCPU;
73
74 class FunctionProfile;
75 class ProfileNode;
76
77 /**
78 * The SimpleThread object provides a combination of the ThreadState
79 * object and the ThreadContext interface. It implements the
80 * ThreadContext interface and adds to the ThreadState object by adding all
81 * the objects needed for simple functional execution, including a
82 * simple architectural register file, and pointers to the ITB and DTB
83 * in full system mode. For CPU models that do not need more advanced
84 * ways to hold state (i.e. a separate physical register file, or
85 * separate fetch and commit PC's), this SimpleThread class provides
86 * all the necessary state for full architecture-level functional
87 * simulation. See the AtomicSimpleCPU or TimingSimpleCPU for
88 * examples.
89 */
90
91 class SimpleThread : public ThreadState, public ThreadContext
92 {
93 protected:
94 typedef TheISA::MachInst MachInst;
95 using VecRegContainer = TheISA::VecRegContainer;
96 using VecElem = TheISA::VecElem;
97 using VecPredRegContainer = TheISA::VecPredRegContainer;
98 public:
99 typedef ThreadContext::Status Status;
100
101 protected:
102 std::array<RegVal, TheISA::NumFloatRegs> floatRegs;
103 std::array<RegVal, TheISA::NumIntRegs> intRegs;
104 std::array<VecRegContainer, TheISA::NumVecRegs> vecRegs;
105 std::array<VecPredRegContainer, TheISA::NumVecPredRegs> vecPredRegs;
106 std::array<RegVal, TheISA::NumCCRegs> ccRegs;
107 TheISA::ISA *const isa; // one "instance" of the current ISA.
108
109 TheISA::PCState _pcState;
110
111 /** Did this instruction execute or is it predicated false */
112 bool predicate;
113
114 /** True if the memory access should be skipped for this instruction */
115 bool memAccPredicate;
116
117 public:
118 std::string name() const
119 {
120 return csprintf("%s.[tid:%i]", baseCpu->name(), threadId());
121 }
122
123 PCEventQueue pcEventQueue;
124 /**
125 * An instruction-based event queue. Used for scheduling events based on
126 * number of instructions committed.
127 */
128 EventQueue comInstEventQueue;
129
130 System *system;
131
132 BaseTLB *itb;
133 BaseTLB *dtb;
134
135 TheISA::Decoder decoder;
136
137 // constructor: initialize SimpleThread from given process structure
138 // FS
139 SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
140 BaseTLB *_itb, BaseTLB *_dtb, BaseISA *_isa);
141 // SE
142 SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
143 Process *_process, BaseTLB *_itb, BaseTLB *_dtb,
144 BaseISA *_isa);
145
146 virtual ~SimpleThread() {}
147
148 void takeOverFrom(ThreadContext *oldContext) override;
149
150 void copyState(ThreadContext *oldContext);
151
152 void serialize(CheckpointOut &cp) const override;
153 void unserialize(CheckpointIn &cp) override;
154
155 /***************************************************************
156 * SimpleThread functions to provide CPU with access to various
157 * state.
158 **************************************************************/
159
160 /** Returns the pointer to this SimpleThread's ThreadContext. Used
161 * when a ThreadContext must be passed to objects outside of the
162 * CPU.
163 */
164 ThreadContext *getTC() { return this; }
165
166 void demapPage(Addr vaddr, uint64_t asn)
167 {
168 itb->demapPage(vaddr, asn);
169 dtb->demapPage(vaddr, asn);
170 }
171
172 void demapInstPage(Addr vaddr, uint64_t asn)
173 {
174 itb->demapPage(vaddr, asn);
175 }
176
177 void demapDataPage(Addr vaddr, uint64_t asn)
178 {
179 dtb->demapPage(vaddr, asn);
180 }
181
182 void dumpFuncProfile() override;
183
184 /*******************************************
185 * ThreadContext interface functions.
186 ******************************************/
187
188 bool schedule(PCEvent *e) override { return pcEventQueue.schedule(e); }
189 bool remove(PCEvent *e) override { return pcEventQueue.remove(e); }
190
191 void
192 scheduleInstCountEvent(Event *event, Tick count) override
193 {
194 comInstEventQueue.schedule(event, count);
195 }
196 void
197 descheduleInstCountEvent(Event *event) override
198 {
199 comInstEventQueue.deschedule(event);
200 }
201 Tick
202 getCurrentInstCount() override
203 {
204 return comInstEventQueue.getCurTick();
205 }
206
207 BaseCPU *getCpuPtr() override { return baseCpu; }
208
209 int cpuId() const override { return ThreadState::cpuId(); }
210 uint32_t socketId() const override { return ThreadState::socketId(); }
211 int threadId() const override { return ThreadState::threadId(); }
212 void setThreadId(int id) override { ThreadState::setThreadId(id); }
213 ContextID contextId() const override { return ThreadState::contextId(); }
214 void setContextId(ContextID id) override { ThreadState::setContextId(id); }
215
216 BaseTLB *getITBPtr() override { return itb; }
217
218 BaseTLB *getDTBPtr() override { return dtb; }
219
220 CheckerCPU *getCheckerCpuPtr() override { return NULL; }
221
222 BaseISA *getIsaPtr() override { return isa; }
223
224 TheISA::Decoder *getDecoderPtr() override { return &decoder; }
225
226 System *getSystemPtr() override { return system; }
227
228 PortProxy &getPhysProxy() override { return ThreadState::getPhysProxy(); }
229 PortProxy &getVirtProxy() override { return ThreadState::getVirtProxy(); }
230
231 void initMemProxies(ThreadContext *tc) override
232 {
233 ThreadState::initMemProxies(tc);
234 }
235
236 Process *getProcessPtr() override { return ThreadState::getProcessPtr(); }
237 void setProcessPtr(Process *p) override { ThreadState::setProcessPtr(p); }
238
239 Status status() const override { return _status; }
240
241 void setStatus(Status newStatus) override { _status = newStatus; }
242
243 /// Set the status to Active.
244 void activate() override;
245
246 /// Set the status to Suspended.
247 void suspend() override;
248
249 /// Set the status to Halted.
250 void halt() override;
251
252 Tick
253 readLastActivate() override
254 {
255 return ThreadState::readLastActivate();
256 }
257 Tick
258 readLastSuspend() override
259 {
260 return ThreadState::readLastSuspend();
261 }
262
263 void profileClear() override { ThreadState::profileClear(); }
264 void profileSample() override { ThreadState::profileSample(); }
265
266 void copyArchRegs(ThreadContext *tc) override;
267
268 void
269 clearArchRegs() override
270 {
271 _pcState = 0;
272 intRegs.fill(0);
273 floatRegs.fill(0);
274 for (auto &vec_reg: vecRegs)
275 vec_reg.zero();
276 for (auto &pred_reg: vecPredRegs)
277 pred_reg.reset();
278 ccRegs.fill(0);
279 isa->clear();
280 }
281
282 //
283 // New accessors for new decoder.
284 //
285 RegVal
286 readIntReg(RegIndex reg_idx) const override
287 {
288 int flatIndex = isa->flattenIntIndex(reg_idx);
289 assert(flatIndex < TheISA::NumIntRegs);
290 uint64_t regVal(readIntRegFlat(flatIndex));
291 DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
292 reg_idx, flatIndex, regVal);
293 return regVal;
294 }
295
296 RegVal
297 readFloatReg(RegIndex reg_idx) const override
298 {
299 int flatIndex = isa->flattenFloatIndex(reg_idx);
300 assert(flatIndex < TheISA::NumFloatRegs);
301 RegVal regVal(readFloatRegFlat(flatIndex));
302 DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x.\n",
303 reg_idx, flatIndex, regVal);
304 return regVal;
305 }
306
307 const VecRegContainer&
308 readVecReg(const RegId& reg) const override
309 {
310 int flatIndex = isa->flattenVecIndex(reg.index());
311 assert(flatIndex < TheISA::NumVecRegs);
312 const VecRegContainer& regVal = readVecRegFlat(flatIndex);
313 DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s.\n",
314 reg.index(), flatIndex, regVal.print());
315 return regVal;
316 }
317
318 VecRegContainer&
319 getWritableVecReg(const RegId& reg) override
320 {
321 int flatIndex = isa->flattenVecIndex(reg.index());
322 assert(flatIndex < TheISA::NumVecRegs);
323 VecRegContainer& regVal = getWritableVecRegFlat(flatIndex);
324 DPRINTF(VecRegs, "Reading vector reg %d (%d) as %s for modify.\n",
325 reg.index(), flatIndex, regVal.print());
326 return regVal;
327 }
328
329 /** Vector Register Lane Interfaces. */
330 /** @{ */
331 /** Reads source vector <T> operand. */
332 template <typename T>
333 VecLaneT<T, true>
334 readVecLane(const RegId& reg) const
335 {
336 int flatIndex = isa->flattenVecIndex(reg.index());
337 assert(flatIndex < TheISA::NumVecRegs);
338 auto regVal = readVecLaneFlat<T>(flatIndex, reg.elemIndex());
339 DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] as %lx.\n",
340 reg.index(), flatIndex, reg.elemIndex(), regVal);
341 return regVal;
342 }
343
344 /** Reads source vector 8bit operand. */
345 virtual ConstVecLane8
346 readVec8BitLaneReg(const RegId &reg) const override
347 {
348 return readVecLane<uint8_t>(reg);
349 }
350
351 /** Reads source vector 16bit operand. */
352 virtual ConstVecLane16
353 readVec16BitLaneReg(const RegId &reg) const override
354 {
355 return readVecLane<uint16_t>(reg);
356 }
357
358 /** Reads source vector 32bit operand. */
359 virtual ConstVecLane32
360 readVec32BitLaneReg(const RegId &reg) const override
361 {
362 return readVecLane<uint32_t>(reg);
363 }
364
365 /** Reads source vector 64bit operand. */
366 virtual ConstVecLane64
367 readVec64BitLaneReg(const RegId &reg) const override
368 {
369 return readVecLane<uint64_t>(reg);
370 }
371
372 /** Write a lane of the destination vector register. */
373 template <typename LD>
374 void
375 setVecLaneT(const RegId &reg, const LD &val)
376 {
377 int flatIndex = isa->flattenVecIndex(reg.index());
378 assert(flatIndex < TheISA::NumVecRegs);
379 setVecLaneFlat(flatIndex, reg.elemIndex(), val);
380 DPRINTF(VecRegs, "Reading vector lane %d (%d)[%d] to %lx.\n",
381 reg.index(), flatIndex, reg.elemIndex(), val);
382 }
383 virtual void
384 setVecLane(const RegId &reg, const LaneData<LaneSize::Byte> &val) override
385 {
386 return setVecLaneT(reg, val);
387 }
388 virtual void
389 setVecLane(const RegId &reg,
390 const LaneData<LaneSize::TwoByte> &val) override
391 {
392 return setVecLaneT(reg, val);
393 }
394 virtual void
395 setVecLane(const RegId &reg,
396 const LaneData<LaneSize::FourByte> &val) override
397 {
398 return setVecLaneT(reg, val);
399 }
400 virtual void
401 setVecLane(const RegId &reg,
402 const LaneData<LaneSize::EightByte> &val) override
403 {
404 return setVecLaneT(reg, val);
405 }
406 /** @} */
407
408 const VecElem &
409 readVecElem(const RegId &reg) const override
410 {
411 int flatIndex = isa->flattenVecElemIndex(reg.index());
412 assert(flatIndex < TheISA::NumVecRegs);
413 const VecElem& regVal = readVecElemFlat(flatIndex, reg.elemIndex());
414 DPRINTF(VecRegs, "Reading element %d of vector reg %d (%d) as"
415 " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, regVal);
416 return regVal;
417 }
418
419 const VecPredRegContainer &
420 readVecPredReg(const RegId &reg) const override
421 {
422 int flatIndex = isa->flattenVecPredIndex(reg.index());
423 assert(flatIndex < TheISA::NumVecPredRegs);
424 const VecPredRegContainer& regVal = readVecPredRegFlat(flatIndex);
425 DPRINTF(VecPredRegs, "Reading predicate reg %d (%d) as %s.\n",
426 reg.index(), flatIndex, regVal.print());
427 return regVal;
428 }
429
430 VecPredRegContainer &
431 getWritableVecPredReg(const RegId &reg) override
432 {
433 int flatIndex = isa->flattenVecPredIndex(reg.index());
434 assert(flatIndex < TheISA::NumVecPredRegs);
435 VecPredRegContainer& regVal = getWritableVecPredRegFlat(flatIndex);
436 DPRINTF(VecPredRegs,
437 "Reading predicate reg %d (%d) as %s for modify.\n",
438 reg.index(), flatIndex, regVal.print());
439 return regVal;
440 }
441
442 RegVal
443 readCCReg(RegIndex reg_idx) const override
444 {
445 int flatIndex = isa->flattenCCIndex(reg_idx);
446 assert(0 <= flatIndex);
447 assert(flatIndex < TheISA::NumCCRegs);
448 uint64_t regVal(readCCRegFlat(flatIndex));
449 DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n",
450 reg_idx, flatIndex, regVal);
451 return regVal;
452 }
453
454 void
455 setIntReg(RegIndex reg_idx, RegVal val) override
456 {
457 int flatIndex = isa->flattenIntIndex(reg_idx);
458 assert(flatIndex < TheISA::NumIntRegs);
459 DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n",
460 reg_idx, flatIndex, val);
461 setIntRegFlat(flatIndex, val);
462 }
463
464 void
465 setFloatReg(RegIndex reg_idx, RegVal val) override
466 {
467 int flatIndex = isa->flattenFloatIndex(reg_idx);
468 assert(flatIndex < TheISA::NumFloatRegs);
469 // XXX: Fix array out of bounds compiler error for gem5.fast
470 // when checkercpu enabled
471 if (flatIndex < TheISA::NumFloatRegs)
472 setFloatRegFlat(flatIndex, val);
473 DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x.\n",
474 reg_idx, flatIndex, val);
475 }
476
477 void
478 setVecReg(const RegId &reg, const VecRegContainer &val) override
479 {
480 int flatIndex = isa->flattenVecIndex(reg.index());
481 assert(flatIndex < TheISA::NumVecRegs);
482 setVecRegFlat(flatIndex, val);
483 DPRINTF(VecRegs, "Setting vector reg %d (%d) to %s.\n",
484 reg.index(), flatIndex, val.print());
485 }
486
487 void
488 setVecElem(const RegId &reg, const VecElem &val) override
489 {
490 int flatIndex = isa->flattenVecElemIndex(reg.index());
491 assert(flatIndex < TheISA::NumVecRegs);
492 setVecElemFlat(flatIndex, reg.elemIndex(), val);
493 DPRINTF(VecRegs, "Setting element %d of vector reg %d (%d) to"
494 " %#x.\n", reg.elemIndex(), reg.index(), flatIndex, val);
495 }
496
497 void
498 setVecPredReg(const RegId &reg, const VecPredRegContainer &val) override
499 {
500 int flatIndex = isa->flattenVecPredIndex(reg.index());
501 assert(flatIndex < TheISA::NumVecPredRegs);
502 setVecPredRegFlat(flatIndex, val);
503 DPRINTF(VecPredRegs, "Setting predicate reg %d (%d) to %s.\n",
504 reg.index(), flatIndex, val.print());
505 }
506
507 void
508 setCCReg(RegIndex reg_idx, RegVal val) override
509 {
510 int flatIndex = isa->flattenCCIndex(reg_idx);
511 assert(flatIndex < TheISA::NumCCRegs);
512 DPRINTF(CCRegs, "Setting CC reg %d (%d) to %#x.\n",
513 reg_idx, flatIndex, val);
514 setCCRegFlat(flatIndex, val);
515 }
516
517 TheISA::PCState pcState() const override { return _pcState; }
518 void pcState(const TheISA::PCState &val) override { _pcState = val; }
519
520 void
521 pcStateNoRecord(const TheISA::PCState &val) override
522 {
523 _pcState = val;
524 }
525
526 Addr instAddr() const override { return _pcState.instAddr(); }
527 Addr nextInstAddr() const override { return _pcState.nextInstAddr(); }
528 MicroPC microPC() const override { return _pcState.microPC(); }
529 bool readPredicate() const { return predicate; }
530 void setPredicate(bool val) { predicate = val; }
531
532 RegVal
533 readMiscRegNoEffect(RegIndex misc_reg) const override
534 {
535 return isa->readMiscRegNoEffect(misc_reg);
536 }
537
538 RegVal
539 readMiscReg(RegIndex misc_reg) override
540 {
541 return isa->readMiscReg(misc_reg);
542 }
543
544 void
545 setMiscRegNoEffect(RegIndex misc_reg, RegVal val) override
546 {
547 return isa->setMiscRegNoEffect(misc_reg, val);
548 }
549
550 void
551 setMiscReg(RegIndex misc_reg, RegVal val) override
552 {
553 return isa->setMiscReg(misc_reg, val);
554 }
555
556 RegId
557 flattenRegId(const RegId& regId) const override
558 {
559 return isa->flattenRegId(regId);
560 }
561
562 unsigned readStCondFailures() const override { return storeCondFailures; }
563
564 bool
565 readMemAccPredicate()
566 {
567 return memAccPredicate;
568 }
569
570 void
571 setMemAccPredicate(bool val)
572 {
573 memAccPredicate = val;
574 }
575
576 void
577 setStCondFailures(unsigned sc_failures) override
578 {
579 storeCondFailures = sc_failures;
580 }
581
582 Counter
583 readFuncExeInst() const override
584 {
585 return ThreadState::readFuncExeInst();
586 }
587
588 void
589 syscall(Fault *fault) override
590 {
591 process->syscall(this, fault);
592 }
593
594 RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; }
595 void
596 setIntRegFlat(RegIndex idx, RegVal val) override
597 {
598 intRegs[idx] = val;
599 }
600
601 RegVal
602 readFloatRegFlat(RegIndex idx) const override
603 {
604 return floatRegs[idx];
605 }
606 void
607 setFloatRegFlat(RegIndex idx, RegVal val) override
608 {
609 floatRegs[idx] = val;
610 }
611
612 const VecRegContainer &
613 readVecRegFlat(RegIndex reg) const override
614 {
615 return vecRegs[reg];
616 }
617
618 VecRegContainer &
619 getWritableVecRegFlat(RegIndex reg) override
620 {
621 return vecRegs[reg];
622 }
623
624 void
625 setVecRegFlat(RegIndex reg, const VecRegContainer &val) override
626 {
627 vecRegs[reg] = val;
628 }
629
630 template <typename T>
631 VecLaneT<T, true>
632 readVecLaneFlat(RegIndex reg, int lId) const
633 {
634 return vecRegs[reg].laneView<T>(lId);
635 }
636
637 template <typename LD>
638 void
639 setVecLaneFlat(RegIndex reg, int lId, const LD &val)
640 {
641 vecRegs[reg].laneView<typename LD::UnderlyingType>(lId) = val;
642 }
643
644 const VecElem &
645 readVecElemFlat(RegIndex reg, const ElemIndex &elemIndex) const override
646 {
647 return vecRegs[reg].as<TheISA::VecElem>()[elemIndex];
648 }
649
650 void
651 setVecElemFlat(RegIndex reg, const ElemIndex &elemIndex,
652 const VecElem &val) override
653 {
654 vecRegs[reg].as<TheISA::VecElem>()[elemIndex] = val;
655 }
656
657 const VecPredRegContainer &
658 readVecPredRegFlat(RegIndex reg) const override
659 {
660 return vecPredRegs[reg];
661 }
662
663 VecPredRegContainer &
664 getWritableVecPredRegFlat(RegIndex reg) override
665 {
666 return vecPredRegs[reg];
667 }
668
669 void
670 setVecPredRegFlat(RegIndex reg, const VecPredRegContainer &val) override
671 {
672 vecPredRegs[reg] = val;
673 }
674
675 RegVal readCCRegFlat(RegIndex idx) const override { return ccRegs[idx]; }
676 void setCCRegFlat(RegIndex idx, RegVal val) override { ccRegs[idx] = val; }
677 };
678
679
680 #endif // __CPU_CPU_EXEC_CONTEXT_HH__