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
This commit is contained in:
parent
f876bc2bf0
commit
c577665040
3 changed files with 39 additions and 4 deletions
11
src/mem/cache/base_cache.cc
vendored
11
src/mem/cache/base_cache.cc
vendored
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue