gem5  v22.1.0.0
base.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2012,2016-2017, 2019-2020 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  * Copyright (c) 2011 Regents of the University of California
16  * Copyright (c) 2013 Advanced Micro Devices, Inc.
17  * Copyright (c) 2013 Mark D. Hill and David A. Wood
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions are
22  * met: redistributions of source code must retain the above copyright
23  * notice, this list of conditions and the following disclaimer;
24  * redistributions in binary form must reproduce the above copyright
25  * notice, this list of conditions and the following disclaimer in the
26  * documentation and/or other materials provided with the distribution;
27  * neither the name of the copyright holders nor the names of its
28  * contributors may be used to endorse or promote products derived from
29  * this software without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  */
43 
44 #include "cpu/base.hh"
45 
46 #include <iostream>
47 #include <sstream>
48 #include <string>
49 
50 #include "arch/generic/tlb.hh"
51 #include "base/cprintf.hh"
52 #include "base/loader/symtab.hh"
53 #include "base/logging.hh"
54 #include "base/output.hh"
55 #include "base/trace.hh"
56 #include "cpu/checker/cpu.hh"
57 #include "cpu/thread_context.hh"
58 #include "debug/Mwait.hh"
59 #include "debug/SyscallVerbose.hh"
60 #include "debug/Thread.hh"
61 #include "mem/page_table.hh"
62 #include "params/BaseCPU.hh"
63 #include "sim/clocked_object.hh"
64 #include "sim/full_system.hh"
65 #include "sim/process.hh"
66 #include "sim/root.hh"
67 #include "sim/sim_events.hh"
68 #include "sim/sim_exit.hh"
69 #include "sim/system.hh"
70 
71 // Hack
72 #include "sim/stat_control.hh"
73 
74 namespace gem5
75 {
76 
77 std::unique_ptr<BaseCPU::GlobalStats> BaseCPU::globalStats;
78 
80 
81 // This variable reflects the max number of threads in any CPU. Be
82 // careful to only use it once all the CPUs that you care about have
83 // been initialized
85 
87  : Event(Event::Progress_Event_Pri), _interval(ival), lastNumInst(0),
88  cpu(_cpu), _repeatEvent(true)
89 {
90  if (_interval)
91  cpu->schedule(this, curTick() + _interval);
92 }
93 
94 void
96 {
97  Counter temp = cpu->totalOps();
98 
99  if (_repeatEvent)
100  cpu->schedule(this, curTick() + _interval);
101 
102  if (cpu->switchedOut()) {
103  return;
104  }
105 
106 #ifndef NDEBUG
107  double ipc = double(temp - lastNumInst) / (_interval / cpu->clockPeriod());
108 
109  DPRINTFN("%s progress event, total committed:%i, progress insts committed: "
110  "%lli, IPC: %0.8d\n", cpu->name(), temp, temp - lastNumInst,
111  ipc);
112  ipc = 0.0;
113 #else
114  cprintf("%lli: %s progress event, total committed:%i, progress insts "
115  "committed: %lli\n", curTick(), cpu->name(), temp,
116  temp - lastNumInst);
117 #endif
118  lastNumInst = temp;
119 }
120 
121 const char *
123 {
124  return "CPU Progress";
125 }
126 
127 BaseCPU::BaseCPU(const Params &p, bool is_checker)
128  : ClockedObject(p), instCnt(0), _cpuId(p.cpu_id), _socketId(p.socket_id),
129  _instRequestorId(p.system->getRequestorId(this, "inst")),
130  _dataRequestorId(p.system->getRequestorId(this, "data")),
131  _taskId(context_switch_task_id::Unknown), _pid(invldPid),
132  _switchedOut(p.switched_out), _cacheLineSize(p.system->cacheLineSize()),
133  interrupts(p.interrupts), numThreads(p.numThreads), system(p.system),
134  previousCycle(0), previousState(CPU_STATE_SLEEP),
135  functionTraceStream(nullptr), currentFunctionStart(0),
136  currentFunctionEnd(0), functionEntryTick(0),
137  baseStats(this),
138  addressMonitor(p.numThreads),
139  syscallRetryLatency(p.syscallRetryLatency),
140  pwrGatingLatency(p.pwr_gating_latency),
141  powerGatingOnIdle(p.power_gating_on_idle),
142  enterPwrGatingEvent([this]{ enterPwrGating(); }, name())
143 {
144  // if Python did not provide a valid ID, do it here
145  if (_cpuId == -1 ) {
146  _cpuId = cpuList.size();
147  }
148 
149  // add self to global list of CPUs
150  cpuList.push_back(this);
151 
152  DPRINTF(SyscallVerbose, "Constructing CPU with id %d, socket id %d\n",
153  _cpuId, _socketId);
154 
155  if (numThreads > maxThreadsPerCPU)
156  maxThreadsPerCPU = numThreads;
157 
158  functionTracingEnabled = false;
159  if (p.function_trace) {
160  const std::string fname = csprintf("ftrace.%s", name());
161  functionTraceStream = simout.findOrCreate(fname)->stream();
162 
163  currentFunctionStart = currentFunctionEnd = 0;
164  functionEntryTick = p.function_trace_start;
165 
166  if (p.function_trace_start == 0) {
167  functionTracingEnabled = true;
168  } else {
169  Event *event = new EventFunctionWrapper(
170  [this]{ enableFunctionTrace(); }, name(), true);
171  schedule(event, p.function_trace_start);
172  }
173  }
174 
175  tracer = params().tracer;
176 
177  if (params().isa.size() != numThreads) {
178  fatal("Number of ISAs (%i) assigned to the CPU does not equal number "
179  "of threads (%i).\n", params().isa.size(), numThreads);
180  }
181 }
182 
183 void
185 {
186  functionTracingEnabled = true;
187 }
188 
190 {
191 }
192 
193 void
194 BaseCPU::postInterrupt(ThreadID tid, int int_num, int index)
195 {
196  interrupts[tid]->post(int_num, index);
197  // Only wake up syscall emulation if it is not waiting on a futex.
198  // This is to model the fact that instructions such as ARM SEV
199  // should wake up a WFE sleep, but not a futex syscall WAIT.
201  wakeup(tid);
202 }
203 
204 void
206 {
207  assert(tid < numThreads);
208  AddressMonitor &monitor = addressMonitor[tid];
209 
210  monitor.armed = true;
211  monitor.vAddr = address;
212  monitor.pAddr = 0x0;
213  DPRINTF(Mwait, "[tid:%d] Armed monitor (vAddr=0x%lx)\n", tid, address);
214 }
215 
216 bool
218 {
219  assert(tid < numThreads);
220  AddressMonitor &monitor = addressMonitor[tid];
221 
222  if (!monitor.gotWakeup) {
223  int block_size = cacheLineSize();
224  uint64_t mask = ~((uint64_t)(block_size - 1));
225 
226  assert(pkt->req->hasPaddr());
227  monitor.pAddr = pkt->getAddr() & mask;
228  monitor.waiting = true;
229 
230  DPRINTF(Mwait, "[tid:%d] mwait called (vAddr=0x%lx, "
231  "line's paddr=0x%lx)\n", tid, monitor.vAddr, monitor.pAddr);
232  return true;
233  } else {
234  monitor.gotWakeup = false;
235  return false;
236  }
237 }
238 
239 void
241 {
242  assert(tid < numThreads);
243  AddressMonitor &monitor = addressMonitor[tid];
244 
245  RequestPtr req = std::make_shared<Request>();
246 
247  Addr addr = monitor.vAddr;
248  int block_size = cacheLineSize();
249  uint64_t mask = ~((uint64_t)(block_size - 1));
250  int size = block_size;
251 
252  //The address of the next line if it crosses a cache line boundary.
253  Addr secondAddr = roundDown(addr + size - 1, block_size);
254 
255  if (secondAddr > addr)
256  size = secondAddr - addr;
257 
258  req->setVirt(addr, size, 0x0, dataRequestorId(),
259  tc->pcState().instAddr());
260 
261  // translate to physical address
262  Fault fault = mmu->translateAtomic(req, tc, BaseMMU::Read);
263  assert(fault == NoFault);
264 
265  monitor.pAddr = req->getPaddr() & mask;
266  monitor.waiting = true;
267 
268  DPRINTF(Mwait, "[tid:%d] mwait called (vAddr=0x%lx, line's paddr=0x%lx)\n",
269  tid, monitor.vAddr, monitor.pAddr);
270 }
271 
272 void
274 {
275  // Set up instruction-count-based termination events, if any. This needs
276  // to happen after threadContexts has been constructed.
277  if (params().max_insts_any_thread != 0) {
278  scheduleInstStopAnyThread(params().max_insts_any_thread);
279  }
280 
281  // Set up instruction-count-based termination events for SimPoints
282  // Typically, there are more than one action points.
283  // Simulation.py is responsible to take the necessary actions upon
284  // exitting the simulation loop.
285  if (!params().simpoint_start_insts.empty()) {
286  scheduleSimpointsInstStop(params().simpoint_start_insts);
287  }
288 
289  if (params().max_insts_all_threads != 0) {
290  std::string cause = "all threads reached the max instruction count";
291 
292  // allocate & initialize shared downcounter: each event will
293  // decrement this when triggered; simulation will terminate
294  // when counter reaches 0
295  int *counter = new int;
296  *counter = numThreads;
297  for (ThreadID tid = 0; tid < numThreads; ++tid) {
298  Event *event = new CountedExitEvent(cause, *counter);
299  threadContexts[tid]->scheduleInstCountEvent(
300  event, params().max_insts_all_threads);
301  }
302  }
303 
304  if (!params().switched_out) {
306 
308  }
309 }
310 
311 void
313 {
314  if (params().progress_interval) {
315  new CPUProgressEvent(this, params().progress_interval);
316  }
317 
318  if (_switchedOut)
320 
321  // Assumption CPU start to operate instantaneously without any latency
322  if (powerState->get() == enums::PwrState::UNDEFINED)
323  powerState->set(enums::PwrState::ON);
324 
325 }
326 
329 {
330  probing::PMUUPtr ptr;
331  ptr.reset(new probing::PMU(getProbeManager(), name));
332 
333  return ptr;
334 }
335 
336 void
338 {
339  ppAllCycles = pmuProbePoint("Cycles");
340  ppActiveCycles = pmuProbePoint("ActiveCycles");
341 
342  ppRetiredInsts = pmuProbePoint("RetiredInsts");
343  ppRetiredInstsPC = pmuProbePoint("RetiredInstsPC");
344  ppRetiredLoads = pmuProbePoint("RetiredLoads");
345  ppRetiredStores = pmuProbePoint("RetiredStores");
346  ppRetiredBranches = pmuProbePoint("RetiredBranches");
347 
349  "Sleeping");
350 }
351 
352 void
354 {
355  if (!inst->isMicroop() || inst->isLastMicroop()) {
356  ppRetiredInsts->notify(1);
357  ppRetiredInstsPC->notify(pc);
358  }
359 
360  if (inst->isLoad())
361  ppRetiredLoads->notify(1);
362 
363  if (inst->isStore() || inst->isAtomic())
364  ppRetiredStores->notify(1);
365 
366  if (inst->isControl())
367  ppRetiredBranches->notify(1);
368 }
369 
372  : statistics::Group(parent),
373  ADD_STAT(numCycles, statistics::units::Cycle::get(),
374  "Number of cpu cycles simulated"),
375  ADD_STAT(numWorkItemsStarted, statistics::units::Count::get(),
376  "Number of work items this cpu started"),
377  ADD_STAT(numWorkItemsCompleted, statistics::units::Count::get(),
378  "Number of work items this cpu completed")
379 {
380 }
381 
382 void
384 {
386 
387  if (!globalStats) {
388  /* We need to construct the global CPU stat structure here
389  * since it needs a pointer to the Root object. */
390  globalStats.reset(new GlobalStats(Root::root()));
391  }
392 
393  using namespace statistics;
394 
395  int size = threadContexts.size();
396  if (size > 1) {
397  for (int i = 0; i < size; ++i) {
398  std::stringstream namestr;
399  ccprintf(namestr, "%s.ctx%d", name(), i);
400  threadContexts[i]->regStats(namestr.str());
401  }
402  } else if (size == 1)
403  threadContexts[0]->regStats(name());
404 }
405 
406 Port &
407 BaseCPU::getPort(const std::string &if_name, PortID idx)
408 {
409  // Get the right port based on name. This applies to all the
410  // subclasses of the base CPU and relies on their implementation
411  // of getDataPort and getInstPort.
412  if (if_name == "dcache_port")
413  return getDataPort();
414  else if (if_name == "icache_port")
415  return getInstPort();
416  else
417  return ClockedObject::getPort(if_name, idx);
418 }
419 
420 void
422 {
423  assert(system->multiThread || numThreads == 1);
424 
425  fatal_if(interrupts.size() != numThreads,
426  "CPU %s has %i interrupt controllers, but is expecting one "
427  "per thread (%i)\n",
428  name(), interrupts.size(), numThreads);
429 
430  for (ThreadID tid = 0; tid < threadContexts.size(); ++tid) {
431  ThreadContext *tc = threadContexts[tid];
432 
434 
435  if (!FullSystem)
437 
438  interrupts[tid]->setThreadContext(tc);
439  tc->getIsaPtr()->setThreadContext(tc);
440  }
441 }
442 
443 void
445 {
448  }
449 }
450 
451 void
453 {
454  for (auto tc : threadContexts) {
455  if (tc->status() == ThreadContext::Active)
456  return;
457  }
458 
459  if (powerState->get() == enums::PwrState::CLK_GATED &&
461  assert(!enterPwrGatingEvent.scheduled());
462  // Schedule a power gating event when clock gated for the specified
463  // amount of time
465  }
466 }
467 
468 int
470 {
471  ThreadID size = threadContexts.size();
472  for (ThreadID tid = 0; tid < size; ++tid) {
473  if (tc == threadContexts[tid])
474  return tid;
475  }
476  return 0;
477 }
478 
479 void
481 {
482  DPRINTF(Thread, "activate contextId %d\n",
483  threadContexts[thread_num]->contextId());
484  // Squash enter power gating event while cpu gets activated
487  // For any active thread running, update CPU power state to active (ON)
488  powerState->set(enums::PwrState::ON);
489 
491 }
492 
493 void
495 {
496  DPRINTF(Thread, "suspend contextId %d\n",
497  threadContexts[thread_num]->contextId());
498  // Check if all threads are suspended
499  for (auto t : threadContexts) {
500  if (t->status() != ThreadContext::Suspended) {
501  return;
502  }
503  }
504 
505  // All CPU thread are suspended, update cycle count
507 
508  // All CPU threads suspended, enter lower power state for the CPU
509  powerState->set(enums::PwrState::CLK_GATED);
510 
511  // If pwrGatingLatency is set to 0 then this mechanism is disabled
512  if (powerGatingOnIdle) {
513  // Schedule power gating event when clock gated for pwrGatingLatency
514  // cycles
516  }
517 }
518 
519 void
521 {
523 }
524 
525 void
527 {
529 }
530 
531 void
533 {
534  assert(!_switchedOut);
535  _switchedOut = true;
536 
537  // Flush all TLBs in the CPU to avoid having stale translations if
538  // it gets switched in later.
539  flushTLBs();
540 
541  // Go to the power gating state
543 }
544 
545 void
547 {
548  assert(threadContexts.size() == oldCPU->threadContexts.size());
549  assert(_cpuId == oldCPU->cpuId());
550  assert(_switchedOut);
551  assert(oldCPU != this);
552  _pid = oldCPU->getPid();
553  _taskId = oldCPU->taskId();
554  // Take over the power state of the switchedOut CPU
555  powerState->set(oldCPU->powerState->get());
556 
557  previousState = oldCPU->previousState;
558  previousCycle = oldCPU->previousCycle;
559 
560  _switchedOut = false;
561 
562  ThreadID size = threadContexts.size();
563  for (ThreadID i = 0; i < size; ++i) {
564  ThreadContext *newTC = threadContexts[i];
565  ThreadContext *oldTC = oldCPU->threadContexts[i];
566 
567  newTC->getIsaPtr()->setThreadContext(newTC);
568 
569  newTC->takeOverFrom(oldTC);
570 
571  assert(newTC->contextId() == oldTC->contextId());
572  assert(newTC->threadId() == oldTC->threadId());
573  system->replaceThreadContext(newTC, newTC->contextId());
574 
575  /* This code no longer works since the zero register (e.g.,
576  * r31 on Alpha) doesn't necessarily contain zero at this
577  * point.
578  if (debug::Context)
579  ThreadContext::compare(oldTC, newTC);
580  */
581 
582  newTC->getMMUPtr()->takeOverFrom(oldTC->getMMUPtr());
583 
584  // Checker whether or not we have to transfer CheckerCPU
585  // objects over in the switch
586  CheckerCPU *old_checker = oldTC->getCheckerCpuPtr();
587  CheckerCPU *new_checker = newTC->getCheckerCpuPtr();
588  if (old_checker && new_checker) {
589  new_checker->getMMUPtr()->takeOverFrom(old_checker->getMMUPtr());
590  }
591  }
592 
593  interrupts = oldCPU->interrupts;
594  for (ThreadID tid = 0; tid < numThreads; tid++) {
595  interrupts[tid]->setThreadContext(threadContexts[tid]);
596  }
597  oldCPU->interrupts.clear();
598 
599  // All CPUs have an instruction and a data port, and the new CPU's
600  // ports are dangling while the old CPU has its ports connected
601  // already. Unbind the old CPU and then bind the ports of the one
602  // we are switching to.
603  getInstPort().takeOverFrom(&oldCPU->getInstPort());
604  getDataPort().takeOverFrom(&oldCPU->getDataPort());
605 }
606 
607 void
609 {
610  for (ThreadID i = 0; i < threadContexts.size(); ++i) {
612  CheckerCPU *checker(tc.getCheckerCpuPtr());
613 
614  tc.getMMUPtr()->flushAll();
615  if (checker) {
616  checker->getMMUPtr()->flushAll();
617  }
618  }
619 }
620 
621 void
623 {
625 
626  if (!_switchedOut) {
627  /* Unlike _pid, _taskId is not serialized, as they are dynamically
628  * assigned unique ids that are only meaningful for the duration of
629  * a specific run. We will need to serialize the entire taskMap in
630  * system. */
632 
633  // Serialize the threads, this is done by the CPU implementation.
634  for (ThreadID i = 0; i < numThreads; ++i) {
635  ScopedCheckpointSection sec(cp, csprintf("xc.%i", i));
636  interrupts[i]->serialize(cp);
637  serializeThread(cp, i);
638  }
639  }
640 }
641 
642 void
644 {
646 
647  if (!_switchedOut) {
649 
650  // Unserialize the threads, this is done by the CPU implementation.
651  for (ThreadID i = 0; i < numThreads; ++i) {
652  ScopedCheckpointSection sec(cp, csprintf("xc.%i", i));
653  interrupts[i]->unserialize(cp);
654  unserializeThread(cp, i);
655  }
656  }
657 }
658 
659 void
660 BaseCPU::scheduleInstStop(ThreadID tid, Counter insts, std::string cause)
661 {
662  const Tick now(getCurrentInstCount(tid));
663  Event *event(new LocalSimLoopExitEvent(cause, 0));
664 
665  threadContexts[tid]->scheduleInstCountEvent(event, now + insts);
666 }
667 
668 Tick
670 {
671  return threadContexts[tid]->getCurrentInstCount();
672 }
673 
675 {
676  armed = false;
677  waiting = false;
678  gotWakeup = false;
679 }
680 
681 bool
683 {
684  assert(pkt->req->hasPaddr());
685  if (armed && waiting) {
686  if (pAddr == pkt->getAddr()) {
687  DPRINTF(Mwait, "pAddr=0x%lx invalidated: waking up core\n",
688  pkt->getAddr());
689  waiting = false;
690  return true;
691  }
692  }
693  return false;
694 }
695 
696 
697 void
699 {
700  if (loader::debugSymbolTable.empty())
701  return;
702 
703  // if pc enters different function, print new function symbol and
704  // update saved range. Otherwise do nothing.
705  if (pc < currentFunctionStart || pc >= currentFunctionEnd) {
708 
709  std::string sym_str;
710  if (it == loader::debugSymbolTable.end()) {
711  // no symbol found: use addr as label
712  sym_str = csprintf("%#x", pc);
714  currentFunctionEnd = pc + 1;
715  } else {
716  sym_str = it->name;
717  currentFunctionStart = it->address;
718  }
719 
720  ccprintf(*functionTraceStream, " (%d)\n%d: %s",
721  curTick() - functionEntryTick, curTick(), sym_str);
723  }
724 }
725 
726 void
728 {
729  std::string cause = "simpoint starting point found";
730  for (size_t i = 0; i < inst_starts.size(); ++i) {
731  scheduleInstStop(0, inst_starts[i], cause);
732  }
733 }
734 
735 void
737 {
738  std::string cause = "a thread reached the max instruction count";
739  for (ThreadID tid = 0; tid < numThreads; ++tid) {
740  scheduleInstStop(tid, max_insts, cause);
741  }
742 }
743 
745  : statistics::Group(parent),
746  ADD_STAT(simInsts, statistics::units::Count::get(),
747  "Number of instructions simulated"),
748  ADD_STAT(simOps, statistics::units::Count::get(),
749  "Number of ops (including micro ops) simulated"),
750  ADD_STAT(hostInstRate, statistics::units::Rate<
751  statistics::units::Count, statistics::units::Second>::get(),
752  "Simulator instruction rate (inst/s)"),
753  ADD_STAT(hostOpRate, statistics::units::Rate<
754  statistics::units::Count, statistics::units::Second>::get(),
755  "Simulator op (including micro ops) rate (op/s)")
756 {
757  simInsts
759  .precision(0)
760  .prereq(simInsts)
761  ;
762 
763  simOps
765  .precision(0)
766  .prereq(simOps)
767  ;
768 
770  .precision(0)
771  .prereq(simInsts)
772  ;
773 
774  hostOpRate
775  .precision(0)
776  .prereq(simOps)
777  ;
778 
781 }
782 
783 } // namespace gem5
#define DPRINTFN(...)
Definition: trace.hh:214
#define DPRINTF(x,...)
Definition: trace.hh:186
void regStats() override
Callback to set stat parameters.
Definition: base.cc:383
int findContext(ThreadContext *tc)
Given a Thread Context pointer return the thread num.
Definition: base.cc:469
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
Definition: base.hh:189
probing::PMUUPtr ppRetiredInsts
Instruction commit probe point.
Definition: base.hh:504
const Cycles pwrGatingLatency
Definition: base.hh:660
virtual void serializeThread(CheckpointOut &cp, ThreadID tid) const
Serialize a single thread.
Definition: base.hh:412
virtual Counter totalOps() const =0
Tick functionEntryTick
Definition: base.hh:575
void traceFunctionsInternal(Addr pc)
Definition: base.cc:698
const bool powerGatingOnIdle
Definition: base.hh:661
void registerThreadContexts()
Definition: base.cc:421
virtual Port & getDataPort()=0
Purely virtual method that returns a reference to the data port.
virtual void haltContext(ThreadID thread_num)
Notify the CPU that the indicated context is now halted.
Definition: base.cc:520
probing::PMUUPtr ppRetiredLoads
Retired load instructions.
Definition: base.hh:508
Tick instCnt
Instruction count used for SPARC misc register.
Definition: base.hh:108
Addr currentFunctionEnd
Definition: base.hh:574
int _cpuId
Definition: base.hh:114
probing::PMUUPtr ppAllCycles
CPU cycle counter even if any thread Context is suspended.
Definition: base.hh:516
probing::PMUUPtr ppRetiredInstsPC
Definition: base.hh:505
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: base.cc:273
uint32_t getPid() const
Definition: base.hh:211
System * system
Definition: base.hh:375
void mwaitAtomic(ThreadID tid, ThreadContext *tc, BaseMMU *mmu)
Definition: base.cc:240
Cycles previousCycle
Definition: base.hh:539
void enterPwrGating()
Definition: base.cc:526
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition: base.hh:544
probing::PMUUPtr pmuProbePoint(const char *name)
Helper method to instantiate probe points belonging to this object.
Definition: base.cc:328
void postInterrupt(ThreadID tid, int int_num, int index)
Definition: base.cc:194
bool mwait(ThreadID tid, PacketPtr pkt)
Definition: base.cc:217
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: base.cc:643
virtual Port & getInstPort()=0
Purely virtual method that returns a reference to the instruction port.
void scheduleInstStopAnyThread(Counter max_insts)
Schedule an exit event when any threads in the core reach the max_insts instructions using the schedu...
Definition: base.cc:736
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: base.cc:622
probing::PMUUPtr ppRetiredStores
Retired store instructions.
Definition: base.hh:510
bool _switchedOut
Is the CPU switched out or active?
Definition: base.hh:141
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port on this CPU.
Definition: base.cc:407
Addr currentFunctionStart
Definition: base.hh:573
void schedulePowerGatingEvent()
Definition: base.cc:452
@ CPU_STATE_SLEEP
Definition: base.hh:535
@ CPU_STATE_WAKEUP
Definition: base.hh:536
static std::unique_ptr< GlobalStats > globalStats
Pointer to the global stat structure.
Definition: base.hh:162
virtual void verifyMemoryMode() const
Verify that the system is in a memory mode supported by the CPU.
Definition: base.hh:367
void regProbePoints() override
Register probe points for this object.
Definition: base.cc:337
void scheduleSimpointsInstStop(std::vector< Counter > inst_starts)
Schedule simpoint events using the scheduleInstStop function.
Definition: base.cc:727
uint32_t taskId() const
Get cpu task id.
Definition: base.hh:207
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition: base.cc:494
void enableFunctionTrace()
Definition: base.cc:184
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:367
probing::PMUUPtr ppRetiredBranches
Retired branches (any type)
Definition: base.hh:513
void deschedulePowerGatingEvent()
Definition: base.cc:444
CPUState previousState
Definition: base.hh:540
virtual void wakeup(ThreadID tid)=0
probing::PMUUPtr ppActiveCycles
CPU cycle counter, only counts if any thread contexts is active.
Definition: base.hh:519
bool functionTracingEnabled
Definition: base.hh:571
int cpuId() const
Reads this CPU's ID.
Definition: base.hh:183
uint32_t _taskId
An intrenal representation of a task identifier within gem5.
Definition: base.hh:134
std::vector< BaseInterrupts * > interrupts
Definition: base.hh:220
void startup() override
startup() is the final initialization call before simulation.
Definition: base.cc:312
virtual void unserializeThread(CheckpointIn &cp, ThreadID tid)
Unserialize one thread.
Definition: base.hh:420
virtual ~BaseCPU()
Definition: base.cc:189
virtual void switchOut()
Prepare for another CPU to take over execution.
Definition: base.cc:532
void flushTLBs()
Flush all TLBs in the CPU.
Definition: base.cc:608
void armMonitor(ThreadID tid, Addr address)
Definition: base.cc:205
unsigned int cacheLineSize() const
Get the cache line size of the system.
Definition: base.hh:380
ProbePointArg< bool > * ppSleeping
ProbePoint that signals transitions of threadContexts sets.
Definition: base.hh:529
static Counter numSimulatedOps()
Definition: base.hh:604
std::ostream * functionTraceStream
Definition: base.hh:572
virtual void takeOverFrom(BaseCPU *cpu)
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
Definition: base.cc:546
std::vector< AddressMonitor > addressMonitor
Definition: base.hh:626
std::vector< ThreadContext * > threadContexts
Definition: base.hh:256
static std::vector< BaseCPU * > cpuList
Static global cpu list.
Definition: base.hh:580
EventFunctionWrapper enterPwrGatingEvent
Definition: base.hh:662
void scheduleInstStop(ThreadID tid, Counter insts, std::string cause)
Schedule an event that exits the simulation loops after a predefined number of instructions.
Definition: base.cc:660
bool switchedOut() const
Determine if the CPU is switched out.
Definition: base.hh:356
BaseCPU(const Params &params, bool is_checker=false)
Definition: base.cc:127
uint32_t _pid
The current OS process ID that is executing on this processor.
Definition: base.hh:138
virtual void probeInstCommit(const StaticInstPtr &inst, Addr pc)
Helper method to trigger PMU probes for a committed instruction.
Definition: base.cc:353
uint64_t getCurrentInstCount(ThreadID tid)
Get the number of instructions executed by the specified thread on this CPU.
Definition: base.cc:669
static Counter numSimulatedInsts()
Definition: base.hh:592
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Definition: base.cc:480
virtual void setThreadContext(ThreadContext *_tc)
Definition: isa.hh:80
virtual void flushAll()
Definition: mmu.cc:81
virtual void takeOverFrom(BaseMMU *old_mmu)
Definition: mmu.cc:157
virtual Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode)
Definition: mmu.cc:104
CPUProgressEvent(BaseCPU *_cpu, Tick ival=0)
Definition: base.cc:86
Counter lastNumInst
Definition: base.hh:85
BaseCPU * cpu
Definition: base.hh:86
virtual const char * description() const
Return a C string describing the event.
Definition: base.cc:122
CheckerCPU class.
Definition: cpu.hh:85
BaseMMU * getMMUPtr()
Definition: cpu.hh:152
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
ClockedObjectParams Params
Parameters of ClockedObject.
PowerState * powerState
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Tick clockPeriod() const
bool is_waiting(ThreadContext *tc)
Determine if the given thread context is currently waiting on a futex wait operation on any of the fu...
Definition: futex_map.cc:185
virtual std::string name() const
Definition: named.hh:47
OutputStream * findOrCreate(const std::string &name, bool binary=false)
Definition: output.cc:262
std::ostream * stream() const
Get the output underlying output stream.
Definition: output.hh:62
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition: pcstate.hh:107
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
Addr getAddr() const
Definition: packet.hh:805
RequestPtr req
A pointer to the original request.
Definition: packet.hh:376
Ports are used to interface objects to each other.
Definition: port.hh:62
void takeOverFrom(Port *old)
A utility function to make it easier to swap out ports.
Definition: port.hh:137
void set(enums::PwrState p)
Change the power state of this object to the power state p.
Definition: power_state.cc:96
enums::PwrState get() const
Definition: power_state.hh:84
ProbePointArg generates a point for the class of Arg.
Definition: probe.hh:264
void assignThreadContext(ContextID context_id)
Definition: process.hh:131
Static instruction class for unknown (illegal) instructions.
Definition: unknown.hh:54
static Root * root()
Use this function to get a pointer to the single Root object in the simulation.
Definition: root.hh:93
bool isLoad() const
Definition: static_inst.hh:147
bool isLastMicroop() const
Definition: static_inst.hh:188
bool isStore() const
Definition: static_inst.hh:148
bool isAtomic() const
Definition: static_inst.hh:149
bool isMicroop() const
Definition: static_inst.hh:186
bool isControl() const
Definition: static_inst.hh:160
void registerThreadContext(ThreadContext *tc)
Definition: system.cc:237
FutexMap futexMap
Definition: system.hh:601
const bool multiThread
Definition: system.hh:315
void replaceThreadContext(ThreadContext *tc, ContextID context_id)
Definition: system.cc:268
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual const PCStateBase & pcState() const =0
virtual BaseISA * getIsaPtr() const =0
virtual CheckerCPU * getCheckerCpuPtr()=0
virtual void takeOverFrom(ThreadContext *old_context)=0
@ Suspended
Temporarily inactive.
virtual int threadId() const =0
virtual ContextID contextId() const =0
virtual Process * getProcessPtr()=0
virtual BaseMMU * getMMUPtr()=0
const_iterator findNearest(Addr addr, Addr &next_addr) const
Find the nearest symbol equal to or less than the supplied address (e.g., the label for the enclosing...
Definition: symtab.hh:361
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Definition: statistics.hh:346
Statistics container.
Definition: group.hh:94
Derived & functor(const T &func)
Definition: statistics.hh:741
STL vector class.
Definition: stl.hh:37
ClockedObject declaration and implementation.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:279
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
void deschedule(Event &event)
Definition: eventq.hh:1028
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
const Params & params() const
Definition: sim_object.hh:176
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:120
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:126
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:69
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 4 > pc
Bitfield< 10, 5 > event
Bitfield< 30, 0 > index
Bitfield< 51 > t
Definition: pagetable.hh:56
Bitfield< 54 > p
Definition: pagetable.hh:70
Bitfield< 15 > system
Definition: misc.hh:1004
Bitfield< 3 > addr
Definition: types.hh:84
SymbolTable debugSymbolTable
Global unified debugging symbol table (for target).
Definition: symtab.cc:44
std::unique_ptr< PMU > PMUUPtr
Definition: pmu.hh:61
double Counter
All counters are of 64-bit values.
Definition: types.hh:47
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:235
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
statistics::Value & hostSeconds
Definition: stats.cc:48
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
std::ostream CheckpointOut
Definition: serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:245
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
OutputDirectory simout
Definition: output.cc:62
uint64_t Tick
Tick count type.
Definition: types.hh:58
int maxThreadsPerCPU
The maximum number of active threads across all cpus.
Definition: base.cc:84
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
Declarations of a non-full system Page Table.
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
bool doMonitor(PacketPtr pkt)
Definition: base.cc:682
BaseCPUStats(statistics::Group *parent)
Definition: base.cc:371
Global CPU statistics that are merged into the Root object.
Definition: base.hh:148
statistics::Value simOps
Definition: base.hh:152
statistics::Formula hostInstRate
Definition: base.hh:154
statistics::Value simInsts
Definition: base.hh:151
GlobalStats(statistics::Group *parent)
Definition: base.cc:744
statistics::Formula hostOpRate
Definition: base.hh:155
const std::string & name()
Definition: trace.cc:49

Generated on Wed Dec 21 2022 10:22:29 for gem5 by doxygen 1.9.1