gem5  v21.2.1.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
timing.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2014 Google, Inc.
3  * Copyright (c) 2010-2013,2015,2017-2018, 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/timing.hh"
43 
44 #include "arch/generic/decoder.hh"
45 #include "base/compiler.hh"
46 #include "config/the_isa.hh"
47 #include "cpu/exetrace.hh"
48 #include "debug/Config.hh"
49 #include "debug/Drain.hh"
50 #include "debug/ExecFaulting.hh"
51 #include "debug/HtmCpu.hh"
52 #include "debug/Mwait.hh"
53 #include "debug/SimpleCPU.hh"
54 #include "mem/packet.hh"
55 #include "mem/packet_access.hh"
56 #include "params/TimingSimpleCPU.hh"
57 #include "sim/faults.hh"
58 #include "sim/full_system.hh"
59 #include "sim/system.hh"
60 
61 namespace gem5
62 {
63 
64 void
66 {
68 }
69 
70 void
72 {
73  pkt = _pkt;
74  cpu->schedule(this, t);
75 }
76 
77 TimingSimpleCPU::TimingSimpleCPU(const TimingSimpleCPUParams &p)
78  : BaseSimpleCPU(p), fetchTranslation(this), icachePort(this),
79  dcachePort(this), ifetch_pkt(NULL), dcache_pkt(NULL), previousCycle(0),
80  fetchEvent([this]{ fetch(); }, name())
81 {
82  _status = Idle;
83 }
84 
85 
86 
88 {
89 }
90 
93 {
94  // Deschedule any power gating event (if any)
95  deschedulePowerGatingEvent();
96 
97  if (switchedOut())
98  return DrainState::Drained;
99 
100  if (_status == Idle ||
102  DPRINTF(Drain, "No need to drain.\n");
103  activeThreads.clear();
104  return DrainState::Drained;
105  } else {
106  DPRINTF(Drain, "Requesting drain.\n");
107 
108  // The fetch event can become descheduled if a drain didn't
109  // succeed on the first attempt. We need to reschedule it if
110  // the CPU is waiting for a microcode routine to complete.
112  schedule(fetchEvent, clockEdge());
113 
114  return DrainState::Draining;
115  }
116 }
117 
118 void
120 {
121  assert(!fetchEvent.scheduled());
122  if (switchedOut())
123  return;
124 
125  DPRINTF(SimpleCPU, "Resume\n");
127 
128  assert(!threadContexts.empty());
129 
131 
132  for (ThreadID tid = 0; tid < numThreads; tid++) {
133  if (threadInfo[tid]->thread->status() == ThreadContext::Active) {
134  threadInfo[tid]->execContextStats.notIdleFraction = 1;
135 
136  activeThreads.push_back(tid);
137 
139 
140  // Fetch if any threads active
141  if (!fetchEvent.scheduled()) {
142  schedule(fetchEvent, nextCycle());
143  }
144  } else {
145  threadInfo[tid]->execContextStats.notIdleFraction = 0;
146  }
147  }
148 
149  // Reschedule any power gating event (if any)
150  schedulePowerGatingEvent();
151 }
152 
153 bool
155 {
156  if (drainState() != DrainState::Draining)
157  return false;
158 
159  DPRINTF(Drain, "tryCompleteDrain.\n");
160  if (!isCpuDrained())
161  return false;
162 
163  DPRINTF(Drain, "CPU done draining, processing drain event\n");
164  signalDrainDone();
165 
166  return true;
167 }
168 
169 void
171 {
173  [[maybe_unused]] SimpleThread* thread = t_info.thread;
174 
175  // hardware transactional memory
176  // Cannot switch out the CPU in the middle of a transaction
177  assert(!t_info.inHtmTransactionalState());
178 
179  BaseSimpleCPU::switchOut();
180 
181  assert(!fetchEvent.scheduled());
182  assert(_status == BaseSimpleCPU::Running || _status == Idle);
183  assert(!t_info.stayAtPC);
184  assert(thread->pcState().microPC() == 0);
185 
187  updateCycleCounters(BaseCPU::CPU_STATE_ON);
188 }
189 
190 
191 void
193 {
195 
196  previousCycle = curCycle();
197 }
198 
199 void
201 {
202  if (!system->isTimingMode()) {
203  fatal("The timing CPU requires the memory system to be in "
204  "'timing' mode.\n");
205  }
206 }
207 
208 void
210 {
211  DPRINTF(SimpleCPU, "ActivateContext %d\n", thread_num);
212 
213  assert(thread_num < numThreads);
214 
215  threadInfo[thread_num]->execContextStats.notIdleFraction = 1;
218 
219  // kick things off by initiating the fetch of the next instruction
220  if (!fetchEvent.scheduled())
221  schedule(fetchEvent, clockEdge(Cycles(0)));
222 
223  if (std::find(activeThreads.begin(), activeThreads.end(), thread_num)
224  == activeThreads.end()) {
225  activeThreads.push_back(thread_num);
226  }
227 
228  BaseCPU::activateContext(thread_num);
229 }
230 
231 
232 void
234 {
235  DPRINTF(SimpleCPU, "SuspendContext %d\n", thread_num);
236 
237  assert(thread_num < numThreads);
238  activeThreads.remove(thread_num);
239 
240  // hardware transactional memory
241  // Cannot suspend context in the middle of a transaction.
242  assert(!threadInfo[curThread]->inHtmTransactionalState());
243 
244  if (_status == Idle)
245  return;
246 
247  assert(_status == BaseSimpleCPU::Running);
248 
249  threadInfo[thread_num]->execContextStats.notIdleFraction = 0;
250 
251  if (activeThreads.empty()) {
252  _status = Idle;
253 
254  if (fetchEvent.scheduled()) {
255  deschedule(fetchEvent);
256  }
257  }
258 
259  BaseCPU::suspendContext(thread_num);
260 }
261 
262 bool
264 {
266  SimpleThread* thread = t_info.thread;
267 
268  const RequestPtr &req = pkt->req;
269 
270  // hardware transactional memory
271  // sanity check
272  if (req->isHTMCmd()) {
273  assert(!req->isLocalAccess());
274  }
275 
276  // We're about the issues a locked load, so tell the monitor
277  // to start caring about this address
278  if (pkt->isRead() && pkt->req->isLLSC()) {
279  thread->getIsaPtr()->handleLockedRead(pkt->req);
280  }
281  if (req->isLocalAccess()) {
282  Cycles delay = req->localAccessor(thread->getTC(), pkt);
283  new IprEvent(pkt, this, clockEdge(delay));
285  dcache_pkt = NULL;
286  } else if (!dcachePort.sendTimingReq(pkt)) {
288  dcache_pkt = pkt;
289  } else {
291  // memory system takes ownership of packet
292  dcache_pkt = NULL;
293  }
294  return dcache_pkt == NULL;
295 }
296 
297 void
298 TimingSimpleCPU::sendData(const RequestPtr &req, uint8_t *data, uint64_t *res,
299  bool read)
300 {
302  SimpleThread* thread = t_info.thread;
303 
304  PacketPtr pkt = buildPacket(req, read);
305  pkt->dataDynamic<uint8_t>(data);
306 
307  // hardware transactional memory
308  // If the core is in transactional mode or if the request is HtmCMD
309  // to abort a transaction, the packet should reflect that it is
310  // transactional and also contain a HtmUid for debugging.
311  const bool is_htm_speculative = t_info.inHtmTransactionalState();
312  if (is_htm_speculative || req->isHTMAbort()) {
314  }
315  if (req->isHTMAbort())
316  DPRINTF(HtmCpu, "htmabort htmUid=%u\n", t_info.getHtmTransactionUid());
317 
318  if (req->getFlags().isSet(Request::NO_ACCESS)) {
319  assert(!dcache_pkt);
320  pkt->makeResponse();
321  completeDataAccess(pkt);
322  } else if (read) {
323  handleReadPacket(pkt);
324  } else {
325  bool do_access = true; // flag to suppress cache access
326 
327  if (req->isLLSC()) {
328  do_access = thread->getIsaPtr()->handleLockedWrite(
330  } else if (req->isCondSwap()) {
331  assert(res);
332  req->setExtraData(*res);
333  }
334 
335  if (do_access) {
336  dcache_pkt = pkt;
338  threadSnoop(pkt, curThread);
339  } else {
341  completeDataAccess(pkt);
342  }
343  }
344 }
345 
346 void
348  const RequestPtr &req, uint8_t *data, bool read)
349 {
351  PacketPtr pkt1, pkt2;
352  buildSplitPacket(pkt1, pkt2, req1, req2, req, data, read);
353 
354  // hardware transactional memory
355  // HTM commands should never use SplitData
356  assert(!req1->isHTMCmd() && !req2->isHTMCmd());
357 
358  // If the thread is executing transactionally,
359  // reflect this in the packets.
360  if (t_info.inHtmTransactionalState()) {
363  }
364 
365  if (req->getFlags().isSet(Request::NO_ACCESS)) {
366  assert(!dcache_pkt);
367  pkt1->makeResponse();
368  completeDataAccess(pkt1);
369  } else if (read) {
370  SplitFragmentSenderState * send_state =
371  dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState);
372  if (handleReadPacket(pkt1)) {
373  send_state->clearFromParent();
374  send_state = dynamic_cast<SplitFragmentSenderState *>(
375  pkt2->senderState);
376  if (handleReadPacket(pkt2)) {
377  send_state->clearFromParent();
378  }
379  }
380  } else {
381  dcache_pkt = pkt1;
382  SplitFragmentSenderState * send_state =
383  dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState);
384  if (handleWritePacket()) {
385  send_state->clearFromParent();
386  dcache_pkt = pkt2;
387  send_state = dynamic_cast<SplitFragmentSenderState *>(
388  pkt2->senderState);
389  if (handleWritePacket()) {
390  send_state->clearFromParent();
391  }
392  }
393  }
394 }
395 
396 void
398 {
399  // fault may be NoFault in cases where a fault is suppressed,
400  // for instance prefetches.
402  updateCycleCounters(BaseCPU::CPU_STATE_ON);
403 
404  if ((fault != NoFault) && traceData) {
405  traceFault();
406  }
407 
408  postExecute();
409 
410  advanceInst(fault);
411 }
412 
413 PacketPtr
415 {
416  return read ? Packet::createRead(req) : Packet::createWrite(req);
417 }
418 
419 void
421  const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req,
422  uint8_t *data, bool read)
423 {
424  pkt1 = pkt2 = NULL;
425 
426  assert(!req1->isLocalAccess() && !req2->isLocalAccess());
427 
428  if (req->getFlags().isSet(Request::NO_ACCESS)) {
429  pkt1 = buildPacket(req, read);
430  return;
431  }
432 
433  pkt1 = buildPacket(req1, read);
434  pkt2 = buildPacket(req2, read);
435 
436  PacketPtr pkt = new Packet(req, pkt1->cmd.responseCommand());
437 
438  pkt->dataDynamic<uint8_t>(data);
439  pkt1->dataStatic<uint8_t>(data);
440  pkt2->dataStatic<uint8_t>(data + req1->getSize());
441 
442  SplitMainSenderState * main_send_state = new SplitMainSenderState;
443  pkt->senderState = main_send_state;
444  main_send_state->fragments[0] = pkt1;
445  main_send_state->fragments[1] = pkt2;
446  main_send_state->outstanding = 2;
447  pkt1->senderState = new SplitFragmentSenderState(pkt, 0);
448  pkt2->senderState = new SplitFragmentSenderState(pkt, 1);
449 }
450 
451 Fault
453  Request::Flags flags,
454  const std::vector<bool>& byte_enable)
455 {
457  SimpleThread* thread = t_info.thread;
458 
459  Fault fault;
460  const Addr pc = thread->pcState().instAddr();
461  unsigned block_size = cacheLineSize();
463 
464  if (traceData)
465  traceData->setMem(addr, size, flags);
466 
467  RequestPtr req = std::make_shared<Request>(
468  addr, size, flags, dataRequestorId(), pc, thread->contextId());
469  req->setByteEnable(byte_enable);
470 
471  req->taskId(taskId());
472 
473  Addr split_addr = roundDown(addr + size - 1, block_size);
474  assert(split_addr <= addr || split_addr - addr < block_size);
475 
477  if (split_addr > addr) {
478  RequestPtr req1, req2;
479  assert(!req->isLLSC() && !req->isSwap());
480  req->splitOnVaddr(split_addr, req1, req2);
481 
482  WholeTranslationState *state =
483  new WholeTranslationState(req, req1, req2, new uint8_t[size],
484  NULL, mode);
486  new DataTranslation<TimingSimpleCPU *>(this, state, 0);
488  new DataTranslation<TimingSimpleCPU *>(this, state, 1);
489 
490  thread->mmu->translateTiming(req1, thread->getTC(), trans1, mode);
491  thread->mmu->translateTiming(req2, thread->getTC(), trans2, mode);
492  } else {
493  WholeTranslationState *state =
494  new WholeTranslationState(req, new uint8_t[size], NULL, mode);
496  = new DataTranslation<TimingSimpleCPU *>(this, state);
497  thread->mmu->translateTiming(req, thread->getTC(), translation, mode);
498  }
499 
500  return NoFault;
501 }
502 
503 bool
505 {
507  SimpleThread* thread = t_info.thread;
508 
509  const RequestPtr &req = dcache_pkt->req;
510  if (req->isLocalAccess()) {
511  Cycles delay = req->localAccessor(thread->getTC(), dcache_pkt);
512  new IprEvent(dcache_pkt, this, clockEdge(delay));
514  dcache_pkt = NULL;
515  } else if (!dcachePort.sendTimingReq(dcache_pkt)) {
517  } else {
519  // memory system takes ownership of packet
520  dcache_pkt = NULL;
521  }
522  return dcache_pkt == NULL;
523 }
524 
525 Fault
526 TimingSimpleCPU::writeMem(uint8_t *data, unsigned size,
527  Addr addr, Request::Flags flags, uint64_t *res,
528  const std::vector<bool>& byte_enable)
529 {
531  SimpleThread* thread = t_info.thread;
532 
533  uint8_t *newData = new uint8_t[size];
534  const Addr pc = thread->pcState().instAddr();
535  unsigned block_size = cacheLineSize();
537 
538  if (data == NULL) {
539  assert(flags & Request::STORE_NO_DATA);
540  // This must be a cache block cleaning request
541  memset(newData, 0, size);
542  } else {
543  memcpy(newData, data, size);
544  }
545 
546  if (traceData)
547  traceData->setMem(addr, size, flags);
548 
549  RequestPtr req = std::make_shared<Request>(
550  addr, size, flags, dataRequestorId(), pc, thread->contextId());
551  req->setByteEnable(byte_enable);
552 
553  req->taskId(taskId());
554 
555  Addr split_addr = roundDown(addr + size - 1, block_size);
556  assert(split_addr <= addr || split_addr - addr < block_size);
557 
559 
560  // TODO: TimingSimpleCPU doesn't support arbitrarily long multi-line mem.
561  // accesses yet
562 
563  if (split_addr > addr) {
564  RequestPtr req1, req2;
565  assert(!req->isLLSC() && !req->isSwap());
566  req->splitOnVaddr(split_addr, req1, req2);
567 
568  WholeTranslationState *state =
569  new WholeTranslationState(req, req1, req2, newData, res, mode);
571  new DataTranslation<TimingSimpleCPU *>(this, state, 0);
573  new DataTranslation<TimingSimpleCPU *>(this, state, 1);
574 
575  thread->mmu->translateTiming(req1, thread->getTC(), trans1, mode);
576  thread->mmu->translateTiming(req2, thread->getTC(), trans2, mode);
577  } else {
578  WholeTranslationState *state =
579  new WholeTranslationState(req, newData, res, mode);
581  new DataTranslation<TimingSimpleCPU *>(this, state);
582  thread->mmu->translateTiming(req, thread->getTC(), translation, mode);
583  }
584 
585  // Translation faults will be returned via finishTranslation()
586  return NoFault;
587 }
588 
589 Fault
591  Request::Flags flags,
592  AtomicOpFunctorPtr amo_op)
593 {
595  SimpleThread* thread = t_info.thread;
596 
597  Fault fault;
598  const Addr pc = thread->pcState().instAddr();
599  unsigned block_size = cacheLineSize();
601 
602  if (traceData)
603  traceData->setMem(addr, size, flags);
604 
605  RequestPtr req = std::make_shared<Request>(addr, size, flags,
606  dataRequestorId(), pc, thread->contextId(),
607  std::move(amo_op));
608 
609  assert(req->hasAtomicOpFunctor());
610 
611  req->taskId(taskId());
612 
613  Addr split_addr = roundDown(addr + size - 1, block_size);
614 
615  // AMO requests that access across a cache line boundary are not
616  // allowed since the cache does not guarantee AMO ops to be executed
617  // atomically in two cache lines
618  // For ISAs such as x86 that requires AMO operations to work on
619  // accesses that cross cache-line boundaries, the cache needs to be
620  // modified to support locking both cache lines to guarantee the
621  // atomicity.
622  if (split_addr > addr) {
623  panic("AMO requests should not access across a cache line boundary\n");
624  }
625 
627 
628  WholeTranslationState *state =
629  new WholeTranslationState(req, new uint8_t[size], NULL, mode);
631  = new DataTranslation<TimingSimpleCPU *>(this, state);
632  thread->mmu->translateTiming(req, thread->getTC(), translation, mode);
633 
634  return NoFault;
635 }
636 
637 void
639 {
640  for (ThreadID tid = 0; tid < numThreads; tid++) {
641  if (tid != sender) {
642  if (getCpuAddrMonitor(tid)->doMonitor(pkt)) {
643  wakeup(tid);
644  }
645  threadInfo[tid]->thread->getIsaPtr()->handleLockedSnoop(pkt,
647  }
648  }
649 }
650 
651 void
653 {
655 
656  if (state->getFault() != NoFault) {
657  if (state->isPrefetch()) {
658  state->setNoFault();
659  }
660  delete [] state->data;
661  state->deleteReqs();
662  translationFault(state->getFault());
663  } else {
664  if (!state->isSplit) {
665  sendData(state->mainReq, state->data, state->res,
666  state->mode == BaseMMU::Read);
667  } else {
668  sendSplitData(state->sreqLow, state->sreqHigh, state->mainReq,
669  state->data, state->mode == BaseMMU::Read);
670  }
671  }
672 
673  delete state;
674 }
675 
676 
677 void
679 {
680  // Change thread if multi-threaded
682 
684  SimpleThread* thread = t_info.thread;
685 
686  DPRINTF(SimpleCPU, "Fetch\n");
687 
691  }
692 
693  // We must have just got suspended by a PC event
694  if (_status == Idle)
695  return;
696 
697  MicroPC upc = thread->pcState().microPC();
698  bool needToFetch = !isRomMicroPC(upc) && !curMacroStaticInst;
699 
700  if (needToFetch) {
702  RequestPtr ifetch_req = std::make_shared<Request>();
703  ifetch_req->taskId(taskId());
704  ifetch_req->setContext(thread->contextId());
705  setupFetchRequest(ifetch_req);
706  DPRINTF(SimpleCPU, "Translating address %#x\n", ifetch_req->getVaddr());
707  thread->mmu->translateTiming(ifetch_req, thread->getTC(),
709  } else {
711  completeIfetch(NULL);
712 
714  updateCycleCounters(BaseCPU::CPU_STATE_ON);
715  }
716 }
717 
718 
719 void
720 TimingSimpleCPU::sendFetch(const Fault &fault, const RequestPtr &req,
721  ThreadContext *tc)
722 {
723  auto &decoder = threadInfo[curThread]->thread->decoder;
724 
725  if (fault == NoFault) {
726  DPRINTF(SimpleCPU, "Sending fetch for addr %#x(pa: %#x)\n",
727  req->getVaddr(), req->getPaddr());
728  ifetch_pkt = new Packet(req, MemCmd::ReadReq);
729  ifetch_pkt->dataStatic(decoder->moreBytesPtr());
730  DPRINTF(SimpleCPU, " -- pkt addr: %#x\n", ifetch_pkt->getAddr());
731 
733  // Need to wait for retry
735  } else {
736  // Need to wait for cache to respond
738  // ownership of packet transferred to memory system
739  ifetch_pkt = NULL;
740  }
741  } else {
742  DPRINTF(SimpleCPU, "Translation of addr %#x faulted\n", req->getVaddr());
743  // fetch fault: advance directly to next instruction (fault handler)
745  advanceInst(fault);
746  }
747 
749  updateCycleCounters(BaseCPU::CPU_STATE_ON);
750 }
751 
752 
753 void
755 {
757 
758  if (_status == Faulting)
759  return;
760 
761  if (fault != NoFault) {
762  // hardware transactional memory
763  // If a fault occurred within a transaction
764  // ensure that the transaction aborts
765  if (t_info.inHtmTransactionalState() &&
766  !std::dynamic_pointer_cast<GenericHtmFailureFault>(fault)) {
767  DPRINTF(HtmCpu, "fault (%s) occurred - "
768  "replacing with HTM abort fault htmUid=%u\n",
769  fault->name(), t_info.getHtmTransactionUid());
770 
771  Fault tmfault = std::make_shared<GenericHtmFailureFault>(
772  t_info.getHtmTransactionUid(),
774 
775  advancePC(tmfault);
776  reschedule(fetchEvent, clockEdge(), true);
777  _status = Faulting;
778  return;
779  }
780 
781  DPRINTF(SimpleCPU, "Fault occured. Handling the fault\n");
782 
783  advancePC(fault);
784 
785  // A syscall fault could suspend this CPU (e.g., futex_wait)
786  // If the _status is not Idle, schedule an event to fetch the next
787  // instruction after 'stall' ticks.
788  // If the cpu has been suspended (i.e., _status == Idle), another
789  // cpu will wake this cpu up later.
790  if (_status != Idle) {
791  DPRINTF(SimpleCPU, "Scheduling fetch event after the Fault\n");
792 
793  Tick stall = std::dynamic_pointer_cast<SyscallRetryFault>(fault) ?
794  clockEdge(syscallRetryLatency) : clockEdge();
795  reschedule(fetchEvent, stall, true);
796  _status = Faulting;
797  }
798 
799  return;
800  }
801 
802  if (!t_info.stayAtPC)
803  advancePC(fault);
804 
805  if (tryCompleteDrain())
806  return;
807 
809 
811  // kick off fetch of next instruction... callback from icache
812  // response will cause that instruction to be executed,
813  // keeping the CPU running.
814  fetch();
815  }
816 }
817 
818 
819 void
821 {
823 
824  DPRINTF(SimpleCPU, "Complete ICache Fetch for addr %#x\n", pkt ?
825  pkt->getAddr() : 0);
826 
827  // received a response from the icache: execute the received
828  // instruction
829  assert(!pkt || !pkt->isError());
830  assert(_status == IcacheWaitResponse);
831 
833 
835  updateCycleCounters(BaseCPU::CPU_STATE_ON);
836 
837  if (pkt)
838  pkt->req->setAccessLatency();
839 
840 
841  preExecute();
842 
843  // hardware transactional memory
845  // if this HtmStart is not within a transaction,
846  // then assign it a new htmTransactionUid
847  if (!t_info.inHtmTransactionalState())
848  t_info.newHtmTransactionUid();
849  SimpleThread* thread = t_info.thread;
850  thread->htmTransactionStarts++;
851  DPRINTF(HtmCpu, "htmTransactionStarts++=%u\n",
852  thread->htmTransactionStarts);
853  }
854 
856  // load or store: just send to dcache
857  Fault fault = curStaticInst->initiateAcc(&t_info, traceData);
858 
859  // If we're not running now the instruction will complete in a dcache
860  // response callback or the instruction faulted and has started an
861  // ifetch
863  if (fault != NoFault && traceData) {
864  traceFault();
865  }
866 
867  postExecute();
868  // @todo remove me after debugging with legion done
869  if (curStaticInst && (!curStaticInst->isMicroop() ||
871  instCnt++;
872  advanceInst(fault);
873  }
874  } else if (curStaticInst) {
875  // non-memory instruction: execute completely now
876  Fault fault = curStaticInst->execute(&t_info, traceData);
877 
878  // keep an instruction count
879  if (fault == NoFault)
880  countInst();
881  else if (traceData) {
882  traceFault();
883  }
884 
885  postExecute();
886  // @todo remove me after debugging with legion done
887  if (curStaticInst && (!curStaticInst->isMicroop() ||
889  instCnt++;
890  advanceInst(fault);
891  } else {
893  }
894 
895  if (pkt) {
896  delete pkt;
897  }
898 }
899 
900 void
902 {
903  cpu->completeIfetch(pkt);
904 }
905 
906 bool
908 {
909  DPRINTF(SimpleCPU, "Received fetch response %#x\n", pkt->getAddr());
910 
911  // hardware transactional memory
912  // Currently, there is no support for tracking instruction fetches
913  // in an transaction's read set.
914  if (pkt->htmTransactionFailedInCache()) {
915  panic("HTM transactional support for"
916  " instruction stream not yet supported\n");
917  }
918 
919  // we should only ever see one response per cycle since we only
920  // issue a new request once this response is sunk
921  assert(!tickEvent.scheduled());
922  // delay processing of returned data until next CPU clock edge
923  tickEvent.schedule(pkt, cpu->clockEdge());
924 
925  return true;
926 }
927 
928 void
930 {
931  // we shouldn't get a retry unless we have a packet that we're
932  // waiting to transmit
933  assert(cpu->ifetch_pkt != NULL);
934  assert(cpu->_status == IcacheRetry);
935  PacketPtr tmp = cpu->ifetch_pkt;
936  if (sendTimingReq(tmp)) {
938  cpu->ifetch_pkt = NULL;
939  }
940 }
941 
942 void
944 {
945  // hardware transactional memory
946 
948  [[maybe_unused]] const bool is_htm_speculative =
949  t_info->inHtmTransactionalState();
950 
951  // received a response from the dcache: complete the load or store
952  // instruction
953  assert(!pkt->isError());
955  pkt->req->getFlags().isSet(Request::NO_ACCESS));
956 
957  pkt->req->setAccessLatency();
958 
960  updateCycleCounters(BaseCPU::CPU_STATE_ON);
961 
962  if (pkt->senderState) {
963  // hardware transactional memory
964  // There shouldn't be HtmCmds occurring in multipacket requests
965  if (pkt->req->isHTMCmd()) {
966  panic("unexpected HTM case");
967  }
968 
969  SplitFragmentSenderState * send_state =
970  dynamic_cast<SplitFragmentSenderState *>(pkt->senderState);
971  assert(send_state);
972  PacketPtr big_pkt = send_state->bigPkt;
973  delete send_state;
974 
975  if (pkt->isHtmTransactional()) {
976  assert(is_htm_speculative);
977 
978  big_pkt->setHtmTransactional(
979  pkt->getHtmTransactionUid()
980  );
981  }
982 
983  if (pkt->htmTransactionFailedInCache()) {
984  assert(is_htm_speculative);
987  );
988  }
989 
990  delete pkt;
991 
992  SplitMainSenderState * main_send_state =
993  dynamic_cast<SplitMainSenderState *>(big_pkt->senderState);
994  assert(main_send_state);
995  // Record the fact that this packet is no longer outstanding.
996  assert(main_send_state->outstanding != 0);
997  main_send_state->outstanding--;
998 
999  if (main_send_state->outstanding) {
1000  return;
1001  } else {
1002  delete main_send_state;
1003  big_pkt->senderState = NULL;
1004  pkt = big_pkt;
1005  }
1006  }
1007 
1009 
1010  Fault fault;
1011 
1012  // hardware transactional memory
1013  // sanity checks
1014  // ensure htmTransactionUids are equivalent
1015  if (pkt->isHtmTransactional())
1016  assert (pkt->getHtmTransactionUid() ==
1017  t_info->getHtmTransactionUid());
1018 
1019  // can't have a packet that fails a transaction while not in a transaction
1020  if (pkt->htmTransactionFailedInCache())
1021  assert(is_htm_speculative);
1022 
1023  // shouldn't fail through stores because this would be inconsistent w/ O3
1024  // which cannot fault after the store has been sent to memory
1025  if (pkt->htmTransactionFailedInCache() && !pkt->isWrite()) {
1026  const HtmCacheFailure htm_rc =
1028  DPRINTF(HtmCpu, "HTM abortion in cache (rc=%s) detected htmUid=%u\n",
1029  htmFailureToStr(htm_rc), pkt->getHtmTransactionUid());
1030 
1031  // Currently there are only two reasons why a transaction would
1032  // fail in the memory subsystem--
1033  // (1) A transactional line was evicted from the cache for
1034  // space (or replacement policy) reasons.
1035  // (2) Another core/device requested a cache line that is in this
1036  // transaction's read/write set that is incompatible with the
1037  // HTM's semantics, e.g. another core requesting exclusive access
1038  // of a line in this core's read set.
1039  if (htm_rc == HtmCacheFailure::FAIL_SELF) {
1040  fault = std::make_shared<GenericHtmFailureFault>(
1041  t_info->getHtmTransactionUid(),
1043  } else if (htm_rc == HtmCacheFailure::FAIL_REMOTE) {
1044  fault = std::make_shared<GenericHtmFailureFault>(
1045  t_info->getHtmTransactionUid(),
1047  } else {
1048  panic("HTM - unhandled rc %s", htmFailureToStr(htm_rc));
1049  }
1050  } else {
1051  fault = curStaticInst->completeAcc(pkt, t_info,
1052  traceData);
1053  }
1054 
1055  // hardware transactional memory
1056  // Track HtmStop instructions,
1057  // e.g. instructions which commit a transaction.
1059  t_info->thread->htmTransactionStops++;
1060  DPRINTF(HtmCpu, "htmTransactionStops++=%u\n",
1061  t_info->thread->htmTransactionStops);
1062  }
1063 
1064  // keep an instruction count
1065  if (fault == NoFault)
1066  countInst();
1067  else if (traceData) {
1068  traceFault();
1069  }
1070 
1071  delete pkt;
1072 
1073  postExecute();
1074 
1075  advanceInst(fault);
1076 }
1077 
1078 void
1080 {
1081  const Cycles delta(curCycle() - previousCycle);
1082 
1083  baseStats.numCycles += delta;
1084 
1085  previousCycle = curCycle();
1086 }
1087 
1088 void
1090 {
1091  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
1092  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1093  cpu->wakeup(tid);
1094  }
1095  }
1096 
1097  // Making it uniform across all CPUs:
1098  // The CPUs need to be woken up only on an invalidation packet (when using caches)
1099  // or on an incoming write packet (when not using caches)
1100  // It is not necessary to wake up the processor on all incoming packets
1101  if (pkt->isInvalidate() || pkt->isWrite()) {
1102  for (auto &t_info : cpu->threadInfo) {
1103  t_info->thread->getIsaPtr()->handleLockedSnoop(pkt,
1104  cacheBlockMask);
1105  }
1106  }
1107 }
1108 
1109 void
1111 {
1112  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
1113  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1114  cpu->wakeup(tid);
1115  }
1116  }
1117 }
1118 
1119 bool
1121 {
1122  DPRINTF(SimpleCPU, "Received load/store response %#x\n", pkt->getAddr());
1123 
1124  // The timing CPU is not really ticked, instead it relies on the
1125  // memory system (fetch and load/store) to set the pace.
1126  if (!tickEvent.scheduled()) {
1127  // Delay processing of returned data until next CPU clock edge
1128  tickEvent.schedule(pkt, cpu->clockEdge());
1129  return true;
1130  } else {
1131  // In the case of a split transaction and a cache that is
1132  // faster than a CPU we could get two responses in the
1133  // same tick, delay the second one
1134  if (!retryRespEvent.scheduled())
1135  cpu->schedule(retryRespEvent, cpu->clockEdge(Cycles(1)));
1136  return false;
1137  }
1138 }
1139 
1140 void
1142 {
1143  cpu->completeDataAccess(pkt);
1144 }
1145 
1146 void
1148 {
1149  // we shouldn't get a retry unless we have a packet that we're
1150  // waiting to transmit
1151  assert(cpu->dcache_pkt != NULL);
1152  assert(cpu->_status == DcacheRetry);
1153  PacketPtr tmp = cpu->dcache_pkt;
1154  if (tmp->senderState) {
1155  // This is a packet from a split access.
1156  SplitFragmentSenderState * send_state =
1157  dynamic_cast<SplitFragmentSenderState *>(tmp->senderState);
1158  assert(send_state);
1159  PacketPtr big_pkt = send_state->bigPkt;
1160 
1161  SplitMainSenderState * main_send_state =
1162  dynamic_cast<SplitMainSenderState *>(big_pkt->senderState);
1163  assert(main_send_state);
1164 
1165  if (sendTimingReq(tmp)) {
1166  // If we were able to send without retrying, record that fact
1167  // and try sending the other fragment.
1168  send_state->clearFromParent();
1169  int other_index = main_send_state->getPendingFragment();
1170  if (other_index > 0) {
1171  tmp = main_send_state->fragments[other_index];
1172  cpu->dcache_pkt = tmp;
1173  if ((big_pkt->isRead() && cpu->handleReadPacket(tmp)) ||
1174  (big_pkt->isWrite() && cpu->handleWritePacket())) {
1175  main_send_state->fragments[other_index] = NULL;
1176  }
1177  } else {
1179  // memory system takes ownership of packet
1180  cpu->dcache_pkt = NULL;
1181  }
1182  }
1183  } else if (sendTimingReq(tmp)) {
1185  // memory system takes ownership of packet
1186  cpu->dcache_pkt = NULL;
1187  }
1188 }
1189 
1191  Tick t)
1192  : pkt(_pkt), cpu(_cpu)
1193 {
1194  cpu->schedule(this, t);
1195 }
1196 
1197 void
1199 {
1200  cpu->completeDataAccess(pkt);
1201 }
1202 
1203 const char *
1205 {
1206  return "Timing Simple CPU Delay IPR event";
1207 }
1208 
1209 
1210 void
1212 {
1214 }
1215 
1216 Fault
1218 {
1220  SimpleThread* thread = t_info.thread;
1221 
1222  const Addr addr = 0x0ul;
1223  const Addr pc = thread->pcState().instAddr();
1224  const int size = 8;
1225 
1226  if (traceData)
1227  traceData->setMem(addr, size, flags);
1228 
1229  RequestPtr req = std::make_shared<Request>(
1230  addr, size, flags, dataRequestorId());
1231 
1232  req->setPC(pc);
1233  req->setContext(thread->contextId());
1234  req->taskId(taskId());
1235  req->setInstCount(t_info.numInst);
1236 
1237  assert(req->isHTMCmd());
1238 
1239  // Use the payload as a sanity check,
1240  // the memory subsystem will clear allocated data
1241  uint8_t *data = new uint8_t[size];
1242  assert(data);
1243  uint64_t rc = 0xdeadbeeflu;
1244  memcpy (data, &rc, size);
1245 
1246  // debugging output
1247  if (req->isHTMStart())
1248  DPRINTF(HtmCpu, "HTMstart htmUid=%u\n", t_info.getHtmTransactionUid());
1249  else if (req->isHTMCommit())
1250  DPRINTF(HtmCpu, "HTMcommit htmUid=%u\n", t_info.getHtmTransactionUid());
1251  else if (req->isHTMCancel())
1252  DPRINTF(HtmCpu, "HTMcancel htmUid=%u\n", t_info.getHtmTransactionUid());
1253  else
1254  panic("initiateHtmCmd: unknown CMD");
1255 
1256  sendData(req, data, nullptr, true);
1257 
1258  return NoFault;
1259 }
1260 
1261 void
1263  HtmFailureFaultCause cause)
1264 {
1265  SimpleExecContext& t_info = *threadInfo[tid];
1266  SimpleThread* thread = t_info.thread;
1267 
1268  const Addr addr = 0x0ul;
1269  const Addr pc = thread->pcState().instAddr();
1270  const int size = 8;
1271  const Request::Flags flags =
1273 
1274  if (traceData)
1275  traceData->setMem(addr, size, flags);
1276 
1277  // notify l1 d-cache (ruby) that core has aborted transaction
1278 
1279  RequestPtr req = std::make_shared<Request>(
1280  addr, size, flags, dataRequestorId());
1281 
1282  req->setPC(pc);
1283  req->setContext(thread->contextId());
1284  req->taskId(taskId());
1285  req->setInstCount(t_info.numInst);
1286  req->setHtmAbortCause(cause);
1287 
1288  assert(req->isHTMAbort());
1289 
1290  uint8_t *data = new uint8_t[size];
1291  assert(data);
1292  uint64_t rc = 0lu;
1293  memcpy (data, &rc, size);
1294 
1295  sendData(req, data, nullptr, true);
1296 }
1297 
1298 } // namespace gem5
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
gem5::TimingSimpleCPU::init
void init() override
Definition: timing.cc:65
gem5::Request::HTM_ABORT
@ HTM_ABORT
The request aborts a HTM transaction.
Definition: request.hh:216
gem5::PCStateBase::instAddr
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition: pcstate.hh:107
gem5::BaseMMU::Read
@ Read
Definition: mmu.hh:56
gem5::BaseSimpleCPU::DcacheRetry
@ DcacheRetry
Definition: base.hh:120
gem5::BaseISA::handleLockedRead
virtual void handleLockedRead(const RequestPtr &req)
Definition: isa.hh:81
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:260
gem5::ThreadContext::Active
@ Active
Running.
Definition: thread_context.hh:109
gem5::StaticInst::isMicroop
bool isMicroop() const
Definition: static_inst.hh:207
gem5::RequestPort::sendTimingReq
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
Definition: port.hh:495
gem5::TimingSimpleCPU::initiateHtmCmd
Fault initiateHtmCmd(Request::Flags flags) override
hardware transactional memory
Definition: timing.cc:1217
gem5::TimingSimpleCPU::htmSendAbortSignal
void htmSendAbortSignal(ThreadID tid, uint64_t htm_uid, HtmFailureFaultCause) override
Definition: timing.cc:1262
gem5::TimingSimpleCPU::sendData
void sendData(const RequestPtr &req, uint8_t *data, uint64_t *res, bool read)
Definition: timing.cc:298
gem5::SimpleThread::htmTransactionStops
int64_t htmTransactionStops
Definition: simple_thread.hh:140
gem5::BaseSimpleCPU::threadInfo
std::vector< SimpleExecContext * > threadInfo
Definition: base.hh:102
gem5::WholeTranslationState::isPrefetch
bool isPrefetch() const
Check if this request is a prefetch.
Definition: translation.hh:173
gem5::TimingSimpleCPU::IprEvent::process
virtual void process()
Definition: timing.cc:1198
system.hh
gem5::Trace::InstRecord::setMem
void setMem(Addr a, Addr s, unsigned f)
Definition: insttracer.hh:182
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::BaseSimpleCPU::traceData
Trace::InstRecord * traceData
Definition: base.hh:99
gem5::HtmFailureFaultCause
HtmFailureFaultCause
Definition: htm.hh:47
gem5::WholeTranslationState::setNoFault
void setNoFault()
Remove all faults from the translation.
Definition: translation.hh:151
timing.hh
gem5::HtmFailureFaultCause::MEMORY
@ MEMORY
gem5::TimingSimpleCPU::TimingCPUPort::retryRespEvent
EventFunctionWrapper retryRespEvent
Definition: timing.hh:185
gem5::TimingSimpleCPU::SplitMainSenderState::fragments
PacketPtr fragments[2]
Definition: timing.hh:78
gem5::TimingSimpleCPU::TimingCPUPort::TickEvent::cpu
TimingSimpleCPU * cpu
Definition: timing.hh:178
gem5::isRomMicroPC
static bool isRomMicroPC(MicroPC upc)
Definition: types.hh:166
gem5::BaseMMU::Mode
Mode
Definition: mmu.hh:56
gem5::TimingSimpleCPU::drain
DrainState drain() override
Definition: timing.cc:92
gem5::Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:366
gem5::MemCmd::responseCommand
Command responseCommand() const
Definition: packet.hh:259
gem5::WholeTranslationState::data
uint8_t * data
Definition: translation.hh:74
gem5::TimingSimpleCPU::buildSplitPacket
void buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2, const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req, uint8_t *data, bool read)
Definition: timing.cc:420
gem5::BaseSimpleCPU::_status
Status _status
Definition: base.hh:125
gem5::BaseMMU::Write
@ Write
Definition: mmu.hh:56
gem5::TimingSimpleCPU::DcachePort::cacheBlockMask
Addr cacheBlockMask
Definition: timing.hh:227
gem5::BaseISA::handleLockedWrite
virtual bool handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask)
Definition: isa.hh:88
gem5::TimingSimpleCPU::SplitFragmentSenderState
Definition: timing.hh:93
gem5::TimingSimpleCPU::IprEvent
Definition: timing.hh:337
gem5::HtmCacheFailure
HtmCacheFailure
Definition: htm.hh:59
gem5::TimingSimpleCPU::ifetch_pkt
PacketPtr ifetch_pkt
Definition: timing.hh:261
gem5::Packet::setHtmTransactional
void setHtmTransactional(uint64_t val)
Stipulates that this packet/request originates in the CPU executing in transactional mode,...
Definition: packet.cc:521
gem5::BaseSimpleCPU::curStaticInst
StaticInstPtr curStaticInst
Current instruction.
Definition: base.hh:106
exetrace.hh
gem5::TimingSimpleCPU::buildPacket
PacketPtr buildPacket(const RequestPtr &req, bool read)
Definition: timing.cc:414
gem5::ArmISA::a
Bitfield< 8 > a
Definition: misc_types.hh:66
gem5::SimpleExecContext::newHtmTransactionUid
uint64_t newHtmTransactionUid() const override
Definition: exec_context.hh:587
gem5::TimingSimpleCPU::verifyMemoryMode
void verifyMemoryMode() const override
Definition: timing.cc:200
gem5::TimingSimpleCPU::fetch
void fetch()
Definition: timing.cc:678
gem5::TimingSimpleCPU::dcachePort
DcachePort dcachePort
Definition: timing.hh:259
gem5::TimingSimpleCPU::SplitMainSenderState::getPendingFragment
int getPendingFragment()
Definition: timing.hh:81
gem5::Packet::isWrite
bool isWrite() const
Definition: packet.hh:583
gem5::TimingSimpleCPU::DcachePort::DTickEvent::process
void process()
Definition: timing.cc:1141
gem5::Packet::createWrite
static PacketPtr createWrite(const RequestPtr &req)
Definition: packet.hh:1013
gem5::X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:1003
std::vector< bool >
gem5::PCStateBase::microPC
MicroPC microPC() const
Returns the current micropc.
Definition: pcstate.hh:118
gem5::TimingSimpleCPU::DcachePort::recvTimingSnoopReq
virtual void recvTimingSnoopReq(PacketPtr pkt)
Snoop a coherence request, we need to check if this causes a wakeup event on a cpu that is monitoring...
Definition: timing.cc:1089
gem5::StaticInst::isDelayedCommit
bool isDelayedCommit() const
Definition: static_inst.hh:208
gem5::TimingSimpleCPU::sendFetch
void sendFetch(const Fault &fault, const RequestPtr &req, ThreadContext *tc)
Definition: timing.cc:720
gem5::TimingSimpleCPU::IcachePort::recvReqRetry
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Definition: timing.cc:929
gem5::StaticInst::isFirstMicroop
bool isFirstMicroop() const
Definition: static_inst.hh:210
faults.hh
gem5::WholeTranslationState::deleteReqs
void deleteReqs()
Delete all requests that make up this translation.
Definition: translation.hh:198
gem5::BaseSimpleCPU::IcacheRetry
@ IcacheRetry
Definition: base.hh:116
gem5::SimpleThread::htmTransactionStarts
int64_t htmTransactionStarts
Definition: simple_thread.hh:139
gem5::SimpleThread
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
Definition: simple_thread.hh:93
gem5::TimingSimpleCPU::completeDataAccess
void completeDataAccess(PacketPtr pkt)
Definition: timing.cc:943
gem5::BaseMMU::Execute
@ Execute
Definition: mmu.hh:56
gem5::BaseSimpleCPU::checkForInterrupts
void checkForInterrupts()
Definition: base.cc:250
gem5::StaticInst::execute
virtual Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const =0
gem5::TimingSimpleCPU::IcachePort::recvTimingResp
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Definition: timing.cc:907
gem5::HtmCacheFailure::FAIL_SELF
@ FAIL_SELF
gem5::takeOverFrom
void takeOverFrom(ThreadContext &ntc, ThreadContext &otc)
Copy state between thread contexts in preparation for CPU handover.
Definition: thread_context.cc:254
packet.hh
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
gem5::HtmFailureFaultCause::EXCEPTION
@ EXCEPTION
gem5::SimpleThread::mmu
BaseMMU * mmu
Definition: simple_thread.hh:134
gem5::Packet::dataStatic
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:1134
gem5::MicroPC
uint16_t MicroPC
Definition: types.hh:149
gem5::TimingSimpleCPU::updateCycleCounts
void updateCycleCounts()
Definition: timing.cc:1079
gem5::PowerISA::rc
Bitfield< 0 > rc
Definition: types.hh:87
gem5::Flags< FlagsType >
gem5::DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:74
gem5::HtmCacheFailure::FAIL_REMOTE
@ FAIL_REMOTE
gem5::TimingSimpleCPU::IprEvent::cpu
TimingSimpleCPU * cpu
Definition: timing.hh:340
gem5::Packet::isRead
bool isRead() const
Definition: packet.hh:582
decoder.hh
gem5::StaticInst::isHtmStart
bool isHtmStart() const
Definition: static_inst.hh:214
gem5::WholeTranslationState::res
uint64_t * res
Definition: translation.hh:75
gem5::TimingSimpleCPU::icachePort
IcachePort icachePort
Definition: timing.hh:258
gem5::TimingSimpleCPU::switchOut
void switchOut() override
Definition: timing.cc:170
gem5::BaseSimpleCPU::checkPcEventQueue
void checkPcEventQueue()
Definition: base.cc:125
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:94
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:255
gem5::DataTranslation
This class represents part of a data address translation.
Definition: translation.hh:219
gem5::SimpleExecContext::inHtmTransactionalState
bool inHtmTransactionalState() const override
Definition: exec_context.hh:593
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::TimingSimpleCPU::initiateMemAMO
Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
Definition: timing.cc:590
gem5::TimingSimpleCPU::fetchEvent
EventFunctionWrapper fetchEvent
Definition: timing.hh:335
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:283
gem5::BaseSimpleCPU::preExecute
void preExecute()
Definition: base.cc:305
gem5::TimingSimpleCPU::printAddr
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
Definition: timing.cc:1211
gem5::Packet::htmTransactionFailedInCache
bool htmTransactionFailedInCache() const
Returns whether or not this packet/request has returned from the cache hierarchy in a failed transact...
Definition: packet.cc:508
gem5::TimingSimpleCPU::~TimingSimpleCPU
virtual ~TimingSimpleCPU()
Definition: timing.cc:87
gem5::probing::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:109
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::StaticInst::isHtmStop
bool isHtmStop() const
Definition: static_inst.hh:215
gem5::SimpleExecContext::stayAtPC
bool stayAtPC
Definition: exec_context.hh:70
gem5::TimingSimpleCPU::handleWritePacket
bool handleWritePacket()
Definition: timing.cc:504
gem5::BaseSimpleCPU::setupFetchRequest
void setupFetchRequest(const RequestPtr &req)
Definition: base.cc:281
gem5::RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
gem5::Request::NO_ACCESS
@ NO_ACCESS
The request should not cause a memory access.
Definition: request.hh:146
gem5::MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:86
gem5::BaseSimpleCPU::DTBWaitResponse
@ DTBWaitResponse
Definition: base.hh:119
gem5::Packet::getHtmTransactionUid
uint64_t getHtmTransactionUid() const
If a packet/request originates in a CPU executing in transactional mode, i.e.
Definition: packet.cc:534
gem5::TimingSimpleCPU::activateContext
void activateContext(ThreadID thread_num) override
Definition: timing.cc:209
gem5::TimingSimpleCPU::IprEvent::IprEvent
IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
Definition: timing.cc:1190
gem5::TimingSimpleCPU::completeIfetch
void completeIfetch(PacketPtr)
Definition: timing.cc:820
gem5::BaseSimpleCPU::activeThreads
std::list< ThreadID > activeThreads
Definition: base.hh:103
gem5::SimpleThread::getIsaPtr
BaseISA * getIsaPtr() override
Definition: simple_thread.hh:213
gem5::TimingSimpleCPU::initiateMemRead
Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
Definition: timing.cc:452
gem5::BaseSimpleCPU
Definition: base.hh:83
compiler.hh
gem5::TimingSimpleCPU::advanceInst
void advanceInst(const Fault &fault)
Definition: timing.cc:754
gem5::Packet::getHtmTransactionFailedInCacheRC
HtmCacheFailure getHtmTransactionFailedInCacheRC() const
If a packet/request has returned from the cache hierarchy in a failed transaction,...
Definition: packet.cc:514
gem5::roundDown
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:279
gem5::BaseSimpleCPU::traceFault
void traceFault()
Handler used when encountering a fault; its purpose is to tear down the InstRecord.
Definition: base.cc:239
gem5::SimpleExecContext::numInst
Counter numInst
PER-THREAD STATS.
Definition: exec_context.hh:76
gem5::DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
gem5::Packet::cmd
MemCmd cmd
The command field of the packet.
Definition: packet.hh:361
gem5::ArmISA::t
Bitfield< 5 > t
Definition: misc_types.hh:71
gem5::SimpleThread::pcState
const PCStateBase & pcState() const override
Definition: simple_thread.hh:422
gem5::TimingSimpleCPU::DcachePort::recvFunctionalSnoop
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
Definition: timing.cc:1110
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::Packet::isError
bool isError() const
Definition: packet.hh:610
gem5::TimingSimpleCPU::DcachePort::recvTimingResp
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Definition: timing.cc:1120
gem5::TimingSimpleCPU::threadSnoop
void threadSnoop(PacketPtr pkt, ThreadID sender)
Definition: timing.cc:638
gem5::Packet::senderState
SenderState * senderState
This packet's sender state.
Definition: packet.hh:534
name
const std::string & name()
Definition: trace.cc:49
gem5::StaticInst::isMemRef
bool isMemRef() const
Definition: static_inst.hh:164
gem5::BaseMMU::translateTiming
virtual void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)
Definition: mmu.cc:111
packet_access.hh
gem5::WholeTranslationState::sreqHigh
RequestPtr sreqHigh
Definition: translation.hh:73
gem5::WholeTranslationState::mainReq
RequestPtr mainReq
Definition: translation.hh:71
full_system.hh
gem5::TimingSimpleCPU::DcachePort::recvReqRetry
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Definition: timing.cc:1147
gem5::BaseSimpleCPU::postExecute
void postExecute()
Definition: base.cc:387
gem5::SimpleThread::contextId
ContextID contextId() const override
Definition: simple_thread.hh:206
gem5::BaseSimpleCPU::Faulting
@ Faulting
Definition: base.hh:114
gem5::TimingSimpleCPU::SplitFragmentSenderState::clearFromParent
void clearFromParent()
Definition: timing.hh:103
gem5::SimpleExecContext::thread
SimpleThread * thread
Definition: exec_context.hh:64
gem5::SimpleThread::getTC
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
Definition: simple_thread.hh:169
gem5::Request::STORE_NO_DATA
static const FlagsType STORE_NO_DATA
Definition: request.hh:246
gem5::TimingSimpleCPU::takeOverFrom
void takeOverFrom(BaseCPU *oldCPU) override
Definition: timing.cc:192
gem5::TimingSimpleCPU::finishTranslation
void finishTranslation(WholeTranslationState *state)
Finish a DTB translation.
Definition: timing.cc:652
gem5::TimingSimpleCPU::tryCompleteDrain
bool tryCompleteDrain()
Try to complete a drain request.
Definition: timing.cc:154
gem5::TimingSimpleCPU::TimingCPUPort::TickEvent::pkt
PacketPtr pkt
Definition: timing.hh:177
gem5::HtmFailureFaultCause::SIZE
@ SIZE
gem5::TimingSimpleCPU::drainResume
void drainResume() override
Definition: timing.cc:119
gem5::TimingSimpleCPU::previousCycle
Cycles previousCycle
Definition: timing.hh:264
gem5::StaticInst::completeAcc
virtual Fault completeAcc(Packet *pkt, ExecContext *xc, Trace::InstRecord *trace_data) const
Definition: static_inst.hh:316
gem5::Request::STRICT_ORDER
@ STRICT_ORDER
The request is required to be strictly ordered by CPU models and is non-speculative.
Definition: request.hh:135
gem5::BaseSimpleCPU::countInst
void countInst()
Definition: base.cc:153
gem5::TimingSimpleCPU::translationFault
void translationFault(const Fault &fault)
Definition: timing.cc:397
gem5::htmFailureToStr
std::string htmFailureToStr(HtmFailureFaultCause cause)
Convert enum into string to be used for debug purposes.
Definition: htm.cc:44
gem5::WholeTranslationState
This class captures the state of an address translation.
Definition: translation.hh:62
gem5::TimingSimpleCPU::dcache_pkt
PacketPtr dcache_pkt
Definition: timing.hh:262
gem5::SimpleExecContext
Definition: exec_context.hh:60
gem5::TimingSimpleCPU::TimingCPUPort::cpu
TimingSimpleCPU * cpu
Definition: timing.hh:173
gem5::BaseSimpleCPU::Running
@ Running
Definition: base.hh:113
gem5::StaticInst::initiateAcc
virtual Fault initiateAcc(ExecContext *xc, Trace::InstRecord *traceData) const
Definition: static_inst.hh:310
gem5::TimingSimpleCPU::handleReadPacket
bool handleReadPacket(PacketPtr pkt)
Definition: timing.cc:263
gem5::TimingSimpleCPU::SplitMainSenderState::outstanding
int outstanding
Definition: timing.hh:77
gem5::TimingSimpleCPU::suspendContext
void suspendContext(ThreadID thread_num) override
Definition: timing.cc:233
gem5::Packet::makeResponse
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition: packet.hh:1031
gem5::BaseSimpleCPU::swapActiveThread
void swapActiveThread()
Definition: base.cc:137
gem5::Packet::dataDynamic
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
Definition: packet.hh:1172
gem5::MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:243
gem5::BaseSimpleCPU::IcacheWaitResponse
@ IcacheWaitResponse
Definition: base.hh:117
gem5::TimingSimpleCPU::IprEvent::description
virtual const char * description() const
Return a C string describing the event.
Definition: timing.cc:1204
gem5::BaseSimpleCPU::serviceInstCountEvents
void serviceInstCountEvents()
Definition: base.cc:298
gem5::TimingSimpleCPU::SplitMainSenderState
Definition: timing.hh:74
gem5::WholeTranslationState::mode
BaseMMU::Mode mode
Definition: translation.hh:76
gem5::BaseSimpleCPU::wakeup
void wakeup(ThreadID tid) override
Definition: base.cc:228
gem5::BaseSimpleCPU::advancePC
void advancePC(const Fault &fault)
Definition: base.cc:462
gem5::TimingSimpleCPU::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: timing.cc:526
gem5::statistics::init
const FlagsType init
This Stat is Initialized.
Definition: info.hh:56
gem5::TimingSimpleCPU::TimingCPUPort::TickEvent::schedule
void schedule(PacketPtr _pkt, Tick t)
Definition: timing.cc:71
gem5::TimingSimpleCPU::SplitFragmentSenderState::bigPkt
PacketPtr bigPkt
Definition: timing.hh:99
gem5::WholeTranslationState::getFault
Fault getFault() const
Determine whether this translation produced a fault.
Definition: translation.hh:137
gem5::Packet::setHtmTransactionFailedInCache
void setHtmTransactionFailedInCache(const HtmCacheFailure ret_code)
Stipulates that this packet/request has returned from the cache hierarchy in a failed transaction.
Definition: packet.cc:498
decoder
output decoder
Definition: nop.cc:61
gem5::Packet::isHtmTransactional
bool isHtmTransactional() const
Returns whether or not this packet/request originates in the CPU executing in transactional mode,...
Definition: packet.cc:528
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:781
gem5::TimingSimpleCPU::sendSplitData
void sendSplitData(const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req, uint8_t *data, bool read)
Definition: timing.cc:347
gem5::AtomicOpFunctorPtr
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Definition: amo.hh:242
gem5::BaseSimpleCPU::DcacheWaitResponse
@ DcacheWaitResponse
Definition: base.hh:121
gem5::WholeTranslationState::isSplit
bool isSplit
Definition: translation.hh:70
gem5::TimingSimpleCPU::fetchTranslation
FetchTranslation fetchTranslation
Definition: timing.hh:135
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: tlb.cc:60
gem5::BaseSimpleCPU::Idle
@ Idle
Definition: base.hh:112
gem5::Packet::createRead
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
Definition: packet.hh:1007
gem5::TimingSimpleCPU::IcachePort::ITickEvent::process
void process()
Definition: timing.cc:901
gem5::TimingSimpleCPU
Definition: timing.hh:53
gem5::SimpleExecContext::getHtmTransactionUid
uint64_t getHtmTransactionUid() const override
Definition: exec_context.hh:581
gem5::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:157
gem5::BaseSimpleCPU::curMacroStaticInst
StaticInstPtr curMacroStaticInst
Definition: base.hh:107
gem5::TimingSimpleCPU::isCpuDrained
bool isCpuDrained() const
Check if a system is in a drained state.
Definition: timing.hh:362
gem5::BaseSimpleCPU::curThread
ThreadID curThread
Definition: base.hh:86
gem5::DrainState::Draining
@ Draining
Draining buffers pending serialization/handover.
gem5::Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
gem5::ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:242
gem5::WholeTranslationState::sreqLow
RequestPtr sreqLow
Definition: translation.hh:72
gem5::Packet::isInvalidate
bool isInvalidate() const
Definition: packet.hh:598
gem5::TimingSimpleCPU::IcachePort::tickEvent
ITickEvent tickEvent
Definition: timing.hh:212
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
gem5::ArmISA::mode
Bitfield< 4, 0 > mode
Definition: misc_types.hh:74
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::Request::PHYSICAL
@ PHYSICAL
The virtual address is also the physical address.
Definition: request.hh:117
gem5::TimingSimpleCPU::TimingSimpleCPU
TimingSimpleCPU(const TimingSimpleCPUParams &params)
Definition: timing.cc:77

Generated on Wed May 4 2022 12:13:54 for gem5 by doxygen 1.8.17