50#include "debug/Activity.hh"
51#include "debug/HtmCpu.hh"
52#include "debug/IEW.hh"
53#include "debug/LSQUnit.hh"
54#include "debug/O3PipeView.hh"
69 assert(_inst->savedRequest);
70 _inst->savedRequest->writebackScheduled();
76 assert(!
lsqPtr->cpu->switchedOut());
80 assert(
inst->savedRequest);
81 inst->savedRequest->writebackDone();
88 return "Store writeback";
95 assert(request !=
nullptr);
127 "store notification (ignored) of HTM transaction failure "
128 "in cache - addr=0x%lx - rc=%s - htmUid=%d\n",
145 panic(
"HTM error - unhandled return code from cache (%s)",
150 std::make_shared<GenericHtmFailureFault>(
151 inst->getHtmTransactionUid(),
155 "load notification of HTM transaction failure "
156 "in cache - pc=%s - addr=0x%lx - "
157 "rc=%u - htmUid=%d\n",
158 inst->pcState(), pkt->
getAddr(),
163 cpu->ppDataAccessComplete->notify(std::make_pair(inst, pkt));
165 assert(!
cpu->switchedOut());
166 if (!inst->isSquashed()) {
170 assert(inst->isLoad() || inst->isStoreConditional() ||
180 if (inst->isStore() || inst->isAtomic()) {
184 }
else if (inst->isStore()) {
204 LSQ *lsq_ptr,
unsigned id)
250 return iewStage->name() +
".lsq.thread" + std::to_string(
lsqID);
257 "Number of loads that had data forwarded from stores"),
259 "Number of loads squashed"),
261 "Number of memory responses ignored because the instruction is "
264 "Number of memory ordering violations"),
266 "Number of stores squashed"),
268 "Number of loads that were rescheduled"),
270 "Number of times an access to memory failed due to the cache "
273 "first time a load is issued and its completion"),
275 "Number of loads and stores written to the Load Store Queue")
307 assert(inst->isMemRef());
309 assert(inst->isLoad() || inst->isStore() || inst->isAtomic());
311 if (inst->isLoad()) {
325 ++
stats.addedLoadsAndStores;
328 load_inst->pcState(),
loadQueue.tail(), load_inst->seqNum);
338 assert(load_inst->lqIdx > 0);
339 load_inst->lqIt =
loadQueue.getIterator(load_inst->lqIdx);
344 if (load_inst->isHtmStart()) {
346 DPRINTF(HtmCpu,
">> htmStarts++ (%d) : htmStops (%d)\n",
350 const auto& htm_cpt =
cpu->tcBase(
lsqID)->getHtmCheckpointPtr();
351 auto htm_uid = htm_cpt->getHtmUid();
354 if (!load_inst->inHtmTransactionalState()) {
355 htm_uid = htm_cpt->newHtmUid();
356 DPRINTF(HtmCpu,
"generating new htmUid=%u\n", htm_uid);
357 if (htm_depth != 1) {
359 "unusual HTM transactional depth (%d)"
360 " possibly caused by mispeculation - htmUid=%u\n",
364 load_inst->setHtmTransactionalState(htm_uid, htm_depth);
367 if (load_inst->isHtmStop()) {
369 DPRINTF(HtmCpu,
">> htmStarts (%d) : htmStops++ (%d)\n",
374 "htmStops==1 && htmStarts==0. "
375 "This generally shouldn't happen "
376 "(unless due to misspeculation)\n");
387 ++
stats.addedLoadsAndStores;
390 store_inst->pcState(),
storeQueue.tail(), store_inst->seqNum);
394 store_inst->sqIt =
storeQueue.getIterator(store_inst->sqIdx);
396 store_inst->lqIdx =
loadQueue.tail() + 1;
397 assert(store_inst->lqIdx > 0);
438 for (
int x = 0;
x <
cpu->numContexts();
x++) {
440 bool no_squash =
cpu->thread[
x]->noSquashFromTC;
441 cpu->thread[
x]->noSquashFromTC =
true;
443 cpu->thread[
x]->noSquashFromTC = no_squash;
458 if (ld_inst->effAddrValid() && request &&
461 ld_inst->tcBase()->getIsaPtr()->handleLockedSnoopHit(ld_inst.
get());
464 bool force_squash =
false;
467 ld_inst = iter->instruction();
469 request = iter->request();
470 if (!ld_inst->effAddrValid() || ld_inst->strictlyOrdered() || !request)
474 ld_inst->seqNum, invalidate_addr);
484 if (ld_inst->possibleLoadViolation() || force_squash) {
486 pkt->
getAddr(), ld_inst->seqNum);
489 ld_inst->fault = std::make_shared<ReExec>();
493 pkt->
getAddr(), ld_inst->seqNum);
499 ld_inst->tcBase()->getIsaPtr()->
500 handleLockedSnoopHit(ld_inst.
get());
506 ld_inst->hitExternalSnoop(
true);
527 if (!ld_inst->effAddrValid() || ld_inst->strictlyOrdered()) {
536 if (inst_eff_addr2 >= ld_eff_addr1 && inst_eff_addr1 <= ld_eff_addr2) {
537 if (inst->isLoad()) {
541 if (ld_inst->hitExternalSnoop()) {
545 "and [sn:%lli] at address %#x\n",
546 inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
549 ++
stats.memOrderViolation;
551 return std::make_shared<GenericISA::M5PanicFault>(
552 "Detected fault with inst [sn:%lli] and "
553 "[sn:%lli] at address %#x\n",
554 inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
560 ld_inst->possibleLoadViolation(
true);
562 " between instructions [sn:%lli] and [sn:%lli]\n",
563 inst_eff_addr1, inst->seqNum, ld_inst->seqNum);
572 "[sn:%lli] at address %#x\n",
573 inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
576 ++
stats.memOrderViolation;
578 return std::make_shared<GenericISA::M5PanicFault>(
579 "Detected fault with "
580 "inst [sn:%lli] and [sn:%lli] at address %#x\n",
581 inst->seqNum, ld_inst->seqNum, ld_eff_addr1);
600 inst->pcState(), inst->seqNum);
602 assert(!inst->isSquashed());
604 if (inst->isExecuted()) {
605 DPRINTF(
LSQUnit,
"Load [sn:%lli] already executed\n", inst->seqNum);
609 load_fault = inst->initiateAcc();
611 if (load_fault ==
NoFault && !inst->readMemAccPredicate()) {
612 assert(inst->readPredicate());
614 inst->completeAcc(
nullptr);
620 if (inst->isTranslationDelayed() && load_fault ==
NoFault)
623 if (load_fault !=
NoFault && inst->translationCompleted() &&
624 inst->savedRequest->isPartialFault()
625 && !inst->savedRequest->isComplete()) {
626 assert(inst->savedRequest->isSplit());
636 if (load_fault !=
NoFault || !inst->readPredicate()) {
641 if (!inst->readPredicate())
642 inst->forwardOldRegs();
645 (load_fault !=
NoFault ?
"fault" :
"predication"));
646 if (!(inst->hasRequest() && inst->strictlyOrdered()) ||
647 inst->isAtCommit()) {
653 if (inst->effAddrValid()) {
654 auto it = inst->lqIt;
671 ssize_t store_idx = store_inst->sqIdx;
674 store_inst->pcState(), store_inst->seqNum);
676 assert(!store_inst->isSquashed());
680 typename LoadQueue::iterator loadIt = store_inst->lqIt;
682 Fault store_fault = store_inst->initiateAcc();
684 if (store_inst->isTranslationDelayed() &&
688 if (!store_inst->readPredicate()) {
689 DPRINTF(
LSQUnit,
"Store [sn:%lli] not executed from predication\n",
691 store_inst->forwardOldRegs();
697 store_inst->pcState(), store_inst->seqNum);
699 if (store_inst->isAtomic()) {
702 if (!(store_inst->hasRequest() && store_inst->strictlyOrdered()) ||
703 store_inst->isAtCommit()) {
704 store_inst->setExecuted();
713 assert(store_fault ==
NoFault);
715 if (store_inst->isStoreConditional() || store_inst->isAtomic()) {
739 if (!inst->isInstPrefetch() && !inst->isDataPrefetch()
740 && inst->firstIssue != -1
741 && inst->lastWakeDependents != -1) {
742 stats.loadToUse.sample(
cpu->ticksToCycles(
743 inst->lastWakeDependents - inst->firstIssue));
772 if (
x.instruction()->seqNum > youngest_inst) {
777 x.instruction()->pcState(),
778 x.instruction()->seqNum);
791 storeWBIt->request()->sendPacketToCache();
810 lsq->cachePortAvailable(
false)) {
828 if (
storeWBIt->instruction()->isDataPrefetch()) {
841 if ((request->
mainReq()->isLLSC() ||
842 request->
mainReq()->isRelease()) &&
845 "[sn:%lli] is %s%s and not head of the queue\n",
847 request->
mainReq()->getPaddr(), inst->seqNum,
848 request->
mainReq()->isLLSC() ?
"SC" :
"",
849 request->
mainReq()->isRelease() ?
"/Release" :
"");
855 assert(!inst->memData);
856 inst->memData =
new uint8_t[request->
_size];
859 memset(inst->memData, 0, request->
_size);
866 "to Addr:%#x, data:%#x [sn:%lli]\n",
868 request->
mainReq()->getPaddr(), (
int)*(inst->memData),
872 if (inst->isStoreConditional()) {
876 inst->recordResult(
false);
877 bool success = inst->tcBase()->getIsaPtr()->handleLockedWrite(
879 inst->recordResult(
true);
886 "Instantly completing it.\n",
901 if (request->
mainReq()->isLocalAccess()) {
902 assert(!inst->isStoreConditional());
903 assert(!inst->inHtmTransactionalState());
908 request->
mainReq()->localAccessor(thread, main_pkt);
921 DPRINTF(
LSQUnit,
"D-Cache became blocked when writing [sn:%lli], "
922 "will retry later\n",
933 "(Loads:%i Stores:%i)\n", squashed_num,
loadQueue.size(),
937 loadQueue.back().instruction()->seqNum > squashed_num) {
940 loadQueue.back().instruction()->pcState(),
952 if (
loadQueue.back().instruction()->isHtmStart())
955 DPRINTF(HtmCpu,
">> htmStarts-- (%d) : htmStops (%d)\n",
958 if (
loadQueue.back().instruction()->isHtmStop())
961 DPRINTF(HtmCpu,
">> htmStarts (%d) : htmStops-- (%d)\n",
965 loadQueue.back().instruction()->setSquashed();
969 ++
stats.squashedLoads;
975 uint64_t in_flight_uid = 0;
977 if (scan_it->instruction()->isHtmStart() &&
978 !scan_it->instruction()->isSquashed()) {
979 in_flight_uid = scan_it->instruction()->getHtmTransactionUid();
980 DPRINTF(HtmCpu,
"loadQueue[%d]: found valid HtmStart htmUid=%u\n",
981 scan_it._idx, in_flight_uid);
987 const auto& htm_cpt =
cpu->tcBase(
lsqID)->getHtmCheckpointPtr();
989 const uint64_t old_local_htm_uid = htm_cpt->getHtmUid();
990 uint64_t new_local_htm_uid;
991 if (in_flight_uid > 0)
992 new_local_htm_uid = in_flight_uid;
996 if (old_local_htm_uid != new_local_htm_uid) {
997 DPRINTF(HtmCpu,
"flush: lastRetiredHtmUid=%u\n",
999 DPRINTF(HtmCpu,
"flush: resetting localHtmUid=%u\n",
1002 htm_cpt->setHtmUid(new_local_htm_uid);
1011 storeQueue.back().instruction()->seqNum > squashed_num) {
1018 "idx:%i [sn:%lli]\n",
1026 panic(
"Is stalled should have been cleared by stalling load!\n");
1032 storeQueue.back().instruction()->setSquashed();
1040 ++
stats.squashedStores;
1047 const auto& htm_cpt =
cpu->tcBase(
lsqID)->getHtmCheckpointPtr();
1048 return htm_cpt->getHtmUid();
1064 if (!
storeWBIt->instruction()->isStoreConditional()) {
1068 storeWBIt->instruction()->setCompleted();
1088 if (inst->isSquashed()) {
1089 assert (!inst->isStore() || inst->isStoreConditional());
1090 ++
stats.ignoredResponses;
1094 if (!inst->isExecuted()) {
1095 inst->setExecuted();
1099 inst->completeAcc(pkt);
1109 auto htm_fault = std::dynamic_pointer_cast<
1113 assert(
dynamic_cast<ReExec*
>(inst->fault.
get()) !=
nullptr ||
1114 inst->savedRequest->isPartialFault());
1122 "%s writeback with HTM failure fault, "
1123 "however, completing packet is not aware of "
1124 "transaction failure. cause=%s htmUid=%u\n",
1125 inst->staticInst->getName(),
1127 htm_fault->getHtmUid());
1131 "due to pending fault.\n", inst->seqNum);
1141 iewStage->checkMisprediction(inst);
1147 assert(store_idx->valid());
1148 store_idx->completed() =
true;
1154 cpu->activityThisCycle();
1158 DynInstPtr store_inst = store_idx->instruction();
1166 iewStage->updateLSQNextCycle =
true;
1169 DPRINTF(
LSQUnit,
"Completing store [sn:%lli], idx:%i, store head "
1171 store_inst->seqNum, store_idx.idx() - 1,
storeQueue.head() - 1);
1174 if (debug::O3PipeView) {
1175 store_inst->storeTick =
1176 curTick() - store_inst->fetchTick;
1190 store_inst->setCompleted();
1202 if (
cpu->checker && !store_inst->isStoreConditional()) {
1203 cpu->checker->verify(store_inst);
1211 bool cache_got_blocked =
false;
1215 if (!
lsq->cacheBlocked() &&
1216 lsq->cachePortAvailable(isLoad)) {
1219 cache_got_blocked =
true;
1229 lsq->cachePortBusy(isLoad);
1232 if (cache_got_blocked) {
1233 lsq->cacheBlocked(
true);
1234 ++
stats.blockedByCache;
1237 assert(request ==
storeWBIt->request());
1242 DPRINTF(
LSQUnit,
"Memory request (pkt: %s) from inst [sn:%llu] was"
1243 " %ssent (cache is blocked: %d, cache_got_blocked: %d)\n",
1245 ret ?
"":
"not ",
lsq->cacheBlocked(), cache_got_blocked);
1252 DPRINTF(
LSQUnit,
"Unit %p marking stale translations %d %d\n",
this,
1255 if (entry.valid() && entry.hasRequest())
1256 entry.request()->markAsStaleTranslation();
1259 if (entry.valid() && entry.hasRequest())
1260 entry.request()->markAsStaleTranslation();
1269 if (entry.valid() && entry.hasRequest()
1270 && entry.request()->hasStaleTranslation())
1274 if (entry.valid() && entry.hasRequest()
1275 && entry.request()->hasStaleTranslation())
1294 cprintf(
"Load store queue: Dumping instructions.\n");
1300 cprintf(
"%s.[sn:%llu] ", inst->pcState(), inst->seqNum);
1309 cprintf(
"%s.[sn:%llu] ", inst->pcState(), inst->seqNum);
1322 return cpu->cacheLineSize();
1334 assert(!load_inst->isExecuted());
1341 if (request->
mainReq()->isStrictlyOrdered() &&
1342 (load_idx !=
loadQueue.head() || !load_inst->isAtCommit())) {
1345 iewStage->rescheduleMemInst(load_inst);
1346 load_inst->clearIssued();
1347 load_inst->effAddrValid(
false);
1348 ++
stats.rescheduledLoads;
1350 load_inst->seqNum, load_inst->pcState());
1357 return std::make_shared<GenericISA::M5PanicFault>(
1358 "Strictly ordered load [sn:%llx] PC %s\n",
1359 load_inst->seqNum, load_inst->pcState());
1363 "storeHead: %i addr: %#x%s\n",
1364 load_idx - 1, load_inst->sqIt._idx,
storeQueue.head() - 1,
1368 if (request->
mainReq()->isLLSC()) {
1372 load_inst->recordResult(
false);
1373 load_inst->tcBase()->getIsaPtr()->handleLockedRead(load_inst.
get(),
1375 load_inst->recordResult(
true);
1378 if (request->
mainReq()->isLocalAccess()) {
1379 assert(!load_inst->memData);
1387 Cycles delay = request->
mainReq()->localAccessor(thread, main_pkt);
1390 cpu->schedule(wb,
cpu->clockEdge(delay));
1395 auto store_it = load_inst->sqIt;
1398 while (store_it !=
storeWBIt && !load_inst->isDataPrefetch()) {
1401 assert(store_it->valid());
1402 assert(store_it->instruction()->seqNum < load_inst->seqNum);
1403 int store_size = store_it->size();
1408 if (store_size != 0 && !store_it->instruction()->strictlyOrdered() &&
1409 !(store_it->request()->mainReq() &&
1410 store_it->request()->mainReq()->isCacheMaintenance())) {
1411 assert(store_it->instruction()->effAddrValid());
1415 auto req_s = request->
mainReq()->getVaddr();
1416 auto req_e = req_s + request->
mainReq()->getSize();
1417 auto st_s = store_it->instruction()->effAddr;
1418 auto st_e = st_s + store_size;
1420 bool store_has_lower_limit = req_s >= st_s;
1421 bool store_has_upper_limit = req_e <= st_e;
1422 bool lower_load_has_store_part = req_s < st_e;
1423 bool upper_load_has_store_part = req_e > st_s;
1431 if (!store_it->instruction()->isAtomic() &&
1432 store_has_lower_limit && store_has_upper_limit &&
1433 !request->
mainReq()->isLLSC()) {
1435 const auto& store_req = store_it->request()->mainReq();
1436 coverage = store_req->isMasked() ?
1442 (!request->
mainReq()->isLLSC() &&
1443 ((store_has_lower_limit && lower_load_has_store_part) ||
1444 (store_has_upper_limit && upper_load_has_store_part) ||
1445 (lower_load_has_store_part && upper_load_has_store_part))) ||
1448 (request->
mainReq()->isLLSC() &&
1449 ((store_has_lower_limit || upper_load_has_store_part) &&
1450 (store_has_upper_limit || lower_load_has_store_part))) ||
1453 (store_it->instruction()->isAtomic() &&
1454 ((store_has_lower_limit || upper_load_has_store_part) &&
1455 (store_has_upper_limit || lower_load_has_store_part)))) {
1462 int shift_amt = request->
mainReq()->getVaddr() -
1463 store_it->instruction()->effAddr;
1466 if (!load_inst->memData) {
1467 load_inst->memData =
1468 new uint8_t[request->
mainReq()->getSize()];
1470 if (store_it->isAllZeros())
1471 memset(load_inst->memData, 0,
1472 request->
mainReq()->getSize());
1474 memcpy(load_inst->memData,
1475 store_it->
data() + shift_amt,
1476 request->
mainReq()->getSize());
1479 "addr %#x\n", store_it._idx,
1480 request->
mainReq()->getVaddr());
1493 assert(!request->
mainReq()->isHTMCmd());
1494 if (load_inst->inHtmTransactionalState()) {
1495 assert (!
storeQueue[store_it._idx].completed());
1498 inHtmTransactionalState());
1500 load_inst->getHtmTransactionUid() ==
1502 getHtmTransactionUid());
1504 load_inst->getHtmTransactionUid());
1505 DPRINTF(HtmCpu,
"HTM LD (ST2LDF) "
1506 "pc=0x%lx - vaddr=0x%lx - "
1507 "paddr=0x%lx - htmUid=%u\n",
1508 load_inst->pcState().instAddr(),
1509 data_pkt->
req->hasVaddr() ?
1510 data_pkt->
req->getVaddr() : 0lu,
1512 load_inst->getHtmTransactionUid());
1542 if (store_it->completed()) {
1543 panic(
"Should not check one of these");
1560 iewStage->rescheduleMemInst(load_inst);
1561 load_inst->clearIssued();
1562 load_inst->effAddrValid(
false);
1563 ++
stats.rescheduledLoads;
1568 "Store idx %i to load addr %#x\n",
1569 store_it._idx, request->
mainReq()->getVaddr());
1580 DPRINTF(
LSQUnit,
"Doing memory access for inst [sn:%lli] PC %s\n",
1581 load_inst->seqNum, load_inst->pcState());
1584 if (!load_inst->memData) {
1585 load_inst->memData =
new uint8_t[request->
mainReq()->getSize()];
1590 if (request->
mainReq()->isHTMCmd()) {
1594 *load_inst->memData = (uint64_t) 0x1ull;
1609 if (!request->
isSent()) {
1610 if (!
lsq->cacheBlocked()) {
1625 DPRINTF(
LSQUnit,
"Doing write to store idx %i, addr %#x | storeHead:%i "
1627 store_idx - 1, request->
req()->getPaddr(),
storeQueue.head() - 1,
1628 storeQueue[store_idx].instruction()->seqNum);
1631 unsigned size = request->
_size;
1633 bool store_no_data =
1635 storeQueue[store_idx].isAllZeros() = store_no_data;
1640 !request->
req()->isCacheMaintenance() &&
1641 !request->
req()->isAtomic())
1653 return loadQueue.front().instruction()->seqNum;
1662 return storeQueue.front().instruction()->seqNum;
virtual void handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask)
Cycles is a wrapper class for representing cycle counts, i.e.
static const FlagsType AutoDelete
Event(Priority p=Default_Pri, Flags f=0)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setHtmTransactionFailedInCache(const HtmCacheFailure ret_code)
Stipulates that this packet/request has returned from the cache hierarchy in a failed transaction.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
SenderState * senderState
This packet's sender state.
HtmCacheFailure getHtmTransactionFailedInCacheRC() const
If a packet/request has returned from the cache hierarchy in a failed transaction,...
bool isHtmTransactional() const
Returns whether or not this packet/request originates in the CPU executing in transactional mode,...
uint64_t getHtmTransactionUid() const
If a packet/request originates in a CPU executing in transactional mode, i.e.
RequestPtr req
A pointer to the original request.
void setHtmTransactional(uint64_t val)
Stipulates that this packet/request originates in the CPU executing in transactional mode,...
bool isInvalidate() const
bool htmTransactionFailedInCache() const
Returns whether or not this packet/request has returned from the cache hierarchy in a failed transact...
T * data
The stored pointer.
T * get() const
Directly access the pointer itself without taking a reference.
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
@ LLSC
The request is a Load locked/store conditional.
@ CACHE_BLOCK_ZERO
This is a write that is targeted and zeroing an entire cache block.
static const FlagsType STORE_NO_DATA
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual BaseISA * getIsaPtr() const =0
O3CPU class, has each of the stages (fetch through commit) within it, as well as all of the time buff...
IEW handles both single threaded and SMT IEW (issue/execute/writeback).
void setRequest(LSQRequest *r)
const DynInstPtr & instruction() const
static constexpr size_t DataSize
Writeback event, specifically for when stores forward data to loads.
WritebackEvent(const DynInstPtr &_inst, PacketPtr pkt, LSQUnit *lsq_ptr)
Constructs a writeback event.
PacketPtr pkt
The packet that would have been sent to memory.
DynInstPtr inst
Instruction whose results are being written back.
const char * description() const
Returns the description of this event.
LSQUnit * lsqPtr
The pointer to the LSQ unit that issued the store.
void process()
Processes the writeback event.
void insertStore(const DynInstPtr &store_inst)
Inserts a store instruction.
Fault write(LSQRequest *requst, uint8_t *data, ssize_t store_idx)
Executes the store at the given index.
Addr cacheBlockMask
Address Mask for a cache block (e.g.
IEW * iewStage
Pointer to the IEW stage.
bool isStoreBlocked
Whehter or not a store is blocked due to the memory system.
@ PartialAddrRangeCoverage
void takeOverFrom()
Takes over from another CPU's thread.
bool checkLoads
Should loads be checked for dependency issues.
Fault read(LSQRequest *request, ssize_t load_idx)
Executes the load at the given index.
bool storeInFlight
Whether or not a store is in flight.
CPU * cpu
Pointer to the CPU.
InstSeqNum getStoreHeadSeqNum()
Returns the sequence number of the head store instruction.
InstSeqNum getLoadHeadSeqNum()
Returns the sequence number of the head load instruction.
unsigned depCheckShift
The number of places to shift addresses in the LSQ before checking for dependency violations.
void storePostSend()
Handles completing the send of a store to memory.
RequestPort * dcachePort
Pointer to the dcache port.
InstSeqNum stallingStoreIsn
The store that causes the stall due to partial store to load forwarding.
bool isStalled()
Returns whether or not the LSQ unit is stalled.
void insertLoad(const DynInstPtr &load_inst)
Inserts a load instruction.
Fault executeStore(const DynInstPtr &inst)
Executes a store instruction.
void insert(const DynInstPtr &inst)
Inserts an instruction.
bool checkStaleTranslations() const
uint64_t getLatestHtmUid() const
void schedule(Event &ev, Tick when)
Schedule event for the cpu.
void writebackStores()
Writes back stores.
Fault checkViolations(typename LoadQueue::iterator &loadIt, const DynInstPtr &inst)
Check for ordering violations in the LSQ.
StoreQueue storeQueue
The store queue.
Fault executeLoad(const DynInstPtr &inst)
Executes a load instruction.
void commitLoad()
Commits the head load.
LSQUnit(uint32_t lqEntries, uint32_t sqEntries)
Constructs an LSQ unit.
void completeStore(typename StoreQueue::iterator store_idx)
Completes the store at the specified index.
void drainSanityCheck() const
Perform sanity checks after a drain.
void setDcachePort(RequestPort *dcache_port)
Sets the pointer to the dcache port.
unsigned int cacheLineSize()
void resetState()
Reset the LSQ state.
unsigned numFreeStoreEntries()
Returns the number of free SQ entries.
uint64_t lastRetiredHtmUid
LSQ::LSQRequest LSQRequest
void dumpInsts() const
Debugging function to dump instructions in the LSQ.
bool stalled
Whether or not the LSQ is stalled.
ssize_t stallingLoadIdx
The index of the above store.
LoadQueue loadQueue
The load queue.
PacketPtr retryPkt
The packet that needs to be retried.
void init(CPU *cpu_ptr, IEW *iew_ptr, const BaseO3CPUParams ¶ms, LSQ *lsq_ptr, unsigned id)
Initializes the LSQ unit with the specified number of entries.
DynInstPtr getMemDepViolator()
Returns the memory ordering violator.
DynInstPtr memDepViolator
The oldest load that caused a memory ordering violation.
void squash(const InstSeqNum &squashed_num)
Squashes all instructions younger than a specific sequence number.
std::string name() const
Returns the name of the LSQ unit.
void checkSnoop(PacketPtr pkt)
Check if an incoming invalidate hits in the lsq on a load that might have issued out of order wrt ano...
static constexpr auto MaxDataBytes
void recvRetry()
Handles doing the retry.
int storesToWB
The number of store instructions in the SQ waiting to writeback.
unsigned numFreeLoadEntries()
Returns the number of free LQ entries.
bool trySendPacket(bool isLoad, PacketPtr data_pkt)
Attempts to send a packet to the cache.
void writeback(const DynInstPtr &inst, PacketPtr pkt)
Writes back the instruction, sending it to IEW.
StoreQueue::iterator storeWBIt
The index of the first instruction that may be ready to be written back, and has not yet been written...
void writebackBlockedStore()
Try to finish a previously blocked write back attempt.
void commitLoads(InstSeqNum &youngest_inst)
Commits loads older than a specific sequence number.
gem5::o3::LSQUnit::LSQUnitStats stats
void completeDataAccess(PacketPtr pkt)
Completes the data access that has been returned from the memory system.
void startStaleTranslationFlush()
LSQ * lsq
Pointer to the LSQ.
bool needsTSO
Flag for memory model.
void commitStores(InstSeqNum &youngest_inst)
Commits stores older than a specific sequence number.
ThreadID lsqID
The LSQUnit thread id.
bool recvTimingResp(PacketPtr pkt)
Handles writing back and completing the load or store that has returned from memory.
virtual bool recvTimingResp(PacketPtr pkt)=0
virtual void buildPackets()=0
virtual RequestPtr mainReq()
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask)=0
Test if the request accesses a particular cache line.
void discard()
The request is discarded (e.g.
PacketPtr packet(int idx=0)
uint32_t _numOutstandingPackets
void packetNotSent()
Update the status to reflect that a packet was not sent.
bool isReleased()
Test if the LSQRequest has been released, i.e.
bool isAnyOutstandingRequest()
Test if there is any in-flight translation or mem access request.
virtual void sendPacketToCache()=0
void packetSent()
Update the status to reflect that a packet was sent.
bool needWBToRegister() const
RequestPtr req(int idx=0)
virtual PacketPtr mainPacket()
const DynInstPtr & instruction()
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
static const Priority Default_Pri
Default is zero for historical reasons.
#define panic(...)
This implements a cprintf based panic() function.
static constexpr int MaxThreads
RefCountingPtr< DynInst > DynInstPtr
const FlagsType nozero
Don't print if this is zero.
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< FaultBase > Fault
void cprintf(const char *format, const Args &...args)
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
std::string htmFailureToStr(HtmFailureFaultCause cause)
Convert enum into string to be used for debug purposes.
uint64_t Tick
Tick count type.
std::string csprintf(const char *format, const Args &...args)
constexpr decltype(nullptr) NoFault
Declaration of the Packet class.
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
statistics::Scalar blockedByCache
Number of times the LSQ is blocked due to the cache.
statistics::Scalar forwLoads
Total number of loads forwaded from LSQ stores.
LSQUnitStats(statistics::Group *parent)
statistics::Scalar addedLoadsAndStores
Total number of loads and stores written to the load store queue.
statistics::Scalar ignoredResponses
Total number of responses from the memory system that are ignored due to the instruction already bein...
statistics::Distribution loadToUse
Distribution of cycle latency between the first time a load is issued and its completion.
statistics::Scalar rescheduledLoads
Number of loads that were rescheduled.
statistics::Scalar squashedStores
Total number of squashed stores.
statistics::Scalar squashedLoads
Total number of squashed loads.
statistics::Scalar memOrderViolation
Tota number of memory ordering violations.