From c577665040342bf27808bfdea272626e4dac786d Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Sun, 12 Nov 2006 06:35:39 -0500 Subject: [PATCH] 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 --- src/mem/cache/base_cache.cc | 11 ++++++++--- src/mem/packet.cc | 18 ++++++++++++++++++ src/mem/packet.hh | 14 +++++++++++++- 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 @@ -143,6 +143,24 @@ Packet::intersect(PacketPtr p) return !(s1 > e2 || e1 < s2); } +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) { 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