gem5  v22.0.0.0
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-2021 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/BaseTimingSimpleCPU.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 BaseTimingSimpleCPUParams &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
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 
483  new WholeTranslationState(req, req1, req2, new uint8_t[size],
484  NULL, mode);
489 
490  thread->mmu->translateTiming(req1, thread->getTC(), trans1, mode);
491  thread->mmu->translateTiming(req2, thread->getTC(), trans2, mode);
492  } else {
494  new WholeTranslationState(req, new uint8_t[size], NULL, mode);
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 
569  new WholeTranslationState(req, req1, req2, newData, res, mode);
574 
575  thread->mmu->translateTiming(req1, thread->getTC(), trans1, mode);
576  thread->mmu->translateTiming(req2, thread->getTC(), trans2, mode);
577  } else {
579  new WholeTranslationState(req, newData, res, mode);
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
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 
629  new WholeTranslationState(req, new uint8_t[size], NULL, mode);
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  panic_if(pkt && pkt->isError(), "Instruction fetch (%s) failed: %s",
830  pkt->getAddrRange().to_string(), pkt->print());
831  assert(_status == IcacheWaitResponse);
832 
834 
836  updateCycleCounters(BaseCPU::CPU_STATE_ON);
837 
838  if (pkt)
839  pkt->req->setAccessLatency();
840 
841 
842  preExecute();
843 
844  // hardware transactional memory
846  // if this HtmStart is not within a transaction,
847  // then assign it a new htmTransactionUid
848  if (!t_info.inHtmTransactionalState())
849  t_info.newHtmTransactionUid();
850  SimpleThread* thread = t_info.thread;
851  thread->htmTransactionStarts++;
852  DPRINTF(HtmCpu, "htmTransactionStarts++=%u\n",
853  thread->htmTransactionStarts);
854  }
855 
857  // load or store: just send to dcache
858  Fault fault = curStaticInst->initiateAcc(&t_info, traceData);
859 
860  // If we're not running now the instruction will complete in a dcache
861  // response callback or the instruction faulted and has started an
862  // ifetch
864  if (fault != NoFault && traceData) {
865  traceFault();
866  }
867 
868  postExecute();
869  // @todo remove me after debugging with legion done
870  if (curStaticInst && (!curStaticInst->isMicroop() ||
872  instCnt++;
873  advanceInst(fault);
874  }
875  } else if (curStaticInst) {
876  // non-memory instruction: execute completely now
877  Fault fault = curStaticInst->execute(&t_info, traceData);
878 
879  // keep an instruction count
880  if (fault == NoFault)
881  countInst();
882  else if (traceData) {
883  traceFault();
884  }
885 
886  postExecute();
887  // @todo remove me after debugging with legion done
888  if (curStaticInst && (!curStaticInst->isMicroop() ||
890  instCnt++;
891  advanceInst(fault);
892  } else {
894  }
895 
896  if (pkt) {
897  delete pkt;
898  }
899 }
900 
901 void
903 {
904  cpu->completeIfetch(pkt);
905 }
906 
907 bool
909 {
910  DPRINTF(SimpleCPU, "Received fetch response %#x\n", pkt->getAddr());
911 
912  // hardware transactional memory
913  // Currently, there is no support for tracking instruction fetches
914  // in an transaction's read set.
915  if (pkt->htmTransactionFailedInCache()) {
916  panic("HTM transactional support for"
917  " instruction stream not yet supported\n");
918  }
919 
920  // we should only ever see one response per cycle since we only
921  // issue a new request once this response is sunk
922  assert(!tickEvent.scheduled());
923  // delay processing of returned data until next CPU clock edge
924  tickEvent.schedule(pkt, cpu->clockEdge());
925 
926  return true;
927 }
928 
929 void
931 {
932  // we shouldn't get a retry unless we have a packet that we're
933  // waiting to transmit
934  assert(cpu->ifetch_pkt != NULL);
935  assert(cpu->_status == IcacheRetry);
936  PacketPtr tmp = cpu->ifetch_pkt;
937  if (sendTimingReq(tmp)) {
939  cpu->ifetch_pkt = NULL;
940  }
941 }
942 
943 void
945 {
946  // hardware transactional memory
947 
949  [[maybe_unused]] const bool is_htm_speculative =
950  t_info->inHtmTransactionalState();
951 
952  // received a response from the dcache: complete the load or store
953  // instruction
954  panic_if(pkt->isError(), "Data access (%s) failed: %s",
955  pkt->getAddrRange().to_string(), pkt->print());
957  pkt->req->getFlags().isSet(Request::NO_ACCESS));
958 
959  pkt->req->setAccessLatency();
960 
962  updateCycleCounters(BaseCPU::CPU_STATE_ON);
963 
964  if (pkt->senderState) {
965  // hardware transactional memory
966  // There shouldn't be HtmCmds occurring in multipacket requests
967  if (pkt->req->isHTMCmd()) {
968  panic("unexpected HTM case");
969  }
970 
971  SplitFragmentSenderState * send_state =
972  dynamic_cast<SplitFragmentSenderState *>(pkt->senderState);
973  assert(send_state);
974  PacketPtr big_pkt = send_state->bigPkt;
975  delete send_state;
976 
977  if (pkt->isHtmTransactional()) {
978  assert(is_htm_speculative);
979 
980  big_pkt->setHtmTransactional(
981  pkt->getHtmTransactionUid()
982  );
983  }
984 
985  if (pkt->htmTransactionFailedInCache()) {
986  assert(is_htm_speculative);
989  );
990  }
991 
992  delete pkt;
993 
994  SplitMainSenderState * main_send_state =
995  dynamic_cast<SplitMainSenderState *>(big_pkt->senderState);
996  assert(main_send_state);
997  // Record the fact that this packet is no longer outstanding.
998  assert(main_send_state->outstanding != 0);
999  main_send_state->outstanding--;
1000 
1001  if (main_send_state->outstanding) {
1002  return;
1003  } else {
1004  delete main_send_state;
1005  big_pkt->senderState = NULL;
1006  pkt = big_pkt;
1007  }
1008  }
1009 
1011 
1012  Fault fault;
1013 
1014  // hardware transactional memory
1015  // sanity checks
1016  // ensure htmTransactionUids are equivalent
1017  if (pkt->isHtmTransactional())
1018  assert (pkt->getHtmTransactionUid() ==
1019  t_info->getHtmTransactionUid());
1020 
1021  // can't have a packet that fails a transaction while not in a transaction
1022  if (pkt->htmTransactionFailedInCache())
1023  assert(is_htm_speculative);
1024 
1025  // shouldn't fail through stores because this would be inconsistent w/ O3
1026  // which cannot fault after the store has been sent to memory
1027  if (pkt->htmTransactionFailedInCache() && !pkt->isWrite()) {
1028  const HtmCacheFailure htm_rc =
1030  DPRINTF(HtmCpu, "HTM abortion in cache (rc=%s) detected htmUid=%u\n",
1031  htmFailureToStr(htm_rc), pkt->getHtmTransactionUid());
1032 
1033  // Currently there are only two reasons why a transaction would
1034  // fail in the memory subsystem--
1035  // (1) A transactional line was evicted from the cache for
1036  // space (or replacement policy) reasons.
1037  // (2) Another core/device requested a cache line that is in this
1038  // transaction's read/write set that is incompatible with the
1039  // HTM's semantics, e.g. another core requesting exclusive access
1040  // of a line in this core's read set.
1041  if (htm_rc == HtmCacheFailure::FAIL_SELF) {
1042  fault = std::make_shared<GenericHtmFailureFault>(
1043  t_info->getHtmTransactionUid(),
1045  } else if (htm_rc == HtmCacheFailure::FAIL_REMOTE) {
1046  fault = std::make_shared<GenericHtmFailureFault>(
1047  t_info->getHtmTransactionUid(),
1049  } else {
1050  panic("HTM - unhandled rc %s", htmFailureToStr(htm_rc));
1051  }
1052  } else {
1053  fault = curStaticInst->completeAcc(pkt, t_info,
1054  traceData);
1055  }
1056 
1057  // hardware transactional memory
1058  // Track HtmStop instructions,
1059  // e.g. instructions which commit a transaction.
1061  t_info->thread->htmTransactionStops++;
1062  DPRINTF(HtmCpu, "htmTransactionStops++=%u\n",
1063  t_info->thread->htmTransactionStops);
1064  }
1065 
1066  // keep an instruction count
1067  if (fault == NoFault)
1068  countInst();
1069  else if (traceData) {
1070  traceFault();
1071  }
1072 
1073  delete pkt;
1074 
1075  postExecute();
1076 
1077  advanceInst(fault);
1078 }
1079 
1080 void
1082 {
1083  const Cycles delta(curCycle() - previousCycle);
1084 
1085  baseStats.numCycles += delta;
1086 
1087  previousCycle = curCycle();
1088 }
1089 
1090 void
1092 {
1093  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
1094  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1095  cpu->wakeup(tid);
1096  }
1097  }
1098 
1099  // Making it uniform across all CPUs:
1100  // The CPUs need to be woken up only on an invalidation packet
1101  // (when using caches) or on an incoming write packet (when not
1102  // using caches) It is not necessary to wake up the processor on
1103  // all incoming packets
1104  if (pkt->isInvalidate() || pkt->isWrite()) {
1105  for (auto &t_info : cpu->threadInfo) {
1106  t_info->thread->getIsaPtr()->handleLockedSnoop(pkt,
1107  cacheBlockMask);
1108  }
1109  } else if (pkt->req && pkt->req->isTlbiExtSync()) {
1110  // We received a TLBI_EXT_SYNC request.
1111  // In a detailed sim we would wait for memory ops to complete,
1112  // but in our simple case we just respond immediately
1113  auto reply_req = Request::createMemManagement(
1115  cpu->dataRequestorId());
1116 
1117  // Extra Data = the transaction ID of the Sync we're completing
1118  reply_req->setExtraData(pkt->req->getExtraData());
1119  PacketPtr reply_pkt = Packet::createRead(reply_req);
1120 
1121  // TODO - reserve some credit for these responses?
1122  if (!sendTimingReq(reply_pkt)) {
1123  panic("Couldn't send TLBI_EXT_SYNC_COMP message");
1124  }
1125  }
1126 }
1127 
1128 void
1130 {
1131  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
1132  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1133  cpu->wakeup(tid);
1134  }
1135  }
1136 }
1137 
1138 bool
1140 {
1141  DPRINTF(SimpleCPU, "Received load/store response %#x\n", pkt->getAddr());
1142 
1143  // The timing CPU is not really ticked, instead it relies on the
1144  // memory system (fetch and load/store) to set the pace.
1145  if (!tickEvent.scheduled()) {
1146  // Delay processing of returned data until next CPU clock edge
1147  tickEvent.schedule(pkt, cpu->clockEdge());
1148  return true;
1149  } else {
1150  // In the case of a split transaction and a cache that is
1151  // faster than a CPU we could get two responses in the
1152  // same tick, delay the second one
1153  if (!retryRespEvent.scheduled())
1154  cpu->schedule(retryRespEvent, cpu->clockEdge(Cycles(1)));
1155  return false;
1156  }
1157 }
1158 
1159 void
1161 {
1162  cpu->completeDataAccess(pkt);
1163 }
1164 
1165 void
1167 {
1168  // we shouldn't get a retry unless we have a packet that we're
1169  // waiting to transmit
1170  assert(cpu->dcache_pkt != NULL);
1171  assert(cpu->_status == DcacheRetry);
1172  PacketPtr tmp = cpu->dcache_pkt;
1173  if (tmp->senderState) {
1174  // This is a packet from a split access.
1175  SplitFragmentSenderState * send_state =
1176  dynamic_cast<SplitFragmentSenderState *>(tmp->senderState);
1177  assert(send_state);
1178  PacketPtr big_pkt = send_state->bigPkt;
1179 
1180  SplitMainSenderState * main_send_state =
1181  dynamic_cast<SplitMainSenderState *>(big_pkt->senderState);
1182  assert(main_send_state);
1183 
1184  if (sendTimingReq(tmp)) {
1185  // If we were able to send without retrying, record that fact
1186  // and try sending the other fragment.
1187  send_state->clearFromParent();
1188  int other_index = main_send_state->getPendingFragment();
1189  if (other_index > 0) {
1190  tmp = main_send_state->fragments[other_index];
1191  cpu->dcache_pkt = tmp;
1192  if ((big_pkt->isRead() && cpu->handleReadPacket(tmp)) ||
1193  (big_pkt->isWrite() && cpu->handleWritePacket())) {
1194  main_send_state->fragments[other_index] = NULL;
1195  }
1196  } else {
1198  // memory system takes ownership of packet
1199  cpu->dcache_pkt = NULL;
1200  }
1201  }
1202  } else if (sendTimingReq(tmp)) {
1204  // memory system takes ownership of packet
1205  cpu->dcache_pkt = NULL;
1206  }
1207 }
1208 
1210  Tick t)
1211  : pkt(_pkt), cpu(_cpu)
1212 {
1213  cpu->schedule(this, t);
1214 }
1215 
1216 void
1218 {
1219  cpu->completeDataAccess(pkt);
1220 }
1221 
1222 const char *
1224 {
1225  return "Timing Simple CPU Delay IPR event";
1226 }
1227 
1228 
1229 void
1231 {
1233 }
1234 
1235 Fault
1237 {
1239  SimpleThread* thread = t_info.thread;
1240 
1241  const Addr addr = 0x0ul;
1242  const Addr pc = thread->pcState().instAddr();
1243  const int size = 8;
1244 
1245  if (traceData)
1246  traceData->setMem(addr, size, flags);
1247 
1248  RequestPtr req = std::make_shared<Request>(
1249  addr, size, flags, dataRequestorId());
1250 
1251  req->setPC(pc);
1252  req->setContext(thread->contextId());
1253  req->taskId(taskId());
1254  req->setInstCount(t_info.numInst);
1255 
1256  assert(req->isHTMCmd() || req->isTlbiCmd());
1257 
1258  // Use the payload as a sanity check,
1259  // the memory subsystem will clear allocated data
1260  uint8_t *data = new uint8_t[size];
1261  assert(data);
1262  uint64_t rc = 0xdeadbeeflu;
1263  memcpy (data, &rc, size);
1264 
1265  // debugging output
1266  if (req->isHTMCmd()) {
1267  if (req->isHTMStart())
1268  DPRINTF(HtmCpu, "HTMstart htmUid=%u\n",
1269  t_info.getHtmTransactionUid());
1270  else if (req->isHTMCommit())
1271  DPRINTF(HtmCpu, "HTMcommit htmUid=%u\n",
1272  t_info.getHtmTransactionUid());
1273  else if (req->isHTMCancel())
1274  DPRINTF(HtmCpu, "HTMcancel htmUid=%u\n",
1275  t_info.getHtmTransactionUid());
1276  else
1277  panic("initiateMemMgmtCmd: unknown HTM CMD");
1278  }
1279 
1280  sendData(req, data, nullptr, true);
1281 
1282  return NoFault;
1283 }
1284 
1285 void
1287  HtmFailureFaultCause cause)
1288 {
1289  SimpleExecContext& t_info = *threadInfo[tid];
1290  SimpleThread* thread = t_info.thread;
1291 
1292  const Addr addr = 0x0ul;
1293  const Addr pc = thread->pcState().instAddr();
1294  const int size = 8;
1295  const Request::Flags flags =
1297 
1298  if (traceData)
1299  traceData->setMem(addr, size, flags);
1300 
1301  // notify l1 d-cache (ruby) that core has aborted transaction
1302 
1303  RequestPtr req = std::make_shared<Request>(
1304  addr, size, flags, dataRequestorId());
1305 
1306  req->setPC(pc);
1307  req->setContext(thread->contextId());
1308  req->taskId(taskId());
1309  req->setInstCount(t_info.numInst);
1310  req->setHtmAbortCause(cause);
1311 
1312  assert(req->isHTMAbort());
1313 
1314  uint8_t *data = new uint8_t[size];
1315  assert(data);
1316  uint64_t rc = 0lu;
1317  memcpy (data, &rc, size);
1318 
1319  sendData(req, data, nullptr, true);
1320 }
1321 
1322 } // 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::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::AddrRange::to_string
std::string to_string() const
Get a string representation of the range.
Definition: addr_range.hh:360
gem5::BaseSimpleCPU::DcacheRetry
@ DcacheRetry
Definition: base.hh:118
gem5::BaseISA::handleLockedRead
virtual void handleLockedRead(const RequestPtr &req)
Definition: isa.hh:81
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
gem5::ThreadContext::Active
@ Active
Running.
Definition: thread_context.hh:109
gem5::StaticInst::isMicroop
bool isMicroop() const
Definition: static_inst.hh:186
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::htmSendAbortSignal
void htmSendAbortSignal(ThreadID tid, uint64_t htm_uid, HtmFailureFaultCause) override
Definition: timing.cc:1286
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:138
gem5::BaseSimpleCPU::threadInfo
std::vector< SimpleExecContext * > threadInfo
Definition: base.hh:100
gem5::TimingSimpleCPU::IprEvent::process
virtual void process()
Definition: timing.cc:1217
system.hh
gem5::Trace::InstRecord::setMem
void setMem(Addr a, Addr s, unsigned f)
Definition: insttracer.hh:180
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::BaseSimpleCPU::traceData
Trace::InstRecord * traceData
Definition: base.hh:97
gem5::HtmFailureFaultCause
HtmFailureFaultCause
Definition: htm.hh:47
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:374
gem5::MemCmd::responseCommand
Command responseCommand() const
Definition: packet.hh:267
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:123
gem5::BaseMMU::Write
@ Write
Definition: mmu.hh:56
gem5::Request::HTM_ABORT
@ HTM_ABORT
The request aborts a HTM transaction.
Definition: request.hh:216
gem5::Request::PHYSICAL
@ PHYSICAL
The virtual address is also the physical address.
Definition: request.hh:117
gem5::Request::NO_ACCESS
@ NO_ACCESS
The request should not cause a memory access.
Definition: request.hh:146
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:512
gem5::BaseSimpleCPU::curStaticInst
StaticInstPtr curStaticInst
Current instruction.
Definition: base.hh:104
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:514
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:591
gem5::TimingSimpleCPU::DcachePort::DTickEvent::process
void process()
Definition: timing.cc:1160
gem5::Packet::createWrite
static PacketPtr createWrite(const RequestPtr &req)
Definition: packet.hh:1026
gem5::X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
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:1091
gem5::StaticInst::isDelayedCommit
bool isDelayedCommit() const
Definition: static_inst.hh:187
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:930
gem5::StaticInst::isFirstMicroop
bool isFirstMicroop() const
Definition: static_inst.hh:189
faults.hh
gem5::BaseSimpleCPU::IcacheRetry
@ IcacheRetry
Definition: base.hh:114
gem5::SimpleThread::htmTransactionStarts
int64_t htmTransactionStarts
Definition: simple_thread.hh:137
gem5::SimpleThread
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
Definition: simple_thread.hh:95
gem5::TimingSimpleCPU::completeDataAccess
void completeDataAccess(PacketPtr pkt)
Definition: timing.cc:944
gem5::Request::createMemManagement
static RequestPtr createMemManagement(Flags flags, RequestorID id)
Factory method for creating memory management requests, with unspecified addr and size.
Definition: request.hh:530
gem5::BaseMMU::Execute
@ Execute
Definition: mmu.hh:56
gem5::BaseSimpleCPU::checkForInterrupts
void checkForInterrupts()
Definition: base.cc:249
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:908
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:312
gem5::TimingSimpleCPU::initiateMemMgmtCmd
Fault initiateMemMgmtCmd(Request::Flags flags) override
hardware transactional memory & TLBI operations
Definition: timing.cc:1236
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:132
gem5::Packet::dataStatic
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:1147
gem5::MicroPC
uint16_t MicroPC
Definition: types.hh:149
gem5::TimingSimpleCPU::updateCycleCounts
void updateCycleCounts()
Definition: timing.cc:1081
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:590
decoder.hh
gem5::StaticInst::isHtmStart
bool isHtmStart() const
Definition: static_inst.hh:193
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:124
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:94
gem5::VegaISA::t
Bitfield< 51 > t
Definition: pagetable.hh:56
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
gem5::DataTranslation
This class represents part of a data address translation.
Definition: translation.hh:219
gem5::Packet::print
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition: packet.cc:364
gem5::SimpleExecContext::inHtmTransactionalState
bool inHtmTransactionalState() const override
Definition: exec_context.hh:520
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:291
gem5::BaseSimpleCPU::preExecute
void preExecute()
Definition: base.cc:304
gem5::TimingSimpleCPU::printAddr
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
Definition: timing.cc:1230
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:499
gem5::TimingSimpleCPU::~TimingSimpleCPU
virtual ~TimingSimpleCPU()
Definition: timing.cc:87
gem5::probing::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:109
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::StaticInst::isHtmStop
bool isHtmStop() const
Definition: static_inst.hh:194
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:280
gem5::RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
gem5::MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:86
gem5::BaseSimpleCPU::DTBWaitResponse
@ DTBWaitResponse
Definition: base.hh:117
gem5::Packet::getHtmTransactionUid
uint64_t getHtmTransactionUid() const
If a packet/request originates in a CPU executing in transactional mode, i.e.
Definition: packet.cc:525
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:1209
gem5::TimingSimpleCPU::completeIfetch
void completeIfetch(PacketPtr)
Definition: timing.cc:820
gem5::BaseSimpleCPU::activeThreads
std::list< ThreadID > activeThreads
Definition: base.hh:101
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::Request::TLBI_EXT_SYNC_COMP
@ TLBI_EXT_SYNC_COMP
The Request tells the interconnect that a remote TLB Sync request has completed.
Definition: request.hh:252
gem5::BaseSimpleCPU
Definition: base.hh:83
compiler.hh
flags
uint8_t flags
Definition: helpers.cc:66
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:505
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:238
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:369
gem5::SimpleThread::pcState
const PCStateBase & pcState() const override
Definition: simple_thread.hh:258
gem5::TimingSimpleCPU::DcachePort::recvFunctionalSnoop
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
Definition: timing.cc:1129
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:619
gem5::TimingSimpleCPU::DcachePort::recvTimingResp
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Definition: timing.cc:1139
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:542
name
const std::string & name()
Definition: trace.cc:49
gem5::SimpleThread::getIsaPtr
BaseISA * getIsaPtr() const override
Definition: simple_thread.hh:211
gem5::StaticInst::isMemRef
bool isMemRef() const
Definition: static_inst.hh:143
gem5::BaseMMU::translateTiming
virtual void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)
Definition: mmu.cc:111
packet_access.hh
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:1166
gem5::BaseSimpleCPU::postExecute
void postExecute()
Definition: base.cc:383
gem5::SimpleThread::contextId
ContextID contextId() const override
Definition: simple_thread.hh:204
gem5::BaseSimpleCPU::Faulting
@ Faulting
Definition: base.hh:112
gem5::TimingSimpleCPU::SplitFragmentSenderState::clearFromParent
void clearFromParent()
Definition: timing.hh:103
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::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:167
gem5::Request::STORE_NO_DATA
static const FlagsType STORE_NO_DATA
Definition: request.hh:260
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
state
atomic_var_t state
Definition: helpers.cc:188
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
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
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:295
gem5::BaseSimpleCPU::countInst
void countInst()
Definition: base.cc:152
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:111
gem5::StaticInst::initiateAcc
virtual Fault initiateAcc(ExecContext *xc, Trace::InstRecord *traceData) const
Definition: static_inst.hh:289
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:1044
gem5::BaseSimpleCPU::swapActiveThread
void swapActiveThread()
Definition: base.cc:136
gem5::Packet::dataDynamic
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
Definition: packet.hh:1185
gem5::MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:243
gem5::BaseSimpleCPU::IcacheWaitResponse
@ IcacheWaitResponse
Definition: base.hh:115
gem5::TimingSimpleCPU::IprEvent::description
virtual const char * description() const
Return a C string describing the event.
Definition: timing.cc:1223
gem5::BaseSimpleCPU::serviceInstCountEvents
void serviceInstCountEvents()
Definition: base.cc:297
gem5::TimingSimpleCPU::SplitMainSenderState
Definition: timing.hh:74
gem5::BaseSimpleCPU::wakeup
void wakeup(ThreadID tid) override
Definition: base.cc:227
gem5::BaseSimpleCPU::advancePC
void advancePC(const Fault &fault)
Definition: base.cc:458
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::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:489
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:519
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:790
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:119
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: gpu_translation_state.hh:37
gem5::BaseSimpleCPU::Idle
@ Idle
Definition: base.hh:110
gem5::Packet::createRead
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
Definition: packet.hh:1020
gem5::Packet::getAddrRange
AddrRange getAddrRange() const
Get address range to which this packet belongs.
Definition: packet.cc:239
gem5::TimingSimpleCPU::IcachePort::ITickEvent::process
void process()
Definition: timing.cc:902
gem5::TimingSimpleCPU
Definition: timing.hh:53
gem5::SimpleExecContext::getHtmTransactionUid
uint64_t getHtmTransactionUid() const override
Definition: exec_context.hh:508
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:105
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:235
gem5::TimingSimpleCPU::TimingSimpleCPU
TimingSimpleCPU(const BaseTimingSimpleCPUParams &params)
Definition: timing.cc:77
gem5::Packet::isInvalidate
bool isInvalidate() const
Definition: packet.hh:606
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

Generated on Thu Jun 16 2022 10:41:48 for gem5 by doxygen 1.8.17