summaryrefslogtreecommitdiff
path: root/src/mem/bus.cc
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2007-08-12 09:56:37 -0700
committerNathan Binkert <nate@binkert.org>2007-08-12 09:56:37 -0700
commit64295b800fd67e9b9bb3eee0131511a71ddf1fdb (patch)
treeed1c759f11384dd2c263b43d7842be2922c5c39d /src/mem/bus.cc
parentb92594dd90f54a892771989a8164148e6647c9ab (diff)
parentec4000e0e284834df0eb1db792074a1b11f21cc8 (diff)
downloadgem5-64295b800fd67e9b9bb3eee0131511a71ddf1fdb.tar.xz
merge
--HG-- extra : convert_revision : 5866eaa4008c4fa5da7fbb443132b8326955f71d
Diffstat (limited to 'src/mem/bus.cc')
-rw-r--r--src/mem/bus.cc82
1 files changed, 56 insertions, 26 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index cb359734b..42c4431bb 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -84,6 +84,7 @@ Bus::deletePortRefs(Port *p)
if (funcPort == bp)
return;
interfaces.erase(bp->getId());
+ clearBusCache();
delete bp;
}
@@ -176,7 +177,16 @@ Bus::recvTiming(PacketPtr pkt)
DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
src, pkt->getDest(), pkt->getAddr(), pkt->cmdString());
- BusPort *src_port = (src == defaultId) ? defaultPort : interfaces[src];
+ BusPort *src_port;
+ if (src == defaultId)
+ src_port = defaultPort;
+ else {
+ src_port = checkBusCache(src);
+ if (src_port == NULL) {
+ src_port = interfaces[src];
+ updateBusCache(src, src_port);
+ }
+ }
// If the bus is busy, or other devices are in line ahead of the current
// one, put this device on the retry list.
@@ -201,25 +211,28 @@ Bus::recvTiming(PacketPtr pkt)
dest_port_id = findPort(pkt->getAddr());
dest_port = (dest_port_id == defaultId) ?
defaultPort : interfaces[dest_port_id];
- for (SnoopIter s_iter = snoopPorts.begin();
- s_iter != snoopPorts.end();
- s_iter++) {
+ SnoopIter s_end = snoopPorts.end();
+ for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
BusPort *p = *s_iter;
if (p != dest_port && p != src_port) {
-#ifndef NDEBUG
// cache is not allowed to refuse snoop
- bool success = p->sendTiming(pkt);
+ bool success M5_VAR_USED = p->sendTiming(pkt);
assert(success);
-#else
- // avoid unused variable warning
- p->sendTiming(pkt);
-#endif
}
}
} else {
assert(dest >= 0 && dest < maxId);
assert(dest != src); // catch infinite loops
dest_port_id = dest;
+ if (dest_port_id == defaultId)
+ dest_port = defaultPort;
+ else {
+ dest_port = checkBusCache(dest);
+ if (dest_port == NULL) {
+ dest_port = interfaces[dest_port_id];
+ // updateBusCache(dest_port_id, dest_port);
+ }
+ }
dest_port = (dest_port_id == defaultId) ?
defaultPort : interfaces[dest_port_id];
}
@@ -291,15 +304,19 @@ Bus::findPort(Addr addr)
/* An interval tree would be a better way to do this. --ali. */
int dest_id = -1;
- PortIter i = portMap.find(RangeSize(addr,1));
- if (i != portMap.end())
- dest_id = i->second;
+ dest_id = checkPortCache(addr);
+ if (dest_id == -1) {
+ PortIter i = portMap.find(RangeSize(addr,1));
+ if (i != portMap.end())
+ dest_id = i->second;
+ updatePortCache(dest_id, i->first.start, i->first.end);
+ }
// Check if this matches the default range
if (dest_id == -1) {
- for (AddrRangeIter iter = defaultRange.begin();
- iter != defaultRange.end(); iter++) {
- if (*iter == addr) {
+ AddrRangeIter a_end = defaultRange.end();
+ for (AddrRangeIter i = defaultRange.begin(); i != a_end; i++) {
+ if (*i == addr) {
DPRINTF(Bus, " found addr %#llx on default\n", addr);
return defaultId;
}
@@ -340,8 +357,16 @@ Bus::recvAtomic(PacketPtr pkt)
int orig_src = pkt->getSrc();
int target_port_id = findPort(pkt->getAddr());
- Port *target_port = (target_port_id == defaultId) ?
- defaultPort : interfaces[target_port_id];
+ BusPort *target_port;
+ if (target_port_id == defaultId)
+ target_port = defaultPort;
+ else {
+ target_port = checkBusCache(target_port_id);
+ if (target_port == NULL) {
+ target_port = interfaces[target_port_id];
+ updateBusCache(target_port_id, target_port);
+ }
+ }
SnoopIter s_end = snoopPorts.end();
for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
@@ -406,9 +431,8 @@ Bus::recvFunctional(PacketPtr pkt)
assert(pkt->isRequest()); // hasn't already been satisfied
- for (SnoopIter s_iter = snoopPorts.begin();
- s_iter != snoopPorts.end();
- s_iter++) {
+ SnoopIter s_end = snoopPorts.end();
+ for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
BusPort *p = *s_iter;
if (p != port && p->getId() != src_id) {
p->sendFunctional(pkt);
@@ -433,11 +457,16 @@ Bus::recvStatusChange(Port::Status status, int id)
bool snoops;
AddrRangeIter iter;
+ if (inRecvStatusChange.count(id))
+ return;
+ inRecvStatusChange.insert(id);
+
assert(status == Port::RangeChange &&
"The other statuses need to be implemented.");
DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id);
+ clearPortCache();
if (id == defaultId) {
defaultRange.clear();
// Only try to update these ranges if the user set a default responder.
@@ -499,6 +528,7 @@ Bus::recvStatusChange(Port::Status status, int id)
if (id != defaultId && defaultPort)
defaultPort->sendStatusChange(Port::RangeChange);
+ inRecvStatusChange.erase(id);
}
void
@@ -557,14 +587,14 @@ Bus::findBlockSize(int id)
int max_bs = -1;
- for (PortIter portIter = portMap.begin();
- portIter != portMap.end(); portIter++) {
- int tmp_bs = interfaces[portIter->second]->peerBlockSize();
+ PortIter p_end = portMap.end();
+ for (PortIter p_iter = portMap.begin(); p_iter != p_end; p_iter++) {
+ int tmp_bs = interfaces[p_iter->second]->peerBlockSize();
if (tmp_bs > max_bs)
max_bs = tmp_bs;
}
- for (SnoopIter s_iter = snoopPorts.begin();
- s_iter != snoopPorts.end(); s_iter++) {
+ SnoopIter s_end = snoopPorts.end();
+ for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
int tmp_bs = (*s_iter)->peerBlockSize();
if (tmp_bs > max_bs)
max_bs = tmp_bs;