gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
lsq_impl.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2012, 2014, 2017-2019 ARM Limited
3  * Copyright (c) 2013 Advanced Micro Devices, Inc.
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) 2005-2006 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 #ifndef __CPU_O3_LSQ_IMPL_HH__
43 #define __CPU_O3_LSQ_IMPL_HH__
44 
45 #include <algorithm>
46 #include <list>
47 #include <string>
48 
49 #include "base/logging.hh"
50 #include "cpu/o3/cpu.hh"
51 #include "cpu/o3/lsq.hh"
52 #include "debug/Drain.hh"
53 #include "debug/Fetch.hh"
54 #include "debug/HtmCpu.hh"
55 #include "debug/LSQ.hh"
56 #include "debug/Writeback.hh"
57 #include "params/DerivO3CPU.hh"
58 
59 template <class Impl>
60 LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, const DerivO3CPUParams &params)
61  : cpu(cpu_ptr), iewStage(iew_ptr),
62  _cacheBlocked(false),
63  cacheStorePorts(params.cacheStorePorts), usedStorePorts(0),
64  cacheLoadPorts(params.cacheLoadPorts), usedLoadPorts(0),
65  lsqPolicy(params.smtLSQPolicy),
66  LQEntries(params.LQEntries),
67  SQEntries(params.SQEntries),
68  maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params.numThreads,
69  params.smtLSQThreshold)),
70  maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params.numThreads,
71  params.smtLSQThreshold)),
72  dcachePort(this, cpu_ptr),
73  numThreads(params.numThreads)
74 {
75  assert(numThreads > 0 && numThreads <= Impl::MaxThreads);
76 
77  //**********************************************
78  //************ Handle SMT Parameters ***********
79  //**********************************************
80 
81  /* Run SMT olicy checks. */
82  if (lsqPolicy == SMTQueuePolicy::Dynamic) {
83  DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
84  } else if (lsqPolicy == SMTQueuePolicy::Partitioned) {
85  DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
86  "%i entries per LQ | %i entries per SQ\n",
88  } else if (lsqPolicy == SMTQueuePolicy::Threshold) {
89 
90  assert(params.smtLSQThreshold > params.LQEntries);
91  assert(params.smtLSQThreshold > params.SQEntries);
92 
93  DPRINTF(LSQ, "LSQ sharing policy set to Threshold: "
94  "%i entries per LQ | %i entries per SQ\n",
96  } else {
97  panic("Invalid LSQ sharing policy. Options are: Dynamic, "
98  "Partitioned, Threshold");
99  }
100 
101  thread.reserve(numThreads);
102  for (ThreadID tid = 0; tid < numThreads; tid++) {
103  thread.emplace_back(maxLQEntries, maxSQEntries);
104  thread[tid].init(cpu, iew_ptr, params, this, tid);
105  thread[tid].setDcachePort(&dcachePort);
106  }
107 }
108 
109 
110 template<class Impl>
111 std::string
113 {
114  return iewStage->name() + ".lsq";
115 }
116 
117 template<class Impl>
118 void
120 {
121  activeThreads = at_ptr;
122  assert(activeThreads != 0);
123 }
124 
125 template <class Impl>
126 void
128 {
129  assert(isDrained());
130 
131  for (ThreadID tid = 0; tid < numThreads; tid++)
132  thread[tid].drainSanityCheck();
133 }
134 
135 template <class Impl>
136 bool
138 {
139  bool drained(true);
140 
141  if (!lqEmpty()) {
142  DPRINTF(Drain, "Not drained, LQ not empty.\n");
143  drained = false;
144  }
145 
146  if (!sqEmpty()) {
147  DPRINTF(Drain, "Not drained, SQ not empty.\n");
148  drained = false;
149  }
150 
151  return drained;
152 }
153 
154 template <class Impl>
155 void
157 {
158  usedStorePorts = 0;
159  _cacheBlocked = false;
160 
161  for (ThreadID tid = 0; tid < numThreads; tid++) {
162  thread[tid].takeOverFrom();
163  }
164 }
165 
166 template <class Impl>
167 void
169 {
170  // Re-issue loads which got blocked on the per-cycle load ports limit.
171  if (usedLoadPorts == cacheLoadPorts && !_cacheBlocked)
172  iewStage->cacheUnblocked();
173 
174  usedLoadPorts = 0;
175  usedStorePorts = 0;
176 }
177 
178 template<class Impl>
179 bool
181 {
182  return _cacheBlocked;
183 }
184 
185 template<class Impl>
186 void
188 {
189  _cacheBlocked = v;
190 }
191 
192 template<class Impl>
193 bool
194 LSQ<Impl>::cachePortAvailable(bool is_load) const
195 {
196  bool ret;
197  if (is_load) {
198  ret = usedLoadPorts < cacheLoadPorts;
199  } else {
200  ret = usedStorePorts < cacheStorePorts;
201  }
202  return ret;
203 }
204 
205 template<class Impl>
206 void
208 {
209  assert(cachePortAvailable(is_load));
210  if (is_load) {
211  usedLoadPorts++;
212  } else {
213  usedStorePorts++;
214  }
215 }
216 
217 template<class Impl>
218 void
220 {
221  ThreadID tid = load_inst->threadNumber;
222 
223  thread[tid].insertLoad(load_inst);
224 }
225 
226 template<class Impl>
227 void
229 {
230  ThreadID tid = store_inst->threadNumber;
231 
232  thread[tid].insertStore(store_inst);
233 }
234 
235 template<class Impl>
236 Fault
238 {
239  ThreadID tid = inst->threadNumber;
240 
241  return thread[tid].executeLoad(inst);
242 }
243 
244 template<class Impl>
245 Fault
247 {
248  ThreadID tid = inst->threadNumber;
249 
250  return thread[tid].executeStore(inst);
251 }
252 
253 template<class Impl>
254 void
256 {
257  std::list<ThreadID>::iterator threads = activeThreads->begin();
258  std::list<ThreadID>::iterator end = activeThreads->end();
259 
260  while (threads != end) {
261  ThreadID tid = *threads++;
262 
263  if (numStoresToWB(tid) > 0) {
264  DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores "
265  "available for Writeback.\n", tid, numStoresToWB(tid));
266  }
267 
268  thread[tid].writebackStores();
269  }
270 }
271 
272 template<class Impl>
273 bool
275 {
276  /* Answers: Does Anybody Have a Violation?*/
277  std::list<ThreadID>::iterator threads = activeThreads->begin();
278  std::list<ThreadID>::iterator end = activeThreads->end();
279 
280  while (threads != end) {
281  ThreadID tid = *threads++;
282 
283  if (thread[tid].violation())
284  return true;
285  }
286 
287  return false;
288 }
289 
290 template <class Impl>
291 void
293 {
294  iewStage->cacheUnblocked();
295  cacheBlocked(false);
296 
297  for (ThreadID tid : *activeThreads) {
298  thread[tid].recvRetry();
299  }
300 }
301 
302 template <class Impl>
303 void
305 {
306  auto senderState = dynamic_cast<LSQSenderState*>(pkt->senderState);
307  thread[cpu->contextToThread(senderState->contextId())]
308  .completeDataAccess(pkt);
309 }
310 
311 template <class Impl>
312 bool
314 {
315  if (pkt->isError())
316  DPRINTF(LSQ, "Got error packet back for address: %#X\n",
317  pkt->getAddr());
318 
319  auto senderState = dynamic_cast<LSQSenderState*>(pkt->senderState);
320  panic_if(!senderState, "Got packet back with unknown sender state\n");
321 
322  thread[cpu->contextToThread(senderState->contextId())].recvTimingResp(pkt);
323 
324  if (pkt->isInvalidate()) {
325  // This response also contains an invalidate; e.g. this can be the case
326  // if cmd is ReadRespWithInvalidate.
327  //
328  // The calling order between completeDataAccess and checkSnoop matters.
329  // By calling checkSnoop after completeDataAccess, we ensure that the
330  // fault set by checkSnoop is not lost. Calling writeback (more
331  // specifically inst->completeAcc) in completeDataAccess overwrites
332  // fault, and in case this instruction requires squashing (as
333  // determined by checkSnoop), the ReExec fault set by checkSnoop would
334  // be lost otherwise.
335 
336  DPRINTF(LSQ, "received invalidation with response for addr:%#x\n",
337  pkt->getAddr());
338 
339  for (ThreadID tid = 0; tid < numThreads; tid++) {
340  thread[tid].checkSnoop(pkt);
341  }
342  }
343  // Update the LSQRequest state (this may delete the request)
344  senderState->request()->packetReplied();
345 
346  return true;
347 }
348 
349 template <class Impl>
350 void
352 {
353  DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
354  pkt->cmdString());
355 
356  // must be a snoop
357  if (pkt->isInvalidate()) {
358  DPRINTF(LSQ, "received invalidation for addr:%#x\n",
359  pkt->getAddr());
360  for (ThreadID tid = 0; tid < numThreads; tid++) {
361  thread[tid].checkSnoop(pkt);
362  }
363  }
364 }
365 
366 template<class Impl>
367 int
369 {
370  unsigned total = 0;
371 
372  std::list<ThreadID>::iterator threads = activeThreads->begin();
373  std::list<ThreadID>::iterator end = activeThreads->end();
374 
375  while (threads != end) {
376  ThreadID tid = *threads++;
377 
378  total += getCount(tid);
379  }
380 
381  return total;
382 }
383 
384 template<class Impl>
385 int
387 {
388  unsigned total = 0;
389 
390  std::list<ThreadID>::iterator threads = activeThreads->begin();
391  std::list<ThreadID>::iterator end = activeThreads->end();
392 
393  while (threads != end) {
394  ThreadID tid = *threads++;
395 
396  total += numLoads(tid);
397  }
398 
399  return total;
400 }
401 
402 template<class Impl>
403 int
405 {
406  unsigned total = 0;
407 
408  std::list<ThreadID>::iterator threads = activeThreads->begin();
409  std::list<ThreadID>::iterator end = activeThreads->end();
410 
411  while (threads != end) {
412  ThreadID tid = *threads++;
413 
414  total += thread[tid].numStores();
415  }
416 
417  return total;
418 }
419 
420 template<class Impl>
421 unsigned
423 {
424  unsigned total = 0;
425 
426  std::list<ThreadID>::iterator threads = activeThreads->begin();
427  std::list<ThreadID>::iterator end = activeThreads->end();
428 
429  while (threads != end) {
430  ThreadID tid = *threads++;
431 
432  total += thread[tid].numFreeLoadEntries();
433  }
434 
435  return total;
436 }
437 
438 template<class Impl>
439 unsigned
441 {
442  unsigned total = 0;
443 
444  std::list<ThreadID>::iterator threads = activeThreads->begin();
445  std::list<ThreadID>::iterator end = activeThreads->end();
446 
447  while (threads != end) {
448  ThreadID tid = *threads++;
449 
450  total += thread[tid].numFreeStoreEntries();
451  }
452 
453  return total;
454 }
455 
456 template<class Impl>
457 unsigned
459 {
460  return thread[tid].numFreeLoadEntries();
461 }
462 
463 template<class Impl>
464 unsigned
466 {
467  return thread[tid].numFreeStoreEntries();
468 }
469 
470 template<class Impl>
471 bool
473 {
474  std::list<ThreadID>::iterator threads = activeThreads->begin();
475  std::list<ThreadID>::iterator end = activeThreads->end();
476 
477  while (threads != end) {
478  ThreadID tid = *threads++;
479 
480  if (!(thread[tid].lqFull() || thread[tid].sqFull()))
481  return false;
482  }
483 
484  return true;
485 }
486 
487 template<class Impl>
488 bool
490 {
491  //@todo: Change to Calculate All Entries for
492  //Dynamic Policy
493  if (lsqPolicy == SMTQueuePolicy::Dynamic)
494  return isFull();
495  else
496  return thread[tid].lqFull() || thread[tid].sqFull();
497 }
498 
499 template<class Impl>
500 bool
502 {
503  return lqEmpty() && sqEmpty();
504 }
505 
506 template<class Impl>
507 bool
509 {
510  std::list<ThreadID>::const_iterator threads = activeThreads->begin();
511  std::list<ThreadID>::const_iterator end = activeThreads->end();
512 
513  while (threads != end) {
514  ThreadID tid = *threads++;
515 
516  if (!thread[tid].lqEmpty())
517  return false;
518  }
519 
520  return true;
521 }
522 
523 template<class Impl>
524 bool
526 {
527  std::list<ThreadID>::const_iterator threads = activeThreads->begin();
528  std::list<ThreadID>::const_iterator end = activeThreads->end();
529 
530  while (threads != end) {
531  ThreadID tid = *threads++;
532 
533  if (!thread[tid].sqEmpty())
534  return false;
535  }
536 
537  return true;
538 }
539 
540 template<class Impl>
541 bool
543 {
544  std::list<ThreadID>::iterator threads = activeThreads->begin();
545  std::list<ThreadID>::iterator end = activeThreads->end();
546 
547  while (threads != end) {
548  ThreadID tid = *threads++;
549 
550  if (!thread[tid].lqFull())
551  return false;
552  }
553 
554  return true;
555 }
556 
557 template<class Impl>
558 bool
560 {
561  //@todo: Change to Calculate All Entries for
562  //Dynamic Policy
563  if (lsqPolicy == SMTQueuePolicy::Dynamic)
564  return lqFull();
565  else
566  return thread[tid].lqFull();
567 }
568 
569 template<class Impl>
570 bool
572 {
573  std::list<ThreadID>::iterator threads = activeThreads->begin();
574  std::list<ThreadID>::iterator end = activeThreads->end();
575 
576  while (threads != end) {
577  ThreadID tid = *threads++;
578 
579  if (!sqFull(tid))
580  return false;
581  }
582 
583  return true;
584 }
585 
586 template<class Impl>
587 bool
589 {
590  //@todo: Change to Calculate All Entries for
591  //Dynamic Policy
592  if (lsqPolicy == SMTQueuePolicy::Dynamic)
593  return sqFull();
594  else
595  return thread[tid].sqFull();
596 }
597 
598 template<class Impl>
599 bool
601 {
602  std::list<ThreadID>::iterator threads = activeThreads->begin();
603  std::list<ThreadID>::iterator end = activeThreads->end();
604 
605  while (threads != end) {
606  ThreadID tid = *threads++;
607 
608  if (!thread[tid].isStalled())
609  return false;
610  }
611 
612  return true;
613 }
614 
615 template<class Impl>
616 bool
618 {
619  if (lsqPolicy == SMTQueuePolicy::Dynamic)
620  return isStalled();
621  else
622  return thread[tid].isStalled();
623 }
624 
625 template<class Impl>
626 bool
628 {
629  std::list<ThreadID>::iterator threads = activeThreads->begin();
630  std::list<ThreadID>::iterator end = activeThreads->end();
631 
632  while (threads != end) {
633  ThreadID tid = *threads++;
634 
635  if (hasStoresToWB(tid))
636  return true;
637  }
638 
639  return false;
640 }
641 
642 template<class Impl>
643 bool
645 {
646  std::list<ThreadID>::iterator threads = activeThreads->begin();
647  std::list<ThreadID>::iterator end = activeThreads->end();
648 
649  while (threads != end) {
650  ThreadID tid = *threads++;
651 
652  if (willWB(tid))
653  return true;
654  }
655 
656  return false;
657 }
658 
659 template<class Impl>
660 void
662 {
663  std::list<ThreadID>::const_iterator threads = activeThreads->begin();
664  std::list<ThreadID>::const_iterator end = activeThreads->end();
665 
666  while (threads != end) {
667  ThreadID tid = *threads++;
668 
669  thread[tid].dumpInsts();
670  }
671 }
672 
673 template<class Impl>
674 Fault
675 LSQ<Impl>::pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data,
676  unsigned int size, Addr addr, Request::Flags flags,
677  uint64_t *res, AtomicOpFunctorPtr amo_op,
678  const std::vector<bool>& byte_enable)
679 {
680  // This comming request can be either load, store or atomic.
681  // Atomic request has a corresponding pointer to its atomic memory
682  // operation
683  M5_VAR_USED bool isAtomic = !isLoad && amo_op;
684 
685  ThreadID tid = cpu->contextToThread(inst->contextId());
686  auto cacheLineSize = cpu->cacheLineSize();
687  bool needs_burst = transferNeedsBurst(addr, size, cacheLineSize);
688  LSQRequest* req = nullptr;
689 
690  // Atomic requests that access data across cache line boundary are
691  // currently not allowed since the cache does not guarantee corresponding
692  // atomic memory operations to be executed atomically across a cache line.
693  // For ISAs such as x86 that supports cross-cache-line atomic instructions,
694  // the cache needs to be modified to perform atomic update to both cache
695  // lines. For now, such cross-line update is not supported.
696  assert(!isAtomic || (isAtomic && !needs_burst));
697 
698  const bool htm_cmd = isLoad && (flags & Request::HTM_CMD);
699 
700  if (inst->translationStarted()) {
701  req = inst->savedReq;
702  assert(req);
703  } else {
704  if (htm_cmd) {
705  assert(addr == 0x0lu);
706  assert(size == 8);
707  req = new HtmCmdRequest(&thread[tid], inst, flags);
708  } else if (needs_burst) {
709  req = new SplitDataRequest(&thread[tid], inst, isLoad, addr,
710  size, flags, data, res);
711  } else {
712  req = new SingleDataRequest(&thread[tid], inst, isLoad, addr,
713  size, flags, data, res, std::move(amo_op));
714  }
715  assert(req);
716  req->_byteEnable = byte_enable;
717  inst->setRequest();
718  req->taskId(cpu->taskId());
719 
720  // There might be fault from a previous execution attempt if this is
721  // a strictly ordered load
722  inst->getFault() = NoFault;
723 
724  req->initiateTranslation();
725  }
726 
727  /* This is the place were instructions get the effAddr. */
728  if (req->isTranslationComplete()) {
729  if (req->isMemAccessRequired()) {
730  inst->effAddr = req->getVaddr();
731  inst->effSize = size;
732  inst->effAddrValid(true);
733 
734  if (cpu->checker) {
735  inst->reqToVerify = std::make_shared<Request>(*req->request());
736  }
737  Fault fault;
738  if (isLoad)
739  fault = cpu->read(req, inst->lqIdx);
740  else
741  fault = cpu->write(req, data, inst->sqIdx);
742  // inst->getFault() may have the first-fault of a
743  // multi-access split request at this point.
744  // Overwrite that only if we got another type of fault
745  // (e.g. re-exec).
746  if (fault != NoFault)
747  inst->getFault() = fault;
748  } else if (isLoad) {
749  inst->setMemAccPredicate(false);
750  // Commit will have to clean up whatever happened. Set this
751  // instruction as executed.
752  inst->setExecuted();
753  }
754  }
755 
756  if (inst->traceData)
757  inst->traceData->setMem(addr, size, flags);
758 
759  return inst->getFault();
760 }
761 
762 template<class Impl>
763 void
766 {
767  _fault.push_back(fault);
770  /* If the instruction has been squahsed, let the request know
771  * as it may have to self-destruct. */
772  if (_inst->isSquashed()) {
773  this->squashTranslation();
774  } else {
775  _inst->strictlyOrdered(req->isStrictlyOrdered());
776 
777  flags.set(Flag::TranslationFinished);
778  if (fault == NoFault) {
779  _inst->physEffAddr = req->getPaddr();
780  _inst->memReqFlags = req->getFlags();
781  if (req->isCondSwap()) {
782  assert(_res);
783  req->setExtraData(*_res);
784  }
785  setState(State::Request);
786  } else {
788  }
789 
790  LSQRequest::_inst->fault = fault;
791  LSQRequest::_inst->translationCompleted(true);
792  }
793 }
794 
795 template<class Impl>
796 void
799 {
800  int i;
801  for (i = 0; i < _requests.size() && _requests[i] != req; i++);
802  assert(i < _requests.size());
803  _fault[i] = fault;
804 
805  numInTranslationFragments--;
806  numTranslatedFragments++;
807 
808  if (fault == NoFault)
809  mainReq->setFlags(req->getFlags());
810 
811  if (numTranslatedFragments == _requests.size()) {
812  if (_inst->isSquashed()) {
813  this->squashTranslation();
814  } else {
815  _inst->strictlyOrdered(mainReq->isStrictlyOrdered());
816  flags.set(Flag::TranslationFinished);
817  _inst->translationCompleted(true);
818 
819  for (i = 0; i < _fault.size() && _fault[i] == NoFault; i++);
820  if (i > 0) {
821  _inst->physEffAddr = request(0)->getPaddr();
822  _inst->memReqFlags = mainReq->getFlags();
823  if (mainReq->isCondSwap()) {
824  assert (i == _fault.size());
825  assert(_res);
826  mainReq->setExtraData(*_res);
827  }
828  if (i == _fault.size()) {
829  _inst->fault = NoFault;
830  setState(State::Request);
831  } else {
832  _inst->fault = _fault[i];
833  setState(State::PartialFault);
834  }
835  } else {
836  _inst->fault = _fault[0];
837  setState(State::Fault);
838  }
839  }
840 
841  }
842 }
843 
844 template<class Impl>
845 void
847 {
848  assert(_requests.size() == 0);
849 
850  this->addRequest(_addr, _size, _byteEnable);
851 
852  if (_requests.size() > 0) {
853  _requests.back()->setReqInstSeqNum(_inst->seqNum);
854  _requests.back()->taskId(_taskId);
855  _inst->translationStarted(true);
856  setState(State::Translation);
857  flags.set(Flag::TranslationStarted);
858 
859  _inst->savedReq = this;
860  sendFragmentToTranslation(0);
861  } else {
862  _inst->setMemAccPredicate(false);
863  }
864 }
865 
866 template<class Impl>
867 PacketPtr
869 {
870  return _mainPacket;
871 }
872 
873 template<class Impl>
876 {
877  return mainReq;
878 }
879 
880 template<class Impl>
881 void
883 {
884  auto cacheLineSize = _port.cacheLineSize();
885  Addr base_addr = _addr;
886  Addr next_addr = addrBlockAlign(_addr + cacheLineSize, cacheLineSize);
887  Addr final_addr = addrBlockAlign(_addr + _size, cacheLineSize);
888  uint32_t size_so_far = 0;
889 
890  mainReq = std::make_shared<Request>(base_addr,
891  _size, _flags, _inst->requestorId(),
892  _inst->instAddr(), _inst->contextId());
893  mainReq->setByteEnable(_byteEnable);
894 
895  // Paddr is not used in mainReq. However, we will accumulate the flags
896  // from the sub requests into mainReq by calling setFlags() in finish().
897  // setFlags() assumes that paddr is set so flip the paddr valid bit here to
898  // avoid a potential assert in setFlags() when we call it from finish().
899  mainReq->setPaddr(0);
900 
901  /* Get the pre-fix, possibly unaligned. */
902  auto it_start = _byteEnable.begin();
903  auto it_end = _byteEnable.begin() + (next_addr - base_addr);
904  this->addRequest(base_addr, next_addr - base_addr,
905  std::vector<bool>(it_start, it_end));
906  size_so_far = next_addr - base_addr;
907 
908  /* We are block aligned now, reading whole blocks. */
909  base_addr = next_addr;
910  while (base_addr != final_addr) {
911  auto it_start = _byteEnable.begin() + size_so_far;
912  auto it_end = _byteEnable.begin() + size_so_far + cacheLineSize;
913  this->addRequest(base_addr, cacheLineSize,
914  std::vector<bool>(it_start, it_end));
915  size_so_far += cacheLineSize;
916  base_addr += cacheLineSize;
917  }
918 
919  /* Deal with the tail. */
920  if (size_so_far < _size) {
921  auto it_start = _byteEnable.begin() + size_so_far;
922  auto it_end = _byteEnable.end();
923  this->addRequest(base_addr, _size - size_so_far,
924  std::vector<bool>(it_start, it_end));
925  }
926 
927  if (_requests.size() > 0) {
928  /* Setup the requests and send them to translation. */
929  for (auto& r: _requests) {
930  r->setReqInstSeqNum(_inst->seqNum);
931  r->taskId(_taskId);
932  }
933 
934  _inst->translationStarted(true);
935  setState(State::Translation);
936  flags.set(Flag::TranslationStarted);
937  this->_inst->savedReq = this;
938  numInTranslationFragments = 0;
939  numTranslatedFragments = 0;
940  _fault.resize(_requests.size());
941 
942  for (uint32_t i = 0; i < _requests.size(); i++) {
943  sendFragmentToTranslation(i);
944  }
945  } else {
946  _inst->setMemAccPredicate(false);
947  }
948 }
949 
950 template<class Impl>
951 void
953 {
954  numInTranslationFragments++;
955  _port.getMMUPtr()->translateTiming(
956  this->request(i),
957  this->_inst->thread->getTC(), this,
958  this->isLoad() ? BaseTLB::Read : BaseTLB::Write);
959 }
960 
961 template<class Impl>
962 bool
964 {
965  assert(_numOutstandingPackets == 1);
966  auto state = dynamic_cast<LSQSenderState*>(pkt->senderState);
967  flags.set(Flag::Complete);
968  state->outstanding--;
969  assert(pkt == _packets.front());
970  _port.completeDataAccess(pkt);
971  return true;
972 }
973 
974 template<class Impl>
975 bool
977 {
978  auto state = dynamic_cast<LSQSenderState*>(pkt->senderState);
979  uint32_t pktIdx = 0;
980  while (pktIdx < _packets.size() && pkt != _packets[pktIdx])
981  pktIdx++;
982  assert(pktIdx < _packets.size());
983  numReceivedPackets++;
984  state->outstanding--;
985  if (numReceivedPackets == _packets.size()) {
986  flags.set(Flag::Complete);
987  /* Assemble packets. */
988  PacketPtr resp = isLoad()
989  ? Packet::createRead(mainReq)
990  : Packet::createWrite(mainReq);
991  if (isLoad())
992  resp->dataStatic(_inst->memData);
993  else
994  resp->dataStatic(_data);
995  resp->senderState = _senderState;
996  _port.completeDataAccess(resp);
997  delete resp;
998  }
999  return true;
1000 }
1001 
1002 template<class Impl>
1003 void
1005 {
1006  assert(_senderState);
1007  /* Retries do not create new packets. */
1008  if (_packets.size() == 0) {
1009  _packets.push_back(
1010  isLoad()
1011  ? Packet::createRead(request())
1012  : Packet::createWrite(request()));
1013  _packets.back()->dataStatic(_inst->memData);
1014  _packets.back()->senderState = _senderState;
1015 
1016  // hardware transactional memory
1017  // If request originates in a transaction (not necessarily a HtmCmd),
1018  // then the packet should be marked as such.
1019  if (_inst->inHtmTransactionalState()) {
1020  _packets.back()->setHtmTransactional(
1021  _inst->getHtmTransactionUid());
1022 
1023  DPRINTF(HtmCpu,
1024  "HTM %s pc=0x%lx - vaddr=0x%lx - paddr=0x%lx - htmUid=%u\n",
1025  isLoad() ? "LD" : "ST",
1026  _inst->instAddr(),
1027  _packets.back()->req->hasVaddr() ?
1028  _packets.back()->req->getVaddr() : 0lu,
1029  _packets.back()->getAddr(),
1030  _inst->getHtmTransactionUid());
1031  }
1032  }
1033  assert(_packets.size() == 1);
1034 }
1035 
1036 template<class Impl>
1037 void
1039 {
1040  /* Extra data?? */
1041  Addr base_address = _addr;
1042 
1043  if (_packets.size() == 0) {
1044  /* New stuff */
1045  if (isLoad()) {
1046  _mainPacket = Packet::createRead(mainReq);
1047  _mainPacket->dataStatic(_inst->memData);
1048 
1049  // hardware transactional memory
1050  // If request originates in a transaction,
1051  // packet should be marked as such
1052  if (_inst->inHtmTransactionalState()) {
1053  _mainPacket->setHtmTransactional(
1054  _inst->getHtmTransactionUid());
1055  DPRINTF(HtmCpu,
1056  "HTM LD.0 pc=0x%lx-vaddr=0x%lx-paddr=0x%lx-htmUid=%u\n",
1057  _inst->instAddr(),
1058  _mainPacket->req->hasVaddr() ?
1059  _mainPacket->req->getVaddr() : 0lu,
1060  _mainPacket->getAddr(),
1061  _inst->getHtmTransactionUid());
1062  }
1063  }
1064  for (int i = 0; i < _requests.size() && _fault[i] == NoFault; i++) {
1065  RequestPtr r = _requests[i];
1066  PacketPtr pkt = isLoad() ? Packet::createRead(r)
1068  ptrdiff_t offset = r->getVaddr() - base_address;
1069  if (isLoad()) {
1070  pkt->dataStatic(_inst->memData + offset);
1071  } else {
1072  uint8_t* req_data = new uint8_t[r->getSize()];
1073  std::memcpy(req_data,
1074  _inst->memData + offset,
1075  r->getSize());
1076  pkt->dataDynamic(req_data);
1077  }
1078  pkt->senderState = _senderState;
1079  _packets.push_back(pkt);
1080 
1081  // hardware transactional memory
1082  // If request originates in a transaction,
1083  // packet should be marked as such
1084  if (_inst->inHtmTransactionalState()) {
1085  _packets.back()->setHtmTransactional(
1086  _inst->getHtmTransactionUid());
1087  DPRINTF(HtmCpu,
1088  "HTM %s.%d pc=0x%lx-vaddr=0x%lx-paddr=0x%lx-htmUid=%u\n",
1089  isLoad() ? "LD" : "ST",
1090  i+1,
1091  _inst->instAddr(),
1092  _packets.back()->req->hasVaddr() ?
1093  _packets.back()->req->getVaddr() : 0lu,
1094  _packets.back()->getAddr(),
1095  _inst->getHtmTransactionUid());
1096  }
1097  }
1098  }
1099  assert(_packets.size() > 0);
1100 }
1101 
1102 template<class Impl>
1103 void
1105 {
1106  assert(_numOutstandingPackets == 0);
1107  if (lsqUnit()->trySendPacket(isLoad(), _packets.at(0)))
1108  _numOutstandingPackets = 1;
1109 }
1110 
1111 template<class Impl>
1112 void
1114 {
1115  /* Try to send the packets. */
1116  while (numReceivedPackets + _numOutstandingPackets < _packets.size() &&
1117  lsqUnit()->trySendPacket(isLoad(),
1118  _packets.at(numReceivedPackets + _numOutstandingPackets))) {
1119  _numOutstandingPackets++;
1120  }
1121 }
1122 
1123 template<class Impl>
1124 Cycles
1127 {
1128  return pkt->req->localAccessor(thread, pkt);
1129 }
1130 
1131 template<class Impl>
1132 Cycles
1134  ThreadContext *thread, PacketPtr mainPkt)
1135 {
1136  Cycles delay(0);
1137  unsigned offset = 0;
1138 
1139  for (auto r: _requests) {
1140  PacketPtr pkt =
1141  new Packet(r, isLoad() ? MemCmd::ReadReq : MemCmd::WriteReq);
1142  pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset);
1143  Cycles d = r->localAccessor(thread, pkt);
1144  if (d > delay)
1145  delay = d;
1146  offset += r->getSize();
1147  delete pkt;
1148  }
1149  return delay;
1150 }
1151 
1152 template<class Impl>
1153 bool
1155 {
1156  return ( (LSQRequest::_requests[0]->getPaddr() & blockMask) == blockAddr);
1157 }
1158 
1174 template<class Impl>
1175 bool
1177 {
1178  bool is_hit = false;
1179  for (auto &r: _requests) {
1189  if (r->hasPaddr() && (r->getPaddr() & blockMask) == blockAddr) {
1190  is_hit = true;
1191  break;
1192  }
1193  }
1194  return is_hit;
1195 }
1196 
1197 template <class Impl>
1198 bool
1200 {
1201  return lsq->recvTimingResp(pkt);
1202 }
1203 
1204 template <class Impl>
1205 void
1207 {
1208  for (ThreadID tid = 0; tid < cpu->numThreads; tid++) {
1209  if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1210  cpu->wakeup(tid);
1211  }
1212  }
1213  lsq->recvTimingSnoopReq(pkt);
1214 }
1215 
1216 template <class Impl>
1217 void
1219 {
1220  lsq->recvReqRetry();
1221 }
1222 
1223 template<class Impl>
1225  const DynInstPtr& inst,
1226  const Request::Flags& flags_) :
1227  SingleDataRequest(port, inst, true, 0x0lu, 8, flags_,
1228  nullptr, nullptr, nullptr)
1229 {
1230  assert(_requests.size() == 0);
1231 
1232  this->addRequest(_addr, _size, _byteEnable);
1233 
1234  if (_requests.size() > 0) {
1235  _requests.back()->setReqInstSeqNum(_inst->seqNum);
1236  _requests.back()->taskId(_taskId);
1237  _requests.back()->setPaddr(_addr);
1238  _requests.back()->setInstCount(_inst->getCpuPtr()->totalInsts());
1239 
1240  _inst->strictlyOrdered(_requests.back()->isStrictlyOrdered());
1241  _inst->fault = NoFault;
1242  _inst->physEffAddr = _requests.back()->getPaddr();
1243  _inst->memReqFlags = _requests.back()->getFlags();
1244  _inst->savedReq = this;
1245 
1246  setState(State::Translation);
1247  } else {
1248  panic("unexpected behaviour");
1249  }
1250 }
1251 
1252 template<class Impl>
1253 void
1255 {
1256  // Transaction commands are implemented as loads to avoid significant
1257  // changes to the cpu and memory interfaces
1258  // The virtual and physical address uses a dummy value of 0x00
1259  // Address translation does not really occur thus the code below
1260 
1261  flags.set(Flag::TranslationStarted);
1262  flags.set(Flag::TranslationFinished);
1263 
1264  _inst->translationStarted(true);
1265  _inst->translationCompleted(true);
1266 
1267  setState(State::Request);
1268 }
1269 
1270 template<class Impl>
1271 void
1274 {
1275  panic("unexpected behaviour");
1276 }
1277 
1278 #endif//__CPU_O3_LSQ_IMPL_HH__
LSQ::insertStore
void insertStore(const DynInstPtr &store_inst)
Inserts a store into the LSQ.
Definition: lsq_impl.hh:228
LSQ::thread
std::vector< LSQUnit > thread
The LSQ units for individual threads.
Definition: lsq.hh:1185
Packet::isError
bool isError() const
Definition: packet.hh:584
AtomicOpFunctorPtr
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Definition: amo.hh:239
LSQ::SingleDataRequest::handleLocalAccess
virtual Cycles handleLocalAccess(ThreadContext *thread, PacketPtr pkt)
Memory mapped IPR accesses.
Definition: lsq_impl.hh:1125
LSQ::willWB
bool willWB()
Returns if the LSQ will write back to memory this cycle.
Definition: lsq_impl.hh:644
LSQ::executeStore
Fault executeStore(const DynInstPtr &inst)
Executes a store.
Definition: lsq_impl.hh:246
LSQ::maxSQEntries
unsigned maxSQEntries
Max SQ Size - Used to Enforce Sharing Policies.
Definition: lsq.hh:1179
BaseTLB::Read
@ Read
Definition: tlb.hh:57
data
const char data[]
Definition: circlebuf.test.cc:47
LSQ::HtmCmdRequest::finish
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseTLB::Mode mode)
Definition: lsq_impl.hh:1272
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:755
LSQ::SplitDataRequest::mainPacket
virtual PacketPtr mainPacket()
Definition: lsq_impl.hh:868
LSQ::SplitDataRequest::mainRequest
virtual RequestPtr mainRequest()
Definition: lsq_impl.hh:875
LSQ::insertLoad
void insertLoad(const DynInstPtr &load_inst)
Inserts a load into the LSQ.
Definition: lsq_impl.hh:219
LSQ::sqEmpty
bool sqEmpty() const
Returns if all of the SQs are empty.
Definition: lsq_impl.hh:525
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
ThreadID
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:233
LSQ::LSQRequest::numInTranslationFragments
uint32_t numInTranslationFragments
Definition: lsq.hh:284
LSQ::LSQRequest::isMemAccessRequired
bool isMemAccessRequired()
Definition: lsq.hh:621
Flags< FlagsType >
LSQ::LSQSenderState::outstanding
uint8_t outstanding
Number of outstanding packets to complete.
Definition: lsq.hh:100
LSQ::SplitDataRequest::initiateTranslation
virtual void initiateTranslation()
Definition: lsq_impl.hh:882
LSQ::LSQRequest::flags
FlagsType flags
Definition: lsq.hh:269
BaseTLB::Mode
Mode
Definition: tlb.hh:57
MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:83
LSQ::DcachePort::recvTimingResp
virtual bool recvTimingResp(PacketPtr pkt)
Timing version of receive.
Definition: lsq_impl.hh:1199
LSQ::recvTimingResp
bool recvTimingResp(PacketPtr pkt)
Handles writing back and completing the load or store that has returned from memory.
Definition: lsq_impl.hh:313
Packet::isInvalidate
bool isInvalidate() const
Definition: packet.hh:572
RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:86
Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:341
LSQ::SingleDataRequest::buildPackets
virtual void buildPackets()
Definition: lsq_impl.hh:1004
LSQ::recvReqRetry
void recvReqRetry()
Retry the previous send that failed.
Definition: lsq_impl.hh:292
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 >
LSQ::SingleDataRequest::recvTimingResp
virtual bool recvTimingResp(PacketPtr pkt)
Definition: lsq_impl.hh:963
Request::HTM_CMD
static const FlagsType HTM_CMD
Definition: request.hh:240
LSQ::LSQRequest::sendFragmentToTranslation
void sendFragmentToTranslation(int i)
Definition: lsq_impl.hh:952
LSQ::numStores
int numStores()
Returns the total number of stores in the store queue.
Definition: lsq_impl.hh:404
LSQ::violation
bool violation()
Returns whether or not there was a memory ordering violation.
Definition: lsq_impl.hh:274
LSQ::SplitDataRequest::finish
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseTLB::Mode mode)
Definition: lsq_impl.hh:797
LSQ::isEmpty
bool isEmpty() const
Returns if the LSQ is empty (both LQ and SQ are empty).
Definition: lsq_impl.hh:501
LSQ::numLoads
int numLoads()
Returns the total number of loads in the load queue.
Definition: lsq_impl.hh:386
LSQ::tick
void tick()
Ticks the LSQ.
Definition: lsq_impl.hh:168
LSQ::lqFull
bool lqFull()
Returns if any of the LQs are full.
Definition: lsq_impl.hh:542
LSQ::isFull
bool isFull()
Returns if the LSQ is full (either LQ or SQ is full).
Definition: lsq_impl.hh:472
LSQ::completeDataAccess
void completeDataAccess(PacketPtr pkt)
Definition: lsq_impl.hh:304
LSQ::isDrained
bool isDrained() const
Has the LSQ drained?
Definition: lsq_impl.hh:137
LSQ::LSQRequest::_requests
std::vector< RequestPtr > _requests
Definition: lsq.hh:298
MemCmd::WriteReq
@ WriteReq
Definition: packet.hh:86
LSQ::SplitDataRequest::sendPacketToCache
virtual void sendPacketToCache()
Definition: lsq_impl.hh:1113
LSQ::takeOverFrom
void takeOverFrom()
Takes over execution from another CPU's thread.
Definition: lsq_impl.hh:156
LSQ::dcachePort
DcachePort dcachePort
Data port.
Definition: lsq.hh:1182
LSQ::O3CPU
Impl::O3CPU O3CPU
Definition: lsq.hh:72
LSQUnit
Class that implements the actual LQ and SQ for each specific thread.
Definition: lsq_unit.hh:78
LSQ::LSQRequest::_byteEnable
std::vector< bool > _byteEnable
Definition: lsq.hh:304
LSQ::LSQRequest::_taskId
uint32_t _taskId
Definition: lsq.hh:295
LSQ::drainSanityCheck
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: lsq_impl.hh:127
LSQ::LSQRequest::addRequest
void addRequest(Addr addr, unsigned size, const std::vector< bool > &byte_enable)
Helper function used to add a (sub)request, given its address addr, size size and byte-enable mask by...
Definition: lsq.hh:412
addrBlockAlign
Addr addrBlockAlign(Addr addr, Addr block_size)
Returns the address of the closest aligned fixed-size block to the given address.
Definition: utils.hh:63
LSQ::isStalled
bool isStalled()
Returns if the LSQ is stalled due to a memory operation that must be replayed.
Definition: lsq_impl.hh:600
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
LSQ
Definition: lsq.hh:68
LSQ::cachePortAvailable
bool cachePortAvailable(bool is_load) const
Is any store port available to use?
Definition: lsq_impl.hh:194
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
LSQ::SingleDataRequest::sendPacketToCache
virtual void sendPacketToCache()
Definition: lsq_impl.hh:1104
Packet::cmdString
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition: packet.hh:552
ArmISA::d
Bitfield< 9 > d
Definition: miscregs_types.hh:60
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:246
LSQ::LSQRequest::_res
uint64_t * _res
Definition: lsq.hh:300
Packet::createRead
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
Definition: packet.hh:981
MipsISA::r
r
Definition: pra_constants.hh:95
LSQ::LSQSenderState
Derived class to hold any sender state the LSQ needs.
Definition: lsq.hh:79
LSQ::cachePortBusy
void cachePortBusy(bool is_load)
Another store port is in use.
Definition: lsq_impl.hh:207
LSQ::numFreeStoreEntries
unsigned numFreeStoreEntries()
Returns the number of free store entries.
Definition: lsq_impl.hh:440
LSQ::SplitDataRequest::buildPackets
virtual void buildPackets()
Definition: lsq_impl.hh:1038
LSQ::executeLoad
Fault executeLoad(const DynInstPtr &inst)
Executes a load.
Definition: lsq_impl.hh:237
ArmISA::mode
Bitfield< 4, 0 > mode
Definition: miscregs_types.hh:70
LSQ::LSQRequest::isTranslationComplete
bool isTranslationComplete()
Definition: lsq.hh:594
LSQ::IEW
Impl::CPUPol::IEW IEW
Definition: lsq.hh:74
Flags::set
void set(Type mask)
Set all flag's bits matching the given mask.
Definition: flags.hh:113
LSQ::HtmCmdRequest
Definition: lsq.hh:753
LSQ::lqEmpty
bool lqEmpty() const
Returns if all of the LQs are empty.
Definition: lsq_impl.hh:508
LSQ::DynInstPtr
Impl::DynInstPtr DynInstPtr
Definition: lsq.hh:73
LSQ::pushRequest
Fault pushRequest(const DynInstPtr &inst, bool isLoad, uint8_t *data, unsigned int size, Addr addr, Request::Flags flags, uint64_t *res, AtomicOpFunctorPtr amo_op, const std::vector< bool > &byte_enable)
Definition: lsq_impl.hh:675
LSQ::getCount
int getCount()
Returns the number of instructions in all of the queues.
Definition: lsq_impl.hh:368
LSQ::LSQRequest::initiateTranslation
virtual void initiateTranslation()=0
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:251
LSQ::writebackStores
void writebackStores()
Attempts to write back stores until all cache ports are used or the interface becomes blocked.
Definition: lsq_impl.hh:255
LSQ::SingleDataRequest::finish
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseTLB::Mode mode)
Definition: lsq_impl.hh:764
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
transferNeedsBurst
bool transferNeedsBurst(Addr addr, unsigned int size, unsigned int block_size)
Returns true if the given memory access (address, size) needs to be fragmented across aligned fixed-s...
Definition: utils.hh:77
LSQ::numFreeLoadEntries
unsigned numFreeLoadEntries()
Returns the number of free load entries.
Definition: lsq_impl.hh:422
LSQ::maxLQEntries
unsigned maxLQEntries
Max LQ Size - Used to Enforce Sharing Policies.
Definition: lsq.hh:1176
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:80
LSQ::LSQRequest::getVaddr
Addr getVaddr(int idx=0) const
Definition: lsq.hh:484
BaseTLB::Write
@ Write
Definition: tlb.hh:57
LSQ::setActiveThreads
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets the pointer to the list of active threads.
Definition: lsq_impl.hh:119
LSQ::LSQRequest::setState
void setState(const State &newState)
Definition: lsq.hh:281
LSQ::DcachePort::recvTimingSnoopReq
virtual void recvTimingSnoopReq(PacketPtr pkt)
Receive a timing snoop request from the peer.
Definition: lsq_impl.hh:1206
Packet::createWrite
static PacketPtr createWrite(const RequestPtr &req)
Definition: packet.hh:987
LSQ::LSQRequest::_fault
std::vector< Fault > _fault
Definition: lsq.hh:299
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
LSQ::hasStoresToWB
bool hasStoresToWB()
Returns whether or not there are any stores to write back to memory.
Definition: lsq_impl.hh:627
LSQ::LSQRequest::_addr
const Addr _addr
Definition: lsq.hh:301
LSQ::LSQRequest
Memory operation metadata.
Definition: lsq.hh:236
LSQ::LSQRequest::squashTranslation
void squashTranslation()
Definition: lsq.hh:678
LSQ::SplitDataRequest::handleLocalAccess
virtual Cycles handleLocalAccess(ThreadContext *thread, PacketPtr pkt)
Memory mapped IPR accesses.
Definition: lsq_impl.hh:1133
LSQ::HtmCmdRequest::initiateTranslation
virtual void initiateTranslation()
Definition: lsq_impl.hh:1254
Packet::dataStatic
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:1108
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:258
LSQ::LSQRequest::numTranslatedFragments
uint32_t numTranslatedFragments
Definition: lsq.hh:283
LSQ::recvTimingSnoopReq
void recvTimingSnoopReq(PacketPtr pkt)
Definition: lsq_impl.hh:351
logging.hh
Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:79
LSQ::SingleDataRequest
Definition: lsq.hh:697
LSQ::sqFull
bool sqFull()
Returns if any of the SQs are full.
Definition: lsq_impl.hh:571
LSQ::LSQRequest::taskId
void taskId(const uint32_t &v)
Definition: lsq.hh:468
Packet::getPtr
T * getPtr()
get a pointer to the data ptr.
Definition: packet.hh:1158
LSQ::cacheBlocked
bool cacheBlocked() const
Is D-cache blocked?
Definition: lsq_impl.hh:180
LSQ::LSQRequest::_inst
const DynInstPtr _inst
Definition: lsq.hh:294
LSQ::SplitDataRequest::recvTimingResp
virtual bool recvTimingResp(PacketPtr pkt)
Definition: lsq_impl.hh:976
LSQ::LSQ
LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, const DerivO3CPUParams &params)
Constructs an LSQ with the given parameters.
Definition: lsq_impl.hh:60
Complete
@ Complete
Definition: misc.hh:55
LSQ::SplitDataRequest
Definition: lsq.hh:778
LSQ::lsqPolicy
SMTQueuePolicy lsqPolicy
The LSQ policy for SMT mode.
Definition: lsq.hh:1142
Packet::senderState
SenderState * senderState
This packet's sender state.
Definition: packet.hh:509
LSQ::name
std::string name() const
Returns the name of the LSQ.
Definition: lsq_impl.hh:112
cpu.hh
std::list< ThreadID >
Stats::total
const FlagsType total
Print the total.
Definition: info.hh:50
lsq.hh
LSQ::SingleDataRequest::initiateTranslation
virtual void initiateTranslation()
Definition: lsq_impl.hh:846
LSQ::SplitDataRequest::isCacheBlockHit
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask)
Caches may probe into the load-store queue to enforce memory ordering guarantees.
Definition: lsq_impl.hh:1176
LSQ::LSQRequest::_size
const uint32_t _size
Definition: lsq.hh:302
LSQ::HtmCmdRequest::HtmCmdRequest
HtmCmdRequest(LSQUnit *port, const DynInstPtr &inst, const Request::Flags &flags_)
Definition: lsq_impl.hh:1224
LSQ::SingleDataRequest::isCacheBlockHit
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask)
Test if the request accesses a particular cache line.
Definition: lsq_impl.hh:1154
LSQ::DcachePort::recvReqRetry
virtual void recvReqRetry()
Handles doing a retry of the previous send.
Definition: lsq_impl.hh:1218
ArmISA::v
Bitfield< 28 > v
Definition: miscregs_types.hh:51
LSQ::dumpInsts
void dumpInsts() const
Debugging function to print out all instructions.
Definition: lsq_impl.hh:661
LSQ::cpu
O3CPU * cpu
The CPU pointer.
Definition: lsq.hh:1112
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
LSQ::numThreads
ThreadID numThreads
Number of Threads.
Definition: lsq.hh:1188
LSQ::LSQRequest::request
RequestPtr request(int idx=0)
Definition: lsq.hh:476
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153

Generated on Tue Jun 22 2021 15:28:26 for gem5 by doxygen 1.8.17