gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cpu.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2012, 2014 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) 2004-2006 The Regents of The University of Michigan
16  * Copyright (c) 2011 Regents of the University of California
17  * All rights reserved.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions are
21  * met: redistributions of source code must retain the above copyright
22  * notice, this list of conditions and the following disclaimer;
23  * redistributions in binary form must reproduce the above copyright
24  * notice, this list of conditions and the following disclaimer in the
25  * documentation and/or other materials provided with the distribution;
26  * neither the name of the copyright holders nor the names of its
27  * contributors may be used to endorse or promote products derived from
28  * this software without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  *
42  * Authors: Kevin Lim
43  * Korey Sewell
44  * Rick Strong
45  */
46 
47 #include "cpu/o3/cpu.hh"
48 
49 #include "arch/kernel_stats.hh"
50 #include "config/the_isa.hh"
51 #include "cpu/activity.hh"
52 #include "cpu/checker/cpu.hh"
54 #include "cpu/o3/isa_specific.hh"
55 #include "cpu/o3/thread_context.hh"
56 #include "cpu/quiesce_event.hh"
57 #include "cpu/simple_thread.hh"
58 #include "cpu/thread_context.hh"
59 #include "debug/Activity.hh"
60 #include "debug/Drain.hh"
61 #include "debug/O3CPU.hh"
62 #include "debug/Quiesce.hh"
63 #include "enums/MemoryMode.hh"
64 #include "sim/core.hh"
65 #include "sim/full_system.hh"
66 #include "sim/process.hh"
67 #include "sim/stat_control.hh"
68 #include "sim/system.hh"
69 
70 #if THE_ISA == ALPHA_ISA
71 #include "arch/alpha/osfpal.hh"
72 #include "debug/Activity.hh"
73 
74 #endif
75 
76 struct BaseCPUParams;
77 
78 using namespace TheISA;
79 using namespace std;
80 
81 BaseO3CPU::BaseO3CPU(BaseCPUParams *params)
82  : BaseCPU(params)
83 {
84 }
85 
86 void
88 {
89  BaseCPU::regStats();
90 }
91 
92 template<class Impl>
93 bool
95 {
96  DPRINTF(O3CPU, "Fetch unit received timing\n");
97  // We shouldn't ever get a cacheable block in Modified state
98  assert(pkt->req->isUncacheable() ||
99  !(pkt->cacheResponding() && !pkt->hasSharers()));
100  fetch->processCacheCompletion(pkt);
101 
102  return true;
103 }
104 
105 template<class Impl>
106 void
108 {
109  fetch->recvReqRetry();
110 }
111 
112 template <class Impl>
113 bool
115 {
116  return lsq->recvTimingResp(pkt);
117 }
118 
119 template <class Impl>
120 void
122 {
123  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
124  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
125  cpu->wakeup(tid);
126  }
127  }
128  lsq->recvTimingSnoopReq(pkt);
129 }
130 
131 template <class Impl>
132 void
134 {
135  lsq->recvReqRetry();
136 }
137 
138 template <class Impl>
140  : Event(CPU_Tick_Pri), cpu(c)
141 {
142 }
143 
144 template <class Impl>
145 void
147 {
148  cpu->tick();
149 }
150 
151 template <class Impl>
152 const char *
154 {
155  return "FullO3CPU tick";
156 }
157 
158 template <class Impl>
159 FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
160  : BaseO3CPU(params),
161  itb(params->itb),
162  dtb(params->dtb),
163  tickEvent(this),
164 #ifndef NDEBUG
165  instcount(0),
166 #endif
167  removeInstsThisCycle(false),
168  fetch(this, params),
169  decode(this, params),
170  rename(this, params),
171  iew(this, params),
172  commit(this, params),
173 
174  regFile(params->numPhysIntRegs,
175  params->numPhysFloatRegs,
176  params->numPhysCCRegs),
177 
178  freeList(name() + ".freelist", &regFile),
179 
180  rob(this, params),
181 
182  scoreboard(name() + ".scoreboard",
183  regFile.totalNumPhysRegs(), TheISA::NumMiscRegs,
184  TheISA::ZeroReg, TheISA::ZeroReg),
185 
186  isa(numThreads, NULL),
187 
188  icachePort(&fetch, this),
189  dcachePort(&iew.ldstQueue, this),
190 
191  timeBuffer(params->backComSize, params->forwardComSize),
192  fetchQueue(params->backComSize, params->forwardComSize),
193  decodeQueue(params->backComSize, params->forwardComSize),
194  renameQueue(params->backComSize, params->forwardComSize),
195  iewQueue(params->backComSize, params->forwardComSize),
197  params->backComSize + params->forwardComSize,
198  params->activity),
199 
200  globalSeqNum(1),
201  system(params->system),
202  lastRunningCycle(curCycle())
203 {
204  if (!params->switched_out) {
205  _status = Running;
206  } else {
208  }
209 
210  if (params->checker) {
211  BaseCPU *temp_checker = params->checker;
212  checker = dynamic_cast<Checker<Impl> *>(temp_checker);
213  checker->setIcachePort(&icachePort);
214  checker->setSystem(params->system);
215  } else {
216  checker = NULL;
217  }
218 
219  if (!FullSystem) {
220  thread.resize(numThreads);
221  tids.resize(numThreads);
222  }
223 
224  // The stages also need their CPU pointer setup. However this
225  // must be done at the upper level CPU because they have pointers
226  // to the upper level CPU, and not this FullO3CPU.
227 
228  // Set up Pointers to the activeThreads list for each stage
229  fetch.setActiveThreads(&activeThreads);
230  decode.setActiveThreads(&activeThreads);
231  rename.setActiveThreads(&activeThreads);
232  iew.setActiveThreads(&activeThreads);
233  commit.setActiveThreads(&activeThreads);
234 
235  // Give each of the stages the time buffer they will use.
236  fetch.setTimeBuffer(&timeBuffer);
237  decode.setTimeBuffer(&timeBuffer);
238  rename.setTimeBuffer(&timeBuffer);
239  iew.setTimeBuffer(&timeBuffer);
240  commit.setTimeBuffer(&timeBuffer);
241 
242  // Also setup each of the stages' queues.
243  fetch.setFetchQueue(&fetchQueue);
244  decode.setFetchQueue(&fetchQueue);
245  commit.setFetchQueue(&fetchQueue);
246  decode.setDecodeQueue(&decodeQueue);
247  rename.setDecodeQueue(&decodeQueue);
248  rename.setRenameQueue(&renameQueue);
249  iew.setRenameQueue(&renameQueue);
250  iew.setIEWQueue(&iewQueue);
251  commit.setIEWQueue(&iewQueue);
252  commit.setRenameQueue(&renameQueue);
253 
254  commit.setIEWStage(&iew);
255  rename.setIEWStage(&iew);
256  rename.setCommitStage(&commit);
257 
258  ThreadID active_threads;
259  if (FullSystem) {
260  active_threads = 1;
261  } else {
262  active_threads = params->workload.size();
263 
264  if (active_threads > Impl::MaxThreads) {
265  panic("Workload Size too large. Increase the 'MaxThreads' "
266  "constant in your O3CPU impl. file (e.g. o3/alpha/impl.hh) "
267  "or edit your workload size.");
268  }
269  }
270 
271  //Make Sure That this a Valid Architeture
272  assert(params->numPhysIntRegs >= numThreads * TheISA::NumIntRegs);
273  assert(params->numPhysFloatRegs >= numThreads * TheISA::NumFloatRegs);
274  assert(params->numPhysCCRegs >= numThreads * TheISA::NumCCRegs);
275 
276  rename.setScoreboard(&scoreboard);
277  iew.setScoreboard(&scoreboard);
278 
279  // Setup the rename map for whichever stages need it.
280  for (ThreadID tid = 0; tid < numThreads; tid++) {
281  isa[tid] = params->isa[tid];
282 
283  // Only Alpha has an FP zero register, so for other ISAs we
284  // use an invalid FP register index to avoid special treatment
285  // of any valid FP reg.
286  RegIndex invalidFPReg = TheISA::NumFloatRegs + 1;
287  RegIndex fpZeroReg =
288  (THE_ISA == ALPHA_ISA) ? TheISA::ZeroReg : invalidFPReg;
289 
290  commitRenameMap[tid].init(&regFile, TheISA::ZeroReg, fpZeroReg,
291  &freeList);
292 
293  renameMap[tid].init(&regFile, TheISA::ZeroReg, fpZeroReg,
294  &freeList);
295  }
296 
297  // Initialize rename map to assign physical registers to the
298  // architectural registers for active threads only.
299  for (ThreadID tid = 0; tid < active_threads; tid++) {
300  for (RegIndex ridx = 0; ridx < TheISA::NumIntRegs; ++ridx) {
301  // Note that we can't use the rename() method because we don't
302  // want special treatment for the zero register at this point
303  PhysRegIndex phys_reg = freeList.getIntReg();
304  renameMap[tid].setIntEntry(ridx, phys_reg);
305  commitRenameMap[tid].setIntEntry(ridx, phys_reg);
306  }
307 
308  for (RegIndex ridx = 0; ridx < TheISA::NumFloatRegs; ++ridx) {
309  PhysRegIndex phys_reg = freeList.getFloatReg();
310  renameMap[tid].setFloatEntry(ridx, phys_reg);
311  commitRenameMap[tid].setFloatEntry(ridx, phys_reg);
312  }
313 
314  for (RegIndex ridx = 0; ridx < TheISA::NumCCRegs; ++ridx) {
315  PhysRegIndex phys_reg = freeList.getCCReg();
316  renameMap[tid].setCCEntry(ridx, phys_reg);
317  commitRenameMap[tid].setCCEntry(ridx, phys_reg);
318  }
319  }
320 
321  rename.setRenameMap(renameMap);
322  commit.setRenameMap(commitRenameMap);
323  rename.setFreeList(&freeList);
324 
325  // Setup the ROB for whichever stages need it.
326  commit.setROB(&rob);
327 
328  lastActivatedCycle = 0;
329 #if 0
330  // Give renameMap & rename stage access to the freeList;
331  for (ThreadID tid = 0; tid < numThreads; tid++)
332  globalSeqNum[tid] = 1;
333 #endif
334 
335  DPRINTF(O3CPU, "Creating O3CPU object.\n");
336 
337  // Setup any thread state.
338  this->thread.resize(this->numThreads);
339 
340  for (ThreadID tid = 0; tid < this->numThreads; ++tid) {
341  if (FullSystem) {
342  // SMT is not supported in FS mode yet.
343  assert(this->numThreads == 1);
344  this->thread[tid] = new Thread(this, 0, NULL);
345  } else {
346  if (tid < params->workload.size()) {
347  DPRINTF(O3CPU, "Workload[%i] process is %#x",
348  tid, this->thread[tid]);
349  this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
350  (typename Impl::O3CPU *)(this),
351  tid, params->workload[tid]);
352 
353  //usedTids[tid] = true;
354  //threadMap[tid] = tid;
355  } else {
356  //Allocate Empty thread so M5 can use later
357  //when scheduling threads to CPU
358  Process* dummy_proc = NULL;
359 
360  this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
361  (typename Impl::O3CPU *)(this),
362  tid, dummy_proc);
363  //usedTids[tid] = false;
364  }
365  }
366 
367  ThreadContext *tc;
368 
369  // Setup the TC that will serve as the interface to the threads/CPU.
371 
372  tc = o3_tc;
373 
374  // If we're using a checker, then the TC should be the
375  // CheckerThreadContext.
376  if (params->checker) {
378  o3_tc, this->checker);
379  }
380 
381  o3_tc->cpu = (typename Impl::O3CPU *)(this);
382  assert(o3_tc->cpu);
383  o3_tc->thread = this->thread[tid];
384 
385  // Setup quiesce event.
386  this->thread[tid]->quiesceEvent = new EndQuiesceEvent(tc);
387 
388  // Give the thread the TC.
389  this->thread[tid]->tc = tc;
390 
391  // Add the TC to the CPU's list of TC's.
392  this->threadContexts.push_back(tc);
393  }
394 
395  // FullO3CPU always requires an interrupt controller.
396  if (!params->switched_out && interrupts.empty()) {
397  fatal("FullO3CPU %s has no interrupt controller.\n"
398  "Ensure createInterruptController() is called.\n", name());
399  }
400 
401  for (ThreadID tid = 0; tid < this->numThreads; tid++)
402  this->thread[tid]->setFuncExeInst(0);
403 }
404 
405 template <class Impl>
407 {
408 }
409 
410 template <class Impl>
411 void
413 {
414  BaseCPU::regProbePoints();
415 
416  ppInstAccessComplete = new ProbePointArg<PacketPtr>(getProbeManager(), "InstAccessComplete");
417  ppDataAccessComplete = new ProbePointArg<std::pair<DynInstPtr, PacketPtr> >(getProbeManager(), "DataAccessComplete");
418 
419  fetch.regProbePoints();
420  rename.regProbePoints();
421  iew.regProbePoints();
422  commit.regProbePoints();
423 }
424 
425 template <class Impl>
426 void
428 {
430 
431  // Register any of the O3CPU's stats here.
432  timesIdled
433  .name(name() + ".timesIdled")
434  .desc("Number of times that the entire CPU went into an idle state and"
435  " unscheduled itself")
436  .prereq(timesIdled);
437 
438  idleCycles
439  .name(name() + ".idleCycles")
440  .desc("Total number of cycles that the CPU has spent unscheduled due "
441  "to idling")
442  .prereq(idleCycles);
443 
445  .name(name() + ".quiesceCycles")
446  .desc("Total number of cycles that CPU has spent quiesced or waiting "
447  "for an interrupt")
448  .prereq(quiesceCycles);
449 
450  // Number of Instructions simulated
451  // --------------------------------
452  // Should probably be in Base CPU but need templated
453  // MaxThreads so put in here instead
454  committedInsts
455  .init(numThreads)
456  .name(name() + ".committedInsts")
457  .desc("Number of Instructions Simulated")
458  .flags(Stats::total);
459 
460  committedOps
461  .init(numThreads)
462  .name(name() + ".committedOps")
463  .desc("Number of Ops (including micro ops) Simulated")
464  .flags(Stats::total);
465 
466  cpi
467  .name(name() + ".cpi")
468  .desc("CPI: Cycles Per Instruction")
469  .precision(6);
470  cpi = numCycles / committedInsts;
471 
472  totalCpi
473  .name(name() + ".cpi_total")
474  .desc("CPI: Total CPI of All Threads")
475  .precision(6);
476  totalCpi = numCycles / sum(committedInsts);
477 
478  ipc
479  .name(name() + ".ipc")
480  .desc("IPC: Instructions Per Cycle")
481  .precision(6);
482  ipc = committedInsts / numCycles;
483 
484  totalIpc
485  .name(name() + ".ipc_total")
486  .desc("IPC: Total IPC of All Threads")
487  .precision(6);
488  totalIpc = sum(committedInsts) / numCycles;
489 
490  this->fetch.regStats();
491  this->decode.regStats();
492  this->rename.regStats();
493  this->iew.regStats();
494  this->commit.regStats();
495  this->rob.regStats();
496 
497  intRegfileReads
498  .name(name() + ".int_regfile_reads")
499  .desc("number of integer regfile reads")
500  .prereq(intRegfileReads);
501 
502  intRegfileWrites
503  .name(name() + ".int_regfile_writes")
504  .desc("number of integer regfile writes")
505  .prereq(intRegfileWrites);
506 
507  fpRegfileReads
508  .name(name() + ".fp_regfile_reads")
509  .desc("number of floating regfile reads")
510  .prereq(fpRegfileReads);
511 
512  fpRegfileWrites
513  .name(name() + ".fp_regfile_writes")
514  .desc("number of floating regfile writes")
515  .prereq(fpRegfileWrites);
516 
517  ccRegfileReads
518  .name(name() + ".cc_regfile_reads")
519  .desc("number of cc regfile reads")
520  .prereq(ccRegfileReads);
521 
522  ccRegfileWrites
523  .name(name() + ".cc_regfile_writes")
524  .desc("number of cc regfile writes")
525  .prereq(ccRegfileWrites);
526 
527  miscRegfileReads
528  .name(name() + ".misc_regfile_reads")
529  .desc("number of misc regfile reads")
530  .prereq(miscRegfileReads);
531 
532  miscRegfileWrites
533  .name(name() + ".misc_regfile_writes")
534  .desc("number of misc regfile writes")
535  .prereq(miscRegfileWrites);
536 }
537 
538 template <class Impl>
539 void
541 {
542  DPRINTF(O3CPU, "\n\nFullO3CPU: Ticking main, FullO3CPU.\n");
543  assert(!switchedOut());
544  assert(drainState() != DrainState::Drained);
545 
546  ++numCycles;
547  ppCycles->notify(1);
548 
549 // activity = false;
550 
551  //Tick each of the stages
552  fetch.tick();
553 
554  decode.tick();
555 
556  rename.tick();
557 
558  iew.tick();
559 
560  commit.tick();
561 
562  // Now advance the time buffers
563  timeBuffer.advance();
564 
565  fetchQueue.advance();
566  decodeQueue.advance();
567  renameQueue.advance();
568  iewQueue.advance();
569 
570  activityRec.advance();
571 
572  if (removeInstsThisCycle) {
573  cleanUpRemovedInsts();
574  }
575 
576  if (!tickEvent.scheduled()) {
577  if (_status == SwitchedOut) {
578  DPRINTF(O3CPU, "Switched out!\n");
579  // increment stat
580  lastRunningCycle = curCycle();
581  } else if (!activityRec.active() || _status == Idle) {
582  DPRINTF(O3CPU, "Idle!\n");
583  lastRunningCycle = curCycle();
584  timesIdled++;
585  } else {
586  schedule(tickEvent, clockEdge(Cycles(1)));
587  DPRINTF(O3CPU, "Scheduling next tick!\n");
588  }
589  }
590 
591  if (!FullSystem)
592  updateThreadPriority();
593 
594  tryDrain();
595 }
596 
597 template <class Impl>
598 void
600 {
601  BaseCPU::init();
602 
603  for (ThreadID tid = 0; tid < numThreads; ++tid) {
604  // Set noSquashFromTC so that the CPU doesn't squash when initially
605  // setting up registers.
606  thread[tid]->noSquashFromTC = true;
607  // Initialise the ThreadContext's memory proxies
608  thread[tid]->initMemProxies(thread[tid]->getTC());
609  }
610 
611  if (FullSystem && !params()->switched_out) {
612  for (ThreadID tid = 0; tid < numThreads; tid++) {
613  ThreadContext *src_tc = threadContexts[tid];
614  TheISA::initCPU(src_tc, src_tc->contextId());
615  }
616  }
617 
618  // Clear noSquashFromTC.
619  for (int tid = 0; tid < numThreads; ++tid)
620  thread[tid]->noSquashFromTC = false;
621 
622  commit.setThreads(thread);
623 }
624 
625 template <class Impl>
626 void
628 {
629  BaseCPU::startup();
630  for (int tid = 0; tid < numThreads; ++tid)
631  isa[tid]->startup(threadContexts[tid]);
632 
633  fetch.startupStage();
634  decode.startupStage();
635  iew.startupStage();
636  rename.startupStage();
637  commit.startupStage();
638 }
639 
640 template <class Impl>
641 void
643 {
644  list<ThreadID>::iterator isActive =
645  std::find(activeThreads.begin(), activeThreads.end(), tid);
646 
647  DPRINTF(O3CPU, "[tid:%i]: Calling activate thread.\n", tid);
648  assert(!switchedOut());
649 
650  if (isActive == activeThreads.end()) {
651  DPRINTF(O3CPU, "[tid:%i]: Adding to active threads list\n",
652  tid);
653 
654  activeThreads.push_back(tid);
655  }
656 }
657 
658 template <class Impl>
659 void
661 {
662  //Remove From Active List, if Active
663  list<ThreadID>::iterator thread_it =
664  std::find(activeThreads.begin(), activeThreads.end(), tid);
665 
666  DPRINTF(O3CPU, "[tid:%i]: Calling deactivate thread.\n", tid);
667  assert(!switchedOut());
668 
669  if (thread_it != activeThreads.end()) {
670  DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
671  tid);
672  activeThreads.erase(thread_it);
673  }
674 
675  fetch.deactivateThread(tid);
676  commit.deactivateThread(tid);
677 }
678 
679 template <class Impl>
680 Counter
682 {
683  Counter total(0);
684 
685  ThreadID size = thread.size();
686  for (ThreadID i = 0; i < size; i++)
687  total += thread[i]->numInst;
688 
689  return total;
690 }
691 
692 template <class Impl>
693 Counter
695 {
696  Counter total(0);
697 
698  ThreadID size = thread.size();
699  for (ThreadID i = 0; i < size; i++)
700  total += thread[i]->numOp;
701 
702  return total;
703 }
704 
705 template <class Impl>
706 void
708 {
709  assert(!switchedOut());
710 
711  // Needs to set each stage to running as well.
712  activateThread(tid);
713 
714  // We don't want to wake the CPU if it is drained. In that case,
715  // we just want to flag the thread as active and schedule the tick
716  // event from drainResume() instead.
717  if (drainState() == DrainState::Drained)
718  return;
719 
720  // If we are time 0 or if the last activation time is in the past,
721  // schedule the next tick and wake up the fetch unit
722  if (lastActivatedCycle == 0 || lastActivatedCycle < curTick()) {
723  scheduleTickEvent(Cycles(0));
724 
725  // Be sure to signal that there's some activity so the CPU doesn't
726  // deschedule itself.
727  activityRec.activity();
728  fetch.wakeFromQuiesce();
729 
730  Cycles cycles(curCycle() - lastRunningCycle);
731  // @todo: This is an oddity that is only here to match the stats
732  if (cycles != 0)
733  --cycles;
734  quiesceCycles += cycles;
735 
736  lastActivatedCycle = curTick();
737 
738  _status = Running;
739 
740  BaseCPU::activateContext(tid);
741  }
742 }
743 
744 template <class Impl>
745 void
747 {
748  DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
749  assert(!switchedOut());
750 
751  deactivateThread(tid);
752 
753  // If this was the last thread then unschedule the tick event.
754  if (activeThreads.size() == 0) {
755  unscheduleTickEvent();
756  lastRunningCycle = curCycle();
757  _status = Idle;
758  }
759 
760  DPRINTF(Quiesce, "Suspending Context\n");
761 
762  BaseCPU::suspendContext(tid);
763 }
764 
765 template <class Impl>
766 void
768 {
769  //For now, this is the same as deallocate
770  DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid);
771  assert(!switchedOut());
772 
773  deactivateThread(tid);
774  removeThread(tid);
775 }
776 
777 template <class Impl>
778 void
780 {
781  DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");
782  // Will change now that the PC and thread state is internal to the CPU
783  // and not in the ThreadContext.
784  ThreadContext *src_tc;
785  if (FullSystem)
786  src_tc = system->threadContexts[tid];
787  else
788  src_tc = tcBase(tid);
789 
790  //Bind Int Regs to Rename Map
791  for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
792  PhysRegIndex phys_reg = freeList.getIntReg();
793 
794  renameMap[tid].setEntry(ireg,phys_reg);
795  scoreboard.setReg(phys_reg);
796  }
797 
798  //Bind Float Regs to Rename Map
800  for (int freg = TheISA::FP_Reg_Base; freg < max_reg; freg++) {
801  PhysRegIndex phys_reg = freeList.getFloatReg();
802 
803  renameMap[tid].setEntry(freg,phys_reg);
804  scoreboard.setReg(phys_reg);
805  }
806 
807  //Bind condition-code Regs to Rename Map
809  for (int creg = TheISA::CC_Reg_Base;
810  creg < max_reg; creg++) {
811  PhysRegIndex phys_reg = freeList.getCCReg();
812 
813  renameMap[tid].setEntry(creg,phys_reg);
814  scoreboard.setReg(phys_reg);
815  }
816 
817  //Copy Thread Data Into RegFile
818  //this->copyFromTC(tid);
819 
820  //Set PC/NPC/NNPC
821  pcState(src_tc->pcState(), tid);
822 
824 
825  activateContext(tid);
826 
827  //Reset ROB/IQ/LSQ Entries
828  commit.rob->resetEntries();
829  iew.resetEntries();
830 }
831 
832 template <class Impl>
833 void
835 {
836  DPRINTF(O3CPU,"[tid:%i] Removing thread context from CPU.\n", tid);
837 
838  // Copy Thread Data From RegFile
839  // If thread is suspended, it might be re-allocated
840  // this->copyToTC(tid);
841 
842 
843  // @todo: 2-27-2008: Fix how we free up rename mappings
844  // here to alleviate the case for double-freeing registers
845  // in SMT workloads.
846 
847  // Unbind Int Regs from Rename Map
848  for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) {
849  PhysRegIndex phys_reg = renameMap[tid].lookup(ireg);
850  scoreboard.unsetReg(phys_reg);
851  freeList.addReg(phys_reg);
852  }
853 
854  // Unbind Float Regs from Rename Map
856  for (int freg = TheISA::FP_Reg_Base; freg < max_reg; freg++) {
857  PhysRegIndex phys_reg = renameMap[tid].lookup(freg);
858  scoreboard.unsetReg(phys_reg);
859  freeList.addReg(phys_reg);
860  }
861 
862  // Unbind condition-code Regs from Rename Map
864  for (int creg = TheISA::CC_Reg_Base; creg < max_reg; creg++) {
865  PhysRegIndex phys_reg = renameMap[tid].lookup(creg);
866  scoreboard.unsetReg(phys_reg);
867  freeList.addReg(phys_reg);
868  }
869 
870  // Squash Throughout Pipeline
871  DynInstPtr inst = commit.rob->readHeadInst(tid);
872  InstSeqNum squash_seq_num = inst->seqNum;
873  fetch.squash(0, squash_seq_num, inst, tid);
874  decode.squash(tid);
875  rename.squash(squash_seq_num, tid);
876  iew.squash(tid);
877  iew.ldstQueue.squash(squash_seq_num, tid);
878  commit.rob->squash(squash_seq_num, tid);
879 
880 
881  assert(iew.instQueue.getCount(tid) == 0);
882  assert(iew.ldstQueue.getCount(tid) == 0);
883 
884  // Reset ROB/IQ/LSQ Entries
885 
886  // Commented out for now. This should be possible to do by
887  // telling all the pipeline stages to drain first, and then
888  // checking until the drain completes. Once the pipeline is
889  // drained, call resetEntries(). - 10-09-06 ktlim
890 /*
891  if (activeThreads.size() >= 1) {
892  commit.rob->resetEntries();
893  iew.resetEntries();
894  }
895 */
896 }
897 
898 template <class Impl>
899 Fault
901 {
902 #if THE_ISA == ALPHA_ISA
903  // Need to clear the lock flag upon returning from an interrupt.
904  this->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, false, tid);
905 
906  this->thread[tid]->kernelStats->hwrei();
907 
908  // FIXME: XXX check for interrupts? XXX
909 #endif
910  return NoFault;
911 }
912 
913 template <class Impl>
914 bool
916 {
917 #if THE_ISA == ALPHA_ISA
918  if (this->thread[tid]->kernelStats)
919  this->thread[tid]->kernelStats->callpal(palFunc,
920  this->threadContexts[tid]);
921 
922  switch (palFunc) {
923  case PAL::halt:
924  halt();
925  if (--System::numSystemsRunning == 0)
926  exitSimLoop("all cpus halted");
927  break;
928 
929  case PAL::bpt:
930  case PAL::bugchk:
931  if (this->system->breakpoint())
932  return false;
933  break;
934  }
935 #endif
936  return true;
937 }
938 
939 template <class Impl>
940 Fault
942 {
943  // Check if there are any outstanding interrupts
944  return this->interrupts[0]->getInterrupt(this->threadContexts[0]);
945 }
946 
947 template <class Impl>
948 void
950 {
951  // Check for interrupts here. For now can copy the code that
952  // exists within isa_fullsys_traits.hh. Also assume that thread 0
953  // is the one that handles the interrupts.
954  // @todo: Possibly consolidate the interrupt checking code.
955  // @todo: Allow other threads to handle interrupts.
956 
957  assert(interrupt != NoFault);
958  this->interrupts[0]->updateIntrInfo(this->threadContexts[0]);
959 
960  DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
961  this->trap(interrupt, 0, nullptr);
962 }
963 
964 template <class Impl>
965 void
967  const StaticInstPtr &inst)
968 {
969  // Pass the thread's TC into the invoke method.
970  fault->invoke(this->threadContexts[tid], inst);
971 }
972 
973 template <class Impl>
974 void
975 FullO3CPU<Impl>::syscall(int64_t callnum, ThreadID tid, Fault *fault)
976 {
977  DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
978 
979  DPRINTF(Activity,"Activity: syscall() called.\n");
980 
981  // Temporarily increase this by one to account for the syscall
982  // instruction.
983  ++(this->thread[tid]->funcExeInst);
984 
985  // Execute the actual syscall.
986  this->thread[tid]->syscall(callnum, fault);
987 
988  // Decrease funcExeInst by one as the normal commit will handle
989  // incrementing it.
990  --(this->thread[tid]->funcExeInst);
991 }
992 
993 template <class Impl>
994 void
996 {
997  thread[tid]->serialize(cp);
998 }
999 
1000 template <class Impl>
1001 void
1003 {
1004  thread[tid]->unserialize(cp);
1005 }
1006 
1007 template <class Impl>
1008 DrainState
1010 {
1011  // If the CPU isn't doing anything, then return immediately.
1012  if (switchedOut())
1013  return DrainState::Drained;
1014 
1015  DPRINTF(Drain, "Draining...\n");
1016 
1017  // We only need to signal a drain to the commit stage as this
1018  // initiates squashing controls the draining. Once the commit
1019  // stage commits an instruction where it is safe to stop, it'll
1020  // squash the rest of the instructions in the pipeline and force
1021  // the fetch stage to stall. The pipeline will be drained once all
1022  // in-flight instructions have retired.
1023  commit.drain();
1024 
1025  // Wake the CPU and record activity so everything can drain out if
1026  // the CPU was not able to immediately drain.
1027  if (!isDrained()) {
1028  wakeCPU();
1029  activityRec.activity();
1030 
1031  DPRINTF(Drain, "CPU not drained\n");
1032 
1033  return DrainState::Draining;
1034  } else {
1035  DPRINTF(Drain, "CPU is already drained\n");
1036  if (tickEvent.scheduled())
1037  deschedule(tickEvent);
1038 
1039  // Flush out any old data from the time buffers. In
1040  // particular, there might be some data in flight from the
1041  // fetch stage that isn't visible in any of the CPU buffers we
1042  // test in isDrained().
1043  for (int i = 0; i < timeBuffer.getSize(); ++i) {
1044  timeBuffer.advance();
1045  fetchQueue.advance();
1046  decodeQueue.advance();
1047  renameQueue.advance();
1048  iewQueue.advance();
1049  }
1050 
1051  drainSanityCheck();
1052  return DrainState::Drained;
1053  }
1054 }
1055 
1056 template <class Impl>
1057 bool
1059 {
1060  if (drainState() != DrainState::Draining || !isDrained())
1061  return false;
1062 
1063  if (tickEvent.scheduled())
1064  deschedule(tickEvent);
1065 
1066  DPRINTF(Drain, "CPU done draining, processing drain event\n");
1067  signalDrainDone();
1068 
1069  return true;
1070 }
1071 
1072 template <class Impl>
1073 void
1075 {
1076  assert(isDrained());
1077  fetch.drainSanityCheck();
1078  decode.drainSanityCheck();
1079  rename.drainSanityCheck();
1080  iew.drainSanityCheck();
1081  commit.drainSanityCheck();
1082 }
1083 
1084 template <class Impl>
1085 bool
1087 {
1088  bool drained(true);
1089 
1090  if (!instList.empty() || !removeList.empty()) {
1091  DPRINTF(Drain, "Main CPU structures not drained.\n");
1092  drained = false;
1093  }
1094 
1095  if (!fetch.isDrained()) {
1096  DPRINTF(Drain, "Fetch not drained.\n");
1097  drained = false;
1098  }
1099 
1100  if (!decode.isDrained()) {
1101  DPRINTF(Drain, "Decode not drained.\n");
1102  drained = false;
1103  }
1104 
1105  if (!rename.isDrained()) {
1106  DPRINTF(Drain, "Rename not drained.\n");
1107  drained = false;
1108  }
1109 
1110  if (!iew.isDrained()) {
1111  DPRINTF(Drain, "IEW not drained.\n");
1112  drained = false;
1113  }
1114 
1115  if (!commit.isDrained()) {
1116  DPRINTF(Drain, "Commit not drained.\n");
1117  drained = false;
1118  }
1119 
1120  return drained;
1121 }
1122 
1123 template <class Impl>
1124 void
1126 {
1127  fetch.drainStall(tid);
1128 }
1129 
1130 template <class Impl>
1131 void
1133 {
1134  if (switchedOut())
1135  return;
1136 
1137  DPRINTF(Drain, "Resuming...\n");
1138  verifyMemoryMode();
1139 
1140  fetch.drainResume();
1141  commit.drainResume();
1142 
1143  _status = Idle;
1144  for (ThreadID i = 0; i < thread.size(); i++) {
1145  if (thread[i]->status() == ThreadContext::Active) {
1146  DPRINTF(Drain, "Activating thread: %i\n", i);
1147  activateThread(i);
1148  _status = Running;
1149  }
1150  }
1151 
1152  assert(!tickEvent.scheduled());
1153  if (_status == Running)
1154  schedule(tickEvent, nextCycle());
1155 }
1156 
1157 template <class Impl>
1158 void
1160 {
1161  DPRINTF(O3CPU, "Switching out\n");
1162  BaseCPU::switchOut();
1163 
1164  activityRec.reset();
1165 
1166  _status = SwitchedOut;
1167 
1168  if (checker)
1169  checker->switchOut();
1170 }
1171 
1172 template <class Impl>
1173 void
1175 {
1176  BaseCPU::takeOverFrom(oldCPU);
1177 
1178  fetch.takeOverFrom();
1179  decode.takeOverFrom();
1180  rename.takeOverFrom();
1181  iew.takeOverFrom();
1182  commit.takeOverFrom();
1183 
1184  assert(!tickEvent.scheduled());
1185 
1186  FullO3CPU<Impl> *oldO3CPU = dynamic_cast<FullO3CPU<Impl>*>(oldCPU);
1187  if (oldO3CPU)
1188  globalSeqNum = oldO3CPU->globalSeqNum;
1189 
1190  lastRunningCycle = curCycle();
1191  _status = Idle;
1192 }
1193 
1194 template <class Impl>
1195 void
1197 {
1198  if (!system->isTimingMode()) {
1199  fatal("The O3 CPU requires the memory system to be in "
1200  "'timing' mode.\n");
1201  }
1202 }
1203 
1204 template <class Impl>
1207 {
1208  return this->isa[tid]->readMiscRegNoEffect(misc_reg);
1209 }
1210 
1211 template <class Impl>
1214 {
1215  miscRegfileReads++;
1216  return this->isa[tid]->readMiscReg(misc_reg, tcBase(tid));
1217 }
1218 
1219 template <class Impl>
1220 void
1222  const TheISA::MiscReg &val, ThreadID tid)
1223 {
1224  this->isa[tid]->setMiscRegNoEffect(misc_reg, val);
1225 }
1226 
1227 template <class Impl>
1228 void
1230  const TheISA::MiscReg &val, ThreadID tid)
1231 {
1232  miscRegfileWrites++;
1233  this->isa[tid]->setMiscReg(misc_reg, val, tcBase(tid));
1234 }
1235 
1236 template <class Impl>
1237 uint64_t
1239 {
1240  intRegfileReads++;
1241  return regFile.readIntReg(reg_idx);
1242 }
1243 
1244 template <class Impl>
1245 FloatReg
1247 {
1248  fpRegfileReads++;
1249  return regFile.readFloatReg(reg_idx);
1250 }
1251 
1252 template <class Impl>
1255 {
1256  fpRegfileReads++;
1257  return regFile.readFloatRegBits(reg_idx);
1258 }
1259 
1260 template <class Impl>
1261 CCReg
1263 {
1264  ccRegfileReads++;
1265  return regFile.readCCReg(reg_idx);
1266 }
1267 
1268 template <class Impl>
1269 void
1270 FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val)
1271 {
1272  intRegfileWrites++;
1273  regFile.setIntReg(reg_idx, val);
1274 }
1275 
1276 template <class Impl>
1277 void
1279 {
1280  fpRegfileWrites++;
1281  regFile.setFloatReg(reg_idx, val);
1282 }
1283 
1284 template <class Impl>
1285 void
1287 {
1288  fpRegfileWrites++;
1289  regFile.setFloatRegBits(reg_idx, val);
1290 }
1291 
1292 template <class Impl>
1293 void
1295 {
1296  ccRegfileWrites++;
1297  regFile.setCCReg(reg_idx, val);
1298 }
1299 
1300 template <class Impl>
1301 uint64_t
1303 {
1304  intRegfileReads++;
1305  PhysRegIndex phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
1306 
1307  return regFile.readIntReg(phys_reg);
1308 }
1309 
1310 template <class Impl>
1311 float
1313 {
1314  fpRegfileReads++;
1315  PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
1316 
1317  return regFile.readFloatReg(phys_reg);
1318 }
1319 
1320 template <class Impl>
1321 uint64_t
1323 {
1324  fpRegfileReads++;
1325  PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
1326 
1327  return regFile.readFloatRegBits(phys_reg);
1328 }
1329 
1330 template <class Impl>
1331 CCReg
1333 {
1334  ccRegfileReads++;
1335  PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
1336 
1337  return regFile.readCCReg(phys_reg);
1338 }
1339 
1340 template <class Impl>
1341 void
1342 FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
1343 {
1344  intRegfileWrites++;
1345  PhysRegIndex phys_reg = commitRenameMap[tid].lookupInt(reg_idx);
1346 
1347  regFile.setIntReg(phys_reg, val);
1348 }
1349 
1350 template <class Impl>
1351 void
1353 {
1354  fpRegfileWrites++;
1355  PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
1356 
1357  regFile.setFloatReg(phys_reg, val);
1358 }
1359 
1360 template <class Impl>
1361 void
1363 {
1364  fpRegfileWrites++;
1365  PhysRegIndex phys_reg = commitRenameMap[tid].lookupFloat(reg_idx);
1366 
1367  regFile.setFloatRegBits(phys_reg, val);
1368 }
1369 
1370 template <class Impl>
1371 void
1373 {
1374  ccRegfileWrites++;
1375  PhysRegIndex phys_reg = commitRenameMap[tid].lookupCC(reg_idx);
1376 
1377  regFile.setCCReg(phys_reg, val);
1378 }
1379 
1380 template <class Impl>
1383 {
1384  return commit.pcState(tid);
1385 }
1386 
1387 template <class Impl>
1388 void
1390 {
1391  commit.pcState(val, tid);
1392 }
1393 
1394 template <class Impl>
1395 Addr
1397 {
1398  return commit.instAddr(tid);
1399 }
1400 
1401 template <class Impl>
1402 Addr
1404 {
1405  return commit.nextInstAddr(tid);
1406 }
1407 
1408 template <class Impl>
1409 MicroPC
1411 {
1412  return commit.microPC(tid);
1413 }
1414 
1415 template <class Impl>
1416 void
1418 {
1419  this->thread[tid]->noSquashFromTC = true;
1420  this->commit.generateTCEvent(tid);
1421 }
1422 
1423 template <class Impl>
1424 typename FullO3CPU<Impl>::ListIt
1426 {
1427  instList.push_back(inst);
1428 
1429  return --(instList.end());
1430 }
1431 
1432 template <class Impl>
1433 void
1435 {
1436  // Keep an instruction count.
1437  if (!inst->isMicroop() || inst->isLastMicroop()) {
1438  thread[tid]->numInst++;
1439  thread[tid]->numInsts++;
1440  committedInsts[tid]++;
1441  system->totalNumInsts++;
1442 
1443  // Check for instruction-count-based events.
1444  comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
1445  system->instEventQueue.serviceEvents(system->totalNumInsts);
1446  }
1447  thread[tid]->numOp++;
1448  thread[tid]->numOps++;
1449  committedOps[tid]++;
1450 
1451  probeInstCommit(inst->staticInst);
1452 }
1453 
1454 template <class Impl>
1455 void
1457 {
1458  DPRINTF(O3CPU, "Removing committed instruction [tid:%i] PC %s "
1459  "[sn:%lli]\n",
1460  inst->threadNumber, inst->pcState(), inst->seqNum);
1461 
1462  removeInstsThisCycle = true;
1463 
1464  // Remove the front instruction.
1465  removeList.push(inst->getInstListIt());
1466 }
1467 
1468 template <class Impl>
1469 void
1471 {
1472  DPRINTF(O3CPU, "Thread %i: Deleting instructions from instruction"
1473  " list.\n", tid);
1474 
1475  ListIt end_it;
1476 
1477  bool rob_empty = false;
1478 
1479  if (instList.empty()) {
1480  return;
1481  } else if (rob.isEmpty(tid)) {
1482  DPRINTF(O3CPU, "ROB is empty, squashing all insts.\n");
1483  end_it = instList.begin();
1484  rob_empty = true;
1485  } else {
1486  end_it = (rob.readTailInst(tid))->getInstListIt();
1487  DPRINTF(O3CPU, "ROB is not empty, squashing insts not in ROB.\n");
1488  }
1489 
1490  removeInstsThisCycle = true;
1491 
1492  ListIt inst_it = instList.end();
1493 
1494  inst_it--;
1495 
1496  // Walk through the instruction list, removing any instructions
1497  // that were inserted after the given instruction iterator, end_it.
1498  while (inst_it != end_it) {
1499  assert(!instList.empty());
1500 
1501  squashInstIt(inst_it, tid);
1502 
1503  inst_it--;
1504  }
1505 
1506  // If the ROB was empty, then we actually need to remove the first
1507  // instruction as well.
1508  if (rob_empty) {
1509  squashInstIt(inst_it, tid);
1510  }
1511 }
1512 
1513 template <class Impl>
1514 void
1516 {
1517  assert(!instList.empty());
1518 
1519  removeInstsThisCycle = true;
1520 
1521  ListIt inst_iter = instList.end();
1522 
1523  inst_iter--;
1524 
1525  DPRINTF(O3CPU, "Deleting instructions from instruction "
1526  "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1527  tid, seq_num, (*inst_iter)->seqNum);
1528 
1529  while ((*inst_iter)->seqNum > seq_num) {
1530 
1531  bool break_loop = (inst_iter == instList.begin());
1532 
1533  squashInstIt(inst_iter, tid);
1534 
1535  inst_iter--;
1536 
1537  if (break_loop)
1538  break;
1539  }
1540 }
1541 
1542 template <class Impl>
1543 inline void
1545 {
1546  if ((*instIt)->threadNumber == tid) {
1547  DPRINTF(O3CPU, "Squashing instruction, "
1548  "[tid:%i] [sn:%lli] PC %s\n",
1549  (*instIt)->threadNumber,
1550  (*instIt)->seqNum,
1551  (*instIt)->pcState());
1552 
1553  // Mark it as squashed.
1554  (*instIt)->setSquashed();
1555 
1556  // @todo: Formulate a consistent method for deleting
1557  // instructions from the instruction list
1558  // Remove the instruction from the list.
1559  removeList.push(instIt);
1560  }
1561 }
1562 
1563 template <class Impl>
1564 void
1566 {
1567  while (!removeList.empty()) {
1568  DPRINTF(O3CPU, "Removing instruction, "
1569  "[tid:%i] [sn:%lli] PC %s\n",
1570  (*removeList.front())->threadNumber,
1571  (*removeList.front())->seqNum,
1572  (*removeList.front())->pcState());
1573 
1574  instList.erase(removeList.front());
1575 
1576  removeList.pop();
1577  }
1578 
1579  removeInstsThisCycle = false;
1580 }
1581 /*
1582 template <class Impl>
1583 void
1584 FullO3CPU<Impl>::removeAllInsts()
1585 {
1586  instList.clear();
1587 }
1588 */
1589 template <class Impl>
1590 void
1592 {
1593  int num = 0;
1594 
1595  ListIt inst_list_it = instList.begin();
1596 
1597  cprintf("Dumping Instruction List\n");
1598 
1599  while (inst_list_it != instList.end()) {
1600  cprintf("Instruction:%i\nPC:%#x\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
1601  "Squashed:%i\n\n",
1602  num, (*inst_list_it)->instAddr(), (*inst_list_it)->threadNumber,
1603  (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1604  (*inst_list_it)->isSquashed());
1605  inst_list_it++;
1606  ++num;
1607  }
1608 }
1609 /*
1610 template <class Impl>
1611 void
1612 FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst)
1613 {
1614  iew.wakeDependents(inst);
1615 }
1616 */
1617 template <class Impl>
1618 void
1620 {
1621  if (activityRec.active() || tickEvent.scheduled()) {
1622  DPRINTF(Activity, "CPU already running.\n");
1623  return;
1624  }
1625 
1626  DPRINTF(Activity, "Waking up CPU\n");
1627 
1628  Cycles cycles(curCycle() - lastRunningCycle);
1629  // @todo: This is an oddity that is only here to match the stats
1630  if (cycles > 1) {
1631  --cycles;
1632  idleCycles += cycles;
1633  numCycles += cycles;
1634  ppCycles->notify(cycles);
1635  }
1636 
1637  schedule(tickEvent, clockEdge());
1638 }
1639 
1640 template <class Impl>
1641 void
1643 {
1644  if (this->thread[tid]->status() != ThreadContext::Suspended)
1645  return;
1646 
1647  this->wakeCPU();
1648 
1649  DPRINTF(Quiesce, "Suspended Processor woken\n");
1650  this->threadContexts[tid]->activate();
1651 }
1652 
1653 template <class Impl>
1654 ThreadID
1656 {
1657  for (ThreadID tid = 0; tid < numThreads; tid++) {
1658  if (!tids[tid]) {
1659  tids[tid] = true;
1660  return tid;
1661  }
1662  }
1663 
1664  return InvalidThreadID;
1665 }
1666 
1667 template <class Impl>
1668 void
1670 {
1671  if (activeThreads.size() > 1) {
1672  //DEFAULT TO ROUND ROBIN SCHEME
1673  //e.g. Move highest priority to end of thread list
1674  list<ThreadID>::iterator list_begin = activeThreads.begin();
1675 
1676  unsigned high_thread = *list_begin;
1677 
1678  activeThreads.erase(list_begin);
1679 
1680  activeThreads.push_back(high_thread);
1681  }
1682 }
1683 
1684 // Forward declaration of FullO3CPU.
1685 template class FullO3CPU<O3CPUImpl>;
void unserializeThread(CheckpointIn &cp, ThreadID tid) override
Definition: cpu.cc:1002
DcachePort dcachePort
Data port.
Definition: cpu.hh:570
#define DPRINTF(x,...)
Definition: trace.hh:212
std::vector< ThreadID > tids
Available thread ids in the cpu.
Definition: cpu.hh:676
uint8_t CCReg
Definition: registers.hh:57
bool isUncacheable() const
Accessor functions for flags.
Definition: request.hh:767
bool removeInstsThisCycle
Records if instructions need to be removed this cycle due to being retired or squashed.
Definition: cpu.hh:525
virtual void recvReqRetry()
Handles doing a retry of a failed fetch.
Definition: cpu.cc:107
decltype(nullptr) constexpr NoFault
Definition: types.hh:189
void setArchFloatReg(int reg_idx, float val, ThreadID tid)
Definition: cpu.cc:1352
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
void syscall(int64_t callnum, ThreadID tid, Fault *fault)
Executes a syscall.
Definition: cpu.cc:975
ThreadID getFreeTid()
Gets a free thread id.
Definition: cpu.cc:1655
const char * description() const
Returns the description of the tick event.
Definition: cpu.cc:153
void squashFromTC(ThreadID tid)
Initiates a squash of all in-flight instructions for a given thread.
Definition: cpu.cc:1417
const std::string & name()
Definition: trace.cc:49
IcachePort icachePort
Instruction port.
Definition: cpu.hh:567
System * system
Pointer to the system.
Definition: cpu.hh:658
Bitfield< 7 > i
Definition: miscregs.hh:1378
uint64_t readIntReg(int reg_idx)
Definition: cpu.cc:1238
std::vector< Thread * > thread
Pointers to all of the threads in the CPU.
Definition: cpu.hh:661
DrainState
Object drain/handover states.
Definition: drain.hh:71
Fault getInterrupts()
Returns the Fault for any valid interrupt.
Definition: cpu.cc:941
#define panic(...)
Definition: misc.hh:153
Running normally.
TickEvent(FullO3CPU< Impl > *c)
Constructs a tick event.
Definition: cpu.cc:139
void activateContext(ThreadID tid) override
Add Thread to Active Threads List.
Definition: cpu.cc:707
void takeOverFrom(BaseCPU *oldCPU) override
Takes over from another CPU.
Definition: cpu.cc:1174
virtual void setStatus(Status new_status)=0
Fault hwrei(ThreadID tid)
HW return from error interrupt.
Definition: cpu.cc:900
~FullO3CPU()
Destructor.
Definition: cpu.cc:406
const int NumFloatRegs
Definition: registers.hh:96
void wakeCPU()
Wakes the CPU, rescheduling the CPU if it's not already active.
Definition: cpu.cc:1619
TheISA::CCReg readArchCCReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1332
Status _status
Overall CPU status.
Definition: cpu.hh:126
CPUPolicy::Decode decode
The decode stage.
Definition: cpu.hh:532
BaseO3CPU(BaseCPUParams *params)
Definition: cpu.cc:81
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:146
CPUPolicy::FreeList freeList
The free list.
Definition: cpu.hh:547
uint64_t MiscReg
Definition: registers.hh:54
TheISA::MiscReg readMiscReg(int misc_reg, ThreadID tid)
Reads a misc.
Definition: cpu.cc:1213
uint64_t readArchIntReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1302
void quiesceCycles(ThreadContext *tc, uint64_t cycles)
Definition: pseudo_inst.cc:261
virtual TheISA::PCState pcState()=0
void setArchIntReg(int reg_idx, uint64_t val, ThreadID tid)
Architectural register accessors.
Definition: cpu.cc:1342
void insertThread(ThreadID tid)
Setup CPU to insert a thread's context.
Definition: cpu.cc:779
FullO3CPU(DerivO3CPUParams *params)
Constructs a CPU with the given parameters.
Definition: cpu.cc:159
ThreadContext is the external interface to all thread state for anything outside of the CPU...
void tick()
Ticks CPU, calling tick() on each stage, and checking the overall activity to see if the CPU should d...
Definition: cpu.cc:540
TimeBuffer< TimeStruct > timeBuffer
The main time buffer to do backwards communication.
Definition: cpu.hh:599
Event for timing out quiesce instruction.
CPUPolicy::Fetch fetch
The fetch stage.
Definition: cpu.hh:529
void trap(const Fault &fault, ThreadID tid, const StaticInstPtr &inst)
Traps to handle given fault.
Definition: cpu.cc:966
void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, ThreadID tid)
Sets a miscellaneous register.
Definition: cpu.cc:1221
void removeFrontInst(DynInstPtr &inst)
Remove an instruction from the front end of the list.
Definition: cpu.cc:1456
CPUPolicy::ROB rob
The re-order buffer.
Definition: cpu.hh:556
void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Remove all instructions younger than the given sequence number.
Definition: cpu.cc:1515
void squashInstIt(const ListIt &instIt, ThreadID tid)
Removes the instruction pointed to by the iterator.
Definition: cpu.cc:1544
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: cpu.cc:1074
Bitfield< 63 > val
Definition: misc.hh:770
Templated Checker class.
Definition: cpu.hh:433
Derived ThreadContext class for use with the Checker.
Bitfield< 5, 0 > status
Definition: miscregs.hh:1604
void verifyMemoryMode() const override
Definition: cpu.cc:1196
virtual void recvReqRetry()
Handles doing a retry of the previous send.
Definition: cpu.cc:133
void setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
Definition: cpu.cc:1362
void deactivateThread(ThreadID tid)
Remove Thread from Active Threads List.
Definition: cpu.cc:660
system
Definition: isa.cc:226
Definition: cpu.hh:83
Tick curTick()
The current simulated tick.
Definition: core.hh:47
uint8_t RegIndex
Definition: registers.hh:46
std::list< ThreadID > activeThreads
Active Threads List.
Definition: cpu.hh:559
uint64_t FloatRegBits
Definition: registers.hh:51
void serializeThread(CheckpointOut &cp, ThreadID tid) const override
Definition: cpu.cc:995
const int NumCCRegs
Definition: registers.hh:97
void suspendContext(ThreadID tid) override
Remove Thread from Active Threads List.
Definition: cpu.cc:746
void takeOverFrom(ThreadContext &ntc, ThreadContext &otc)
Copy state between thread contexts in preparation for CPU handover.
bool hasSharers() const
Definition: packet.hh:585
void haltContext(ThreadID tid) override
Remove Thread from Active Threads List && Remove Thread Context from CPU.
Definition: cpu.cc:767
void initCPU(ThreadContext *tc, int cpuId)
Definition: ev5.cc:51
CPUPolicy::Commit commit
The commit stage.
Definition: cpu.hh:541
const RegIndex ZeroReg
Definition: registers.hh:77
Cycles lastRunningCycle
The cycle that the CPU was last running, used for statistics.
Definition: cpu.hh:667
Addr instAddr(ThreadID tid)
Reads the commit PC of a specific thread.
Definition: cpu.cc:1396
TimeBuffer< DecodeStruct > decodeQueue
The decode stage's instruction queue.
Definition: cpu.hh:605
#define fatal(...)
Definition: misc.hh:163
const RequestPtr req
A pointer to the original request.
Definition: packet.hh:304
uint16_t MicroPC
Definition: types.hh:144
ListIt addInst(DynInstPtr &inst)
Function to add instruction onto the head of the list of the instructions.
Definition: cpu.cc:1425
MicroPC microPC(ThreadID tid)
Reads the commit micro PC of a specific thread.
Definition: cpu.cc:1410
uint64_t InstSeqNum
Definition: inst_seq.hh:40
Counter totalInsts() const override
Count the Total Instructions Committed in the CPU.
Definition: cpu.cc:681
TheISA::CCReg readCCReg(int reg_idx)
Definition: cpu.cc:1262
virtual void recvTimingSnoopReq(PacketPtr pkt)
Receive a timing snoop request from the slave port.
Definition: cpu.cc:121
TimeBuffer< FetchStruct > fetchQueue
The fetch stage's instruction queue.
Definition: cpu.hh:602
void activateThread(ThreadID tid)
Add Thread to Active Threads List.
Definition: cpu.cc:642
STL list class.
Definition: stl.hh:54
Tick lastActivatedCycle
The cycle that the CPU was last activated by a new thread.
Definition: cpu.hh:670
void init() override
Initialize the CPU.
Definition: cpu.cc:599
int instcount
Count of total number of dynamic instructions in flight.
Definition: cpu.hh:504
double FloatReg
Definition: registers.hh:50
TheISA::TLB * dtb
Definition: cpu.hh:123
void removeThread(ThreadID tid)
Remove all of a thread's context from CPU.
Definition: cpu.cc:834
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
bool cacheResponding() const
Definition: packet.hh:558
void regStats()
Definition: cpu.cc:87
Draining buffers pending serialization/handover.
int64_t Counter
Statistics counter type.
Definition: types.hh:58
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
virtual bool recvTimingResp(PacketPtr pkt)
Timing version of receive.
Definition: cpu.cc:114
bool tryDrain()
Check if the pipeline has drained and signal drain done.
Definition: cpu.cc:1058
const FlagsType total
Print the total.
Definition: info.hh:49
const ThreadID InvalidThreadID
Definition: types.hh:172
void removeInstsNotInROB(ThreadID tid)
Remove all instructions that are not currently in the ROB.
Definition: cpu.cc:1470
Checker< Impl > * checker
Pointer to the checker, which can dynamically verify instruction results at run time.
Definition: cpu.hh:655
cbk_int func interrupt
Definition: gpu_nomali.cc:94
const int NumMiscRegs
Definition: registers.hh:98
void setIntReg(int reg_idx, uint64_t val)
Definition: cpu.cc:1270
Temp sum(Temp val)
Definition: statistics.hh:3224
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:171
TheISA::FloatReg readFloatReg(int reg_idx)
Definition: cpu.cc:1246
DefaultFetch< Impl > * fetch
Pointer to fetch.
Definition: cpu.hh:137
void switchOut() override
Switches out this CPU.
Definition: cpu.cc:1159
ProbePointArg generates a point for the class of Arg.
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
Definition: sim_events.cc:83
int size()
Definition: pagetable.hh:146
O3CPU * cpu
Pointer to the CPU.
Bitfield< 29 > c
Definition: miscregs.hh:1365
void wakeCPU(ThreadContext *tc, uint64_t cpuid)
Definition: pseudo_inst.cc:284
TimeBuffer< IEWStruct > iewQueue
The IEW stage's instruction queue.
Definition: cpu.hh:611
void process()
Processes a tick event, calling tick() on the CPU.
Definition: cpu.cc:146
bool simPalCheck(int palFunc, ThreadID tid)
Definition: cpu.cc:915
std::ostream CheckpointOut
Definition: serialize.hh:67
static int numSystemsRunning
Definition: system.hh:551
O3ThreadState< Impl > Thread
Definition: cpu.hh:107
void startup() override
Definition: cpu.cc:627
void setMiscReg(int misc_reg, const TheISA::MiscReg &val, ThreadID tid)
Sets a misc.
Definition: cpu.cc:1229
PhysRegFile regFile
The register file.
Definition: cpu.hh:544
void dumpInsts()
Debug function to print all instructions on the list.
Definition: cpu.cc:1591
Definition: eventq.hh:185
GenericISA::SimplePCState< MachInst > PCState
Definition: types.hh:43
void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val)
Definition: cpu.cc:1286
ActivityRecorder activityRec
The activity recorder; used to tell if the CPU has any activity remaining or if it can go to idle and...
Definition: cpu.hh:618
void setFloatReg(int reg_idx, TheISA::FloatReg val)
Definition: cpu.cc:1278
O3ThreadState< Impl > * thread
Pointer to the thread state that this TC corrseponds to.
virtual int contextId() const =0
TheISA::FloatRegBits readFloatRegBits(int reg_idx)
Definition: cpu.cc:1254
short int PhysRegIndex
Definition: comm.hh:57
Addr nextInstAddr(ThreadID tid)
Reads the next PC of a specific thread.
Definition: cpu.cc:1403
uint64_t readArchFloatRegInt(int reg_idx, ThreadID tid)
Definition: cpu.cc:1322
void setCCReg(int reg_idx, TheISA::CCReg val)
Definition: cpu.cc:1294
TheISA::TLB * itb
Definition: cpu.hh:122
CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads]
The commit rename map.
Definition: cpu.hh:553
Counter totalOps() const override
Count the Total Ops (including micro ops) committed in the CPU.
Definition: cpu.cc:694
Impl::O3CPU O3CPU
Definition: cpu.hh:104
InstSeqNum globalSeqNum
The global sequence number counter.
Definition: cpu.hh:649
TimeBuffer< RenameStruct > renameQueue
The rename stage's instruction queue.
Definition: cpu.hh:608
TheISA::MiscReg readMiscRegNoEffect(int misc_reg, ThreadID tid) const
Register accessors.
Definition: cpu.cc:1206
Scoreboard scoreboard
Integer Register Scoreboard.
Definition: cpu.hh:562
Derived ThreadContext class for use with the O3CPU.
Definition: cpu.hh:75
void regStats() override
Registers statistics.
Definition: cpu.cc:427
Temporarily inactive.
DrainState drain() override
Starts draining the CPU's pipeline of all instructions in order to stop all memory accesses...
Definition: cpu.cc:1009
CPUPolicy::IEW iew
The issue/execute/writeback stages.
Definition: cpu.hh:538
void setArchCCReg(int reg_idx, TheISA::CCReg val, ThreadID tid)
Definition: cpu.cc:1372
std::list< DynInstPtr >::iterator ListIt
Definition: cpu.hh:109
float readArchFloatReg(int reg_idx, ThreadID tid)
Definition: cpu.cc:1312
std::vector< TheISA::ISA * > isa
Definition: cpu.hh:564
void cleanUpRemovedInsts()
Cleans up all instructions on the remove list.
Definition: cpu.cc:1565
virtual bool recvTimingResp(PacketPtr pkt)
Timing version of receive.
Definition: cpu.cc:94
TickEvent tickEvent
The tick event used for scheduling CPU ticks.
Definition: cpu.hh:215
void drainResume() override
Resumes execution after a drain.
Definition: cpu.cc:1132
Impl::DynInstPtr DynInstPtr
Definition: cpu.hh:103
void commitDrained(ThreadID tid)
Commit has reached a safe point to drain a thread.
Definition: cpu.cc:1125
virtual void wakeup(ThreadID tid) override
Definition: cpu.cc:1642
std::shared_ptr< FaultBase > Fault
Definition: types.hh:184
const int NumIntRegs
Definition: registers.hh:95
void instDone(ThreadID tid, DynInstPtr &inst)
Function to tell the CPU that an instruction has completed.
Definition: cpu.cc:1434
void updateThreadPriority()
Update The Order In Which We Process Threads.
Definition: cpu.cc:1669
void processInterrupts(const Fault &interrupt)
Processes any an interrupt fault.
Definition: cpu.cc:949
const FlagsType init
This Stat is Initialized.
Definition: info.hh:45
CPUPolicy::RenameMap renameMap[Impl::MaxThreads]
The rename map.
Definition: cpu.hh:550
bool isDrained() const
Check if a system is in a drained state.
Definition: cpu.cc:1086
void pcState(const TheISA::PCState &newPCState, ThreadID tid)
Sets the commit PC state of a specific thread.
Definition: cpu.cc:1389
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155
Bitfield< 26 > halt
Definition: dt_constants.hh:46
FullO3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time ...
Definition: cpu.hh:98
void regProbePoints() override
Register probe points.
Definition: cpu.cc:412
CPUPolicy::Rename rename
The dispatch stage.
Definition: cpu.hh:535

Generated on Fri Jun 9 2017 13:03:42 for gem5 by doxygen 1.8.6