summaryrefslogtreecommitdiff
path: root/src/mem/cache
diff options
context:
space:
mode:
authorNikos Nikoleris <nikos.nikoleris@arm.com>2016-09-22 10:07:11 +0100
committerNikos Nikoleris <nikos.nikoleris@arm.com>2017-12-05 11:47:01 +0000
commit992fa9958da913aa1a40c78dd566d6498ee7d610 (patch)
tree6c5447e40b33e21029089f869096b65678a91906 /src/mem/cache
parent2f6d69ee08bd92d9fcfb9b78f84b2d7c0ba113d0 (diff)
downloadgem5-992fa9958da913aa1a40c78dd566d6498ee7d610.tar.xz
mem: Support for specifying the destination of a WriteClean
Previously, WriteClean packets would always write to the first memory below unless the memory was unable to allocate in which case it would be forwarded further below. This change adds support for specifying the destination of a WriteClean packet. The cache annotates the request with the specified destination and marks the packet as write-through upon its creation. The coherent xbar checks packets for their destination and resets the write-through flag when necessary e.g., the coherent xbar that is set as the PoC will reset the write-through flag for packets to the PoC. Change-Id: I84b653f5cb6e46e97e09508649a3725d72d94606 Reviewed-by: Curtis Dunham <curtis.dunham@arm.com> Reviewed-by: Anouk Van Laer <anouk.vanlaer@arm.com> Reviewed-on: https://gem5-review.googlesource.com/5046 Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Diffstat (limited to 'src/mem/cache')
-rw-r--r--src/mem/cache/cache.cc44
-rw-r--r--src/mem/cache/cache.hh3
2 files changed, 31 insertions, 16 deletions
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc
index 74c488084..97df5625b 100644
--- a/src/mem/cache/cache.cc
+++ b/src/mem/cache/cache.cc
@@ -430,20 +430,26 @@ Cache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
assert(blkSize == pkt->getSize());
if (!blk) {
- // a writeback that misses needs to allocate a new block
- blk = allocateBlock(pkt->getAddr(), pkt->isSecure(),
- writebacks);
- if (!blk) {
- // no replaceable block available: give up, fwd to
- // next level.
- incMissCount(pkt);
+ if (pkt->writeThrough()) {
+ // if this is a write through packet, we don't try to
+ // allocate if the block is not present
return false;
- }
- tags->insertBlock(pkt, blk);
+ } else {
+ // a writeback that misses needs to allocate a new block
+ blk = allocateBlock(pkt->getAddr(), pkt->isSecure(),
+ writebacks);
+ if (!blk) {
+ // no replaceable block available: give up, fwd to
+ // next level.
+ incMissCount(pkt);
+ return false;
+ }
+ tags->insertBlock(pkt, blk);
- blk->status = (BlkValid | BlkReadable);
- if (pkt->isSecure()) {
- blk->status |= BlkSecure;
+ blk->status = (BlkValid | BlkReadable);
+ if (pkt->isSecure()) {
+ blk->status |= BlkSecure;
+ }
}
}
@@ -451,7 +457,9 @@ Cache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
// write clean operation and the block is already in this
// cache, we need to update the data and the block flags
assert(blk);
- blk->status |= BlkDirty;
+ if (!pkt->writeThrough()) {
+ blk->status |= BlkDirty;
+ }
// nothing else to do; writeback doesn't expect response
assert(!pkt->needsResponse());
std::memcpy(blk->data, pkt->getConstPtr<uint8_t>(), blkSize);
@@ -461,7 +469,9 @@ Cache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
// populate the time when the block will be ready to access.
blk->whenReady = clockEdge(fillLatency) + pkt->headerDelay +
pkt->payloadDelay;
- return true;
+ // if this a write-through packet it will be sent to cache
+ // below
+ return !pkt->writeThrough();
} else if (blk && (pkt->needsWritable() ? blk->isWritable() :
blk->isReadable())) {
// OK to satisfy access
@@ -1623,7 +1633,7 @@ Cache::writebackBlk(CacheBlk *blk)
}
PacketPtr
-Cache::writecleanBlk(CacheBlk *blk)
+Cache::writecleanBlk(CacheBlk *blk, Request::Flags dest)
{
Request *req = new Request(tags->regenerateBlkAddr(blk->tag, blk->set),
blkSize, 0, Request::wbMasterId);
@@ -1641,6 +1651,10 @@ Cache::writecleanBlk(CacheBlk *blk)
// We inform the cache below that the block has sharers in the
// system as we retain our copy.
pkt->setHasSharers();
+ if (dest) {
+ req->setFlags(dest);
+ pkt->setWriteThrough();
+ }
std::memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
return pkt;
}
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index bbbda500b..cd3a1d8e5 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -455,9 +455,10 @@ class Cache : public BaseCache
/**
* Create a writeclean request for the given block.
* @param blk The block to write clean
+ * @param dest The destination of this clean operation
* @return The write clean packet for the block.
*/
- PacketPtr writecleanBlk(CacheBlk *blk);
+ PacketPtr writecleanBlk(CacheBlk *blk, Request::Flags dest = 0);
/**
* Create a CleanEvict request for the given block.