gem5  v20.1.0.0
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 "arch/utility.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 using namespace std;
62 using namespace TheISA;
63 
64 void
66 {
68 }
69 
70 void
72 {
73  pkt = _pkt;
74  cpu->schedule(this, t);
75 }
76 
77 TimingSimpleCPU::TimingSimpleCPU(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.
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]->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]->notIdleFraction = 0;
146  }
147  }
148 
149  // Reschedule any power gating event (if any)
151 
152  system->totalNumInsts = 0;
153 }
154 
155 bool
157 {
158  if (drainState() != DrainState::Draining)
159  return false;
160 
161  DPRINTF(Drain, "tryCompleteDrain.\n");
162  if (!isCpuDrained())
163  return false;
164 
165  DPRINTF(Drain, "CPU done draining, processing drain event\n");
166  signalDrainDone();
167 
168  return true;
169 }
170 
171 void
173 {
175  M5_VAR_USED SimpleThread* thread = t_info.thread;
176 
177  // hardware transactional memory
178  // Cannot switch out the CPU in the middle of a transaction
179  assert(!t_info.inHtmTransactionalState());
180 
182 
183  assert(!fetchEvent.scheduled());
184  assert(_status == BaseSimpleCPU::Running || _status == Idle);
185  assert(!t_info.stayAtPC);
186  assert(thread->microPC() == 0);
187 
190 }
191 
192 
193 void
195 {
197 
198  previousCycle = curCycle();
199 }
200 
201 void
203 {
204  if (!system->isTimingMode()) {
205  fatal("The timing CPU requires the memory system to be in "
206  "'timing' mode.\n");
207  }
208 }
209 
210 void
212 {
213  DPRINTF(SimpleCPU, "ActivateContext %d\n", thread_num);
214 
215  assert(thread_num < numThreads);
216 
217  threadInfo[thread_num]->notIdleFraction = 1;
220 
221  // kick things off by initiating the fetch of the next instruction
222  if (!fetchEvent.scheduled())
223  schedule(fetchEvent, clockEdge(Cycles(0)));
224 
225  if (std::find(activeThreads.begin(), activeThreads.end(), thread_num)
226  == activeThreads.end()) {
227  activeThreads.push_back(thread_num);
228  }
229 
230  BaseCPU::activateContext(thread_num);
231 }
232 
233 
234 void
236 {
237  DPRINTF(SimpleCPU, "SuspendContext %d\n", thread_num);
238 
239  assert(thread_num < numThreads);
240  activeThreads.remove(thread_num);
241 
242  // hardware transactional memory
243  // Cannot suspend context in the middle of a transaction.
244  assert(!threadInfo[curThread]->inHtmTransactionalState());
245 
246  if (_status == Idle)
247  return;
248 
249  assert(_status == BaseSimpleCPU::Running);
250 
251  threadInfo[thread_num]->notIdleFraction = 0;
252 
253  if (activeThreads.empty()) {
254  _status = Idle;
255 
256  if (fetchEvent.scheduled()) {
257  deschedule(fetchEvent);
258  }
259  }
260 
261  BaseCPU::suspendContext(thread_num);
262 }
263 
264 bool
266 {
268  SimpleThread* thread = t_info.thread;
269 
270  const RequestPtr &req = pkt->req;
271 
272  // hardware transactional memory
273  // sanity check
274  if (req->isHTMCmd()) {
275  assert(!req->isLocalAccess());
276  }
277 
278  // We're about the issues a locked load, so tell the monitor
279  // to start caring about this address
280  if (pkt->isRead() && pkt->req->isLLSC()) {
281  TheISA::handleLockedRead(thread, pkt->req);
282  }
283  if (req->isLocalAccess()) {
284  Cycles delay = req->localAccessor(thread->getTC(), pkt);
285  new IprEvent(pkt, this, clockEdge(delay));
287  dcache_pkt = NULL;
288  } else if (!dcachePort.sendTimingReq(pkt)) {
290  dcache_pkt = pkt;
291  } else {
293  // memory system takes ownership of packet
294  dcache_pkt = NULL;
295  }
296  return dcache_pkt == NULL;
297 }
298 
299 void
300 TimingSimpleCPU::sendData(const RequestPtr &req, uint8_t *data, uint64_t *res,
301  bool read)
302 {
304  SimpleThread* thread = t_info.thread;
305 
306  PacketPtr pkt = buildPacket(req, read);
307  pkt->dataDynamic<uint8_t>(data);
308 
309  // hardware transactional memory
310  // If the core is in transactional mode or if the request is HtmCMD
311  // to abort a transaction, the packet should reflect that it is
312  // transactional and also contain a HtmUid for debugging.
313  const bool is_htm_speculative = t_info.inHtmTransactionalState();
314  if (is_htm_speculative || req->isHTMAbort()) {
316  }
317  if (req->isHTMAbort())
318  DPRINTF(HtmCpu, "htmabort htmUid=%u\n", t_info.getHtmTransactionUid());
319 
320  if (req->getFlags().isSet(Request::NO_ACCESS)) {
321  assert(!dcache_pkt);
322  pkt->makeResponse();
323  completeDataAccess(pkt);
324  } else if (read) {
325  handleReadPacket(pkt);
326  } else {
327  bool do_access = true; // flag to suppress cache access
328 
329  if (req->isLLSC()) {
330  do_access = TheISA::handleLockedWrite(thread, req, dcachePort.cacheBlockMask);
331  } else if (req->isCondSwap()) {
332  assert(res);
333  req->setExtraData(*res);
334  }
335 
336  if (do_access) {
337  dcache_pkt = pkt;
339  threadSnoop(pkt, curThread);
340  } else {
342  completeDataAccess(pkt);
343  }
344  }
345 }
346 
347 void
349  const RequestPtr &req, uint8_t *data, bool read)
350 {
352  PacketPtr pkt1, pkt2;
353  buildSplitPacket(pkt1, pkt2, req1, req2, req, data, read);
354 
355  // hardware transactional memory
356  // HTM commands should never use SplitData
357  assert(!req1->isHTMCmd() && !req2->isHTMCmd());
358 
359  // If the thread is executing transactionally,
360  // reflect this in the packets.
361  if (t_info.inHtmTransactionalState()) {
364  }
365 
366  if (req->getFlags().isSet(Request::NO_ACCESS)) {
367  assert(!dcache_pkt);
368  pkt1->makeResponse();
369  completeDataAccess(pkt1);
370  } else if (read) {
371  SplitFragmentSenderState * send_state =
372  dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState);
373  if (handleReadPacket(pkt1)) {
374  send_state->clearFromParent();
375  send_state = dynamic_cast<SplitFragmentSenderState *>(
376  pkt2->senderState);
377  if (handleReadPacket(pkt2)) {
378  send_state->clearFromParent();
379  }
380  }
381  } else {
382  dcache_pkt = pkt1;
383  SplitFragmentSenderState * send_state =
384  dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState);
385  if (handleWritePacket()) {
386  send_state->clearFromParent();
387  dcache_pkt = pkt2;
388  send_state = dynamic_cast<SplitFragmentSenderState *>(
389  pkt2->senderState);
390  if (handleWritePacket()) {
391  send_state->clearFromParent();
392  }
393  }
394  }
395 }
396 
397 void
399 {
400  // fault may be NoFault in cases where a fault is suppressed,
401  // for instance prefetches.
404 
405  if ((fault != NoFault) && traceData) {
406  traceFault();
407  }
408 
409  postExecute();
410 
411  advanceInst(fault);
412 }
413 
414 PacketPtr
416 {
417  return read ? Packet::createRead(req) : Packet::createWrite(req);
418 }
419 
420 void
422  const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req,
423  uint8_t *data, bool read)
424 {
425  pkt1 = pkt2 = NULL;
426 
427  assert(!req1->isLocalAccess() && !req2->isLocalAccess());
428 
429  if (req->getFlags().isSet(Request::NO_ACCESS)) {
430  pkt1 = buildPacket(req, read);
431  return;
432  }
433 
434  pkt1 = buildPacket(req1, read);
435  pkt2 = buildPacket(req2, read);
436 
437  PacketPtr pkt = new Packet(req, pkt1->cmd.responseCommand());
438 
439  pkt->dataDynamic<uint8_t>(data);
440  pkt1->dataStatic<uint8_t>(data);
441  pkt2->dataStatic<uint8_t>(data + req1->getSize());
442 
443  SplitMainSenderState * main_send_state = new SplitMainSenderState;
444  pkt->senderState = main_send_state;
445  main_send_state->fragments[0] = pkt1;
446  main_send_state->fragments[1] = pkt2;
447  main_send_state->outstanding = 2;
448  pkt1->senderState = new SplitFragmentSenderState(pkt, 0);
449  pkt2->senderState = new SplitFragmentSenderState(pkt, 1);
450 }
451 
452 Fault
454  Request::Flags flags,
455  const std::vector<bool>& byte_enable)
456 {
458  SimpleThread* thread = t_info.thread;
459 
460  Fault fault;
461  const Addr pc = thread->instAddr();
462  unsigned block_size = cacheLineSize();
464 
465  if (traceData)
466  traceData->setMem(addr, size, flags);
467 
468  RequestPtr req = std::make_shared<Request>(
469  addr, size, flags, dataRequestorId(), pc, thread->contextId());
470  if (!byte_enable.empty()) {
471  req->setByteEnable(byte_enable);
472  }
473 
474  req->taskId(taskId());
475 
476  Addr split_addr = roundDown(addr + size - 1, block_size);
477  assert(split_addr <= addr || split_addr - addr < block_size);
478 
480  if (split_addr > addr) {
481  RequestPtr req1, req2;
482  assert(!req->isLLSC() && !req->isSwap());
483  req->splitOnVaddr(split_addr, req1, req2);
484 
485  WholeTranslationState *state =
486  new WholeTranslationState(req, req1, req2, new uint8_t[size],
487  NULL, mode);
489  new DataTranslation<TimingSimpleCPU *>(this, state, 0);
491  new DataTranslation<TimingSimpleCPU *>(this, state, 1);
492 
493  thread->dtb->translateTiming(req1, thread->getTC(), trans1, mode);
494  thread->dtb->translateTiming(req2, thread->getTC(), trans2, mode);
495  } else {
496  WholeTranslationState *state =
497  new WholeTranslationState(req, new uint8_t[size], NULL, mode);
499  = new DataTranslation<TimingSimpleCPU *>(this, state);
500  thread->dtb->translateTiming(req, thread->getTC(), translation, mode);
501  }
502 
503  return NoFault;
504 }
505 
506 bool
508 {
510  SimpleThread* thread = t_info.thread;
511 
512  const RequestPtr &req = dcache_pkt->req;
513  if (req->isLocalAccess()) {
514  Cycles delay = req->localAccessor(thread->getTC(), dcache_pkt);
515  new IprEvent(dcache_pkt, this, clockEdge(delay));
517  dcache_pkt = NULL;
518  } else if (!dcachePort.sendTimingReq(dcache_pkt)) {
520  } else {
522  // memory system takes ownership of packet
523  dcache_pkt = NULL;
524  }
525  return dcache_pkt == NULL;
526 }
527 
528 Fault
529 TimingSimpleCPU::writeMem(uint8_t *data, unsigned size,
530  Addr addr, Request::Flags flags, uint64_t *res,
531  const std::vector<bool>& byte_enable)
532 {
534  SimpleThread* thread = t_info.thread;
535 
536  uint8_t *newData = new uint8_t[size];
537  const Addr pc = thread->instAddr();
538  unsigned block_size = cacheLineSize();
540 
541  if (data == NULL) {
542  assert(flags & Request::STORE_NO_DATA);
543  // This must be a cache block cleaning request
544  memset(newData, 0, size);
545  } else {
546  memcpy(newData, data, size);
547  }
548 
549  if (traceData)
550  traceData->setMem(addr, size, flags);
551 
552  RequestPtr req = std::make_shared<Request>(
553  addr, size, flags, dataRequestorId(), pc, thread->contextId());
554  if (!byte_enable.empty()) {
555  req->setByteEnable(byte_enable);
556  }
557 
558  req->taskId(taskId());
559 
560  Addr split_addr = roundDown(addr + size - 1, block_size);
561  assert(split_addr <= addr || split_addr - addr < block_size);
562 
564 
565  // TODO: TimingSimpleCPU doesn't support arbitrarily long multi-line mem.
566  // accesses yet
567 
568  if (split_addr > addr) {
569  RequestPtr req1, req2;
570  assert(!req->isLLSC() && !req->isSwap());
571  req->splitOnVaddr(split_addr, req1, req2);
572 
573  WholeTranslationState *state =
574  new WholeTranslationState(req, req1, req2, newData, res, mode);
576  new DataTranslation<TimingSimpleCPU *>(this, state, 0);
578  new DataTranslation<TimingSimpleCPU *>(this, state, 1);
579 
580  thread->dtb->translateTiming(req1, thread->getTC(), trans1, mode);
581  thread->dtb->translateTiming(req2, thread->getTC(), trans2, mode);
582  } else {
583  WholeTranslationState *state =
584  new WholeTranslationState(req, newData, res, mode);
586  new DataTranslation<TimingSimpleCPU *>(this, state);
587  thread->dtb->translateTiming(req, thread->getTC(), translation, mode);
588  }
589 
590  // Translation faults will be returned via finishTranslation()
591  return NoFault;
592 }
593 
594 Fault
596  Request::Flags flags,
597  AtomicOpFunctorPtr amo_op)
598 {
600  SimpleThread* thread = t_info.thread;
601 
602  Fault fault;
603  const Addr pc = thread->instAddr();
604  unsigned block_size = cacheLineSize();
606 
607  if (traceData)
608  traceData->setMem(addr, size, flags);
609 
610  RequestPtr req = make_shared<Request>(addr, size, flags,
611  dataRequestorId(), pc, thread->contextId(),
612  std::move(amo_op));
613 
614  assert(req->hasAtomicOpFunctor());
615 
616  req->taskId(taskId());
617 
618  Addr split_addr = roundDown(addr + size - 1, block_size);
619 
620  // AMO requests that access across a cache line boundary are not
621  // allowed since the cache does not guarantee AMO ops to be executed
622  // atomically in two cache lines
623  // For ISAs such as x86 that requires AMO operations to work on
624  // accesses that cross cache-line boundaries, the cache needs to be
625  // modified to support locking both cache lines to guarantee the
626  // atomicity.
627  if (split_addr > addr) {
628  panic("AMO requests should not access across a cache line boundary\n");
629  }
630 
632 
633  WholeTranslationState *state =
634  new WholeTranslationState(req, new uint8_t[size], NULL, mode);
636  = new DataTranslation<TimingSimpleCPU *>(this, state);
637  thread->dtb->translateTiming(req, thread->getTC(), translation, mode);
638 
639  return NoFault;
640 }
641 
642 void
644 {
645  for (ThreadID tid = 0; tid < numThreads; tid++) {
646  if (tid != sender) {
647  if (getCpuAddrMonitor(tid)->doMonitor(pkt)) {
648  wakeup(tid);
649  }
650  TheISA::handleLockedSnoop(threadInfo[tid]->thread, pkt,
652  }
653  }
654 }
655 
656 void
658 {
660 
661  if (state->getFault() != NoFault) {
662  if (state->isPrefetch()) {
663  state->setNoFault();
664  }
665  delete [] state->data;
666  state->deleteReqs();
667  translationFault(state->getFault());
668  } else {
669  if (!state->isSplit) {
670  sendData(state->mainReq, state->data, state->res,
671  state->mode == BaseTLB::Read);
672  } else {
673  sendSplitData(state->sreqLow, state->sreqHigh, state->mainReq,
674  state->data, state->mode == BaseTLB::Read);
675  }
676  }
677 
678  delete state;
679 }
680 
681 
682 void
684 {
685  // Change thread if multi-threaded
687 
689  SimpleThread* thread = t_info.thread;
690 
691  DPRINTF(SimpleCPU, "Fetch\n");
692 
696  }
697 
698  // We must have just got suspended by a PC event
699  if (_status == Idle)
700  return;
701 
702  TheISA::PCState pcState = thread->pcState();
703  bool needToFetch = !isRomMicroPC(pcState.microPC()) &&
705 
706  if (needToFetch) {
708  RequestPtr ifetch_req = std::make_shared<Request>();
709  ifetch_req->taskId(taskId());
710  ifetch_req->setContext(thread->contextId());
711  setupFetchRequest(ifetch_req);
712  DPRINTF(SimpleCPU, "Translating address %#x\n", ifetch_req->getVaddr());
713  thread->itb->translateTiming(ifetch_req, thread->getTC(),
715  } else {
717  completeIfetch(NULL);
718 
721  }
722 }
723 
724 
725 void
726 TimingSimpleCPU::sendFetch(const Fault &fault, const RequestPtr &req,
727  ThreadContext *tc)
728 {
729  if (fault == NoFault) {
730  DPRINTF(SimpleCPU, "Sending fetch for addr %#x(pa: %#x)\n",
731  req->getVaddr(), req->getPaddr());
732  ifetch_pkt = new Packet(req, MemCmd::ReadReq);
734  DPRINTF(SimpleCPU, " -- pkt addr: %#x\n", ifetch_pkt->getAddr());
735 
737  // Need to wait for retry
739  } else {
740  // Need to wait for cache to respond
742  // ownership of packet transferred to memory system
743  ifetch_pkt = NULL;
744  }
745  } else {
746  DPRINTF(SimpleCPU, "Translation of addr %#x faulted\n", req->getVaddr());
747  // fetch fault: advance directly to next instruction (fault handler)
749  advanceInst(fault);
750  }
751 
754 }
755 
756 
757 void
759 {
761 
762  if (_status == Faulting)
763  return;
764 
765  if (fault != NoFault) {
766  // hardware transactional memory
767  // If a fault occurred within a transaction
768  // ensure that the transaction aborts
769  if (t_info.inHtmTransactionalState() &&
770  !std::dynamic_pointer_cast<GenericHtmFailureFault>(fault)) {
771  DPRINTF(HtmCpu, "fault (%s) occurred - "
772  "replacing with HTM abort fault htmUid=%u\n",
773  fault->name(), t_info.getHtmTransactionUid());
774 
775  Fault tmfault = std::make_shared<GenericHtmFailureFault>(
776  t_info.getHtmTransactionUid(),
778 
779  advancePC(tmfault);
780  reschedule(fetchEvent, clockEdge(), true);
781  _status = Faulting;
782  return;
783  }
784 
785  DPRINTF(SimpleCPU, "Fault occured. Handling the fault\n");
786 
787  advancePC(fault);
788 
789  // A syscall fault could suspend this CPU (e.g., futex_wait)
790  // If the _status is not Idle, schedule an event to fetch the next
791  // instruction after 'stall' ticks.
792  // If the cpu has been suspended (i.e., _status == Idle), another
793  // cpu will wake this cpu up later.
794  if (_status != Idle) {
795  DPRINTF(SimpleCPU, "Scheduling fetch event after the Fault\n");
796 
797  Tick stall = dynamic_pointer_cast<SyscallRetryFault>(fault) ?
798  clockEdge(syscallRetryLatency) : clockEdge();
799  reschedule(fetchEvent, stall, true);
800  _status = Faulting;
801  }
802 
803  return;
804  }
805 
806  if (!t_info.stayAtPC)
807  advancePC(fault);
808 
809  if (tryCompleteDrain())
810  return;
811 
813  // kick off fetch of next instruction... callback from icache
814  // response will cause that instruction to be executed,
815  // keeping the CPU running.
816  fetch();
817  }
818 }
819 
820 
821 void
823 {
825 
826  DPRINTF(SimpleCPU, "Complete ICache Fetch for addr %#x\n", pkt ?
827  pkt->getAddr() : 0);
828 
829  // received a response from the icache: execute the received
830  // instruction
831  assert(!pkt || !pkt->isError());
832  assert(_status == IcacheWaitResponse);
833 
835 
838 
839  if (pkt)
840  pkt->req->setAccessLatency();
841 
842 
843  preExecute();
844 
845  // hardware transactional memory
847  // if this HtmStart is not within a transaction,
848  // then assign it a new htmTransactionUid
849  if (!t_info.inHtmTransactionalState())
850  t_info.newHtmTransactionUid();
851  SimpleThread* thread = t_info.thread;
852  thread->htmTransactionStarts++;
853  DPRINTF(HtmCpu, "htmTransactionStarts++=%u\n",
854  thread->htmTransactionStarts);
855  }
856 
858  // load or store: just send to dcache
859  Fault fault = curStaticInst->initiateAcc(&t_info, traceData);
860 
861  // If we're not running now the instruction will complete in a dcache
862  // response callback or the instruction faulted and has started an
863  // ifetch
865  if (fault != NoFault && traceData) {
866  traceFault();
867  }
868 
869  postExecute();
870  // @todo remove me after debugging with legion done
871  if (curStaticInst && (!curStaticInst->isMicroop() ||
873  instCnt++;
874  advanceInst(fault);
875  }
876  } else if (curStaticInst) {
877  // non-memory instruction: execute completely now
878  Fault fault = curStaticInst->execute(&t_info, traceData);
879 
880  // keep an instruction count
881  if (fault == NoFault)
882  countInst();
883  else if (traceData) {
884  traceFault();
885  }
886 
887  postExecute();
888  // @todo remove me after debugging with legion done
889  if (curStaticInst && (!curStaticInst->isMicroop() ||
891  instCnt++;
892  advanceInst(fault);
893  } else {
895  }
896 
897  if (pkt) {
898  delete pkt;
899  }
900 }
901 
902 void
904 {
905  cpu->completeIfetch(pkt);
906 }
907 
908 bool
910 {
911  DPRINTF(SimpleCPU, "Received fetch response %#x\n", pkt->getAddr());
912 
913  // hardware transactional memory
914  // Currently, there is no support for tracking instruction fetches
915  // in an transaction's read set.
916  if (pkt->htmTransactionFailedInCache()) {
917  panic("HTM transactional support for"
918  " instruction stream not yet supported\n");
919  }
920 
921  // we should only ever see one response per cycle since we only
922  // issue a new request once this response is sunk
923  assert(!tickEvent.scheduled());
924  // delay processing of returned data until next CPU clock edge
925  tickEvent.schedule(pkt, cpu->clockEdge());
926 
927  return true;
928 }
929 
930 void
932 {
933  // we shouldn't get a retry unless we have a packet that we're
934  // waiting to transmit
935  assert(cpu->ifetch_pkt != NULL);
936  assert(cpu->_status == IcacheRetry);
937  PacketPtr tmp = cpu->ifetch_pkt;
938  if (sendTimingReq(tmp)) {
940  cpu->ifetch_pkt = NULL;
941  }
942 }
943 
944 void
946 {
947  // hardware transactional memory
948 
950  const bool is_htm_speculative M5_VAR_USED =
951  t_info->inHtmTransactionalState();
952 
953  // received a response from the dcache: complete the load or store
954  // instruction
955  assert(!pkt->isError());
957  pkt->req->getFlags().isSet(Request::NO_ACCESS));
958 
959  pkt->req->setAccessLatency();
960 
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  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 (when using caches)
1101  // or on an incoming write packet (when not using caches)
1102  // It is not necessary to wake up the processor on all incoming packets
1103  if (pkt->isInvalidate() || pkt->isWrite()) {
1104  for (auto &t_info : cpu->threadInfo) {
1105  TheISA::handleLockedSnoop(t_info->thread, pkt, cacheBlockMask);
1106  }
1107  }
1108 }
1109 
1110 void
1112 {
1113  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
1114  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1115  cpu->wakeup(tid);
1116  }
1117  }
1118 }
1119 
1120 bool
1122 {
1123  DPRINTF(SimpleCPU, "Received load/store response %#x\n", pkt->getAddr());
1124 
1125  // The timing CPU is not really ticked, instead it relies on the
1126  // memory system (fetch and load/store) to set the pace.
1127  if (!tickEvent.scheduled()) {
1128  // Delay processing of returned data until next CPU clock edge
1129  tickEvent.schedule(pkt, cpu->clockEdge());
1130  return true;
1131  } else {
1132  // In the case of a split transaction and a cache that is
1133  // faster than a CPU we could get two responses in the
1134  // same tick, delay the second one
1135  if (!retryRespEvent.scheduled())
1136  cpu->schedule(retryRespEvent, cpu->clockEdge(Cycles(1)));
1137  return false;
1138  }
1139 }
1140 
1141 void
1143 {
1144  cpu->completeDataAccess(pkt);
1145 }
1146 
1147 void
1149 {
1150  // we shouldn't get a retry unless we have a packet that we're
1151  // waiting to transmit
1152  assert(cpu->dcache_pkt != NULL);
1153  assert(cpu->_status == DcacheRetry);
1154  PacketPtr tmp = cpu->dcache_pkt;
1155  if (tmp->senderState) {
1156  // This is a packet from a split access.
1157  SplitFragmentSenderState * send_state =
1158  dynamic_cast<SplitFragmentSenderState *>(tmp->senderState);
1159  assert(send_state);
1160  PacketPtr big_pkt = send_state->bigPkt;
1161 
1162  SplitMainSenderState * main_send_state =
1163  dynamic_cast<SplitMainSenderState *>(big_pkt->senderState);
1164  assert(main_send_state);
1165 
1166  if (sendTimingReq(tmp)) {
1167  // If we were able to send without retrying, record that fact
1168  // and try sending the other fragment.
1169  send_state->clearFromParent();
1170  int other_index = main_send_state->getPendingFragment();
1171  if (other_index > 0) {
1172  tmp = main_send_state->fragments[other_index];
1173  cpu->dcache_pkt = tmp;
1174  if ((big_pkt->isRead() && cpu->handleReadPacket(tmp)) ||
1175  (big_pkt->isWrite() && cpu->handleWritePacket())) {
1176  main_send_state->fragments[other_index] = NULL;
1177  }
1178  } else {
1180  // memory system takes ownership of packet
1181  cpu->dcache_pkt = NULL;
1182  }
1183  }
1184  } else if (sendTimingReq(tmp)) {
1186  // memory system takes ownership of packet
1187  cpu->dcache_pkt = NULL;
1188  }
1189 }
1190 
1192  Tick t)
1193  : pkt(_pkt), cpu(_cpu)
1194 {
1195  cpu->schedule(this, t);
1196 }
1197 
1198 void
1200 {
1201  cpu->completeDataAccess(pkt);
1202 }
1203 
1204 const char *
1206 {
1207  return "Timing Simple CPU Delay IPR event";
1208 }
1209 
1210 
1211 void
1213 {
1215 }
1216 
1217 Fault
1219 {
1221  SimpleThread* thread = t_info.thread;
1222 
1223  const Addr addr = 0x0ul;
1224  const Addr pc = thread->instAddr();
1225  const int size = 8;
1226 
1227  if (traceData)
1228  traceData->setMem(addr, size, flags);
1229 
1230  RequestPtr req = std::make_shared<Request>(
1231  addr, size, flags, dataRequestorId());
1232 
1233  req->setPC(pc);
1234  req->setContext(thread->contextId());
1235  req->taskId(taskId());
1236  req->setInstCount(t_info.numInst);
1237 
1238  assert(req->isHTMCmd());
1239 
1240  // Use the payload as a sanity check,
1241  // the memory subsystem will clear allocated data
1242  uint8_t *data = new uint8_t[size];
1243  assert(data);
1244  uint64_t rc = 0xdeadbeeflu;
1245  memcpy (data, &rc, size);
1246 
1247  // debugging output
1248  if (req->isHTMStart())
1249  DPRINTF(HtmCpu, "HTMstart htmUid=%u\n", t_info.getHtmTransactionUid());
1250  else if (req->isHTMCommit())
1251  DPRINTF(HtmCpu, "HTMcommit htmUid=%u\n", t_info.getHtmTransactionUid());
1252  else if (req->isHTMCancel())
1253  DPRINTF(HtmCpu, "HTMcancel htmUid=%u\n", t_info.getHtmTransactionUid());
1254  else
1255  panic("initiateHtmCmd: unknown CMD");
1256 
1257  sendData(req, data, nullptr, true);
1258 
1259  return NoFault;
1260 }
1261 
1262 void
1264 {
1266  SimpleThread* thread = t_info.thread;
1267 
1268  const Addr addr = 0x0ul;
1269  const Addr pc = thread->instAddr();
1270  const int size = 8;
1271  const Request::Flags flags =
1273 
1274  if (traceData)
1275  traceData->setMem(addr, size, flags);
1276 
1277  // notify l1 d-cache (ruby) that core has aborted transaction
1278 
1279  RequestPtr req = std::make_shared<Request>(
1280  addr, size, flags, dataRequestorId());
1281 
1282  req->setPC(pc);
1283  req->setContext(thread->contextId());
1284  req->taskId(taskId());
1285  req->setInstCount(t_info.numInst);
1286  req->setHtmAbortCause(cause);
1287 
1288  assert(req->isHTMAbort());
1289 
1290  uint8_t *data = new uint8_t[size];
1291  assert(data);
1292  uint64_t rc = 0lu;
1293  memcpy (data, &rc, size);
1294 
1295  sendData(req, data, nullptr, true);
1296 }
1297 
1298 
1300 //
1301 // TimingSimpleCPU Simulation Object
1302 //
1304 TimingSimpleCPUParams::create()
1305 {
1306  return new TimingSimpleCPU(this);
1307 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
Packet::isError
bool isError() const
Definition: packet.hh:583
AtomicOpFunctorPtr
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Definition: amo.hh:239
TimingSimpleCPU::dcachePort
DcachePort dcachePort
Definition: timing.hh:255
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:460
ArmISA::handleLockedWrite
bool handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask)
Definition: locked_mem.hh:111
TimingSimpleCPU::initiateMemRead
Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
Definition: timing.cc:453
SimpleThread::contextId
ContextID contextId() const override
Definition: simple_thread.hh:216
WholeTranslationState::mainReq
RequestPtr mainReq
Definition: translation.hh:67
TimingSimpleCPU::TimingCPUPort::TickEvent::schedule
void schedule(PacketPtr _pkt, Tick t)
Definition: timing.cc:71
roundDown
T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:150
SimpleExecContext
Definition: exec_context.hh:57
TimingSimpleCPU::completeIfetch
void completeIfetch(PacketPtr)
Definition: timing.cc:822
SimpleThread::pcState
TheISA::PCState pcState() const override
Definition: simple_thread.hh:517
BaseSimpleCPU::traceData
Trace::InstRecord * traceData
Definition: base.hh:95
StaticInst::initiateAcc
virtual Fault initiateAcc(ExecContext *xc, Trace::InstRecord *traceData) const
Definition: static_inst.hh:290
system.hh
BaseTLB::Read
@ Read
Definition: tlb.hh:57
BaseSimpleCPU::curMacroStaticInst
StaticInstPtr curMacroStaticInst
Definition: base.hh:104
TimingSimpleCPU::SplitMainSenderState::getPendingFragment
int getPendingFragment()
Definition: timing.hh:77
BaseSimpleCPU::DTBWaitResponse
@ DTBWaitResponse
Definition: base.hh:115
data
const char data[]
Definition: circlebuf.test.cc:42
BaseSimpleCPU::_status
Status _status
Definition: base.hh:121
StaticInst::isMemRef
bool isMemRef() const
Definition: static_inst.hh:160
TimingSimpleCPU::SplitFragmentSenderState
Definition: timing.hh:89
ArmISA::handleLockedSnoop
void handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
Definition: locked_mem.hh:62
System::isTimingMode
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:269
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:754
TimingSimpleCPU::IcachePort::tickEvent
ITickEvent tickEvent
Definition: timing.hh:208
timing.hh
Packet::isHtmTransactional
bool isHtmTransactional() const
Returns whether or not this packet/request originates in the CPU executing in transactional mode,...
Definition: packet.cc:544
ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
WholeTranslationState::setNoFault
void setNoFault()
Remove all faults from the translation.
Definition: translation.hh:147
Flags< FlagsType >
Request::NO_ACCESS
@ NO_ACCESS
The request should not cause a memory access.
Definition: request.hh:135
AddressMonitor::doMonitor
bool doMonitor(PacketPtr pkt)
Definition: base.cc:709
TheISA
Definition: decode_cache.hh:37
BaseCPU::cacheLineSize
unsigned int cacheLineSize() const
Get the cache line size of the system.
Definition: base.hh:376
Packet::isRead
bool isRead() const
Definition: packet.hh:556
BaseTLB::translateTiming
virtual void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)=0
BaseTLB::Mode
Mode
Definition: tlb.hh:57
TimingSimpleCPU::IprEvent::IprEvent
IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
Definition: timing.cc:1191
MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:82
TimingSimpleCPU::translationFault
void translationFault(const Fault &fault)
Definition: timing.cc:398
TimingSimpleCPU::previousCycle
Cycles previousCycle
Definition: timing.hh:260
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
TimingSimpleCPU::isCpuDrained
bool isCpuDrained() const
Check if a system is in a drained state.
Definition: timing.hh:356
exetrace.hh
TimingSimpleCPU::DcachePort::DTickEvent::process
void process()
Definition: timing.cc:1142
BaseCPU::syscallRetryLatency
Cycles syscallRetryLatency
Definition: base.hh:607
Trace::InstRecord::setMem
void setMem(Addr a, Addr s, unsigned f)
Definition: insttracer.hh:176
TimingSimpleCPU::IcachePort::ITickEvent::process
void process()
Definition: timing.cc:903
BaseSimpleCPU::setupFetchRequest
void setupFetchRequest(const RequestPtr &req)
Definition: base.cc:478
Packet::isInvalidate
bool isInvalidate() const
Definition: packet.hh:571
TimingSimpleCPU::DcachePort::cacheBlockMask
Addr cacheBlockMask
Definition: timing.hh:223
RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:82
Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:340
TimingSimpleCPU::suspendContext
void suspendContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now suspended.
Definition: timing.cc:235
TimingSimpleCPU::drainResume
void drainResume() override
Definition: timing.cc:119
WholeTranslationState::data
uint8_t * data
Definition: translation.hh:70
WholeTranslationState::isPrefetch
bool isPrefetch() const
Check if this request is a prefetch.
Definition: translation.hh:169
Packet::dataDynamic
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
Definition: packet.hh:1145
std::vector< bool >
BaseCPU::deschedulePowerGatingEvent
void deschedulePowerGatingEvent()
Definition: base.cc:444
HtmFailureFaultCause
HtmFailureFaultCause
Definition: htm.hh:44
HtmCacheFailure::FAIL_REMOTE
@ FAIL_REMOTE
WholeTranslationState::mode
BaseTLB::Mode mode
Definition: translation.hh:72
BaseCPU::numCycles
Stats::Scalar numCycles
Definition: base.hh:588
BaseSimpleCPU::threadInfo
std::vector< SimpleExecContext * > threadInfo
Definition: base.hh:98
BaseSimpleCPU::traceFault
void traceFault()
Handler used when encountering a fault; its purpose is to tear down the InstRecord.
Definition: base.cc:436
TimingSimpleCPU::IprEvent::cpu
TimingSimpleCPU * cpu
Definition: timing.hh:334
BaseSimpleCPU::countInst
void countInst()
Definition: base.cc:161
faults.hh
WholeTranslationState
This class captures the state of an address translation.
Definition: translation.hh:58
TimingSimpleCPU::ifetch_pkt
PacketPtr ifetch_pkt
Definition: timing.hh:257
TimingSimpleCPU::fetchEvent
EventFunctionWrapper fetchEvent
Definition: timing.hh:330
TimingSimpleCPU::SplitFragmentSenderState::clearFromParent
void clearFromParent()
Definition: timing.hh:99
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:421
TimingSimpleCPU::buildPacket
PacketPtr buildPacket(const RequestPtr &req, bool read)
Definition: timing.cc:415
BaseSimpleCPU::postExecute
void postExecute()
Definition: base.cc:583
TimingSimpleCPU::SplitMainSenderState::outstanding
int outstanding
Definition: timing.hh:73
BaseCPU::updateCycleCounters
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Definition: base.hh:517
packet.hh
SimpleThread
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
Definition: simple_thread.hh:89
TimingSimpleCPU::IprEvent::process
virtual void process()
Definition: timing.cc:1199
DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
TimingSimpleCPU::threadSnoop
void threadSnoop(PacketPtr pkt, ThreadID sender)
Definition: timing.cc:643
TimingSimpleCPU::dcache_pkt
PacketPtr dcache_pkt
Definition: timing.hh:258
BaseSimpleCPU::activeThreads
std::list< ThreadID > activeThreads
Definition: base.hh:99
DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:71
WholeTranslationState::isSplit
bool isSplit
Definition: translation.hh:66
Request::STRICT_ORDER
@ STRICT_ORDER
The request is required to be strictly ordered by CPU models and is non-speculative.
Definition: request.hh:124
TimingSimpleCPU::DcachePort::recvFunctionalSnoop
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
Definition: timing.cc:1111
TimingSimpleCPU::initiateHtmCmd
Fault initiateHtmCmd(Request::Flags flags) override
hardware transactional memory
Definition: timing.cc:1218
StaticInst::isFirstMicroop
bool isFirstMicroop() const
Definition: static_inst.hh:202
Request::PHYSICAL
@ PHYSICAL
The virtual address is also the physical address.
Definition: request.hh:106
TimingSimpleCPU::fetchTranslation
FetchTranslation fetchTranslation
Definition: timing.hh:131
BaseSimpleCPU::checkPcEventQueue
void checkPcEventQueue()
Definition: base.cc:133
SimpleThread::htmTransactionStops
int64_t htmTransactionStops
Definition: simple_thread.hh:140
StaticInst::isHtmStart
bool isHtmStart() const
Definition: static_inst.hh:208
TimingSimpleCPU::TimingCPUPort::retryRespEvent
EventFunctionWrapper retryRespEvent
Definition: timing.hh:181
SimpleThread::instAddr
Addr instAddr() const override
Definition: simple_thread.hh:526
ArmISA::a
Bitfield< 8 > a
Definition: miscregs_types.hh:62
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
StaticInst::isDelayedCommit
bool isDelayedCommit() const
Definition: static_inst.hh:200
SimpleThread::getTC
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
Definition: simple_thread.hh:169
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:492
HtmFailureFaultCause::EXCEPTION
@ EXCEPTION
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
BaseCPU::instCnt
Tick instCnt
Instruction count used for SPARC misc register.
Definition: base.hh:110
TimingSimpleCPU::advanceInst
void advanceInst(const Fault &fault)
Definition: timing.cc:758
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:240
TimingSimpleCPU::IprEvent::description
virtual const char * description() const
Return a C string describing the event.
Definition: timing.cc:1205
Packet::createRead
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
Definition: packet.hh:980
BaseSimpleCPU::Idle
@ Idle
Definition: base.hh:108
BaseSimpleCPU::inst
TheISA::MachInst inst
Current instruction.
Definition: base.hh:102
TimingSimpleCPU::init
void init() override
Definition: timing.cc:65
TimingSimpleCPU::icachePort
IcachePort icachePort
Definition: timing.hh:254
BaseCPU::threadContexts
std::vector< ThreadContext * > threadContexts
Definition: base.hh:252
BaseSimpleCPU::IcacheWaitResponse
@ IcacheWaitResponse
Definition: base.hh:113
TimingSimpleCPU::finishTranslation
void finishTranslation(WholeTranslationState *state)
Finish a DTB translation.
Definition: timing.cc:657
ArmISA::mode
Bitfield< 4, 0 > mode
Definition: miscregs_types.hh:70
TimingSimpleCPU::completeDataAccess
void completeDataAccess(PacketPtr pkt)
Definition: timing.cc:945
BaseCPU::activateContext
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Definition: base.cc:480
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:514
SimpleExecContext::thread
SimpleThread * thread
Definition: exec_context.hh:64
Packet::setHtmTransactional
void setHtmTransactional(uint64_t val)
Stipulates that this packet/request originates in the CPU executing in transactional mode,...
Definition: packet.cc:537
TimingSimpleCPU::drain
DrainState drain() override
Definition: timing.cc:92
BaseSimpleCPU::init
void init() override
Definition: base.cc:122
BaseSimpleCPU::checkForInterrupts
void checkForInterrupts()
Definition: base.cc:447
WholeTranslationState::sreqHigh
RequestPtr sreqHigh
Definition: translation.hh:69
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:1148
BaseSimpleCPU
Definition: base.hh:80
BaseCPU::getCpuAddrMonitor
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
Definition: base.hh:599
WholeTranslationState::res
uint64_t * res
Definition: translation.hh:71
BaseSimpleCPU::curThread
ThreadID curThread
Definition: base.hh:83
TimingSimpleCPU::SplitMainSenderState
Definition: timing.hh:70
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:529
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:245
BaseSimpleCPU::IcacheRetry
@ IcacheRetry
Definition: base.hh:112
ProbePoints::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:103
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
TimingSimpleCPU::fetch
void fetch()
Definition: timing.cc:683
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:1004
name
const std::string & name()
Definition: trace.cc:50
TimingSimpleCPU::handleWritePacket
bool handleWritePacket()
Definition: timing.cc:507
isRomMicroPC
static bool isRomMicroPC(MicroPC upc)
Definition: types.hh:161
BaseSimpleCPU::DcacheWaitResponse
@ DcacheWaitResponse
Definition: base.hh:117
HtmCacheFailure
HtmCacheFailure
Definition: htm.hh:56
TimingSimpleCPU::sendData
void sendData(const RequestPtr &req, uint8_t *data, uint64_t *res, bool read)
Definition: timing.cc:300
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:524
packet_access.hh
BaseSimpleCPU::Faulting
@ Faulting
Definition: base.hh:110
full_system.hh
StaticInst::isMicroop
bool isMicroop() const
Definition: static_inst.hh:199
Packet::getHtmTransactionUid
uint64_t getHtmTransactionUid() const
If a packet/request originates in a CPU executing in transactional mode, i.e.
Definition: packet.cc:550
BaseCPU::taskId
uint32_t taskId() const
Get cpu task id.
Definition: base.hh:202
BaseTLB::Write
@ Write
Definition: tlb.hh:57
WholeTranslationState::sreqLow
RequestPtr sreqLow
Definition: translation.hh:68
BaseCPU
Definition: cpu_dummy.hh:43
BaseSimpleCPU::wakeup
void wakeup(ThreadID tid) override
Definition: base.cc:425
BaseSimpleCPU::curStaticInst
StaticInstPtr curStaticInst
Definition: base.hh:103
Packet::cmd
MemCmd cmd
The command field of the packet.
Definition: packet.hh:335
BaseSimpleCPU::swapActiveThread
void swapActiveThread()
Definition: base.cc:145
BaseSimpleCPU::advancePC
void advancePC(const Fault &fault)
Definition: base.cc:659
Packet::createWrite
static PacketPtr createWrite(const RequestPtr &req)
Definition: packet.hh:986
ArmISA::handleLockedRead
void handleLockedRead(XC *xc, const RequestPtr &req)
Definition: locked_mem.hh:91
SimpleExecContext::numInst
Counter numInst
PER-THREAD STATS.
Definition: exec_context.hh:78
TimingSimpleCPU::updateCycleCounts
void updateCycleCounts()
Definition: timing.cc:1081
WholeTranslationState::deleteReqs
void deleteReqs()
Delete all requests that make up this translation.
Definition: translation.hh:194
WholeTranslationState::getFault
Fault getFault() const
Determine whether this translation produced a fault.
Definition: translation.hh:133
TimingSimpleCPU::handleReadPacket
bool handleReadPacket(PacketPtr pkt)
Definition: timing.cc:265
StaticInst::isHtmStop
bool isHtmStop() const
Definition: static_inst.hh:209
SimpleExecContext::newHtmTransactionUid
uint64_t newHtmTransactionUid() const override
Definition: exec_context.hh:542
SimpleThread::htmTransactionStarts
int64_t htmTransactionStarts
Definition: simple_thread.hh:139
Request::HTM_ABORT
@ HTM_ABORT
The request aborts a HTM transaction.
Definition: request.hh:203
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
MipsISA::PCState
GenericISA::DelaySlotPCState< MachInst > PCState
Definition: types.hh:41
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
BaseCPU::schedulePowerGatingEvent
void schedulePowerGatingEvent()
Definition: base.cc:452
BaseCPU::system
System * system
Definition: base.hh:371
TimingSimpleCPU::TimingCPUPort::cpu
TimingSimpleCPU * cpu
Definition: timing.hh:169
Packet::dataStatic
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:1107
BaseCPU::takeOverFrom
virtual void takeOverFrom(BaseCPU *cpu)
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
Definition: base.cc:546
System::totalNumInsts
Counter totalNumInsts
Definition: system.hh:603
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:931
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
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:194
BaseCPU::switchOut
virtual void switchOut()
Prepare for another CPU to take over execution.
Definition: base.cc:532
BaseSimpleCPU::preExecute
void preExecute()
Definition: base.cc:495
SimpleThread::dtb
BaseTLB * dtb
Definition: simple_thread.hh:134
StaticInst::completeAcc
virtual Fault completeAcc(Packet *pkt, ExecContext *xc, Trace::InstRecord *traceData) const
Definition: static_inst.hh:296
RequestPort::printAddr
void printAddr(Addr a)
Inject a PrintReq for the given address to print the state of that address throughout the memory syst...
Definition: port.cc:154
addr
ip6_addr_t addr
Definition: inet.hh:423
TimingSimpleCPU
Definition: timing.hh:49
BaseCPU::numThreads
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Definition: base.hh:363
TimingSimpleCPU::TimingSimpleCPU
TimingSimpleCPU(TimingSimpleCPUParams *params)
Definition: timing.cc:77
TimingSimpleCPU::switchOut
void switchOut() override
Prepare for another CPU to take over execution.
Definition: timing.cc:172
htmFailureToStr
std::string htmFailureToStr(HtmFailureFaultCause cause)
Convert enum into string to be used for debug purposes.
Definition: htm.cc:41
BaseCPU::dataRequestorId
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
Definition: base.hh:184
Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
Packet::isWrite
bool isWrite() const
Definition: packet.hh:557
ThreadContext::Active
@ Active
Running.
Definition: thread_context.hh:102
BaseSimpleCPU::DcacheRetry
@ DcacheRetry
Definition: base.hh:116
TimingSimpleCPU::DcachePort::recvTimingResp
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Definition: timing.cc:1121
BaseCPU::CPU_STATE_ON
@ CPU_STATE_ON
Definition: base.hh:508
TimingSimpleCPU::sendFetch
void sendFetch(const Fault &fault, const RequestPtr &req, ThreadContext *tc)
Definition: timing.cc:726
BaseCPU::suspendContext
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Definition: base.cc:494
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
StaticInst::execute
virtual Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const =0
TimingSimpleCPU::SplitMainSenderState::fragments
PacketPtr fragments[2]
Definition: timing.hh:74
Packet::senderState
SenderState * senderState
This packet's sender state.
Definition: packet.hh:508
Packet::getHtmTransactionFailedInCacheRC
HtmCacheFailure getHtmTransactionFailedInCacheRC() const
If a packet/request has returned from the cache hierarchy in a failed transaction,...
Definition: packet.cc:530
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
DataTranslation
This class represents part of a data address translation.
Definition: translation.hh:215
Request::STORE_NO_DATA
static const FlagsType STORE_NO_DATA
Definition: request.hh:233
TimingSimpleCPU::tryCompleteDrain
bool tryCompleteDrain()
Try to complete a drain request.
Definition: timing.cc:156
BaseCPU::switchedOut
bool switchedOut() const
Determine if the CPU is switched out.
Definition: base.hh:352
SimpleExecContext::inHtmTransactionalState
bool inHtmTransactionalState() const override
Definition: exec_context.hh:548
SimpleExecContext::getHtmTransactionUid
uint64_t getHtmTransactionUid() const override
Definition: exec_context.hh:536
BaseTLB::Execute
@ Execute
Definition: tlb.hh:57
SimpleThread::itb
BaseTLB * itb
Definition: simple_thread.hh:133
HtmFailureFaultCause::SIZE
@ SIZE
TimingSimpleCPU::~TimingSimpleCPU
virtual ~TimingSimpleCPU()
Definition: timing.cc:87
TimingSimpleCPU::sendSplitData
void sendSplitData(const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req, uint8_t *data, bool read)
Definition: timing.cc:348
HtmFailureFaultCause::MEMORY
@ MEMORY
HtmCacheFailure::FAIL_SELF
@ FAIL_SELF
TimingSimpleCPU::verifyMemoryMode
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
Definition: timing.cc:202
TimingSimpleCPU::SplitFragmentSenderState::bigPkt
PacketPtr bigPkt
Definition: timing.hh:95
TimingSimpleCPU::initiateMemAMO
Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
Definition: timing.cc:595
TimingSimpleCPU::activateContext
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
Definition: timing.cc:211
MemCmd::responseCommand
Command responseCommand() const
Definition: packet.hh:233
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:1263
SimpleExecContext::stayAtPC
bool stayAtPC
Definition: exec_context.hh:70
TimingSimpleCPU::IprEvent
Definition: timing.hh:332
TimingSimpleCPU::IcachePort::recvTimingResp
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Definition: timing.cc:909
DrainState::Draining
@ Draining
Draining buffers pending serialization/handover.
TimingSimpleCPU::printAddr
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
Definition: timing.cc:1212
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
BaseSimpleCPU::Running
@ Running
Definition: base.hh:109

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