gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
lsq.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2012, 2014, 2018-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) 2004-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  * Authors: Korey Sewell
42  */
43 
44 #ifndef __CPU_O3_LSQ_HH__
45 #define __CPU_O3_LSQ_HH__
46 
47 #include <map>
48 #include <queue>
49 
50 #include "arch/generic/tlb.hh"
51 #include "cpu/inst_seq.hh"
52 #include "cpu/o3/lsq_unit.hh"
53 #include "cpu/utils.hh"
54 #include "enums/SMTQueuePolicy.hh"
55 #include "mem/port.hh"
56 #include "sim/sim_object.hh"
57 
58 struct DerivO3CPUParams;
59 
60 template <class Impl>
61 class FullO3CPU;
62 
63 template <class Impl>
64 class LSQ
65 
66 {
67  public:
68  typedef typename Impl::O3CPU O3CPU;
69  typedef typename Impl::DynInstPtr DynInstPtr;
70  typedef typename Impl::CPUPol::IEW IEW;
71  typedef typename Impl::CPUPol::LSQUnit LSQUnit;
72 
73  class LSQRequest;
76  {
77  protected:
80 
83  : _request(request), mainPkt(nullptr), pendingPacket(nullptr),
84  outstanding(0), isLoad(isLoad_), needWB(isLoad_), isSplit(false),
85  pktToSend(false), deleted(false)
86  { }
87  public:
88 
90  DynInstPtr inst;
96  uint8_t outstanding;
98  bool isLoad;
100  bool needWB;
102  bool isSplit;
104  bool pktToSend;
109  bool deleted;
110  ContextID contextId() { return inst->contextId(); }
111 
113  inline bool isComplete() { return outstanding == 0; }
114  inline void deleteRequest() { deleted = true; }
115  inline bool alive() { return !deleted; }
116  LSQRequest* request() { return _request; }
117  virtual void complete() = 0;
118  void writebackDone() { _request->writebackDone(); }
119  };
120 
124  class DcachePort : public MasterPort
125  {
126  protected:
127 
131 
132  public:
135  : MasterPort(_cpu->name() + ".dcache_port", _cpu), lsq(_lsq),
136  cpu(_cpu)
137  { }
138 
139  protected:
140 
144  virtual bool recvTimingResp(PacketPtr pkt);
145  virtual void recvTimingSnoopReq(PacketPtr pkt);
146 
147  virtual void recvFunctionalSnoop(PacketPtr pkt)
148  {
149  // @todo: Is there a need for potential invalidation here?
150  }
151 
153  virtual void recvReqRetry();
154 
161  virtual bool isSnooping() const { return true; }
162  };
163 
233  {
234  protected:
235  typedef uint32_t FlagsStorage;
236  typedef ::Flags<FlagsStorage> FlagsType;
237 
238  enum Flag : FlagsStorage
239  {
240  IsLoad = 0x00000001,
242  WbStore = 0x00000002,
243  Delayed = 0x00000004,
244  IsSplit = 0x00000008,
246  TranslationStarted = 0x00000010,
248  TranslationFinished = 0x00000020,
249  Sent = 0x00000040,
250  Retry = 0x00000080,
251  Complete = 0x00000100,
254  TranslationSquashed = 0x00000200,
256  Discarded = 0x00000400,
258  LSQEntryFreed = 0x00000800,
260  WritebackScheduled = 0x00001000,
261  WritebackDone = 0x00002000,
263  IsAtomic = 0x00004000
264  };
265  FlagsType flags;
266 
267  enum class State
268  {
269  NotIssued,
270  Translation,
271  Request,
272  Fault,
273  PartialFault,
274  };
277  void setState(const State& newState) { _state = newState; }
278 
281 
283  uint32_t _entryIdx;
284 
285  void markDelayed() override { flags.set(Flag::Delayed); }
286  bool isDelayed() { return flags.isSet(Flag::Delayed); }
287 
288  public:
289  LSQUnit& _port;
290  const DynInstPtr _inst;
291  uint32_t _taskId;
296  uint64_t* _res;
297  const Addr _addr;
298  const uint32_t _size;
303  protected:
304  LSQUnit* lsqUnit() { return &_port; }
305  LSQRequest(LSQUnit* port, const DynInstPtr& inst, bool isLoad) :
306  _state(State::NotIssued), _senderState(nullptr),
307  _port(*port), _inst(inst), _data(nullptr),
308  _res(nullptr), _addr(0), _size(0), _flags(0),
309  _numOutstandingPackets(0), _amo_op(nullptr)
310  {
311  flags.set(Flag::IsLoad, isLoad);
312  flags.set(Flag::WbStore,
313  _inst->isStoreConditional() || _inst->isAtomic());
314  flags.set(Flag::IsAtomic, _inst->isAtomic());
315  install();
316  }
317  LSQRequest(LSQUnit* port, const DynInstPtr& inst, bool isLoad,
318  const Addr& addr, const uint32_t& size,
319  const Request::Flags& flags_,
320  PacketDataPtr data = nullptr, uint64_t* res = nullptr,
321  AtomicOpFunctorPtr amo_op = nullptr)
322  : _state(State::NotIssued), _senderState(nullptr),
323  numTranslatedFragments(0),
324  numInTranslationFragments(0),
325  _port(*port), _inst(inst), _data(data),
326  _res(res), _addr(addr), _size(size),
327  _flags(flags_),
328  _numOutstandingPackets(0),
329  _amo_op(std::move(amo_op))
330  {
331  flags.set(Flag::IsLoad, isLoad);
332  flags.set(Flag::WbStore,
333  _inst->isStoreConditional() || _inst->isAtomic());
334  flags.set(Flag::IsAtomic, _inst->isAtomic());
335  install();
336  }
337 
338  bool
339  isLoad() const
340  {
341  return flags.isSet(Flag::IsLoad);
342  }
343 
344  bool
345  isAtomic() const
346  {
347  return flags.isSet(Flag::IsAtomic);
348  }
349 
351  void install()
352  {
353  if (isLoad()) {
354  _port.loadQueue[_inst->lqIdx].setRequest(this);
355  } else {
356  // Store, StoreConditional, and Atomic requests are pushed
357  // to this storeQueue
358  _port.storeQueue[_inst->sqIdx].setRequest(this);
359  }
360  }
361  virtual bool
362  squashed() const override
363  {
364  return _inst->isSquashed();
365  }
366 
372  bool
374  {
375  return flags.isSet(Flag::LSQEntryFreed) ||
376  flags.isSet(Flag::Discarded);
377  }
378 
388  void release(Flag reason)
389  {
390  assert(reason == Flag::LSQEntryFreed || reason == Flag::Discarded);
391  if (!isAnyOutstandingRequest()) {
392  delete this;
393  } else {
394  if (_senderState) {
395  _senderState->deleteRequest();
396  }
397  flags.set(reason);
398  }
399  }
400 
407  void
408  addRequest(Addr addr, unsigned size,
409  const std::vector<bool>& byte_enable)
410  {
411  if (byte_enable.empty() ||
412  isAnyActiveElement(byte_enable.begin(), byte_enable.end())) {
413  auto request = std::make_shared<Request>(_inst->getASID(),
414  addr, size, _flags, _inst->masterId(),
415  _inst->instAddr(), _inst->contextId(),
416  std::move(_amo_op));
417  if (!byte_enable.empty()) {
418  request->setByteEnable(byte_enable);
419  }
420  _requests.push_back(request);
421  }
422  }
423 
428  virtual ~LSQRequest()
429  {
430  assert(!isAnyOutstandingRequest());
431  _inst->savedReq = nullptr;
432  if (_senderState)
433  delete _senderState;
434 
435  for (auto r: _packets)
436  delete r;
437  };
438 
439 
440  public:
444  void
445  setContext(const ContextID& context_id)
446  {
447  request()->setContext(context_id);
448  }
449 
450  const DynInstPtr&
452  {
453  return _inst;
454  }
455 
459  void
460  setVirt(int asid, Addr vaddr, unsigned size, Request::Flags flags_,
461  MasterID mid, Addr pc)
462  {
463  request()->setVirt(asid, vaddr, size, flags_, mid, pc);
464  }
465 
466  void
467  taskId(const uint32_t& v)
468  {
469  _taskId = v;
470  for (auto& r: _requests)
471  r->taskId(v);
472  }
473 
474  uint32_t taskId() const { return _taskId; }
475  RequestPtr request(int idx = 0) { return _requests.at(idx); }
476 
477  const RequestPtr
478  request(int idx = 0) const
479  {
480  return _requests.at(idx);
481  }
482 
483  Addr getVaddr(int idx = 0) const { return request(idx)->getVaddr(); }
484  virtual void initiateTranslation() = 0;
485 
486  PacketPtr packet(int idx = 0) { return _packets.at(idx); }
487 
488  virtual PacketPtr
490  {
491  assert (_packets.size() == 1);
492  return packet();
493  }
494 
495  virtual RequestPtr
497  {
498  assert (_requests.size() == 1);
499  return request();
500  }
501 
502  void
504  {
505  _senderState = st;
506  for (auto& pkt: _packets) {
507  if (pkt)
508  pkt->senderState = st;
509  }
510  }
511 
512  const LSQSenderState*
513  senderState() const
514  {
515  return _senderState;
516  }
517 
522  void
524  {
525  assert(_senderState);
526  _senderState->deleteRequest();
527  }
528 
532  bool
534  {
535  return numInTranslationFragments > 0 ||
536  _numOutstandingPackets > 0 ||
537  (flags.isSet(Flag::WritebackScheduled) &&
538  !flags.isSet(Flag::WritebackDone));
539  }
540 
541  bool
542  isSplit() const
543  {
544  return flags.isSet(Flag::IsSplit);
545  }
547  virtual bool recvTimingResp(PacketPtr pkt) = 0;
548  virtual void sendPacketToCache() = 0;
549  virtual void buildPackets() = 0;
550 
554  virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt) = 0;
555  virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt) = 0;
556 
560  virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask) = 0;
561 
563  void
565  {
566  flags.set(Flag::Sent);
567  }
572  void
574  {
575  flags.set(Flag::Retry);
576  flags.clear(Flag::Sent);
577  }
578 
579  void sendFragmentToTranslation(int i);
580  bool
582  {
583  return flags.isSet(Flag::Complete);
584  }
585 
586  bool
588  {
589  return _state == State::Translation;
590  }
591 
592  bool
594  {
595  return flags.isSet(Flag::TranslationStarted) &&
596  !isInTranslation();
597  }
598 
599  bool
601  {
602  return _state == State::Translation &&
603  flags.isSet(Flag::TranslationStarted) &&
604  !flags.isSet(Flag::TranslationFinished);
605  }
606 
607  bool
609  {
610  return flags.isSet(Flag::Sent);
611  }
612 
613  bool
615  {
616  return _state == State::PartialFault;
617  }
618 
619  bool
621  {
622  return (_state == State::Request ||
623  (isPartialFault() && isLoad()));
624  }
625 
626  void
628  {
629  setState(State::Fault);
630  }
631 
635  void
637  {
638  release(Flag::LSQEntryFreed);
639  }
640 
644  void
646  {
647  release(Flag::Discarded);
648  }
649 
650  void
652  {
653  assert(_numOutstandingPackets > 0);
654  _numOutstandingPackets--;
655  if (_numOutstandingPackets == 0 && isReleased())
656  delete this;
657  }
658 
659  void
661  {
662  assert(!flags.isSet(Flag::WritebackScheduled));
663  flags.set(Flag::WritebackScheduled);
664  }
665 
666  void
668  {
669  flags.set(Flag::WritebackDone);
670  /* If the lsq resources are already free */
671  if (isReleased()) {
672  delete this;
673  }
674  }
675 
676  void
678  {
679  assert(numInTranslationFragments == 0);
680  flags.set(Flag::TranslationSquashed);
681  /* If we are on our own, self-destruct. */
682  if (isReleased()) {
683  delete this;
684  }
685  }
686 
687  void
689  {
690  flags.set(Flag::Complete);
691  }
692  };
693 
695  {
696  protected:
697  /* Given that we are inside templates, children need explicit
698  * declaration of the names in the parent class. */
699  using Flag = typename LSQRequest::Flag;
700  using State = typename LSQRequest::State;
701  using LSQRequest::_addr;
702  using LSQRequest::_fault;
703  using LSQRequest::_flags;
704  using LSQRequest::_size;
706  using LSQRequest::_requests;
707  using LSQRequest::_inst;
708  using LSQRequest::_packets;
709  using LSQRequest::_port;
710  using LSQRequest::_res;
711  using LSQRequest::_taskId;
713  using LSQRequest::_state;
714  using LSQRequest::flags;
715  using LSQRequest::isLoad;
717  using LSQRequest::lsqUnit;
718  using LSQRequest::request;
720  using LSQRequest::setState;
724  using LSQRequest::_amo_op;
725  public:
726  SingleDataRequest(LSQUnit* port, const DynInstPtr& inst, bool isLoad,
727  const Addr& addr, const uint32_t& size,
728  const Request::Flags& flags_,
729  PacketDataPtr data = nullptr,
730  uint64_t* res = nullptr,
731  AtomicOpFunctorPtr amo_op = nullptr) :
732  LSQRequest(port, inst, isLoad, addr, size, flags_, data, res,
733  std::move(amo_op)) {}
734 
735  inline virtual ~SingleDataRequest() {}
736  virtual void initiateTranslation();
737  virtual void finish(const Fault &fault, const RequestPtr &req,
739  virtual bool recvTimingResp(PacketPtr pkt);
740  virtual void sendPacketToCache();
741  virtual void buildPackets();
742  virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt);
743  virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt);
744  virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask);
745  };
746 
748  {
749  protected:
750  /* Given that we are inside templates, children need explicit
751  * declaration of the names in the parent class. */
752  using Flag = typename LSQRequest::Flag;
753  using State = typename LSQRequest::State;
754  using LSQRequest::_addr;
755  using LSQRequest::_data;
756  using LSQRequest::_fault;
757  using LSQRequest::_flags;
758  using LSQRequest::_inst;
759  using LSQRequest::_packets;
760  using LSQRequest::_port;
761  using LSQRequest::_requests;
762  using LSQRequest::_res;
765  using LSQRequest::_size;
766  using LSQRequest::_state;
767  using LSQRequest::_taskId;
768  using LSQRequest::flags;
769  using LSQRequest::isLoad;
771  using LSQRequest::lsqUnit;
774  using LSQRequest::request;
776  using LSQRequest::setState;
778 
779  uint32_t numFragments;
783 
784  public:
785  SplitDataRequest(LSQUnit* port, const DynInstPtr& inst, bool isLoad,
786  const Addr& addr, const uint32_t& size,
787  const Request::Flags & flags_,
788  PacketDataPtr data = nullptr,
789  uint64_t* res = nullptr) :
790  LSQRequest(port, inst, isLoad, addr, size, flags_, data, res,
791  nullptr),
792  numFragments(0),
793  numReceivedPackets(0),
794  mainReq(nullptr),
795  _mainPacket(nullptr)
796  {
797  flags.set(Flag::IsSplit);
798  }
800  {
801  if (mainReq) {
802  mainReq = nullptr;
803  }
804  if (_mainPacket) {
805  delete _mainPacket;
806  _mainPacket = nullptr;
807  }
808  }
809  virtual void finish(const Fault &fault, const RequestPtr &req,
811  virtual bool recvTimingResp(PacketPtr pkt);
812  virtual void initiateTranslation();
813  virtual void sendPacketToCache();
814  virtual void buildPackets();
815 
816  virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt);
817  virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt);
818  virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask);
819 
820  virtual RequestPtr mainRequest();
821  virtual PacketPtr mainPacket();
822  };
823 
825  LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params);
826  ~LSQ() { }
827 
829  std::string name() const;
830 
832  void regStats();
833 
836 
838  void drainSanityCheck() const;
840  bool isDrained() const;
842  void takeOverFrom();
843 
845  int entryAmount(ThreadID num_threads);
846 
848  void tick();
849 
851  void insertLoad(const DynInstPtr &load_inst);
853  void insertStore(const DynInstPtr &store_inst);
854 
856  Fault executeLoad(const DynInstPtr &inst);
857 
859  Fault executeStore(const DynInstPtr &inst);
860 
864  void commitLoads(InstSeqNum &youngest_inst, ThreadID tid)
865  { thread.at(tid).commitLoads(youngest_inst); }
866 
870  void commitStores(InstSeqNum &youngest_inst, ThreadID tid)
871  { thread.at(tid).commitStores(youngest_inst); }
872 
877  void writebackStores();
879  void writebackStores(ThreadID tid);
880 
884  void
885  squash(const InstSeqNum &squashed_num, ThreadID tid)
886  {
887  thread.at(tid).squash(squashed_num);
888  }
889 
891  bool violation();
896  bool violation(ThreadID tid) { return thread.at(tid).violation(); }
897 
899  DynInstPtr
901  {
902  return thread.at(tid).getMemDepViolator();
903  }
904 
906  int getLoadHead(ThreadID tid) { return thread.at(tid).getLoadHead(); }
907 
909  InstSeqNum
911  {
912  return thread.at(tid).getLoadHeadSeqNum();
913  }
914 
916  int getStoreHead(ThreadID tid) { return thread.at(tid).getStoreHead(); }
917 
919  InstSeqNum
921  {
922  return thread.at(tid).getStoreHeadSeqNum();
923  }
924 
926  int getCount();
928  int getCount(ThreadID tid) { return thread.at(tid).getCount(); }
929 
931  int numLoads();
933  int numLoads(ThreadID tid) { return thread.at(tid).numLoads(); }
934 
936  int numStores();
938  int numStores(ThreadID tid) { return thread.at(tid).numStores(); }
939 
941  unsigned numFreeLoadEntries();
942 
944  unsigned numFreeStoreEntries();
945 
947  unsigned numFreeEntries(ThreadID tid);
948 
950  unsigned numFreeLoadEntries(ThreadID tid);
951 
953  unsigned numFreeStoreEntries(ThreadID tid);
954 
956  bool isFull();
961  bool isFull(ThreadID tid);
962 
964  bool isEmpty() const;
966  bool lqEmpty() const;
968  bool sqEmpty() const;
969 
971  bool lqFull();
973  bool lqFull(ThreadID tid);
974 
976  bool sqFull();
978  bool sqFull(ThreadID tid);
979 
984  bool isStalled();
989  bool isStalled(ThreadID tid);
990 
992  bool hasStoresToWB();
993 
997  bool hasStoresToWB(ThreadID tid) { return thread.at(tid).hasStoresToWB(); }
998 
1000  int numStoresToWB(ThreadID tid) { return thread.at(tid).numStoresToWB(); }
1001 
1003  bool willWB();
1007  bool willWB(ThreadID tid) { return thread.at(tid).willWB(); }
1008 
1010  void dumpInsts() const;
1012  void dumpInsts(ThreadID tid) const { thread.at(tid).dumpInsts(); }
1013 
1017  Fault read(LSQRequest* req, int load_idx);
1018 
1022  Fault write(LSQRequest* req, uint8_t *data, int store_idx);
1023 
1027  void recvReqRetry();
1028 
1029  void completeDataAccess(PacketPtr pkt);
1036  bool recvTimingResp(PacketPtr pkt);
1037 
1038  void recvTimingSnoopReq(PacketPtr pkt);
1039 
1040  Fault pushRequest(const DynInstPtr& inst, bool isLoad, uint8_t *data,
1041  unsigned int size, Addr addr, Request::Flags flags,
1042  uint64_t *res, AtomicOpFunctorPtr amo_op,
1043  const std::vector<bool>& byte_enable);
1044 
1046  O3CPU *cpu;
1047 
1049  IEW *iewStage;
1050 
1052  bool cacheBlocked() const;
1054  void cacheBlocked(bool v);
1056  bool cachePortAvailable(bool is_load) const;
1058  void cachePortBusy(bool is_load);
1059 
1061 
1062  protected:
1073 
1074 
1076  SMTQueuePolicy lsqPolicy;
1077 
1083  static uint32_t
1084  maxLSQAllocation(SMTQueuePolicy pol, uint32_t entries,
1085  uint32_t numThreads, uint32_t SMTThreshold)
1086  {
1087  if (pol == SMTQueuePolicy::Dynamic) {
1088  return entries;
1089  } else if (pol == SMTQueuePolicy::Partitioned) {
1090  //@todo:make work if part_amt doesnt divide evenly.
1091  return entries / numThreads;
1092  } else if (pol == SMTQueuePolicy::Threshold) {
1093  //Divide up by threshold amount
1094  //@todo: Should threads check the max and the total
1095  //amount of the LSQ
1096  return SMTThreshold;
1097  }
1098  return 0;
1099  }
1100 
1103 
1105  unsigned LQEntries;
1107  unsigned SQEntries;
1108 
1110  unsigned maxLQEntries;
1111 
1113  unsigned maxSQEntries;
1114 
1117 
1120 
1123 };
1124 
1125 template <class Impl>
1126 Fault
1127 LSQ<Impl>::read(LSQRequest* req, int load_idx)
1128 {
1129  ThreadID tid = cpu->contextToThread(req->request()->contextId());
1130 
1131  return thread.at(tid).read(req, load_idx);
1132 }
1133 
1134 template <class Impl>
1135 Fault
1136 LSQ<Impl>::write(LSQRequest* req, uint8_t *data, int store_idx)
1137 {
1138  ThreadID tid = cpu->contextToThread(req->request()->contextId());
1139 
1140  return thread.at(tid).write(req, data, store_idx);
1141 }
1142 
1143 #endif // __CPU_O3_LSQ_HH__
A MasterPort is a specialisation of a BaseMasterPort, which implements the default protocol for the t...
Definition: port.hh:75
IEW * iewStage
The IEW stage pointer.
Definition: lsq.hh:1049
unsigned SQEntries
Total Size of SQ Entries.
Definition: lsq.hh:1107
void takeOverFrom()
Takes over execution from another CPU&#39;s thread.
Definition: lsq_impl.hh:169
FlagsType flags
Definition: lsq.hh:265
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
ThreadID numThreads
Number of Threads.
Definition: lsq.hh:1122
DynInstPtr inst
Instruction which initiated the access to memory.
Definition: lsq.hh:90
Impl::DynInstPtr DynInstPtr
Definition: lsq.hh:69
Bitfield< 28 > v
uint32_t _numOutstandingPackets
Definition: lsq.hh:301
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:688
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
PacketPtr mainPkt
The main packet from a split load, used during writeback.
Definition: lsq.hh:92
int getCount(ThreadID tid)
Returns the number of instructions in the queues of one thread.
Definition: lsq.hh:928
void taskId(const uint32_t &v)
Definition: lsq.hh:467
LSQSenderState * _senderState
Definition: lsq.hh:276
const uint32_t _size
Definition: lsq.hh:298
PacketDataPtr _data
Definition: lsq.hh:292
unsigned LQEntries
Total Size of LQ Entries.
Definition: lsq.hh:1105
bool willWB()
Returns if the LSQ will write back to memory this cycle.
Definition: lsq_impl.hh:657
Bitfield< 7 > i
LSQUnit * lsqUnit()
Definition: lsq.hh:304
std::vector< RequestPtr > _requests
Definition: lsq.hh:294
unsigned maxSQEntries
Max SQ Size - Used to Enforce Sharing Policies.
Definition: lsq.hh:1113
SMTQueuePolicy lsqPolicy
The LSQ policy for SMT mode.
Definition: lsq.hh:1076
void dumpInsts(ThreadID tid) const
Debugging function to print out instructions from a specific thread.
Definition: lsq.hh:1012
std::vector< LSQUnit > thread
The LSQ units for individual threads.
Definition: lsq.hh:1119
std::vector< bool > _byteEnable
Definition: lsq.hh:300
uint32_t _taskId
Definition: lsq.hh:291
std::string name() const
Returns the name of the LSQ.
Definition: lsq_impl.hh:115
State _state
Definition: lsq.hh:275
void tick()
Ticks the LSQ.
Definition: lsq_impl.hh:181
bool isInTranslation()
Definition: lsq.hh:587
std::shared_ptr< Request > RequestPtr
Definition: request.hh:83
bool isSet() const
Definition: flags.hh:62
uint8_t * PacketDataPtr
Definition: packet.hh:72
void packetSent()
Update the status to reflect that a packet was sent.
Definition: lsq.hh:564
bool sqFull()
Returns if any of the SQs are full.
Definition: lsq_impl.hh:584
void clear()
Definition: flags.hh:68
void packetNotSent()
Update the status to reflect that a packet was not sent.
Definition: lsq.hh:573
ip6_addr_t addr
Definition: inet.hh:335
bool isComplete()
Completes a packet and returns whether the access is finished.
Definition: lsq.hh:113
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Definition: amo.hh:230
const Request::Flags _flags
Definition: lsq.hh:299
Cycles handleIprRead(ThreadContext *, Packet *)
Definition: mmapped_ipr.hh:48
LSQ< Impl > * lsq
Pointer to LSQ.
Definition: lsq.hh:129
LSQRequest * _request
The senderState needs to know the LSQRequest who owns it.
Definition: lsq.hh:79
FullO3CPU< Impl > * cpu
Definition: lsq.hh:130
bool violation()
Returns whether or not there was a memory ordering violation.
Definition: lsq_impl.hh:287
bool hasStoresToWB()
Returns whether or not there are any stores to write back to memory.
Definition: lsq_impl.hh:640
bool isPartialFault()
Definition: lsq.hh:614
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:586
Derived class to hold any sender state the LSQ needs.
Definition: lsq.hh:75
Fault executeLoad(const DynInstPtr &inst)
Executes a load.
Definition: lsq_impl.hh:250
bool isComplete()
Definition: lsq.hh:581
LSQSenderState(LSQRequest *request, bool isLoad_)
Default constructor.
Definition: lsq.hh:82
Bitfield< 4, 0 > mode
bool isTranslationComplete()
Definition: lsq.hh:593
int usedStorePorts
The number of used cache ports in this cycle by stores.
Definition: lsq.hh:1068
virtual ~LSQRequest()
Destructor.
Definition: lsq.hh:428
bool isFull()
Returns if the LSQ is full (either LQ or SQ is full).
Definition: lsq_impl.hh:485
Definition: lsq.hh:64
int getLoadHead(ThreadID tid)
Returns the head index of the load queue for a specific thread.
Definition: lsq.hh:906
bool lqEmpty() const
Returns if all of the LQs are empty.
Definition: lsq_impl.hh:521
void packetReplied()
Definition: lsq.hh:651
ThreadContext is the external interface to all thread state for anything outside of the CPU...
bool hasStoresToWB(ThreadID tid)
Returns whether or not a specific thread has any stores to write back to memory.
Definition: lsq.hh:997
void writebackStores()
Attempts to write back stores until all cache ports are used or the interface becomes blocked...
Definition: lsq_impl.hh:268
bool needWB
Whether or not the instruction will need to writeback.
Definition: lsq.hh:100
std::vector< PacketPtr > _packets
Definition: lsq.hh:293
void dumpInsts() const
Debugging function to print out all instructions.
Definition: lsq_impl.hh:674
STL vector class.
Definition: stl.hh:40
AtomicOpFunctorPtr _amo_op
Definition: lsq.hh:302
bool violation(ThreadID tid)
Returns whether or not there was a memory ordering violation for a specific thread.
Definition: lsq.hh:896
uint32_t numFragments
Definition: lsq.hh:779
LSQRequest(LSQUnit *port, const DynInstPtr &inst, bool isLoad)
Definition: lsq.hh:305
bool willWB(ThreadID tid)
Returns if the LSQ of a specific thread will write back to memory this cycle.
Definition: lsq.hh:1007
::Flags< FlagsStorage > FlagsType
Definition: lsq.hh:236
bool isSplit
Whether or not this access is split in two.
Definition: lsq.hh:102
uint32_t numInTranslationFragments
Definition: lsq.hh:280
void writebackScheduled()
Definition: lsq.hh:660
virtual bool squashed() const override
This function is used by the page table walker to determine if it should translate the a pending requ...
Definition: lsq.hh:362
Impl::CPUPol::LSQUnit LSQUnit
Definition: lsq.hh:71
void release(Flag reason)
Release the LSQRequest.
Definition: lsq.hh:388
bool isMemAccessRequired()
Definition: lsq.hh:620
bool _cacheBlocked
D-cache is blocked.
Definition: lsq.hh:1064
Bitfield< 4 > pc
void writebackDone()
Definition: lsq.hh:118
void senderState(LSQSenderState *st)
Definition: lsq.hh:503
LSQUnit & _port
Definition: lsq.hh:289
void insertLoad(const DynInstPtr &load_inst)
Inserts a load into the LSQ.
Definition: lsq_impl.hh:232
bool isDrained() const
Has the LSQ drained?
Definition: lsq_impl.hh:150
bool isDelayed()
Definition: lsq.hh:286
Addr getVaddr(int idx=0) const
Definition: lsq.hh:483
void setState(const State &newState)
Definition: lsq.hh:277
LSQRequest * request()
Definition: lsq.hh:116
void cachePortBusy(bool is_load)
Another store port is in use.
Definition: lsq_impl.hh:220
unsigned numFreeStoreEntries()
Returns the number of free store entries.
Definition: lsq_impl.hh:453
InstSeqNum getLoadHeadSeqNum(ThreadID tid)
Returns the sequence number of the head of the load queue.
Definition: lsq.hh:910
DcachePort dcachePort
Data port.
Definition: lsq.hh:1116
std::vector< Fault > _fault
Definition: lsq.hh:295
void setContext(const ContextID &context_id)
Convenience getters/setters.
Definition: lsq.hh:445
int numStores(ThreadID tid)
Returns the total number of stores for a single thread.
Definition: lsq.hh:938
int usedLoadPorts
The number of used cache ports in this cycle by loads.
Definition: lsq.hh:1072
void drainSanityCheck() const
Perform sanity checks after a drain.
Definition: lsq_impl.hh:140
int numLoads()
Returns the total number of loads in the load queue.
Definition: lsq_impl.hh:399
DcachePort(LSQ< Impl > *_lsq, FullO3CPU< Impl > *_cpu)
Default constructor.
Definition: lsq.hh:134
unsigned maxLQEntries
Max LQ Size - Used to Enforce Sharing Policies.
Definition: lsq.hh:1110
void sendFragmentToTranslation(int i)
Definition: lsq_impl.hh:975
bool isSplit() const
Definition: lsq.hh:542
int numStoresToWB(ThreadID tid)
Returns the number of stores a specific thread has to write back.
Definition: lsq.hh:1000
Fault executeStore(const DynInstPtr &inst)
Executes a store.
Definition: lsq_impl.hh:259
Fault write(LSQRequest *req, uint8_t *data, int store_idx)
Executes a store operation, using the store specified at the store index.
Definition: lsq.hh:1136
uint64_t InstSeqNum
Definition: inst_seq.hh:40
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:408
Port Object Declaration.
virtual bool isSnooping() const
As this CPU requires snooping to maintain the load store queue change the behaviour from the base CPU...
Definition: lsq.hh:161
void squashTranslation()
Definition: lsq.hh:677
bool isLoad() const
Definition: lsq.hh:339
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
void writebackDone()
Definition: lsq.hh:667
void complete()
Definition: lsq.hh:688
bool deleted
Has the request been deleted? LSQ entries can be squashed before the response comes back...
Definition: lsq.hh:109
uint16_t MasterID
Definition: request.hh:86
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
InstSeqNum getStoreHeadSeqNum(ThreadID tid)
Returns the sequence number of the head of the store queue.
Definition: lsq.hh:920
void deleteRequest()
Definition: lsq.hh:114
void markDelayed() override
Signal that the translation has been delayed due to a hw page table walk.
Definition: lsq.hh:285
bool isSent()
Definition: lsq.hh:608
uint32_t numTranslatedFragments
Definition: lsq.hh:279
uint64_t * _res
Definition: lsq.hh:296
bool isLoad
Whether or not it is a load.
Definition: lsq.hh:98
A virtual base opaque structure used to hold state associated with the packet (e.g., an MSHR), specific to a SimObject that sees the packet.
Definition: packet.hh:403
void insertStore(const DynInstPtr &store_inst)
Inserts a store into the LSQ.
Definition: lsq_impl.hh:241
bool isReleased()
Test if the LSQRequest has been released, i.e.
Definition: lsq.hh:373
uint32_t _entryIdx
LQ/SQ entry idx.
Definition: lsq.hh:283
bool isEmpty() const
Returns if the LSQ is empty (both LQ and SQ are empty).
Definition: lsq_impl.hh:514
PacketPtr pendingPacket
A second packet from a split store that needs sending.
Definition: lsq.hh:94
virtual void complete()=0
const DynInstPtr _inst
Definition: lsq.hh:290
void discardSenderState()
Mark senderState as discarded.
Definition: lsq.hh:523
int getCount()
Returns the number of instructions in all of the queues.
Definition: lsq_impl.hh:381
Mode
Definition: tlb.hh:59
bool isTranslationBlocked()
Definition: lsq.hh:600
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
bool alive()
Definition: lsq.hh:115
SingleDataRequest(LSQUnit *port, const DynInstPtr &inst, bool isLoad, const Addr &addr, const uint32_t &size, const Request::Flags &flags_, PacketDataPtr data=nullptr, uint64_t *res=nullptr, AtomicOpFunctorPtr amo_op=nullptr)
Definition: lsq.hh:726
Impl::O3CPU O3CPU
Definition: lsq.hh:68
void commitStores(InstSeqNum &youngest_inst, ThreadID tid)
Commits stores up until the given sequence number for a specific thread.
Definition: lsq.hh:870
const LSQSenderState * senderState() const
Definition: lsq.hh:513
uint8_t outstanding
Number of outstanding packets to complete.
Definition: lsq.hh:96
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
Definition: lsq.hh:147
unsigned numFreeLoadEntries()
Returns the number of free load entries.
Definition: lsq_impl.hh:435
int entryAmount(ThreadID num_threads)
Number of entries needed for the given amount of threads.
void setStateToFault()
Definition: lsq.hh:627
virtual PacketPtr mainPacket()
Definition: lsq.hh:489
LSQRequest(LSQUnit *port, const DynInstPtr &inst, bool isLoad, const Addr &addr, const uint32_t &size, const Request::Flags &flags_, PacketDataPtr data=nullptr, uint64_t *res=nullptr, AtomicOpFunctorPtr amo_op=nullptr)
Definition: lsq.hh:317
RequestPtr request(int idx=0)
Definition: lsq.hh:475
Fault read(LSQRequest *req, int load_idx)
Executes a read operation, using the load specified at the load index.
Definition: lsq.hh:1127
void recvReqRetry()
Retry the previous send that failed.
Definition: lsq_impl.hh:305
Bitfield< 31, 28 > st
DcachePort class for the load/store queue.
Definition: lsq.hh:124
const DynInstPtr & instruction()
Definition: lsq.hh:451
void setActiveThreads(std::list< ThreadID > *at_ptr)
Sets the pointer to the list of active threads.
Definition: lsq_impl.hh:132
uint32_t numReceivedPackets
Definition: lsq.hh:780
int cacheStorePorts
The number of cache ports available each cycle (stores only).
Definition: lsq.hh:1066
RequestPtr mainReq
Definition: lsq.hh:781
uint32_t taskId() const
Definition: lsq.hh:474
virtual RequestPtr mainRequest()
Definition: lsq.hh:496
LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
Constructs an LSQ with the given parameters.
Definition: lsq_impl.hh:63
int numStores()
Returns the total number of stores in the store queue.
Definition: lsq_impl.hh:417
bool isAnyOutstandingRequest()
Test if there is any in-flight translation or mem access request.
Definition: lsq.hh:533
void setVirt(int asid, Addr vaddr, unsigned size, Request::Flags flags_, MasterID mid, Addr pc)
Set up virtual request.
Definition: lsq.hh:460
void install()
Install the request in the LQ/SQ.
Definition: lsq.hh:351
ContextID contextId()
Definition: lsq.hh:110
bool isAnyActiveElement(const std::vector< bool >::const_iterator &it_start, const std::vector< bool >::const_iterator &it_end)
Test if there is any active element in an enablement range.
Definition: utils.hh:88
bool cachePortAvailable(bool is_load) const
Is any store port available to use?
Definition: lsq_impl.hh:207
PacketPtr _mainPacket
Definition: lsq.hh:782
SplitDataRequest(LSQUnit *port, const DynInstPtr &inst, bool isLoad, const Addr &addr, const uint32_t &size, const Request::Flags &flags_, PacketDataPtr data=nullptr, uint64_t *res=nullptr)
Definition: lsq.hh:785
virtual ~SingleDataRequest()
Definition: lsq.hh:735
void discard()
The request is discarded (e.g.
Definition: lsq.hh:645
Memory operation metadata.
Definition: lsq.hh:232
void completeDataAccess(PacketPtr pkt)
Definition: lsq_impl.hh:317
int cacheLoadPorts
The number of cache ports available each cycle (loads only).
Definition: lsq.hh:1070
void regStats()
Registers statistics of each LSQ unit.
Definition: lsq_impl.hh:122
bool recvTimingResp(PacketPtr pkt)
Handles writing back and completing the load or store that has returned from memory.
Definition: lsq_impl.hh:326
LoadQueue loadQueue
The load queue.
Definition: lsq_unit.hh:486
virtual ~SplitDataRequest()
Definition: lsq.hh:799
Cycles handleIprWrite(ThreadContext *, Packet *)
Definition: mmapped_ipr.hh:49
bool pktToSend
Whether or not there is a packet that needs sending.
Definition: lsq.hh:104
void squash(const InstSeqNum &squashed_num, ThreadID tid)
Squash instructions from a thread until the specified sequence number.
Definition: lsq.hh:885
CircularQueue< SQEntry > storeQueue
The store queue.
Definition: lsq_unit.hh:483
static uint32_t maxLSQAllocation(SMTQueuePolicy pol, uint32_t entries, uint32_t numThreads, uint32_t SMTThreshold)
Auxiliary function to calculate per-thread max LSQ allocation limit.
Definition: lsq.hh:1084
bool cacheBlocked() const
Is D-cache blocked?
Definition: lsq_impl.hh:193
PacketPtr packet(int idx=0)
Definition: lsq.hh:486
Impl::CPUPol::IEW IEW
Definition: lsq.hh:70
MasterPort & getDataPort()
Definition: lsq.hh:1060
O3CPU * cpu
The CPU pointer.
Definition: lsq.hh:1046
std::list< ThreadID > * activeThreads
List of Active Threads in System.
Definition: lsq.hh:1102
bool isStalled()
Returns if the LSQ is stalled due to a memory operation that must be replayed.
Definition: lsq_impl.hh:613
void freeLSQEntry()
The LSQ entry is cleared.
Definition: lsq.hh:636
DynInstPtr getMemDepViolator(ThreadID tid)
Gets the instruction that caused the memory ordering violation.
Definition: lsq.hh:900
void recvTimingSnoopReq(PacketPtr pkt)
Definition: lsq_impl.hh:364
const char data[]
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
unsigned numFreeEntries(ThreadID tid)
Returns the number of free entries for a specific thread.
int getStoreHead(ThreadID tid)
Returns the head index of the store queue.
Definition: lsq.hh:916
void set(Type flags)
Definition: flags.hh:70
int ContextID
Globally unique thread context ID.
Definition: types.hh:231
int numLoads(ThreadID tid)
Returns the total number of loads for a single thread.
Definition: lsq.hh:933
void commitLoads(InstSeqNum &youngest_inst, ThreadID tid)
Commits loads up until the given sequence number for a specific thread.
Definition: lsq.hh:864
bool sqEmpty() const
Returns if all of the SQs are empty.
Definition: lsq_impl.hh:538
~LSQ()
Definition: lsq.hh:826
const RequestPtr request(int idx=0) const
Definition: lsq.hh:478
bool lqFull()
Returns if any of the LQs are full.
Definition: lsq_impl.hh:555
FullO3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time ...
Definition: cpu.hh:98
const Addr _addr
Definition: lsq.hh:297
uint32_t FlagsStorage
Definition: lsq.hh:235
bool isAtomic() const
Definition: lsq.hh:345

Generated on Fri Feb 28 2020 16:26:59 for gem5 by doxygen 1.8.13