summaryrefslogtreecommitdiff
path: root/src/mem/cache
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2015-07-03 10:14:40 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2015-07-03 10:14:40 -0400
commit0ddde83a47e8a129de1a5c00475772c6ac0fd004 (patch)
tree0b49eb8b61a7a8ce9ec2e0b340999b9b78d8c7ab /src/mem/cache
parent893533a1264bb369b47f74493adf30ce22829f34 (diff)
downloadgem5-0ddde83a47e8a129de1a5c00475772c6ac0fd004.tar.xz
mem: Add ReadCleanReq and ReadSharedReq packets
This patch adds two new read requests packets: ReadCleanReq - For a cache to explicitly request clean data. The response is thus exclusive or shared, but not owned or modified. The read-only caches (see previous patch) use this request type to ensure they do not get dirty data. ReadSharedReq - We add this to distinguish cache read requests from those issued by other masters, such as devices and CPUs. Thus, devices use ReadReq, and caches use ReadCleanReq, ReadExReq, or ReadSharedReq. For the latter, the response can be any state, shared, exclusive, owned or even modified. Both ReadCleanReq and ReadSharedReq re-use the normal ReadResp. The two transactions are aligned with the emerging cache-coherent TLM standard and the AMBA nomenclature. With this change, the normal ReadReq should never be used by a cache, and is reserved for the actual (non-caching) masters in the system. We thus have a way of identifying if a request came from a cache or not. The introduction of ReadSharedReq thus removes the need for the current isTopLevel hack, and also allows us to stop relying on checking the packet size to determine if the source is a cache or not. This is fixed in follow-on patches.
Diffstat (limited to 'src/mem/cache')
-rw-r--r--src/mem/cache/base.cc3
-rw-r--r--src/mem/cache/cache_impl.hh12
2 files changed, 11 insertions, 4 deletions
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index af504d9bc..b1c512079 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -190,7 +190,8 @@ BaseCache::regStats()
// to change the subset of commands that are considered "demand" vs
// "non-demand"
#define SUM_DEMAND(s) \
- (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + s[MemCmd::ReadExReq])
+ (s[MemCmd::ReadReq] + s[MemCmd::WriteReq] + \
+ s[MemCmd::ReadExReq] + s[MemCmd::ReadCleanReq] + s[MemCmd::ReadSharedReq])
// should writebacks be included here? prior code was inconsistent...
#define SUM_NON_DEMAND(s) \
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 5a9205894..1955b9001 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -184,6 +184,10 @@ Cache::satisfyCpuSideRequest(PacketPtr pkt, CacheBlk *blk,
// special handling for coherent block requests from
// upper-level caches
if (pkt->needsExclusive()) {
+ // sanity check
+ assert(pkt->cmd == MemCmd::ReadExReq ||
+ pkt->cmd == MemCmd::SCUpgradeFailReq);
+
// if we have a dirty copy, make sure the recipient
// keeps it marked dirty
if (blk->isDirty()) {
@@ -193,8 +197,9 @@ Cache::satisfyCpuSideRequest(PacketPtr pkt, CacheBlk *blk,
if (blk != tempBlock)
tags->invalidate(blk);
blk->invalidate();
- } else if (blk->isWritable() && !pending_downgrade
- && !pkt->sharedAsserted() && !pkt->req->isInstFetch()) {
+ } else if (blk->isWritable() && !pending_downgrade &&
+ !pkt->sharedAsserted() &&
+ pkt->cmd != MemCmd::ReadCleanReq) {
// we can give the requester an exclusive copy (by not
// asserting shared line) on a read request if:
// - we have an exclusive copy at this level (& below)
@@ -901,7 +906,8 @@ Cache::getBusPacket(PacketPtr cpu_pkt, CacheBlk *blk,
cmd = cpu_pkt->cmd;
} else {
// block is invalid
- cmd = needsExclusive ? MemCmd::ReadExReq : MemCmd::ReadReq;
+ cmd = needsExclusive ? MemCmd::ReadExReq :
+ (isReadOnly ? MemCmd::ReadCleanReq : MemCmd::ReadSharedReq);
}
PacketPtr pkt = new Packet(cpu_pkt->req, cmd, blkSize);