summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Dreslinski <rdreslin@umich.edu>2006-11-12 06:35:39 -0500
committerRon Dreslinski <rdreslin@umich.edu>2006-11-12 06:35:39 -0500
commitc577665040342bf27808bfdea272626e4dac786d (patch)
treea635e61b9b235130f613150706812790258b8414
parentf876bc2bf0e04b888c2748c0cabf8d11b31f41b7 (diff)
downloadgem5-c577665040342bf27808bfdea272626e4dac786d.tar.xz
Fix functional access errors related to delayed respnoses in cachePort
src/mem/cache/base_cache.cc: On a delayed response, be sure to call the fixPacket wrapper to toggle hasData flag. src/mem/packet.cc: src/mem/packet.hh: Create a wrapper to toggle the hasData flag on delayed responses --HG-- extra : convert_revision : 1ced8d4e3dc12a059fb7636d59e429cd3dd46901
-rw-r--r--src/mem/cache/base_cache.cc11
-rw-r--r--src/mem/packet.cc18
-rw-r--r--src/mem/packet.hh14
3 files changed, 39 insertions, 4 deletions
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index 489a24d4c..c16cb6945 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -114,6 +114,8 @@ BaseCache::CachePort::checkFunctional(PacketPtr pkt)
// If the target contains data, and it overlaps the
// probed request, need to update data
if (target->intersect(pkt)) {
+ DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a drain\n",
+ pkt->cmdString(), pkt->getAddr() & ~(cache->getBlockSize() - 1));
notDone = fixPacket(pkt, target);
}
i++;
@@ -126,8 +128,11 @@ BaseCache::CachePort::checkFunctional(PacketPtr pkt)
PacketPtr target = j->second;
// If the target contains data, and it overlaps the
// probed request, need to update data
- if (target->intersect(pkt))
- notDone = fixPacket(pkt, target);
+ if (target->intersect(pkt)) {
+ DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a response\n",
+ pkt->cmdString(), pkt->getAddr() & ~(cache->getBlockSize() - 1));
+ notDone = fixDelayedResponsePacket(pkt, target);
+ }
j++;
}
return notDone;
@@ -348,7 +353,7 @@ BaseCache::CacheEvent::process()
}
return;
}
- //Else it's a response Response
+ //Else it's a response
assert(cachePort->transmitList.size());
assert(cachePort->transmitList.front().first <= curTick);
pkt = cachePort->transmitList.front().second;
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index 938116ab5..e2faf4527 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -144,6 +144,24 @@ Packet::intersect(PacketPtr p)
}
bool
+fixDelayedResponsePacket(PacketPtr func, PacketPtr timing)
+{
+ bool result;
+
+ if (timing->isRead() || timing->isWrite()) {
+ timing->toggleData();
+ result = fixPacket(func, timing);
+ timing->toggleData();
+ }
+ else {
+ //Don't toggle if it isn't a read/write response
+ result = fixPacket(func, timing);
+ }
+
+ return result;
+}
+
+bool
fixPacket(PacketPtr func, PacketPtr timing)
{
Addr funcStart = func->getAddr();
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index cb97dd036..2bc51bf12 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -344,6 +344,13 @@ class Packet
srcValid = false;
}
+
+ void toggleData() {
+ int icmd = (int)cmd;
+ icmd ^= HasData;
+ cmd = (Command)icmd;
+ }
+
/**
* Take a request packet and modify it in place to be suitable for
* returning as a response to that request.
@@ -448,7 +455,6 @@ class Packet
bool intersect(PacketPtr p);
};
-
/** This function given a functional packet and a timing packet either satisfies
* the timing packet, or updates the timing packet to reflect the updated state
* in the timing packet. It returns if the functional packet should continue to
@@ -456,6 +462,12 @@ class Packet
*/
bool fixPacket(PacketPtr func, PacketPtr timing);
+/** This function is a wrapper for the fixPacket field that toggles the hasData bit
+ * it is used when a response is waiting in the caches, but hasn't been marked as a
+ * response yet (so the fixPacket needs to get the correct value for the hasData)
+ */
+bool fixDelayedResponsePacket(PacketPtr func, PacketPtr timing);
+
std::ostream & operator<<(std::ostream &o, const Packet &p);
#endif //__MEM_PACKET_HH