63 #include "debug/Cache.hh" 64 #include "debug/CacheTags.hh" 65 #include "debug/CacheVerbose.hh" 66 #include "enums/Clusivity.hh" 72 #include "params/Cache.hh" 82 bool deferred_response,
bool pending_downgrade)
104 }
else if (blk->
isWritable() && !pending_downgrade &&
119 if (!deferred_response) {
168 if (pkt->
req->isUncacheable()) {
172 "Should never see a write in a read-only cache %s\n",
179 if (old_blk && old_blk->isValid()) {
195 while (!writebacks.empty()) {
230 writebacks.pop_front();
237 while (!writebacks.empty()) {
260 writebacks.pop_front();
280 if (!forwardAsSnoop) {
287 DPRINTF(
Cache,
"Got prefetch response from above for addr " 311 DPRINTF(
Cache,
"packet promoted from Write to WriteLineReq\n");
321 assert(!pkt->
req->isUncacheable());
330 if (pkt->
req->isUncacheable()) {
335 assert(!blk || !blk->
isValid());
370 assert(pkt->
req->hasPaddr());
371 assert(!pkt->
req->isUncacheable());
381 RequestPtr req = std::make_shared<Request>(pkt->
req->getPaddr(),
383 pkt->
req->getFlags(),
384 pkt->
req->masterId());
387 assert(pf->matchAddr(pkt));
388 assert(pf->getSize() == pkt->
getSize());
416 DPRINTF(
Cache,
"Cache above responding to %s: not responding\n",
445 snoop_pkt->headerDelay = snoop_pkt->payloadDelay = 0;
452 snoop_pkt->setExpressSnoop();
453 snoop_pkt->setCacheResponding();
482 bool is_whole_line_write)
const 487 bool blkValid = blk && blk->
isValid();
489 if (cpu_pkt->
req->isUncacheable() ||
504 const bool useUpgrades =
true;
506 if (is_whole_line_write) {
512 }
else if (blkValid && useUpgrades) {
515 assert(needsWritable);
545 if (cpu_pkt->
hasSharers() && !needsWritable) {
551 DPRINTF(
Cache,
"%s: passing hasSharers from %s to %s\n",
572 (pkt->
req->isUncacheable() && pkt->
isWrite())) {
578 assert(!(pkt->
req->isUncacheable() && pkt->
isWrite()) ||
589 bool is_forward = (bus_pkt ==
nullptr);
609 DPRINTF(
Cache,
"%s: Receive response: %s in state %i\n", __func__,
610 bus_pkt->
print(), old_state);
629 blk =
handleFill(bus_pkt, blk, writebacks, allocate);
631 is_invalidate =
false;
633 }
else if (bus_pkt->
isRead() ||
650 if (is_invalidate && blk && blk->
isValid()) {
665 assert(!pkt->
req->isCacheInvalidate());
666 DPRINTF(
Cache,
"Cache above responding to %s: not responding\n",
695 const bool is_error = pkt->
isError();
702 for (
auto &target: targets) {
703 Packet *tgt_pkt = target.pkt;
704 switch (target.source) {
706 Tick completion_time;
736 "read-only cache %s\n",
name());
770 int transfer_offset =
772 if (transfer_offset < 0) {
783 assert(!tgt_pkt->
req->isUncacheable());
788 completion_time - target.recvTime;
799 tgt_pkt->
req->setExtraData(0);
801 if (is_invalidate && blk && blk->
isValid()) {
880 pkt->
req->isCacheMaintenance() ||
886 panic(
"Illegal target->source enum %d\n", target.source);
945 bool already_copied,
bool pending_inval)
963 pkt->makeTimingResponse();
965 pkt->setDataFromBlock(blk_data,
blkSize);
982 pkt->headerDelay = pkt->payloadDelay = 0;
983 DPRINTF(CacheVerbose,
"%s: created response: %s tick: %lu\n", __func__,
984 pkt->print(), forward_time);
990 bool is_deferred,
bool pending_inval)
992 DPRINTF(CacheVerbose,
"%s: for %s\n", __func__, pkt->
print());
994 assert(!(is_deferred && !is_timing));
996 assert(!(pending_inval && !is_deferred));
1009 "%s got an invalidating uncacheable snoop request %s",
1012 uint32_t snoop_delay = 0;
1023 Packet snoopPkt(pkt,
true,
true);
1061 bool respond =
false;
1062 bool blk_valid = blk && blk->
isValid();
1064 if (blk_valid && blk->
isDirty()) {
1065 DPRINTF(CacheVerbose,
"%s: packet (snoop) %s found block: %s\n",
1069 writebacks.push_back(wb_pkt);
1082 }
else if (!blk_valid) {
1083 DPRINTF(CacheVerbose,
"%s: snoop miss for %s\n", __func__,
1099 DPRINTF(
Cache,
"%s: snoop hit for %s, old state is %s\n", __func__,
1112 "a dirty block in a read-only cache %s\n",
name());
1120 DPRINTF(
Cache,
"Found addr %#llx in upper level cache for snoop %s " 1126 if (pkt->
isRead() && !invalidate) {
1128 assert(!needs_writable);
1136 if (!pkt->
req->isUncacheable())
1165 "%s is passing a Modified line through %s, " 1166 "but keeping the block",
name(), pkt->
print());
1185 if (!respond && is_deferred) {
1192 if (blk_valid && invalidate) {
1204 DPRINTF(CacheVerbose,
"%s: for %s\n", __func__, pkt->
print());
1228 DPRINTF(
Cache,
"Setting block cached for %s from lower cache on " 1229 "mshr hit\n", pkt->
print());
1237 DPRINTF(
Cache,
"Deferring snoop on in-service MSHR to blk %#llx (%s)." 1238 "mshrs: %s\n", blk_addr, is_secure ?
"s" :
"ns",
1242 warn(
"allocating bonus target for snoop");
1249 DPRINTF(
Cache,
"Snoop hit in writeback to addr %#llx (%s)\n",
1250 pkt->
getAddr(), is_secure ?
"s" :
"ns");
1266 DPRINTF(
Cache,
"%s: Squashing %s from lower cache on writequeue " 1267 "hit\n", __func__, pkt->
print());
1278 bool have_writable = !wb_pkt->hasSharers();
1281 if (!pkt->
req->isUncacheable() && pkt->
isRead() && !invalidate) {
1284 wb_pkt->setHasSharers();
1290 if (have_writable) {
1311 uint32_t snoop_delay =
handleSnoop(pkt, blk,
true,
false,
false);
1328 uint32_t snoop_delay =
handleSnoop(pkt, blk,
false,
false,
false);
1343 Packet snoop_pkt(pkt,
true,
false);
1380 Packet snoop_pkt(tgt_pkt,
true,
false);
1381 snoop_pkt.setExpressSnoop();
1386 snoop_pkt.senderState = mshr;
1401 if (snoop_pkt.cacheResponding()) {
1407 bool pending_modified_resp = !snoop_pkt.hasSharers();
1416 if (snoop_pkt.isBlockCached()) {
1417 DPRINTF(
Cache,
"Block present, prefetch squashed by cache. " 1418 "Deallocating mshr target %#x.\n",
1439 CacheParams::create()
1442 assert(replacement_policy);
1444 return new Cache(
this);
Miss Status and Handling Register (MSHR) declaration.
virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks)
Does all the processing necessary to perform the provided request.
#define panic(...)
This implements a cprintf based panic() function.
void doWritebacks(PacketList &writebacks, Tick forward_time) override
Insert writebacks into the write buffer.
bool forwardSnoops
Do we forward snoops from mem side port through to cpu side port?
bool isSecure
True if the entry targets the secure memory space.
void setResponderHadWritable()
On responding to a snoop request (which only happens for Modified or Owned lines), make sure that we can transform an Owned response to a Modified one.
bool hasPostInvalidate() const
PacketPtr writebackBlk(CacheBlk *blk)
Create a writeback request for the given block.
void setHasSharers()
On fills, the hasSharers flag is used by the caches in combination with the cacheResponding flag...
bool mustCheckAbove() const
Does the request need to check for cached copies of the same block in the memory hierarchy above...
void recvTimingSnoopReq(PacketPtr pkt) override
Snoops bus transactions to maintain coherence.
State status
The current status of this block.
Cycles is a wrapper class for representing cycle counts, i.e.
void serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk) override
Service non-deferred MSHR targets using the received response.
Tick recvAtomic(PacketPtr pkt) override
Performs the access specified by the request.
Stats::Vector missLatency
Total number of cycles per thread/command spent waiting for a miss.
bool isValid() const
Checks that a block is valid.
bool isWritable() const
Checks the write permissions of this block.
WriteQueue writeBuffer
Write/writeback buffer.
std::string print() const override
Pretty-print tag, set and way, and interpret state bits to readable form including mapping to a MOESI...
uint32_t snoopDelay
Keep track of the extra delay incurred by snooping upwards before sending a request down the memory s...
void makeTimingResponse()
bool forceDeallocateTarget(MSHR *mshr)
Deallocate top target, possibly freeing the MSHR.
int getNumTargets() const
Returns the current number of allocated targets.
const Cycles lookupLatency
The latency of tag lookup of a cache.
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
std::shared_ptr< Request > RequestPtr
bool hasPostDowngrade() const
const Enums::Clusivity clusivity
Clusivity with respect to the upstream cache, determining if we fill into both this cache and the cac...
bool isSWPrefetch() const
Tick sendAtomicSnoop(PacketPtr pkt)
Send an atomic snoop request packet, where the data is moved and the state is updated in zero time...
System * system
System we are currently operating in.
bool cacheResponding() const
void handleTimingReqHit(PacketPtr pkt, CacheBlk *blk, Tick request_time) override
const bool isReadOnly
Is this cache read only, for example the instruction cache, or table-walker cache.
virtual void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time)=0
BaseCache::CacheStats stats
void invalidateBlock(CacheBlk *blk)
Invalidate a cache block.
The request targets the secure memory space.
void doWritebacksAtomic(PacketList &writebacks) override
Send writebacks down the memory hierarchy in atomic mode.
MSHR * allocateMissBuffer(PacketPtr pkt, Tick time, bool sched_send=true)
bool allocate() const
Should writes allocate?
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the slave port by calling its corresponding receive function...
M5_NODISCARD PacketPtr evictBlock(CacheBlk *blk) override
Evict a cache block.
WriteAllocator *const writeAllocator
The writeAllocator drive optimizations for streaming writes.
bool isInvalidate() const
void setSatisfied()
Set when a request hits in a cache and the cache is not going to respond.
#define chatty_assert(cond,...)
The chatty assert macro will function like a normal assert, but will allow the specification of addit...
This master id is used for writeback requests by the caches.
void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time) override
block was a hardware prefetch yet unaccessed
CacheCmdStats & cmdStats(const PacketPtr p)
void schedTimingSnoopResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing snoop response.
bool needsWritable() const
Addr getBlockAddr(unsigned int blk_size) const
bool isUncacheable() const
RequestPtr req
A pointer to the original request.
const Cycles responseLatency
The latency of sending reponse to its upper level cache/core on a linefill.
bool isBlockCached() const
virtual void recvTimingReq(PacketPtr pkt)
Performs the access specified by the request.
A coherent cache that can be arranged in flexible topologies.
virtual Tick recvAtomic(PacketPtr pkt)
Performs the access specified by the request.
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...
bool needsResponse() const
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Addr getOffset(unsigned int blk_size) const
bool inRange(Addr addr) const
Determine if an address is in the ranges covered by this cache.
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
void makeAtomicResponse()
PacketPtr cleanEvictBlk(CacheBlk *blk)
Create a CleanEvict request for the given block.
bool sendMSHRQueuePacket(MSHR *mshr) override
Take an MSHR, turn it into a suitable downstream packet, and send it out.
uint64_t Tick
Tick count type.
Target * getTarget() override
Returns a reference to the first target.
PacketPtr writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id)
Create a writeclean request for the given block.
unsigned State
block state: OR of CacheBlkStatusBit
bool isSecure() const
Check if this block holds data from the secure memory space.
Miss Status and handling Register.
virtual void recvTimingResp(PacketPtr pkt)
Handles a response (cache line fill/write ack) from the bus.
void recvTimingSnoopResp(PacketPtr pkt) override
Handle a snoop response.
QueueEntry::Target * getTarget() override
Returns a reference to the first target.
bool isCachedAbove(PacketPtr pkt, bool is_timing=true)
Send up a snoop request and find cached copies.
void copyResponderFlags(const PacketPtr pkt)
Copy the reponse flags from an input packet to this packet.
void recvTimingReq(PacketPtr pkt) override
Performs the access specified by the request.
std::unique_ptr< Packet > pendingDelete
Upstream caches need this packet until true is returned, so hold it for deletion until a subsequent c...
void allocateWriteBuffer(PacketPtr pkt, Tick time)
virtual void handleTimingReqHit(PacketPtr pkt, CacheBlk *blk, Tick request_time)
void promoteWholeLineWrites(PacketPtr pkt)
Turn line-sized writes into WriteInvalidate transactions.
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Tick recvAtomicSnoop(PacketPtr pkt) override
Snoop for the provided request in the cache and return the estimated time taken.
CacheBlk * handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks, bool allocate)
Handle a fill operation caused by a received packet.
virtual const std::string name() const
const bool writebackClean
Determine if clean lines should be written back or not.
const unsigned blkSize
Block size of this cache.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Entry * findMatch(Addr blk_addr, bool is_secure, bool ignore_uncacheable=true) const
Find the first entry that matches the provided address.
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...
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...
uint64_t order
Increasing order number assigned to each incoming request.
bool responderHadWritable() const
A queue entry is holding packets that will be serviced as soon as resources are available.
virtual M5_NODISCARD PacketPtr evictBlock(CacheBlk *blk)=0
Evict a cache block.
MasterID maxMasters()
Get the number of masters registered in the system.
bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks) override
Does all the processing necessary to perform the provided request.
bool isMaskedWrite() const
Definitions of a simple cache block class.
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...
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...
bool wasWholeLineWrite
Track if we sent this as a whole line write or not.
bool allocOnFill(MemCmd cmd) const
Determine whether we should allocate on a fill or not.
Cycles ticksToCycles(Tick t) const
Addr blkAddr
Block aligned address.
bool handleSnoop(PacketPtr target, Counter order)
Cache(const CacheParams *p)
Instantiates a basic cache object.
void doTimingSupplyResponse(PacketPtr req_pkt, const uint8_t *blk_data, bool already_copied, bool pending_inval)
SenderState * senderState
This packet's sender state.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
MemCmd cmd
The command field of the packet.
TargetList extractServiceableTargets(PacketPtr pkt)
Extracts the subset of the targets that can be serviced given a received response.
bool isForward
True if the entry is just a simple forward from an upper level.
int getNumTargets() const
Returns the current number of allocated targets.
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)...
Cycles getDecompressionLatency(const CacheBlk *blk)
Get the decompression latency if the block is compressed.
const bool doFastWrites
This cache should allocate a block on a line-sized write miss.
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 sendTimingSnoopReq(PacketPtr pkt)
Attempt to send a timing snoop request packet to the master port by calling its corresponding receive...
Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk, PacketList &writebacks) override
Handle a request in atomic mode that missed in this cache.
const PacketPtr pkt
Pending request packet.
void print(std::ostream &os, int verbosity=0, const std::string &prefix="") const override
Prints the contents of this MSHR for debugging.
const int numTarget
The number of targets for each MSHR.
const T * getConstPtr() const
virtual bool sendMSHRQueuePacket(MSHR *mshr)
Take an MSHR, turn it into a suitable downstream packet, and send it out.
uint32_t task_id
Task Id associated with this block.
const Cycles forwardLatency
This is the forward latency of the cache.
std::unordered_set< RequestPtr > outstandingSnoop
Store the outstanding requests that we are expecting snoop responses from so we can determine which s...
void copyError(Packet *pkt)
void setExpressSnoop()
The express snoop flag is used for two purposes.
Addr regenerateBlkAddr(CacheBlk *blk)
Regenerate block address using tags.
static const int NumArgumentRegs M5_VAR_USED
bool isWholeLineWrite(unsigned blk_size)
BaseCacheCompressor * compressor
Compression method being used.
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
bool matchAddr(const Addr addr, const bool is_secure) const
Check if packet corresponds to a given address and address space.
uint8_t * data
Contains a copy of the data in this block for easy access.
BaseTags * tags
Tag and data Storage.
void allocate()
Allocate memory for the packet.
Stats::Vector mshr_uncacheable
Number of misses that miss in the MSHRs, per command and thread.
void clearBlocked(BlockedCause cause)
Marks the cache as unblocked for the given cause.
ProbePointArg< PacketInfo > Packet
Packet probe point.
MSHRQueue mshrQueue
Miss status registers.
void maintainClusivity(bool from_cache, CacheBlk *blk)
Maintain the clusivity of this cache by potentially invalidating a block.
bool isDirty() const
Check to see if a block has been written.
void setCacheResponding()
Snoop flags.