mem: Fix the snoop filter when there is a downstream addr mapper

The snoop filter handles requests in two steps which preceed and
follow the call to send the packet downstream. An address mapper could
possibly change the address of the packet when it is sent downstream
breaking the snoop filter assumption that the address is unchanged

Change-Id: Ib2db755e9ebef4f2f7c0169a46b1b11185ffbe79
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Nikos Nikoleris 2016-06-20 15:11:18 +01:00
parent dd0f54fed6
commit 40e4453ddc
3 changed files with 9 additions and 8 deletions

View file

@ -115,7 +115,6 @@ CoherentXBar::~CoherentXBar()
void void
CoherentXBar::init() CoherentXBar::init()
{ {
// the base class is responsible for determining the block size
BaseXBar::init(); BaseXBar::init();
// iterate over our slave ports and determine which of our // iterate over our slave ports and determine which of our
@ -233,7 +232,9 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
// in certain cases the crossbar is responsible for responding // in certain cases the crossbar is responsible for responding
bool respond_directly = false; bool respond_directly = false;
// store the original address as an address mapper could possibly
// modify the address upon a sendTimingRequest
const Addr addr(pkt->getAddr());
if (sink_packet) { if (sink_packet) {
DPRINTF(CoherentXBar, "Not forwarding %s to %#llx\n", DPRINTF(CoherentXBar, "Not forwarding %s to %#llx\n",
pkt->cmdString(), pkt->getAddr()); pkt->cmdString(), pkt->getAddr());
@ -265,7 +266,7 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
if (snoopFilter && !system->bypassCaches()) { if (snoopFilter && !system->bypassCaches()) {
// Let the snoop filter know about the success of the send operation // Let the snoop filter know about the success of the send operation
snoopFilter->finishRequest(!success, pkt); snoopFilter->finishRequest(!success, addr);
} }
// check if we were successful in sending the packet onwards // check if we were successful in sending the packet onwards
@ -660,7 +661,7 @@ CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
// operation, and do it even before sending it onwards to // operation, and do it even before sending it onwards to
// avoid situations where atomic upward snoops sneak in // avoid situations where atomic upward snoops sneak in
// between and change the filter state // between and change the filter state
snoopFilter->finishRequest(false, pkt); snoopFilter->finishRequest(false, pkt->getAddr());
snoop_result = forwardAtomic(pkt, slave_port_id, InvalidPortID, snoop_result = forwardAtomic(pkt, slave_port_id, InvalidPortID,
sf_res.first); sf_res.first);

View file

@ -146,12 +146,12 @@ SnoopFilter::lookupRequest(const Packet* cpkt, const SlavePort& slave_port)
} }
void void
SnoopFilter::finishRequest(bool will_retry, const Packet* cpkt) SnoopFilter::finishRequest(bool will_retry, const Addr addr)
{ {
if (reqLookupResult != cachedLocations.end()) { if (reqLookupResult != cachedLocations.end()) {
// since we rely on the caller, do a basic check to ensure // since we rely on the caller, do a basic check to ensure
// that finishRequest is being called following lookupRequest // that finishRequest is being called following lookupRequest
assert(reqLookupResult->first == cpkt->getBlockAddr(linesize)); assert(reqLookupResult->first == (addr & ~(Addr(linesize - 1))));
if (will_retry) { if (will_retry) {
// Undo any changes made in lookupRequest to the snoop filter // Undo any changes made in lookupRequest to the snoop filter
// entry if the request will come again. retryItem holds // entry if the request will come again. retryItem holds

View file

@ -141,9 +141,9 @@ class SnoopFilter : public SimObject {
* reqLookupResult. * reqLookupResult.
* *
* @param will_retry This request will retry on this bus / snoop filter * @param will_retry This request will retry on this bus / snoop filter
* @param cpkt Request packet, merely for sanity checking * @param addr Packet address, merely for sanity checking
*/ */
void finishRequest(bool will_retry, const Packet* cpkt); void finishRequest(bool will_retry, const Addr addr);
/** /**
* Handle an incoming snoop from below (the master port). These * Handle an incoming snoop from below (the master port). These