gem5  v21.1.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 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/locked_mem.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)
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.
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()) {
143  }
144  } else {
145  threadInfo[tid]->execContextStats.notIdleFraction = 0;
146  }
147  }
148 
149  // Reschedule any power gating event (if any)
151 }
152 
153 bool
155 {
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  GEM5_VAR_USED 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 
180 
181  assert(!fetchEvent.scheduled());
182  assert(_status == BaseSimpleCPU::Running || _status == Idle);
183  assert(!t_info.stayAtPC);
184  assert(thread->microPC() == 0);
185 
188 }
189 
190 
191 void
193 {
195 
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())
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()) {
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  TheISA::handleLockedRead(thread, 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 = TheISA::handleLockedWrite(thread, req, dcachePort.cacheBlockMask);
329  } else if (req->isCondSwap()) {
330  assert(res);
331  req->setExtraData(*res);
332  }
333 
334  if (do_access) {
335  dcache_pkt = pkt;
337  threadSnoop(pkt, curThread);
338  } else {
340  completeDataAccess(pkt);
341  }
342  }
343 }
344 
345 void
347  const RequestPtr &req, uint8_t *data, bool read)
348 {
350  PacketPtr pkt1, pkt2;
351  buildSplitPacket(pkt1, pkt2, req1, req2, req, data, read);
352 
353  // hardware transactional memory
354  // HTM commands should never use SplitData
355  assert(!req1->isHTMCmd() && !req2->isHTMCmd());
356 
357  // If the thread is executing transactionally,
358  // reflect this in the packets.
359  if (t_info.inHtmTransactionalState()) {
362  }
363 
364  if (req->getFlags().isSet(Request::NO_ACCESS)) {
365  assert(!dcache_pkt);
366  pkt1->makeResponse();
367  completeDataAccess(pkt1);
368  } else if (read) {
369  SplitFragmentSenderState * send_state =
370  dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState);
371  if (handleReadPacket(pkt1)) {
372  send_state->clearFromParent();
373  send_state = dynamic_cast<SplitFragmentSenderState *>(
374  pkt2->senderState);
375  if (handleReadPacket(pkt2)) {
376  send_state->clearFromParent();
377  }
378  }
379  } else {
380  dcache_pkt = pkt1;
381  SplitFragmentSenderState * send_state =
382  dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState);
383  if (handleWritePacket()) {
384  send_state->clearFromParent();
385  dcache_pkt = pkt2;
386  send_state = dynamic_cast<SplitFragmentSenderState *>(
387  pkt2->senderState);
388  if (handleWritePacket()) {
389  send_state->clearFromParent();
390  }
391  }
392  }
393 }
394 
395 void
397 {
398  // fault may be NoFault in cases where a fault is suppressed,
399  // for instance prefetches.
402 
403  if ((fault != NoFault) && traceData) {
404  traceFault();
405  }
406 
407  postExecute();
408 
409  advanceInst(fault);
410 }
411 
412 PacketPtr
414 {
415  return read ? Packet::createRead(req) : Packet::createWrite(req);
416 }
417 
418 void
420  const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req,
421  uint8_t *data, bool read)
422 {
423  pkt1 = pkt2 = NULL;
424 
425  assert(!req1->isLocalAccess() && !req2->isLocalAccess());
426 
427  if (req->getFlags().isSet(Request::NO_ACCESS)) {
428  pkt1 = buildPacket(req, read);
429  return;
430  }
431 
432  pkt1 = buildPacket(req1, read);
433  pkt2 = buildPacket(req2, read);
434 
435  PacketPtr pkt = new Packet(req, pkt1->cmd.responseCommand());
436 
437  pkt->dataDynamic<uint8_t>(data);
438  pkt1->dataStatic<uint8_t>(data);
439  pkt2->dataStatic<uint8_t>(data + req1->getSize());
440 
441  SplitMainSenderState * main_send_state = new SplitMainSenderState;
442  pkt->senderState = main_send_state;
443  main_send_state->fragments[0] = pkt1;
444  main_send_state->fragments[1] = pkt2;
445  main_send_state->outstanding = 2;
446  pkt1->senderState = new SplitFragmentSenderState(pkt, 0);
447  pkt2->senderState = new SplitFragmentSenderState(pkt, 1);
448 }
449 
450 Fault
452  Request::Flags flags,
453  const std::vector<bool>& byte_enable)
454 {
456  SimpleThread* thread = t_info.thread;
457 
458  Fault fault;
459  const Addr pc = thread->instAddr();
460  unsigned block_size = cacheLineSize();
462 
463  if (traceData)
464  traceData->setMem(addr, size, flags);
465 
466  RequestPtr req = std::make_shared<Request>(
467  addr, size, flags, dataRequestorId(), pc, thread->contextId());
468  req->setByteEnable(byte_enable);
469 
470  req->taskId(taskId());
471 
472  Addr split_addr = roundDown(addr + size - 1, block_size);
473  assert(split_addr <= addr || split_addr - addr < block_size);
474 
476  if (split_addr > addr) {
477  RequestPtr req1, req2;
478  assert(!req->isLLSC() && !req->isSwap());
479  req->splitOnVaddr(split_addr, req1, req2);
480 
481  WholeTranslationState *state =
482  new WholeTranslationState(req, req1, req2, new uint8_t[size],
483  NULL, mode);
485  new DataTranslation<TimingSimpleCPU *>(this, state, 0);
487  new DataTranslation<TimingSimpleCPU *>(this, state, 1);
488 
489  thread->mmu->translateTiming(req1, thread->getTC(), trans1, mode);
490  thread->mmu->translateTiming(req2, thread->getTC(), trans2, mode);
491  } else {
492  WholeTranslationState *state =
493  new WholeTranslationState(req, new uint8_t[size], NULL, mode);
495  = new DataTranslation<TimingSimpleCPU *>(this, state);
496  thread->mmu->translateTiming(req, thread->getTC(), translation, mode);
497  }
498 
499  return NoFault;
500 }
501 
502 bool
504 {
506  SimpleThread* thread = t_info.thread;
507 
508  const RequestPtr &req = dcache_pkt->req;
509  if (req->isLocalAccess()) {
510  Cycles delay = req->localAccessor(thread->getTC(), dcache_pkt);
511  new IprEvent(dcache_pkt, this, clockEdge(delay));
513  dcache_pkt = NULL;
514  } else if (!dcachePort.sendTimingReq(dcache_pkt)) {
516  } else {
518  // memory system takes ownership of packet
519  dcache_pkt = NULL;
520  }
521  return dcache_pkt == NULL;
522 }
523 
524 Fault
525 TimingSimpleCPU::writeMem(uint8_t *data, unsigned size,
526  Addr addr, Request::Flags flags, uint64_t *res,
527  const std::vector<bool>& byte_enable)
528 {
530  SimpleThread* thread = t_info.thread;
531 
532  uint8_t *newData = new uint8_t[size];
533  const Addr pc = thread->instAddr();
534  unsigned block_size = cacheLineSize();
536 
537  if (data == NULL) {
538  assert(flags & Request::STORE_NO_DATA);
539  // This must be a cache block cleaning request
540  memset(newData, 0, size);
541  } else {
542  memcpy(newData, data, size);
543  }
544 
545  if (traceData)
546  traceData->setMem(addr, size, flags);
547 
548  RequestPtr req = std::make_shared<Request>(
549  addr, size, flags, dataRequestorId(), pc, thread->contextId());
550  req->setByteEnable(byte_enable);
551 
552  req->taskId(taskId());
553 
554  Addr split_addr = roundDown(addr + size - 1, block_size);
555  assert(split_addr <= addr || split_addr - addr < block_size);
556 
558 
559  // TODO: TimingSimpleCPU doesn't support arbitrarily long multi-line mem.
560  // accesses yet
561 
562  if (split_addr > addr) {
563  RequestPtr req1, req2;
564  assert(!req->isLLSC() && !req->isSwap());
565  req->splitOnVaddr(split_addr, req1, req2);
566 
567  WholeTranslationState *state =
568  new WholeTranslationState(req, req1, req2, newData, res, mode);
570  new DataTranslation<TimingSimpleCPU *>(this, state, 0);
572  new DataTranslation<TimingSimpleCPU *>(this, state, 1);
573 
574  thread->mmu->translateTiming(req1, thread->getTC(), trans1, mode);
575  thread->mmu->translateTiming(req2, thread->getTC(), trans2, mode);
576  } else {
577  WholeTranslationState *state =
578  new WholeTranslationState(req, newData, res, mode);
580  new DataTranslation<TimingSimpleCPU *>(this, state);
581  thread->mmu->translateTiming(req, thread->getTC(), translation, mode);
582  }
583 
584  // Translation faults will be returned via finishTranslation()
585  return NoFault;
586 }
587 
588 Fault
590  Request::Flags flags,
591  AtomicOpFunctorPtr amo_op)
592 {
594  SimpleThread* thread = t_info.thread;
595 
596  Fault fault;
597  const Addr pc = thread->instAddr();
598  unsigned block_size = cacheLineSize();
600 
601  if (traceData)
602  traceData->setMem(addr, size, flags);
603 
604  RequestPtr req = std::make_shared<Request>(addr, size, flags,
605  dataRequestorId(), pc, thread->contextId(),
606  std::move(amo_op));
607 
608  assert(req->hasAtomicOpFunctor());
609 
610  req->taskId(taskId());
611 
612  Addr split_addr = roundDown(addr + size - 1, block_size);
613 
614  // AMO requests that access across a cache line boundary are not
615  // allowed since the cache does not guarantee AMO ops to be executed
616  // atomically in two cache lines
617  // For ISAs such as x86 that requires AMO operations to work on
618  // accesses that cross cache-line boundaries, the cache needs to be
619  // modified to support locking both cache lines to guarantee the
620  // atomicity.
621  if (split_addr > addr) {
622  panic("AMO requests should not access across a cache line boundary\n");
623  }
624 
626 
627  WholeTranslationState *state =
628  new WholeTranslationState(req, new uint8_t[size], NULL, mode);
630  = new DataTranslation<TimingSimpleCPU *>(this, state);
631  thread->mmu->translateTiming(req, thread->getTC(), translation, mode);
632 
633  return NoFault;
634 }
635 
636 void
638 {
639  for (ThreadID tid = 0; tid < numThreads; tid++) {
640  if (tid != sender) {
641  if (getCpuAddrMonitor(tid)->doMonitor(pkt)) {
642  wakeup(tid);
643  }
644  TheISA::handleLockedSnoop(threadInfo[tid]->thread, pkt,
646  }
647  }
648 }
649 
650 void
652 {
654 
655  if (state->getFault() != NoFault) {
656  if (state->isPrefetch()) {
657  state->setNoFault();
658  }
659  delete [] state->data;
660  state->deleteReqs();
661  translationFault(state->getFault());
662  } else {
663  if (!state->isSplit) {
664  sendData(state->mainReq, state->data, state->res,
665  state->mode == BaseMMU::Read);
666  } else {
667  sendSplitData(state->sreqLow, state->sreqHigh, state->mainReq,
668  state->data, state->mode == BaseMMU::Read);
669  }
670  }
671 
672  delete state;
673 }
674 
675 
676 void
678 {
679  // Change thread if multi-threaded
681 
683  SimpleThread* thread = t_info.thread;
684 
685  DPRINTF(SimpleCPU, "Fetch\n");
686 
690  }
691 
692  // We must have just got suspended by a PC event
693  if (_status == Idle)
694  return;
695 
696  TheISA::PCState pcState = thread->pcState();
697  bool needToFetch = !isRomMicroPC(pcState.microPC()) &&
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 
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 
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) ?
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 
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  GEM5_VAR_USED 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 
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  TheISA::handleLockedSnoop(t_info->thread, pkt, cacheBlockMask);
1104  }
1105  }
1106 }
1107 
1108 void
1110 {
1111  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
1112  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1113  cpu->wakeup(tid);
1114  }
1115  }
1116 }
1117 
1118 bool
1120 {
1121  DPRINTF(SimpleCPU, "Received load/store response %#x\n", pkt->getAddr());
1122 
1123  // The timing CPU is not really ticked, instead it relies on the
1124  // memory system (fetch and load/store) to set the pace.
1125  if (!tickEvent.scheduled()) {
1126  // Delay processing of returned data until next CPU clock edge
1127  tickEvent.schedule(pkt, cpu->clockEdge());
1128  return true;
1129  } else {
1130  // In the case of a split transaction and a cache that is
1131  // faster than a CPU we could get two responses in the
1132  // same tick, delay the second one
1133  if (!retryRespEvent.scheduled())
1135  return false;
1136  }
1137 }
1138 
1139 void
1141 {
1142  cpu->completeDataAccess(pkt);
1143 }
1144 
1145 void
1147 {
1148  // we shouldn't get a retry unless we have a packet that we're
1149  // waiting to transmit
1150  assert(cpu->dcache_pkt != NULL);
1151  assert(cpu->_status == DcacheRetry);
1152  PacketPtr tmp = cpu->dcache_pkt;
1153  if (tmp->senderState) {
1154  // This is a packet from a split access.
1155  SplitFragmentSenderState * send_state =
1156  dynamic_cast<SplitFragmentSenderState *>(tmp->senderState);
1157  assert(send_state);
1158  PacketPtr big_pkt = send_state->bigPkt;
1159 
1160  SplitMainSenderState * main_send_state =
1161  dynamic_cast<SplitMainSenderState *>(big_pkt->senderState);
1162  assert(main_send_state);
1163 
1164  if (sendTimingReq(tmp)) {
1165  // If we were able to send without retrying, record that fact
1166  // and try sending the other fragment.
1167  send_state->clearFromParent();
1168  int other_index = main_send_state->getPendingFragment();
1169  if (other_index > 0) {
1170  tmp = main_send_state->fragments[other_index];
1171  cpu->dcache_pkt = tmp;
1172  if ((big_pkt->isRead() && cpu->handleReadPacket(tmp)) ||
1173  (big_pkt->isWrite() && cpu->handleWritePacket())) {
1174  main_send_state->fragments[other_index] = NULL;
1175  }
1176  } else {
1178  // memory system takes ownership of packet
1179  cpu->dcache_pkt = NULL;
1180  }
1181  }
1182  } else if (sendTimingReq(tmp)) {
1184  // memory system takes ownership of packet
1185  cpu->dcache_pkt = NULL;
1186  }
1187 }
1188 
1190  Tick t)
1191  : pkt(_pkt), cpu(_cpu)
1192 {
1193  cpu->schedule(this, t);
1194 }
1195 
1196 void
1198 {
1199  cpu->completeDataAccess(pkt);
1200 }
1201 
1202 const char *
1204 {
1205  return "Timing Simple CPU Delay IPR event";
1206 }
1207 
1208 
1209 void
1211 {
1213 }
1214 
1215 Fault
1217 {
1219  SimpleThread* thread = t_info.thread;
1220 
1221  const Addr addr = 0x0ul;
1222  const Addr pc = thread->instAddr();
1223  const int size = 8;
1224 
1225  if (traceData)
1226  traceData->setMem(addr, size, flags);
1227 
1228  RequestPtr req = std::make_shared<Request>(
1229  addr, size, flags, dataRequestorId());
1230 
1231  req->setPC(pc);
1232  req->setContext(thread->contextId());
1233  req->taskId(taskId());
1234  req->setInstCount(t_info.numInst);
1235 
1236  assert(req->isHTMCmd());
1237 
1238  // Use the payload as a sanity check,
1239  // the memory subsystem will clear allocated data
1240  uint8_t *data = new uint8_t[size];
1241  assert(data);
1242  uint64_t rc = 0xdeadbeeflu;
1243  memcpy (data, &rc, size);
1244 
1245  // debugging output
1246  if (req->isHTMStart())
1247  DPRINTF(HtmCpu, "HTMstart htmUid=%u\n", t_info.getHtmTransactionUid());
1248  else if (req->isHTMCommit())
1249  DPRINTF(HtmCpu, "HTMcommit htmUid=%u\n", t_info.getHtmTransactionUid());
1250  else if (req->isHTMCancel())
1251  DPRINTF(HtmCpu, "HTMcancel htmUid=%u\n", t_info.getHtmTransactionUid());
1252  else
1253  panic("initiateHtmCmd: unknown CMD");
1254 
1255  sendData(req, data, nullptr, true);
1256 
1257  return NoFault;
1258 }
1259 
1260 void
1262 {
1264  SimpleThread* thread = t_info.thread;
1265 
1266  const Addr addr = 0x0ul;
1267  const Addr pc = thread->instAddr();
1268  const int size = 8;
1269  const Request::Flags flags =
1271 
1272  if (traceData)
1273  traceData->setMem(addr, size, flags);
1274 
1275  // notify l1 d-cache (ruby) that core has aborted transaction
1276 
1277  RequestPtr req = std::make_shared<Request>(
1278  addr, size, flags, dataRequestorId());
1279 
1280  req->setPC(pc);
1281  req->setContext(thread->contextId());
1282  req->taskId(taskId());
1283  req->setInstCount(t_info.numInst);
1284  req->setHtmAbortCause(cause);
1285 
1286  assert(req->isHTMAbort());
1287 
1288  uint8_t *data = new uint8_t[size];
1289  assert(data);
1290  uint64_t rc = 0lu;
1291  memcpy (data, &rc, size);
1292 
1293  sendData(req, data, nullptr, true);
1294 }
1295 
1296 } // namespace gem5
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:189
gem5::TimingSimpleCPU::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: timing.cc:65
gem5::BaseMMU::Read
@ Read
Definition: mmu.hh:53
gem5::BaseSimpleCPU::DcacheRetry
@ DcacheRetry
Definition: base.hh:118
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:260
gem5::ThreadContext::Active
@ Active
Running.
Definition: thread_context.hh:108
gem5::BaseCPU::switchedOut
bool switchedOut() const
Determine if the CPU is switched out.
Definition: base.hh:357
gem5::StaticInst::isMicroop
bool isMicroop() const
Definition: static_inst.hh:208
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:1216
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:100
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:1197
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
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::Clocked::curCycle
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Definition: clocked_object.hh:195
gem5::BaseSimpleCPU::traceData
Trace::InstRecord * traceData
Definition: base.hh:97
gem5::HtmFailureFaultCause
HtmFailureFaultCause
Definition: htm.hh:47
gem5::WholeTranslationState::setNoFault
void setNoFault()
Remove all faults from the translation.
Definition: translation.hh:151
gem5::Drainable::drainState
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:324
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::Request::HTM_ABORT
@ HTM_ABORT
The request aborts a HTM transaction.
Definition: request.hh:214
gem5::BaseMMU::Mode
Mode
Definition: mmu.hh:53
gem5::TimingSimpleCPU::drain
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
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:419
gem5::BaseSimpleCPU::_status
Status _status
Definition: base.hh:123
gem5::BaseMMU::Write
@ Write
Definition: mmu.hh:53
gem5::BaseCPU::cacheLineSize
unsigned int cacheLineSize() const
Get the cache line size of the system.
Definition: base.hh:381
gem5::TimingSimpleCPU::DcachePort::cacheBlockMask
Addr cacheBlockMask
Definition: timing.hh:227
gem5::AddressMonitor::doMonitor
bool doMonitor(PacketPtr pkt)
Definition: base.cc:688
gem5::SimpleThread::instAddr
Addr instAddr() const override
Definition: simple_thread.hh:439
gem5::BaseCPU::updateCycleCounters
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition: base.hh:523
gem5::TimingSimpleCPU::SplitFragmentSenderState
Definition: timing.hh:93
gem5::TimingSimpleCPU::IprEvent
Definition: timing.hh:336
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:104
exetrace.hh
gem5::TimingSimpleCPU::buildPacket
PacketPtr buildPacket(const RequestPtr &req, bool read)
Definition: timing.cc:413
gem5::ArmISA::a
Bitfield< 8 > a
Definition: misc_types.hh:65
gem5::SimpleExecContext::newHtmTransactionUid
uint64_t newHtmTransactionUid() const override
Definition: exec_context.hh:580
gem5::TimingSimpleCPU::verifyMemoryMode
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
Definition: timing.cc:200
gem5::TimingSimpleCPU::fetch
void fetch()
Definition: timing.cc:677
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::Request::PHYSICAL
@ PHYSICAL
The virtual address is also the physical address.
Definition: request.hh:117
gem5::BaseCPU::system
System * system
Definition: base.hh:376
gem5::TimingSimpleCPU::DcachePort::DTickEvent::process
void process()
Definition: timing.cc:1140
gem5::Packet::createWrite
static PacketPtr createWrite(const RequestPtr &req)
Definition: packet.hh:1013
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
std::vector< bool >
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:209
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:211
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:114
gem5::BaseCPU::schedulePowerGatingEvent
void schedulePowerGatingEvent()
Definition: base.cc:460
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:94
gem5::TimingSimpleCPU::completeDataAccess
void completeDataAccess(PacketPtr pkt)
Definition: timing.cc:943
gem5::BaseMMU::Execute
@ Execute
Definition: mmu.hh:53
gem5::BaseSimpleCPU::checkForInterrupts
void checkForInterrupts()
Definition: base.cc:258
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
packet.hh
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
gem5::HtmFailureFaultCause::EXCEPTION
@ EXCEPTION
gem5::ArmISA::handleLockedWrite
bool handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask)
Definition: locked_mem.hh:113
gem5::BaseCPU::numThreads
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:368
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::BaseCPU::deschedulePowerGatingEvent
void deschedulePowerGatingEvent()
Definition: base.cc:452
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::BaseCPU::suspendContext
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition: base.cc:502
gem5::HtmCacheFailure::FAIL_REMOTE
@ FAIL_REMOTE
gem5::BaseCPU::baseStats
gem5::BaseCPU::BaseCPUStats baseStats
gem5::TimingSimpleCPU::IprEvent::cpu
TimingSimpleCPU * cpu
Definition: timing.hh:339
gem5::Packet::isRead
bool isRead() const
Definition: packet.hh:582
gem5::BaseCPU::taskId
uint32_t taskId() const
Get cpu task id.
Definition: base.hh:212
gem5::StaticInst::isHtmStart
bool isHtmStart() const
Definition: static_inst.hh:215
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
Prepare for another CPU to take over execution.
Definition: timing.cc:170
gem5::BaseSimpleCPU::checkPcEventQueue
void checkPcEventQueue()
Definition: base.cc:133
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:93
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:586
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:589
gem5::TimingSimpleCPU::fetchEvent
EventFunctionWrapper fetchEvent
Definition: timing.hh:334
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:313
gem5::TimingSimpleCPU::printAddr
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
Definition: timing.cc:1210
gem5::BaseCPU::BaseCPUStats::numCycles
statistics::Scalar numCycles
Definition: base.hh:597
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::MipsISA::PCState
GenericISA::DelaySlotPCState< 4 > PCState
Definition: pcstate.hh:40
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:216
gem5::SimpleExecContext::stayAtPC
bool stayAtPC
Definition: exec_context.hh:70
gem5::TimingSimpleCPU::handleWritePacket
bool handleWritePacket()
Definition: timing.cc:503
gem5::BaseSimpleCPU::setupFetchRequest
void setupFetchRequest(const RequestPtr &req)
Definition: base.cc:289
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:534
gem5::TimingSimpleCPU::activateContext
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
Definition: timing.cc:209
gem5::TimingSimpleCPU::IprEvent::IprEvent
IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
Definition: timing.cc:1189
gem5::BaseCPU::CPU_STATE_ON
@ CPU_STATE_ON
Definition: base.hh:514
gem5::TimingSimpleCPU::completeIfetch
void completeIfetch(PacketPtr)
Definition: timing.cc:820
gem5::BaseSimpleCPU::activeThreads
std::list< ThreadID > activeThreads
Definition: base.hh:101
gem5::BaseCPU
Definition: base.hh:107
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:451
gem5::EventManager::reschedule
void reschedule(Event &event, Tick when, bool always=false)
Definition: eventq.hh:1037
gem5::BaseSimpleCPU
Definition: base.hh:80
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:247
gem5::SimpleExecContext::numInst
Counter numInst
PER-THREAD STATS.
Definition: exec_context.hh:76
gem5::SimpleThread::pcState
TheISA::PCState pcState() const override
Definition: simple_thread.hh:430
gem5::DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
gem5::System::isTimingMode
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:276
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:70
gem5::TimingSimpleCPU::DcachePort::recvFunctionalSnoop
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
Definition: timing.cc:1109
gem5::BaseCPU::getCpuAddrMonitor
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
Definition: base.hh:609
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:1119
gem5::TimingSimpleCPU::threadSnoop
void threadSnoop(PacketPtr pkt, ThreadID sender)
Definition: timing.cc:637
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:165
gem5::BaseMMU::translateTiming
void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)
Definition: mmu.cc:72
gem5::BaseCPU::instCnt
Tick instCnt
Instruction count used for SPARC misc register.
Definition: base.hh:113
packet_access.hh
gem5::WholeTranslationState::sreqHigh
RequestPtr sreqHigh
Definition: translation.hh:73
gem5::Clocked::clockEdge
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Definition: clocked_object.hh:177
gem5::WholeTranslationState::mainReq
RequestPtr mainReq
Definition: translation.hh:71
gem5::EventManager::deschedule
void deschedule(Event &event)
Definition: eventq.hh:1028
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:1146
gem5::BaseSimpleCPU::postExecute
void postExecute()
Definition: base.cc:394
gem5::SimpleThread::contextId
ContextID contextId() const override
Definition: simple_thread.hh:206
gem5::BaseSimpleCPU::Faulting
@ Faulting
Definition: base.hh:112
gem5::TimingSimpleCPU::SplitFragmentSenderState::clearFromParent
void clearFromParent()
Definition: timing.hh:103
gem5::Drainable::signalDrainDone
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:305
gem5::SimpleExecContext::thread
SimpleThread * thread
Definition: exec_context.hh:64
gem5::TimingSimpleCPU::htmSendAbortSignal
void htmSendAbortSignal(HtmFailureFaultCause) override
This function is used to instruct the memory subsystem that a transaction should be aborted and the s...
Definition: timing.cc:1261
gem5::Clocked::nextCycle
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
Definition: clocked_object.hh:213
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:244
gem5::TimingSimpleCPU::takeOverFrom
void takeOverFrom(BaseCPU *oldCPU) override
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
Definition: timing.cc:192
gem5::TimingSimpleCPU::finishTranslation
void finishTranslation(WholeTranslationState *state)
Finish a DTB translation.
Definition: timing.cc:651
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
Resume execution after a successful drain.
Definition: timing.cc:119
gem5::TimingSimpleCPU::previousCycle
Cycles previousCycle
Definition: timing.hh:264
gem5::BaseCPU::threadContexts
std::vector< ThreadContext * > threadContexts
Definition: base.hh:262
gem5::StaticInst::completeAcc
virtual Fault completeAcc(Packet *pkt, ExecContext *xc, Trace::InstRecord *trace_data) const
Definition: static_inst.hh:317
gem5::BaseSimpleCPU::countInst
void countInst()
Definition: base.cc:161
gem5::TimingSimpleCPU::translationFault
void translationFault(const Fault &fault)
Definition: timing.cc:396
gem5::BaseCPU::takeOverFrom
virtual void takeOverFrom(BaseCPU *cpu)
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
Definition: base.cc:554
gem5::htmFailureToStr
std::string htmFailureToStr(HtmFailureFaultCause cause)
Convert enum into string to be used for debug purposes.
Definition: htm.cc:44
gem5::BaseCPU::activateContext
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Definition: base.cc:488
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:311
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
Notify the CPU that the indicated context is now suspended.
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:145
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:115
gem5::TimingSimpleCPU::IprEvent::description
virtual const char * description() const
Return a C string describing the event.
Definition: timing.cc:1203
gem5::BaseSimpleCPU::serviceInstCountEvents
void serviceInstCountEvents()
Definition: base.cc:306
gem5::TimingSimpleCPU::SplitMainSenderState
Definition: timing.hh:74
gem5::BaseCPU::switchOut
virtual void switchOut()
Prepare for another CPU to take over execution.
Definition: base.cc:540
gem5::WholeTranslationState::mode
BaseMMU::Mode mode
Definition: translation.hh:76
gem5::ArmISA::handleLockedRead
void handleLockedRead(XC *xc, const RequestPtr &req)
Definition: locked_mem.hh:93
gem5::BaseCPU::syscallRetryLatency
Cycles syscallRetryLatency
Definition: base.hh:615
gem5::BaseSimpleCPU::wakeup
void wakeup(ThreadID tid) override
Definition: base.cc:236
gem5::Request::NO_ACCESS
@ NO_ACCESS
The request should not cause a memory access.
Definition: request.hh:146
gem5::BaseSimpleCPU::advancePC
void advancePC(const Fault &fault)
Definition: base.cc:470
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:525
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::BaseCPU::dataRequestorId
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
Definition: base.hh:194
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::ArmISA::handleLockedSnoop
void handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
Definition: locked_mem.hh:64
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:346
gem5::AtomicOpFunctorPtr
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Definition: amo.hh:242
gem5::BaseSimpleCPU::DcacheWaitResponse
@ DcacheWaitResponse
Definition: base.hh:119
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: decoder.cc:40
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: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:574
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:361
gem5::BaseSimpleCPU::curThread
ThreadID curThread
Definition: base.hh:83
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::BaseSimpleCPU::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: base.cc:122
gem5::TimingSimpleCPU::IcachePort::tickEvent
ITickEvent tickEvent
Definition: timing.hh:212
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::ArmISA::mode
Bitfield< 4, 0 > mode
Definition: misc_types.hh:73
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::TimingSimpleCPU::TimingSimpleCPU
TimingSimpleCPU(const TimingSimpleCPUParams &params)
Definition: timing.cc:77

Generated on Wed Jul 28 2021 12:10:25 for gem5 by doxygen 1.8.17