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

Generated on Tue Mar 23 2021 19:41:25 for gem5 by doxygen 1.8.17