summaryrefslogtreecommitdiff
path: root/src/mem/coherent_xbar.cc
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/coherent_xbar.cc
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/coherent_xbar.cc')
-rw-r--r--src/mem/coherent_xbar.cc40
1 files changed, 38 insertions, 2 deletions
diff --git a/src/mem/coherent_xbar.cc b/src/mem/coherent_xbar.cc
index 6aec0b335..e946134d3 100644
--- a/src/mem/coherent_xbar.cc
+++ b/src/mem/coherent_xbar.cc
@@ -183,6 +183,12 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
// determine how long to be crossbar layer is busy
Tick packetFinishTime = clockEdge(Cycles(1)) + pkt->payloadDelay;
+ // is this the destination point for this packet? (e.g. true if
+ // this xbar is the PoC for a cache maintenance operation to the
+ // PoC) otherwise the destination is any cache that can satisfy
+ // the request
+ const bool is_destination = isDestination(pkt);
+
const bool snoop_caches = !system->bypassCaches() &&
pkt->cmd != MemCmd::WriteClean;
if (snoop_caches) {
@@ -243,7 +249,7 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
} else {
// determine if we are forwarding the packet, or responding to
// it
- if (!pointOfCoherency || pkt->isRead() || pkt->isWrite()) {
+ if (forwardPacket(pkt)) {
// if we are passing on, rather than sinking, a packet to
// which an upstream cache has committed to responding,
// the line was needs writable, and the responding only
@@ -253,6 +259,13 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
pkt->setExpressSnoop();
}
+ // make sure that the write request (e.g., WriteClean)
+ // will stop at the memory below if this crossbar is its
+ // destination
+ if (pkt->isWrite() && is_destination) {
+ pkt->clearWriteThrough();
+ }
+
// since it is a normal request, attempt to send the packet
success = masterPorts[master_port_id]->sendTimingReq(pkt);
} else {
@@ -646,6 +659,12 @@ CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
MemCmd snoop_response_cmd = MemCmd::InvalidCmd;
Tick snoop_response_latency = 0;
+ // is this the destination point for this packet? (e.g. true if
+ // this xbar is the PoC for a cache maintenance operation to the
+ // PoC) otherwise the destination is any cache that can satisfy
+ // the request
+ const bool is_destination = isDestination(pkt);
+
const bool snoop_caches = !system->bypassCaches() &&
pkt->cmd != MemCmd::WriteClean;
if (snoop_caches) {
@@ -698,7 +717,14 @@ CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
DPRINTF(CoherentXBar, "%s: Not forwarding %s\n", __func__,
pkt->print());
} else {
- if (!pointOfCoherency || pkt->isRead() || pkt->isWrite()) {
+ if (forwardPacket(pkt)) {
+ // make sure that the write request (e.g., WriteClean)
+ // will stop at the memory below if this crossbar is its
+ // destination
+ if (pkt->isWrite() && is_destination) {
+ pkt->clearWriteThrough();
+ }
+
// forward the request to the appropriate destination
response_latency = masterPorts[master_port_id]->sendAtomic(pkt);
} else {
@@ -958,6 +984,16 @@ CoherentXBar::sinkPacket(const PacketPtr pkt) const
(!pkt->needsWritable() || pkt->responderHadWritable()));
}
+bool
+CoherentXBar::forwardPacket(const PacketPtr pkt)
+{
+ // we are forwarding the packet if:
+ // 1) this is a read or a write
+ // 2) this crossbar is above the point of coherency
+ return pkt->isRead() || pkt->isWrite() || !pointOfCoherency;
+}
+
+
void
CoherentXBar::regStats()
{