mem-ruby: fix downstream destinations

AddrRangeMap::intersects doesn't support ranges with different
interleavings, thus the current implementation of the destination
seach won't work in cases when different machines map the same address
with different interleaving.

The fixed implementation uses a different AddrRangeMap for each mach
type.

Change-Id: Idd0184da343c46c92a4c86f142938902096c2b1f
Signed-off-by: Tiago Mück <tiago.muck@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/63671
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
Tiago Mück
2021-07-19 19:39:39 -05:00
committed by Tiago Muck
parent 9f550d5519
commit 1dfd39499f
2 changed files with 26 additions and 28 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017,2019-2021 ARM Limited
* Copyright (c) 2017,2019-2022 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -96,15 +96,13 @@ AbstractController::init()
MachineID mid = abs_cntrl->getMachineID();
const AddrRangeList &ranges = abs_cntrl->getAddrRanges();
for (const auto &addr_range : ranges) {
auto i = downstreamAddrMap.intersects(addr_range);
if (i == downstreamAddrMap.end()) {
i = downstreamAddrMap.insert(addr_range, AddrMapEntry());
auto i = downstreamAddrMap.find(mid.getType());
if ((i != downstreamAddrMap.end()) &&
(i->second.intersects(addr_range) != i->second.end())) {
fatal("%s: %s mapped to multiple machines of the same type\n",
name(), addr_range.to_string());
}
AddrMapEntry &entry = i->second;
fatal_if(entry.count(mid.getType()) > 0,
"%s: %s mapped to multiple machines of the same type\n",
name(), addr_range.to_string());
entry[mid.getType()] = mid;
downstreamAddrMap[mid.getType()].insert(addr_range, mid);
}
downstreamDestinations.add(mid);
}
@@ -419,23 +417,24 @@ MachineID
AbstractController::mapAddressToDownstreamMachine(Addr addr, MachineType mtype)
const
{
const auto i = downstreamAddrMap.contains(addr);
fatal_if(i == downstreamAddrMap.end(),
"%s: couldn't find mapping for address %x\n", name(), addr);
const AddrMapEntry &entry = i->second;
assert(!entry.empty());
if (mtype == MachineType_NUM) {
fatal_if(entry.size() > 1,
"%s: address %x mapped to multiple machine types.\n", name(), addr);
return entry.begin()->second;
} else {
auto j = entry.find(mtype);
fatal_if(j == entry.end(),
"%s: couldn't find mapping for address %x\n", name(), addr);
return j->second;
// map to the first match
for (const auto &i : downstreamAddrMap) {
const auto mapping = i.second.contains(addr);
if (mapping != i.second.end())
return mapping->second;
}
}
else {
const auto i = downstreamAddrMap.find(mtype);
if (i != downstreamAddrMap.end()) {
const auto mapping = i->second.contains(addr);
if (mapping != i->second.end())
return mapping->second;
}
}
fatal("%s: couldn't find mapping for address %x mtype=%s\n",
name(), addr, mtype);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017,2019-2021 ARM Limited
* Copyright (c) 2017,2019-2022 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -405,9 +405,8 @@ class AbstractController : public ClockedObject, public Consumer
/** The address range to which the controller responds on the CPU side. */
const AddrRangeList addrRanges;
typedef std::unordered_map<MachineType, MachineID> AddrMapEntry;
AddrRangeMap<AddrMapEntry, 3> downstreamAddrMap;
std::unordered_map<MachineType, AddrRangeMap<MachineID, 3>>
downstreamAddrMap;
NetDest downstreamDestinations;
NetDest upstreamDestinations;