55#include "debug/Cache.hh"
56#include "debug/CacheTags.hh"
57#include "debug/CacheVerbose.hh"
58#include "enums/Clusivity.hh"
64#include "params/Cache.hh"
74 assert(
p.replacement_policy);
79 bool deferred_response,
bool pending_downgrade)
116 if (!deferred_response) {
165 if (pkt->
req->isUncacheable()) {
169 "Should never see a write in a read-only cache %s\n",
176 if (old_blk && old_blk->
isValid()) {
192 while (!writebacks.empty()) {
227 writebacks.pop_front();
234 while (!writebacks.empty()) {
257 writebacks.pop_front();
277 if (!forwardAsSnoop) {
284 DPRINTF(
Cache,
"Got prefetch response from above for addr "
308 DPRINTF(
Cache,
"packet promoted from Write to WriteLineReq\n");
318 assert(!pkt->
req->isUncacheable());
330 if (pkt->
req->isUncacheable()) {
335 assert(!blk || !blk->
isValid());
382 assert(pkt->
req->hasPaddr());
383 assert(!pkt->
req->isUncacheable());
393 RequestPtr req = std::make_shared<Request>(pkt->
req->getPaddr(),
395 pkt->
req->getFlags(),
396 pkt->
req->requestorId());
399 assert(
pf->matchAddr(pkt));
428 DPRINTF(
Cache,
"Cache above responding to %s: not responding\n",
494 bool is_whole_line_write)
const
499 bool blkValid = blk && blk->
isValid();
501 if (cpu_pkt->
req->isUncacheable() ||
516 const bool useUpgrades =
true;
518 if (is_whole_line_write) {
524 }
else if (blkValid && useUpgrades) {
527 assert(needsWritable);
557 if (cpu_pkt->
hasSharers() && !needsWritable) {
563 DPRINTF(
Cache,
"%s: passing hasSharers from %s to %s\n",
584 (pkt->
req->isUncacheable() && pkt->
isWrite())) {
590 assert(!(pkt->
req->isUncacheable() && pkt->
isWrite()) ||
601 bool is_forward = (bus_pkt ==
nullptr);
612 const std::string old_state = blk ? blk->
print() :
"";
619 DPRINTF(
Cache,
"%s: Receive response: %s for %s\n", __func__,
620 bus_pkt->
print(), old_state);
639 blk =
handleFill(bus_pkt, blk, writebacks, allocate);
641 is_invalidate =
false;
643 }
else if (bus_pkt->
isRead() ||
660 if (is_invalidate && blk && blk->
isValid()) {
675 assert(!pkt->
req->isCacheInvalidate());
676 DPRINTF(
Cache,
"Cache above responding to %s: not responding\n",
705 const bool is_error = pkt->
isError();
711 bool from_core =
false;
712 bool from_pref =
false;
725 delete initial_tgt->
pkt;
726 initial_tgt =
nullptr;
730 for (
auto &target: targets) {
731 Packet *tgt_pkt = target.pkt;
732 switch (target.source) {
736 Tick completion_time;
766 "read-only cache %s\n",
name());
800 int transfer_offset =
802 if (transfer_offset < 0) {
813 assert(!tgt_pkt->
req->isUncacheable());
818 completion_time - target.recvTime;
844 tgt_pkt->
req->setExtraData(0);
851 if (is_invalidate && blk && blk->
isValid()) {
930 pkt->
req->isCacheMaintenance() ||
936 panic(
"Illegal target->source enum %d\n", target.source);
940 if (blk && !from_core && from_pref) {
1001 bool already_copied,
bool pending_inval)
1011 if (!already_copied)
1039 DPRINTF(CacheVerbose,
"%s: created response: %s tick: %lu\n", __func__,
1040 pkt->
print(), forward_time);
1046 bool is_deferred,
bool pending_inval)
1048 DPRINTF(CacheVerbose,
"%s: for %s\n", __func__, pkt->
print());
1050 assert(!(is_deferred && !is_timing));
1052 assert(!(pending_inval && !is_deferred));
1059 [[maybe_unused]]
bool needs_writable = pkt->
needsWritable();
1065 "%s got an invalidating uncacheable snoop request %s",
1068 uint32_t snoop_delay = 0;
1079 Packet snoopPkt(pkt,
true,
true);
1117 bool respond =
false;
1118 bool blk_valid = blk && blk->
isValid();
1121 DPRINTF(CacheVerbose,
"%s: packet (snoop) %s found block: %s\n",
1126 writebacks.push_back(wb_pkt);
1139 }
else if (!blk_valid) {
1140 DPRINTF(CacheVerbose,
"%s: snoop miss for %s\n", __func__,
1156 DPRINTF(
Cache,
"%s: snoop hit for %s, old state is %s\n", __func__,
1169 "Should never have a dirty block in a read-only cache %s\n",
1178 DPRINTF(
Cache,
"Found addr %#llx in upper level cache for snoop %s "
1184 if (pkt->
isRead() && !invalidate) {
1186 assert(!needs_writable);
1194 if (!pkt->
req->isUncacheable()) {
1224 "%s is passing a Modified line through %s, "
1225 "but keeping the block",
name(), pkt->
print());
1244 if (!respond && is_deferred) {
1251 if (blk_valid && invalidate) {
1263 DPRINTF(CacheVerbose,
"%s: for %s\n", __func__, pkt->
print());
1287 DPRINTF(
Cache,
"Setting block cached for %s from lower cache on "
1288 "mshr hit\n", pkt->
print());
1296 DPRINTF(
Cache,
"Deferring snoop on in-service MSHR to blk %#llx (%s)."
1297 "mshrs: %s\n", blk_addr, is_secure ?
"s" :
"ns",
1301 warn(
"allocating bonus target for snoop");
1308 DPRINTF(
Cache,
"Snoop hit in writeback to addr %#llx (%s)\n",
1309 pkt->
getAddr(), is_secure ?
"s" :
"ns");
1325 DPRINTF(
Cache,
"%s: Squashing %s from lower cache on writequeue "
1326 "hit\n", __func__, pkt->
print());
1340 if (!pkt->
req->isUncacheable() && pkt->
isRead() && !invalidate) {
1349 if (have_writable) {
1370 uint32_t snoop_delay =
handleSnoop(pkt, blk,
true,
false,
false);
1387 uint32_t snoop_delay =
handleSnoop(pkt, blk,
false,
false,
false);
1402 Packet snoop_pkt(pkt,
true,
false);
1439 Packet snoop_pkt(tgt_pkt,
true,
false);
1466 bool pending_modified_resp = !snoop_pkt.
hasSharers();
1476 DPRINTF(
Cache,
"Block present, prefetch squashed by cache. "
1477 "Deallocating mshr target %#x.\n",
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
Definitions of a simple cache block class.
const bool isReadOnly
Is this cache read only, for example the instruction cache, or table-walker cache.
virtual void recvTimingReq(PacketPtr pkt)
Performs the access specified by the request.
MSHR * allocateMissBuffer(PacketPtr pkt, Tick time, bool sched_send=true)
void invalidateBlock(CacheBlk *blk)
Invalidate a cache block.
const bool writebackClean
Determine if clean lines should be written back or not.
bool inRange(Addr addr) const
Determine if an address is in the ranges covered by this cache.
virtual void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time)=0
bool allocOnFill(MemCmd cmd) const
Determine whether we should allocate on a fill or not.
bool forwardSnoops
Do we forward snoops from mem side port through to cpu side port?
uint64_t order
Increasing order number assigned to each incoming request.
virtual void satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool deferred_response=false, bool pending_downgrade=false)
Perform any necessary updates to the block and perform any data exchange between the packet and the b...
gem5::BaseCache::CacheStats stats
const Cycles lookupLatency
The latency of tag lookup of a cache.
MSHRQueue mshrQueue
Miss status registers.
const unsigned blkSize
Block size of this cache.
const Cycles forwardLatency
This is the forward latency of the cache.
compression::Base * compressor
Compression method being used.
const Cycles responseLatency
The latency of sending reponse to its upper level cache/core on a linefill.
PacketPtr writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id)
Create a writeclean request for the given block.
virtual void handleTimingReqHit(PacketPtr pkt, CacheBlk *blk, Tick request_time)
virtual Tick recvAtomic(PacketPtr pkt)
Performs the access specified by the request.
virtual void recvTimingResp(PacketPtr pkt)
Handles a response (cache line fill/write ack) from the bus.
virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks)
Does all the processing necessary to perform the provided request.
Addr regenerateBlkAddr(CacheBlk *blk)
Regenerate block address using tags.
std::unique_ptr< Packet > pendingDelete
Upstream caches need this packet until true is returned, so hold it for deletion until a subsequent c...
const int numTarget
The number of targets for each MSHR.
WriteAllocator *const writeAllocator
The writeAllocator drive optimizations for streaming writes.
void markInService(MSHR *mshr, bool pending_modified_resp)
Mark a request as in service (sent downstream in the memory system), effectively making this MSHR the...
void allocateWriteBuffer(PacketPtr pkt, Tick time)
CacheBlk * handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks, bool allocate)
Handle a fill operation caused by a received packet.
WriteQueue writeBuffer
Write/writeback buffer.
PacketPtr writebackBlk(CacheBlk *blk)
Create a writeback request for the given block.
void clearBlocked(BlockedCause cause)
Marks the cache as unblocked for the given cause.
virtual PacketPtr evictBlock(CacheBlk *blk)=0
Evict a cache block.
BaseTags * tags
Tag and data Storage.
const enums::Clusivity clusivity
Clusivity with respect to the upstream cache, determining if we fill into both this cache and the cac...
virtual bool sendMSHRQueuePacket(MSHR *mshr)
Take an MSHR, turn it into a suitable downstream packet, and send it out.
void maintainClusivity(bool from_cache, CacheBlk *blk)
Maintain the clusivity of this cache by potentially invalidating a block.
System * system
System we are currently operating in.
@ ReadableBit
Read permission.
@ WritableBit
write permission
@ DirtyBit
dirty (modified)
void setPrefetched()
Marks this blocks as a recently prefetched block.
std::string print() const override
Pretty-print tag, set and way, and interpret state bits to readable form including mapping to a MOESI...
bool isSet(unsigned bits) const
Checks the given coherence bits are set.
void clearCoherenceBits(unsigned bits)
Clear the corresponding coherence bits.
uint32_t getTaskId() const
Get the task id associated to this block.
uint8_t * data
Contains a copy of the data in this block for easy access.
void setCoherenceBits(unsigned bits)
Sets the corresponding coherence bits.
virtual bool isValid() const
Checks if the entry is valid.
A coherent cache that can be arranged in flexible topologies.
PacketPtr cleanEvictBlk(CacheBlk *blk)
Create a CleanEvict request for the given block.
Cache(const CacheParams &p)
Instantiates a basic cache object.
void recvTimingSnoopReq(PacketPtr pkt) override
Snoops bus transactions to maintain coherence.
bool isCachedAbove(PacketPtr pkt, bool is_timing=true)
Send up a snoop request and find cached copies.
void promoteWholeLineWrites(PacketPtr pkt)
Turn line-sized writes into WriteInvalidate transactions.
void serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk) override
Service non-deferred MSHR targets using the received response.
Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk, PacketList &writebacks) override
Handle a request in atomic mode that missed in this cache.
Tick recvAtomicSnoop(PacketPtr pkt) override
Snoop for the provided request in the cache and return the estimated time taken.
std::unordered_set< RequestPtr > outstandingSnoop
Store the outstanding requests that we are expecting snoop responses from so we can determine which s...
void satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool deferred_response=false, bool pending_downgrade=false) override
Perform any necessary updates to the block and perform any data exchange between the packet and the b...
void recvTimingSnoopResp(PacketPtr pkt) override
Handle a snoop response.
void recvTimingReq(PacketPtr pkt) override
Performs the access specified by the request.
Tick recvAtomic(PacketPtr pkt) override
Performs the access specified by the request.
void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time) override
bool sendMSHRQueuePacket(MSHR *mshr) override
Take an MSHR, turn it into a suitable downstream packet, and send it out.
void doTimingSupplyResponse(PacketPtr req_pkt, const uint8_t *blk_data, bool already_copied, bool pending_inval)
PacketPtr createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, bool needs_writable, bool is_whole_line_write) const override
Create an appropriate downstream bus request packet.
void handleTimingReqHit(PacketPtr pkt, CacheBlk *blk, Tick request_time) override
uint32_t handleSnoop(PacketPtr pkt, CacheBlk *blk, bool is_timing, bool is_deferred, bool pending_inval)
Perform an upward snoop if needed, and update the block state (possibly invalidating the block).
PacketPtr evictBlock(CacheBlk *blk) override
Evict a cache block.
const bool doFastWrites
This cache should allocate a block on a line-sized write miss.
void doWritebacks(PacketList &writebacks, Tick forward_time) override
Insert writebacks into the write buffer.
bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks) override
Does all the processing necessary to perform the provided request.
void doWritebacksAtomic(PacketList &writebacks) override
Send writebacks down the memory hierarchy in atomic mode.
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles ticksToCycles(Tick t) const
Cycles is a wrapper class for representing cycle counts, i.e.
bool forceDeallocateTarget(MSHR *mshr)
Deallocate top target, possibly freeing the MSHR.
bool hasFromCache
Determine whether there was at least one non-snooping target coming from another cache.
Miss Status and handling Register.
bool wasWholeLineWrite
Track if we sent this as a whole line write or not.
void updateLockedRMWReadTarget(PacketPtr pkt)
Replaces the matching packet in the Targets list with a dummy packet to ensure the MSHR remains alloc...
TargetList extractServiceableTargets(PacketPtr pkt)
Extracts the subset of the targets that can be serviced given a received response.
void popTarget()
Pop first target.
void print(std::ostream &os, int verbosity=0, const std::string &prefix="") const override
Prints the contents of this MSHR for debugging.
int getNumTargets() const
Returns the current number of allocated targets.
bool hasPostDowngrade() const
QueueEntry::Target * getTarget() override
Returns a reference to the first target.
bool handleSnoop(PacketPtr target, Counter order)
bool isForward
True if the entry is just a simple forward from an upper level.
bool hasLockedRMWReadTarget()
Determine if there are any LockedRMWReads in the Targets list.
bool hasPostInvalidate() const
bool isSWPrefetch() const
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setExpressSnoop()
The express snoop flag is used for two purposes.
bool responderHadWritable() const
uint32_t snoopDelay
Keep track of the extra delay incurred by snooping upwards before sending a request down the memory s...
void makeTimingResponse()
bool needsWritable() const
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
void copyError(Packet *pkt)
bool needsResponse() const
SenderState * senderState
This packet's sender state.
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
bool matchAddr(const Addr addr, const bool is_secure) const
Check if packet corresponds to a given address and address space.
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
void setResponderHadWritable()
On responding to a snoop request (which only happens for Modified or Owned lines),...
Addr getOffset(unsigned int blk_size) const
bool mustCheckAbove() const
Does the request need to check for cached copies of the same block in the memory hierarchy above.
void copyResponderFlags(const PacketPtr pkt)
Copy the reponse flags from an input packet to this packet.
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
void setDataFromBlock(const uint8_t *blk_data, int blkSize)
Copy data into the packet from the provided block pointer, which is aligned to the given block size.
Addr getBlockAddr(unsigned int blk_size) const
RequestPtr req
A pointer to the original request.
bool isCleanInvalidateRequest() const
Is this packet a clean invalidate request, e.g., clflush/clflushopt?
void setCacheResponding()
Snoop flags.
const T * getConstPtr() const
void setHasSharers()
On fills, the hasSharers flag is used by the caches in combination with the cacheResponding flag,...
bool cacheResponding() const
void makeAtomicResponse()
void setSatisfied()
Set when a request hits in a cache and the cache is not going to respond.
MemCmd cmd
The command field of the packet.
bool isMaskedWrite() const
bool isInvalidate() const
bool isWholeLineWrite(unsigned blk_size)
bool isBlockCached() const
void allocate()
Allocate memory for the packet.
A queue entry is holding packets that will be serviced as soon as resources are available.
PacketPtr pkt
Pending request packet.
bool isUncacheable() const
Addr blkAddr
Block aligned address.
bool isSecure
True if the entry targets the secure memory space.
Entry * findMatch(Addr blk_addr, bool is_secure, bool ignore_uncacheable=true) const
Find the first entry that matches the provided address.
void schedTimingSnoopResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing snoop response.
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
@ SECURE
The request targets the secure memory space.
@ wbRequestorId
This requestor id is used for writeback requests by the caches.
Tick sendAtomicSnoop(PacketPtr pkt)
Send an atomic snoop request packet, where the data is moved and the state is updated in zero time,...
void sendTimingSnoopReq(PacketPtr pkt)
Attempt to send a timing snoop request packet to the request port by calling its corresponding receiv...
RequestorID maxRequestors()
Get the number of requestors registered in the system.
bool isSecure() const
Check if this block holds data from the secure memory space.
bool allocate() const
Should writes allocate?
int getNumTargets() const
Returns the current number of allocated targets.
Target * getTarget() override
Returns a reference to the first target.
Cycles getDecompressionLatency(const CacheBlk *blk)
Get the decompression latency if the block is compressed.
#define panic(...)
This implements a cprintf based panic() function.
#define gem5_assert(cond,...)
The assert macro will function like a normal assert, but will use panic instead of straight abort().
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Miss Status and Handling Register (MSHR) declaration.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::shared_ptr< Request > RequestPtr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t Tick
Tick count type.
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
statistics::Vector missLatency
Total number of ticks per thread/command spent waiting for a miss.
statistics::Vector mshrUncacheable
Number of misses that miss in the MSHRs, per command and thread.
CacheCmdStats & cmdStats(const PacketPtr p)