gem5  v20.1.0.0
atomic.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2014 Google, Inc.
3  * Copyright (c) 2012-2013,2015,2017-2020 ARM Limited
4  * All rights reserved.
5  *
6  * The license below extends only to copyright in the software and shall
7  * not be construed as granting a license to any other intellectual
8  * property including but not limited to intellectual property relating
9  * to a hardware implementation of the functionality of the software
10  * licensed hereunder. You may use the software subject to the license
11  * terms below provided that you ensure that this notice is replicated
12  * unmodified and in its entirety in all distributions of the software,
13  * modified or unmodified, in source code or in binary form.
14  *
15  * Copyright (c) 2002-2005 The Regents of The University of Michigan
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 #include "cpu/simple/atomic.hh"
43 
44 #include "arch/locked_mem.hh"
45 #include "arch/utility.hh"
46 #include "base/output.hh"
47 #include "config/the_isa.hh"
48 #include "cpu/exetrace.hh"
49 #include "cpu/utils.hh"
50 #include "debug/Drain.hh"
51 #include "debug/ExecFaulting.hh"
52 #include "debug/SimpleCPU.hh"
53 #include "mem/packet.hh"
54 #include "mem/packet_access.hh"
55 #include "mem/physical.hh"
56 #include "params/AtomicSimpleCPU.hh"
57 #include "sim/faults.hh"
58 #include "sim/full_system.hh"
59 #include "sim/system.hh"
60 
61 using namespace std;
62 using namespace TheISA;
63 
64 void
66 {
68 
69  int cid = threadContexts[0]->contextId();
70  ifetch_req->setContext(cid);
71  data_read_req->setContext(cid);
72  data_write_req->setContext(cid);
73  data_amo_req->setContext(cid);
74 }
75 
76 AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
77  : BaseSimpleCPU(p),
78  tickEvent([this]{ tick(); }, "AtomicSimpleCPU tick",
79  false, Event::CPU_Tick_Pri),
80  width(p->width), locked(false),
81  simulate_data_stalls(p->simulate_data_stalls),
82  simulate_inst_stalls(p->simulate_inst_stalls),
83  icachePort(name() + ".icache_port", this),
84  dcachePort(name() + ".dcache_port", this),
85  dcache_access(false), dcache_latency(0),
86  ppCommit(nullptr)
87 {
88  _status = Idle;
89  ifetch_req = std::make_shared<Request>();
90  data_read_req = std::make_shared<Request>();
91  data_write_req = std::make_shared<Request>();
92  data_amo_req = std::make_shared<Request>();
93 }
94 
95 
97 {
98  if (tickEvent.scheduled()) {
99  deschedule(tickEvent);
100  }
101 }
102 
105 {
106  // Deschedule any power gating event (if any)
108 
109  if (switchedOut())
110  return DrainState::Drained;
111 
112  if (!isCpuDrained()) {
113  DPRINTF(Drain, "Requesting drain.\n");
114  return DrainState::Draining;
115  } else {
116  if (tickEvent.scheduled())
117  deschedule(tickEvent);
118 
119  activeThreads.clear();
120  DPRINTF(Drain, "Not executing microcode, no need to drain.\n");
121  return DrainState::Drained;
122  }
123 }
124 
125 void
127 {
128  DPRINTF(SimpleCPU, "%s received snoop pkt for addr:%#x %s\n",
129  __func__, pkt->getAddr(), pkt->cmdString());
130 
131  for (ThreadID tid = 0; tid < numThreads; tid++) {
132  if (tid != sender) {
133  if (getCpuAddrMonitor(tid)->doMonitor(pkt)) {
134  wakeup(tid);
135  }
136 
139  }
140  }
141 }
142 
143 void
145 {
146  assert(!tickEvent.scheduled());
147  if (switchedOut())
148  return;
149 
150  DPRINTF(SimpleCPU, "Resume\n");
152 
153  assert(!threadContexts.empty());
154 
156 
157  for (ThreadID tid = 0; tid < numThreads; tid++) {
158  if (threadInfo[tid]->thread->status() == ThreadContext::Active) {
159  threadInfo[tid]->notIdleFraction = 1;
160  activeThreads.push_back(tid);
162 
163  // Tick if any threads active
164  if (!tickEvent.scheduled()) {
165  schedule(tickEvent, nextCycle());
166  }
167  } else {
168  threadInfo[tid]->notIdleFraction = 0;
169  }
170  }
171 
172  // Reschedule any power gating event (if any)
174 }
175 
176 bool
178 {
179  if (drainState() != DrainState::Draining)
180  return false;
181 
182  DPRINTF(Drain, "tryCompleteDrain.\n");
183  if (!isCpuDrained())
184  return false;
185 
186  DPRINTF(Drain, "CPU done draining, processing drain event\n");
187  signalDrainDone();
188 
189  return true;
190 }
191 
192 
193 void
195 {
197 
198  assert(!tickEvent.scheduled());
199  assert(_status == BaseSimpleCPU::Running || _status == Idle);
200  assert(isCpuDrained());
201 }
202 
203 
204 void
206 {
208 
209  // The tick event should have been descheduled by drain()
210  assert(!tickEvent.scheduled());
211 }
212 
213 void
215 {
216  if (!system->isAtomicMode()) {
217  fatal("The atomic CPU requires the memory system to be in "
218  "'atomic' mode.\n");
219  }
220 }
221 
222 void
224 {
225  DPRINTF(SimpleCPU, "ActivateContext %d\n", thread_num);
226 
227  assert(thread_num < numThreads);
228 
229  threadInfo[thread_num]->notIdleFraction = 1;
230  Cycles delta = ticksToCycles(threadInfo[thread_num]->thread->lastActivate -
231  threadInfo[thread_num]->thread->lastSuspend);
232  numCycles += delta;
233 
234  if (!tickEvent.scheduled()) {
235  //Make sure ticks are still on multiples of cycles
236  schedule(tickEvent, clockEdge(Cycles(0)));
237  }
239  if (std::find(activeThreads.begin(), activeThreads.end(), thread_num)
240  == activeThreads.end()) {
241  activeThreads.push_back(thread_num);
242  }
243 
244  BaseCPU::activateContext(thread_num);
245 }
246 
247 
248 void
250 {
251  DPRINTF(SimpleCPU, "SuspendContext %d\n", thread_num);
252 
253  assert(thread_num < numThreads);
254  activeThreads.remove(thread_num);
255 
256  if (_status == Idle)
257  return;
258 
259  assert(_status == BaseSimpleCPU::Running);
260 
261  threadInfo[thread_num]->notIdleFraction = 0;
262 
263  if (activeThreads.empty()) {
264  _status = Idle;
265 
266  if (tickEvent.scheduled()) {
267  deschedule(tickEvent);
268  }
269  }
270 
271  BaseCPU::suspendContext(thread_num);
272 }
273 
274 Tick
276 {
277  return port.sendAtomic(pkt);
278 }
279 
280 Tick
282 {
283  DPRINTF(SimpleCPU, "%s received atomic snoop pkt for addr:%#x %s\n",
284  __func__, pkt->getAddr(), pkt->cmdString());
285 
286  // X86 ISA: Snooping an invalidation for monitor/mwait
288 
289  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
290  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
291  cpu->wakeup(tid);
292  }
293  }
294 
295  // if snoop invalidates, release any associated locks
296  // When run without caches, Invalidation packets will not be received
297  // hence we must check if the incoming packets are writes and wakeup
298  // the processor accordingly
299  if (pkt->isInvalidate() || pkt->isWrite()) {
300  DPRINTF(SimpleCPU, "received invalidation for addr:%#x\n",
301  pkt->getAddr());
302  for (auto &t_info : cpu->threadInfo) {
303  TheISA::handleLockedSnoop(t_info->thread, pkt, cacheBlockMask);
304  }
305  }
306 
307  return 0;
308 }
309 
310 void
312 {
313  DPRINTF(SimpleCPU, "%s received functional snoop pkt for addr:%#x %s\n",
314  __func__, pkt->getAddr(), pkt->cmdString());
315 
316  // X86 ISA: Snooping an invalidation for monitor/mwait
317  AtomicSimpleCPU *cpu = (AtomicSimpleCPU *)(&owner);
318  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
319  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
320  cpu->wakeup(tid);
321  }
322  }
323 
324  // if snoop invalidates, release any associated locks
325  if (pkt->isInvalidate()) {
326  DPRINTF(SimpleCPU, "received invalidation for addr:%#x\n",
327  pkt->getAddr());
328  for (auto &t_info : cpu->threadInfo) {
329  TheISA::handleLockedSnoop(t_info->thread, pkt, cacheBlockMask);
330  }
331  }
332 }
333 
334 bool
336  int size, Request::Flags flags,
337  const std::vector<bool>& byte_enable,
338  int& frag_size, int& size_left) const
339 {
340  bool predicate = true;
341  Addr inst_addr = threadInfo[curThread]->thread->pcState().instAddr();
342 
343  frag_size = std::min(
344  cacheLineSize() - addrBlockOffset(frag_addr, cacheLineSize()),
345  (Addr) size_left);
346  size_left -= frag_size;
347 
348  if (!byte_enable.empty()) {
349  // Set up byte-enable mask for the current fragment
350  auto it_start = byte_enable.begin() + (size - (frag_size + size_left));
351  auto it_end = byte_enable.begin() + (size - size_left);
352  if (isAnyActiveElement(it_start, it_end)) {
353  req->setVirt(frag_addr, frag_size, flags, dataRequestorId(),
354  inst_addr);
355  req->setByteEnable(std::vector<bool>(it_start, it_end));
356  } else {
357  predicate = false;
358  }
359  } else {
360  req->setVirt(frag_addr, frag_size, flags, dataRequestorId(),
361  inst_addr);
362  req->setByteEnable(std::vector<bool>());
363  }
364 
365  return predicate;
366 }
367 
368 Fault
369 AtomicSimpleCPU::readMem(Addr addr, uint8_t * data, unsigned size,
370  Request::Flags flags,
371  const std::vector<bool>& byte_enable)
372 {
374  SimpleThread* thread = t_info.thread;
375 
376  // use the CPU's statically allocated read request and packet objects
377  const RequestPtr &req = data_read_req;
378 
379  if (traceData)
380  traceData->setMem(addr, size, flags);
381 
382  dcache_latency = 0;
383 
384  req->taskId(taskId());
385 
386  Addr frag_addr = addr;
387  int frag_size = 0;
388  int size_left = size;
389  bool predicate;
390  Fault fault = NoFault;
391 
392  while (1) {
393  predicate = genMemFragmentRequest(req, frag_addr, size, flags,
394  byte_enable, frag_size, size_left);
395 
396  // translate to physical address
397  if (predicate) {
398  fault = thread->dtb->translateAtomic(req, thread->getTC(),
399  BaseTLB::Read);
400  }
401 
402  // Now do the access.
403  if (predicate && fault == NoFault &&
404  !req->getFlags().isSet(Request::NO_ACCESS)) {
405  Packet pkt(req, Packet::makeReadCmd(req));
406  pkt.dataStatic(data);
407 
408  if (req->isLocalAccess()) {
409  dcache_latency += req->localAccessor(thread->getTC(), &pkt);
410  } else {
412  }
413  dcache_access = true;
414 
415  assert(!pkt.isError());
416 
417  if (req->isLLSC()) {
418  TheISA::handleLockedRead(thread, req);
419  }
420  }
421 
422  //If there's a fault, return it
423  if (fault != NoFault) {
424  if (req->isPrefetch()) {
425  return NoFault;
426  } else {
427  return fault;
428  }
429  }
430 
431  // If we don't need to access further cache lines, stop now.
432  if (size_left == 0) {
433  if (req->isLockedRMW() && fault == NoFault) {
434  assert(!locked);
435  locked = true;
436  }
437  return fault;
438  }
439 
440  /*
441  * Set up for accessing the next cache line.
442  */
443  frag_addr += frag_size;
444 
445  //Move the pointer we're reading into to the correct location.
446  data += frag_size;
447  }
448 }
449 
450 Fault
451 AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size, Addr addr,
452  Request::Flags flags, uint64_t *res,
453  const std::vector<bool>& byte_enable)
454 {
456  SimpleThread* thread = t_info.thread;
457  static uint8_t zero_array[64] = {};
458 
459  if (data == NULL) {
460  assert(size <= 64);
461  assert(flags & Request::STORE_NO_DATA);
462  // This must be a cache block cleaning request
463  data = zero_array;
464  }
465 
466  // use the CPU's statically allocated write request and packet objects
467  const RequestPtr &req = data_write_req;
468 
469  if (traceData)
470  traceData->setMem(addr, size, flags);
471 
472  dcache_latency = 0;
473 
474  req->taskId(taskId());
475 
476  Addr frag_addr = addr;
477  int frag_size = 0;
478  int size_left = size;
479  int curr_frag_id = 0;
480  bool predicate;
481  Fault fault = NoFault;
482 
483  while (1) {
484  predicate = genMemFragmentRequest(req, frag_addr, size, flags,
485  byte_enable, frag_size, size_left);
486 
487  // translate to physical address
488  if (predicate)
489  fault = thread->dtb->translateAtomic(req, thread->getTC(),
491 
492  // Now do the access.
493  if (predicate && fault == NoFault) {
494  bool do_access = true; // flag to suppress cache access
495 
496  if (req->isLLSC()) {
497  assert(curr_frag_id == 0);
498  do_access =
499  TheISA::handleLockedWrite(thread, req,
501  } else if (req->isSwap()) {
502  assert(curr_frag_id == 0);
503  if (req->isCondSwap()) {
504  assert(res);
505  req->setExtraData(*res);
506  }
507  }
508 
509  if (do_access && !req->getFlags().isSet(Request::NO_ACCESS)) {
510  Packet pkt(req, Packet::makeWriteCmd(req));
511  pkt.dataStatic(data);
512 
513  if (req->isLocalAccess()) {
514  dcache_latency +=
515  req->localAccessor(thread->getTC(), &pkt);
516  } else {
518 
519  // Notify other threads on this CPU of write
520  threadSnoop(&pkt, curThread);
521  }
522  dcache_access = true;
523  assert(!pkt.isError());
524 
525  if (req->isSwap()) {
526  assert(res && curr_frag_id == 0);
527  memcpy(res, pkt.getConstPtr<uint8_t>(), size);
528  }
529  }
530 
531  if (res && !req->isSwap()) {
532  *res = req->getExtraData();
533  }
534  }
535 
536  //If there's a fault or we don't need to access a second cache line,
537  //stop now.
538  if (fault != NoFault || size_left == 0)
539  {
540  if (req->isLockedRMW() && fault == NoFault) {
541  assert(!req->isMasked());
542  locked = false;
543  }
544 
545  if (fault != NoFault && req->isPrefetch()) {
546  return NoFault;
547  } else {
548  return fault;
549  }
550  }
551 
552  /*
553  * Set up for accessing the next cache line.
554  */
555  frag_addr += frag_size;
556 
557  //Move the pointer we're reading into to the correct location.
558  data += frag_size;
559 
560  curr_frag_id++;
561  }
562 }
563 
564 Fault
565 AtomicSimpleCPU::amoMem(Addr addr, uint8_t* data, unsigned size,
566  Request::Flags flags, AtomicOpFunctorPtr amo_op)
567 {
569  SimpleThread* thread = t_info.thread;
570 
571  // use the CPU's statically allocated amo request and packet objects
572  const RequestPtr &req = data_amo_req;
573 
574  if (traceData)
575  traceData->setMem(addr, size, flags);
576 
577  //The address of the second part of this access if it needs to be split
578  //across a cache line boundary.
579  Addr secondAddr = roundDown(addr + size - 1, cacheLineSize());
580 
581  // AMO requests that access across a cache line boundary are not
582  // allowed since the cache does not guarantee AMO ops to be executed
583  // atomically in two cache lines
584  // For ISAs such as x86 that requires AMO operations to work on
585  // accesses that cross cache-line boundaries, the cache needs to be
586  // modified to support locking both cache lines to guarantee the
587  // atomicity.
588  if (secondAddr > addr) {
589  panic("AMO request should not access across a cache line boundary\n");
590  }
591 
592  dcache_latency = 0;
593 
594  req->taskId(taskId());
595  req->setVirt(addr, size, flags, dataRequestorId(),
596  thread->pcState().instAddr(), std::move(amo_op));
597 
598  // translate to physical address
599  Fault fault = thread->dtb->translateAtomic(req, thread->getTC(),
601 
602  // Now do the access.
603  if (fault == NoFault && !req->getFlags().isSet(Request::NO_ACCESS)) {
604  // We treat AMO accesses as Write accesses with SwapReq command
605  // data will hold the return data of the AMO access
606  Packet pkt(req, Packet::makeWriteCmd(req));
607  pkt.dataStatic(data);
608 
609  if (req->isLocalAccess())
610  dcache_latency += req->localAccessor(thread->getTC(), &pkt);
611  else {
613  }
614 
615  dcache_access = true;
616 
617  assert(!pkt.isError());
618  assert(!req->isLLSC());
619  }
620 
621  if (fault != NoFault && req->isPrefetch()) {
622  return NoFault;
623  }
624 
625  //If there's a fault and we're not doing prefetch, return it
626  return fault;
627 }
628 
629 void
631 {
632  DPRINTF(SimpleCPU, "Tick\n");
633 
634  // Change thread if multi-threaded
636 
637  // Set memroy request ids to current thread
638  if (numThreads > 1) {
639  ContextID cid = threadContexts[curThread]->contextId();
640 
641  ifetch_req->setContext(cid);
642  data_read_req->setContext(cid);
643  data_write_req->setContext(cid);
644  data_amo_req->setContext(cid);
645  }
646 
648  SimpleThread* thread = t_info.thread;
649 
650  Tick latency = 0;
651 
652  for (int i = 0; i < width || locked; ++i) {
653  numCycles++;
655 
659  }
660 
661  // We must have just got suspended by a PC event
662  if (_status == Idle) {
664  return;
665  }
666 
667  Fault fault = NoFault;
668 
669  TheISA::PCState pcState = thread->pcState();
670 
671  bool needToFetch = !isRomMicroPC(pcState.microPC()) &&
673  if (needToFetch) {
674  ifetch_req->taskId(taskId());
676  fault = thread->itb->translateAtomic(ifetch_req, thread->getTC(),
678  }
679 
680  if (fault == NoFault) {
681  Tick icache_latency = 0;
682  bool icache_access = false;
683  dcache_access = false; // assume no dcache access
684 
685  if (needToFetch) {
686  // This is commented out because the decoder would act like
687  // a tiny cache otherwise. It wouldn't be flushed when needed
688  // like the I cache. It should be flushed, and when that works
689  // this code should be uncommented.
690  //Fetch more instruction memory if necessary
691  //if (decoder.needMoreBytes())
692  //{
693  icache_access = true;
694  Packet ifetch_pkt = Packet(ifetch_req, MemCmd::ReadReq);
695  ifetch_pkt.dataStatic(&inst);
696 
697  icache_latency = sendPacket(icachePort, &ifetch_pkt);
698 
699  assert(!ifetch_pkt.isError());
700 
701  // ifetch_req is initialized to read the instruction directly
702  // into the CPU object's inst field.
703  //}
704  }
705 
706  preExecute();
707 
708  Tick stall_ticks = 0;
709  if (curStaticInst) {
710  fault = curStaticInst->execute(&t_info, traceData);
711 
712  // keep an instruction count
713  if (fault == NoFault) {
714  countInst();
715  ppCommit->notify(std::make_pair(thread, curStaticInst));
716  } else if (traceData) {
717  traceFault();
718  }
719 
720  if (fault != NoFault &&
721  dynamic_pointer_cast<SyscallRetryFault>(fault)) {
722  // Retry execution of system calls after a delay.
723  // Prevents immediate re-execution since conditions which
724  // caused the retry are unlikely to change every tick.
725  stall_ticks += clockEdge(syscallRetryLatency) - curTick();
726  }
727 
728  postExecute();
729  }
730 
731  // @todo remove me after debugging with legion done
732  if (curStaticInst && (!curStaticInst->isMicroop() ||
734  instCnt++;
735 
736  if (simulate_inst_stalls && icache_access)
737  stall_ticks += icache_latency;
738 
740  stall_ticks += dcache_latency;
741 
742  if (stall_ticks) {
743  // the atomic cpu does its accounting in ticks, so
744  // keep counting in ticks but round to the clock
745  // period
746  latency += divCeil(stall_ticks, clockPeriod()) *
747  clockPeriod();
748  }
749 
750  }
751  if (fault != NoFault || !t_info.stayAtPC)
752  advancePC(fault);
753  }
754 
755  if (tryCompleteDrain())
756  return;
757 
758  // instruction takes at least one cycle
759  if (latency < clockPeriod())
760  latency = clockPeriod();
761 
762  if (_status != Idle)
763  reschedule(tickEvent, curTick() + latency, true);
764 }
765 
766 void
768 {
770 
772  (getProbeManager(), "Commit");
773 }
774 
775 void
777 {
779 }
780 
782 //
783 // AtomicSimpleCPU Simulation Object
784 //
786 AtomicSimpleCPUParams::create()
787 {
788  return new AtomicSimpleCPU(this);
789 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
Packet::isError
bool isError() const
Definition: packet.hh:583
AtomicOpFunctorPtr
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Definition: amo.hh:239
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:460
AtomicSimpleCPU::activateContext
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
Definition: atomic.cc:223
ArmISA::handleLockedWrite
bool handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask)
Definition: locked_mem.hh:111
roundDown
T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:150
utils.hh
SimpleExecContext
Definition: exec_context.hh:57
SimpleThread::pcState
TheISA::PCState pcState() const override
Definition: simple_thread.hh:517
AtomicSimpleCPU::ppCommit
ProbePointArg< std::pair< SimpleThread *, const StaticInstPtr > > * ppCommit
Probe Points.
Definition: atomic.hh:170
BaseSimpleCPU::traceData
Trace::InstRecord * traceData
Definition: base.hh:95
system.hh
BaseTLB::Read
@ Read
Definition: tlb.hh:57
BaseSimpleCPU::curMacroStaticInst
StaticInstPtr curMacroStaticInst
Definition: base.hh:104
EventBase::CPU_Tick_Pri
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Definition: eventq.hh:199
BaseTLB::translateAtomic
virtual Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode)=0
data
const char data[]
Definition: circlebuf.test.cc:42
BaseSimpleCPU::_status
Status _status
Definition: base.hh:121
ArmISA::handleLockedSnoop
void handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
Definition: locked_mem.hh:62
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:754
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
atomic.hh
ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
AtomicSimpleCPU::sendPacket
virtual Tick sendPacket(RequestPort &port, const PacketPtr &pkt)
Definition: atomic.cc:275
AtomicSimpleCPU::init
void init() override
Definition: atomic.cc:65
Flags< FlagsType >
Request::NO_ACCESS
@ NO_ACCESS
The request should not cause a memory access.
Definition: request.hh:135
AtomicSimpleCPU::drainResume
void drainResume() override
Definition: atomic.cc:144
ArmISA::width
Bitfield< 4 > width
Definition: miscregs_types.hh:68
ContextID
int ContextID
Globally unique thread context ID.
Definition: types.hh:231
AddressMonitor::doMonitor
bool doMonitor(PacketPtr pkt)
Definition: base.cc:709
TheISA
Definition: decode_cache.hh:37
BaseCPU::cacheLineSize
unsigned int cacheLineSize() const
Get the cache line size of the system.
Definition: base.hh:376
AtomicSimpleCPU::data_amo_req
RequestPtr data_amo_req
Definition: atomic.hh:164
ProbePointArg
ProbePointArg generates a point for the class of Arg.
Definition: thermal_domain.hh:50
MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:82
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
exetrace.hh
Packet::makeReadCmd
static MemCmd makeReadCmd(const RequestPtr &req)
Generate the appropriate read MemCmd based on the Request flags.
Definition: packet.hh:939
BaseCPU::syscallRetryLatency
Cycles syscallRetryLatency
Definition: base.hh:607
Trace::InstRecord::setMem
void setMem(Addr a, Addr s, unsigned f)
Definition: insttracer.hh:176
BaseSimpleCPU::setupFetchRequest
void setupFetchRequest(const RequestPtr &req)
Definition: base.cc:478
Packet::isInvalidate
bool isInvalidate() const
Definition: packet.hh:571
RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:82
AtomicSimpleCPU::tickEvent
EventFunctionWrapper tickEvent
Definition: atomic.hh:61
AtomicSimpleCPU::regProbePoints
void regProbePoints() override
Definition: atomic.cc:767
std::vector< bool >
BaseCPU::deschedulePowerGatingEvent
void deschedulePowerGatingEvent()
Definition: base.cc:444
BaseCPU::numCycles
Stats::Scalar numCycles
Definition: base.hh:588
BaseSimpleCPU::threadInfo
std::vector< SimpleExecContext * > threadInfo
Definition: base.hh:98
BaseSimpleCPU::traceFault
void traceFault()
Handler used when encountering a fault; its purpose is to tear down the InstRecord.
Definition: base.cc:436
AtomicSimpleCPU::readMem
Fault readMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
Definition: atomic.cc:369
AtomicSimpleCPU::AtomicCPUDPort::recvFunctionalSnoop
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
Definition: atomic.cc:311
BaseSimpleCPU::countInst
void countInst()
Definition: base.cc:161
faults.hh
output.hh
AtomicSimpleCPU::AtomicSimpleCPU
AtomicSimpleCPU(AtomicSimpleCPUParams *params)
Definition: atomic.cc:76
BaseSimpleCPU::postExecute
void postExecute()
Definition: base.cc:583
AtomicSimpleCPU::icachePort
AtomicCPUPort icachePort
Definition: atomic.hh:157
AtomicSimpleCPU::simulate_inst_stalls
const bool simulate_inst_stalls
Definition: atomic.hh:66
BaseCPU::updateCycleCounters
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition: base.hh:517
packet.hh
SimpleThread
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
Definition: simple_thread.hh:89
isAnyActiveElement
bool isAnyActiveElement(const std::vector< bool >::const_iterator &it_start, const std::vector< bool >::const_iterator &it_end)
Test if there is any active element in an enablement range.
Definition: utils.hh:86
AtomicSimpleCPU::AtomicCPUDPort::cpu
BaseSimpleCPU * cpu
Definition: atomic.hh:150
DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
BaseSimpleCPU::activeThreads
std::list< ThreadID > activeThreads
Definition: base.hh:99
DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:71
AtomicSimpleCPU::takeOverFrom
void takeOverFrom(BaseCPU *oldCPU) override
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
Definition: atomic.cc:205
AtomicSimpleCPU::isCpuDrained
bool isCpuDrained() const
Check if a system is in a drained state.
Definition: atomic.hh:89
AtomicSimpleCPU::tick
void tick()
Definition: atomic.cc:630
AtomicSimpleCPU::dcache_latency
Tick dcache_latency
Definition: atomic.hh:167
StaticInst::isFirstMicroop
bool isFirstMicroop() const
Definition: static_inst.hh:202
divCeil
T divCeil(const T &a, const U &b)
Definition: intmath.hh:114
BaseSimpleCPU::checkPcEventQueue
void checkPcEventQueue()
Definition: base.cc:133
ArmISA::a
Bitfield< 8 > a
Definition: miscregs_types.hh:62
StaticInst::isDelayedCommit
bool isDelayedCommit() const
Definition: static_inst.hh:200
AtomicSimpleCPU::threadSnoop
void threadSnoop(PacketPtr pkt, ThreadID sender)
Perform snoop for other cpu-local thread contexts.
Definition: atomic.cc:126
SimpleThread::getTC
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
Definition: simple_thread.hh:169
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
BaseCPU::instCnt
Tick instCnt
Instruction count used for SPARC misc register.
Definition: base.hh:110
Packet::cmdString
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition: packet.hh:551
AtomicSimpleCPU::ifetch_req
RequestPtr ifetch_req
Definition: atomic.hh:161
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
BaseSimpleCPU::Idle
@ Idle
Definition: base.hh:108
BaseSimpleCPU::inst
TheISA::MachInst inst
Current instruction.
Definition: base.hh:102
AtomicSimpleCPU::data_write_req
RequestPtr data_write_req
Definition: atomic.hh:163
BaseCPU::threadContexts
std::vector< ThreadContext * > threadContexts
Definition: base.hh:252
AtomicSimpleCPU::AtomicCPUDPort::cacheBlockMask
Addr cacheBlockMask
Definition: atomic.hh:148
AtomicSimpleCPU::suspendContext
void suspendContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now suspended.
Definition: atomic.cc:249
AtomicSimpleCPU::locked
bool locked
Definition: atomic.hh:64
BaseCPU::activateContext
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Definition: base.cc:480
SimpleExecContext::thread
SimpleThread * thread
Definition: exec_context.hh:64
BaseSimpleCPU::init
void init() override
Definition: base.cc:122
AtomicSimpleCPU::printAddr
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
Definition: atomic.cc:776
BaseSimpleCPU::checkForInterrupts
void checkForInterrupts()
Definition: base.cc:447
AtomicSimpleCPU::amoMem
Fault amoMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
Definition: atomic.cc:565
BaseSimpleCPU
Definition: base.hh:80
BaseCPU::getCpuAddrMonitor
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
Definition: base.hh:599
addrBlockOffset
Addr addrBlockOffset(Addr addr, Addr block_size)
Calculates the offset of a given address wrt aligned fixed-size blocks.
Definition: utils.hh:50
Packet::makeWriteCmd
static MemCmd makeWriteCmd(const RequestPtr &req)
Generate the appropriate write MemCmd based on the Request flags.
Definition: packet.hh:960
AtomicSimpleCPU
Definition: atomic.hh:50
BaseSimpleCPU::curThread
ThreadID curThread
Definition: base.hh:83
RequestPort
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Definition: port.hh:74
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:245
AtomicSimpleCPU::switchOut
void switchOut() override
Prepare for another CPU to take over execution.
Definition: atomic.cc:194
ProbePoints::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:103
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
name
const std::string & name()
Definition: trace.cc:50
isRomMicroPC
static bool isRomMicroPC(MicroPC upc)
Definition: types.hh:161
packet_access.hh
full_system.hh
RequestPort::owner
SimObject & owner
Definition: port.hh:83
StaticInst::isMicroop
bool isMicroop() const
Definition: static_inst.hh:199
AtomicSimpleCPU::AtomicCPUDPort::recvAtomicSnoop
virtual Tick recvAtomicSnoop(PacketPtr pkt)
Receive an atomic snoop request packet from our peer.
Definition: atomic.cc:281
BaseCPU::taskId
uint32_t taskId() const
Get cpu task id.
Definition: base.hh:202
BaseTLB::Write
@ Write
Definition: tlb.hh:57
BaseCPU
Definition: cpu_dummy.hh:43
BaseSimpleCPU::wakeup
void wakeup(ThreadID tid) override
Definition: base.cc:425
BaseSimpleCPU::curStaticInst
StaticInstPtr curStaticInst
Definition: base.hh:103
BaseSimpleCPU::swapActiveThread
void swapActiveThread()
Definition: base.cc:145
BaseSimpleCPU::advancePC
void advancePC(const Fault &fault)
Definition: base.cc:659
ArmISA::handleLockedRead
void handleLockedRead(XC *xc, const RequestPtr &req)
Definition: locked_mem.hh:91
AtomicSimpleCPU::width
const int width
Definition: atomic.hh:63
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
MipsISA::PCState
GenericISA::DelaySlotPCState< MachInst > PCState
Definition: types.hh:41
BaseCPU::schedulePowerGatingEvent
void schedulePowerGatingEvent()
Definition: base.cc:452
BaseCPU::system
System * system
Definition: base.hh:371
Packet::dataStatic
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:1107
BaseCPU::takeOverFrom
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
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
BaseCPU::switchOut
virtual void switchOut()
Prepare for another CPU to take over execution.
Definition: base.cc:532
BaseSimpleCPU::preExecute
void preExecute()
Definition: base.cc:495
SimpleThread::dtb
BaseTLB * dtb
Definition: simple_thread.hh:134
physical.hh
RequestPort::printAddr
void printAddr(Addr a)
Inject a PrintReq for the given address to print the state of that address throughout the memory syst...
Definition: port.cc:154
addr
ip6_addr_t addr
Definition: inet.hh:423
AtomicSimpleCPU::data_read_req
RequestPtr data_read_req
Definition: atomic.hh:162
BaseCPU::numThreads
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:363
BaseCPU::dataRequestorId
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
Definition: base.hh:184
Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
Packet::isWrite
bool isWrite() const
Definition: packet.hh:557
ThreadContext::Active
@ Active
Running.
Definition: thread_context.hh:102
AtomicSimpleCPU::dcache_access
bool dcache_access
Definition: atomic.hh:166
BaseCPU::regProbePoints
void regProbePoints() override
Definition: base.cc:335
BaseCPU::CPU_STATE_ON
@ CPU_STATE_ON
Definition: base.hh:508
BaseCPU::suspendContext
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition: base.cc:494
AtomicSimpleCPU::simulate_data_stalls
const bool simulate_data_stalls
Definition: atomic.hh:65
StaticInst::execute
virtual Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const =0
RequestPort::sendAtomic
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
Definition: port.hh:461
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
AtomicSimpleCPU::tryCompleteDrain
bool tryCompleteDrain()
Try to complete a drain request.
Definition: atomic.cc:177
Request::STORE_NO_DATA
static const FlagsType STORE_NO_DATA
Definition: request.hh:233
BaseCPU::switchedOut
bool switchedOut() const
Determine if the CPU is switched out.
Definition: base.hh:352
AtomicSimpleCPU::genMemFragmentRequest
bool genMemFragmentRequest(const RequestPtr &req, Addr frag_addr, int size, Request::Flags flags, const std::vector< bool > &byte_enable, int &frag_size, int &size_left) const
Helper function used to set up the request for a single fragment of a memory access.
Definition: atomic.cc:335
BaseTLB::Execute
@ Execute
Definition: tlb.hh:57
SimpleThread::itb
BaseTLB * itb
Definition: simple_thread.hh:133
System::isAtomicMode
bool isAtomicMode() const
Is the system in atomic mode?
Definition: system.hh:258
Packet::getConstPtr
const T * getConstPtr() const
Definition: packet.hh:1166
AtomicSimpleCPU::verifyMemoryMode
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
Definition: atomic.cc:214
AtomicSimpleCPU::writeMem
Fault writeMem(uint8_t *data, unsigned size, Addr addr, Request::Flags flags, uint64_t *res, const std::vector< bool > &byte_enable=std::vector< bool >()) override
Definition: atomic.cc:451
SimpleExecContext::stayAtPC
bool stayAtPC
Definition: exec_context.hh:70
AtomicSimpleCPU::~AtomicSimpleCPU
virtual ~AtomicSimpleCPU()
Definition: atomic.cc:96
DrainState::Draining
@ Draining
Draining buffers pending serialization/handover.
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
BaseSimpleCPU::Running
@ Running
Definition: base.hh:109
AtomicSimpleCPU::drain
DrainState drain() override
Definition: atomic.cc:104
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
AtomicSimpleCPU::dcachePort
AtomicCPUDPort dcachePort
Definition: atomic.hh:158

Generated on Wed Sep 30 2020 14:02:09 for gem5 by doxygen 1.8.17