diff options
author | Ali Saidi <saidi@eecs.umich.edu> | 2006-07-06 14:41:09 -0400 |
---|---|---|
committer | Ali Saidi <saidi@eecs.umich.edu> | 2006-07-06 14:41:09 -0400 |
commit | 4b741100714c6f20749f344ddd4b16459f28df72 (patch) | |
tree | 613d4bf11ced3c8df4b5bb2e9a68a3df04b11333 /src/mem | |
parent | e60f998e2993df35460c8835016b3043a13da80a (diff) | |
parent | 93839380e7dc4799d234843d10329c03d38487fa (diff) | |
download | gem5-4b741100714c6f20749f344ddd4b16459f28df72.tar.xz |
Merge zizzer:/bk/newmem
into zeep.pool:/z/saidi/work/m5.newmem
--HG--
extra : convert_revision : 4669e87d29fa3e0ca9009f6b9dce72113220d7bc
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/bus.cc | 116 | ||||
-rw-r--r-- | src/mem/bus.hh | 12 |
2 files changed, 98 insertions, 30 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 19a3dc9e4..31271106b 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -33,6 +33,7 @@ */ +#include "base/misc.hh" #include "base/trace.hh" #include "mem/bus.hh" #include "sim/builder.hh" @@ -40,6 +41,14 @@ Port * Bus::getPort(const std::string &if_name, int idx) { + if (if_name == "default") + if (defaultPort == NULL) { + defaultPort = new BusPort(csprintf("%s-default",name()), this, + defaultId); + return defaultPort; + } else + fatal("Default port already set\n"); + // if_name ignored? forced to be empty? int id = interfaces.size(); BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id); @@ -47,11 +56,12 @@ Bus::getPort(const std::string &if_name, int idx) return bp; } -/** Get the ranges of anyone that we are connected to. */ +/** Get the ranges of anyone other buses that we are connected to. */ void Bus::init() { std::vector<Port*>::iterator intIter; + for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++) (*intIter)->sendStatusChange(Port::RangeChange); } @@ -110,6 +120,7 @@ Bus::findPort(Addr addr, int id) int dest_id = -1; int i = 0; bool found = false; + AddrRangeIter iter; while (i < portList.size() && !found) { @@ -120,8 +131,18 @@ Bus::findPort(Addr addr, int id) } i++; } - if (dest_id == -1) + + // Check if this matches the default range + if (dest_id == -1) { + for (iter = defaultRange.begin(); iter != defaultRange.end(); iter++) { + if (*iter == addr) { + DPRINTF(Bus, " found addr 0x%llx on default\n", addr); + return defaultPort; + } + } panic("Unable to find destination for addr: %llx", addr); + } + // we shouldn't be sending this back to where it came from assert(dest_id != id); @@ -155,39 +176,52 @@ Bus::recvFunctional(Packet *pkt) void Bus::recvStatusChange(Port::Status status, int id) { + AddrRangeList ranges; + AddrRangeList snoops; + int x; + AddrRangeIter iter; + assert(status == Port::RangeChange && "The other statuses need to be implemented."); DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id); - assert(id < interfaces.size() && id >= 0); - int x; - Port *port = interfaces[id]; - AddrRangeList ranges; - AddrRangeList snoops; - AddrRangeIter iter; - std::vector<DevMap>::iterator portIter; + if (id == defaultId) { + defaultRange.clear(); + defaultPort->getPeerAddressRanges(ranges, snoops); + assert(snoops.size() == 0); + for(iter = ranges.begin(); iter != ranges.end(); iter++) { + defaultRange.push_back(*iter); + DPRINTF(BusAddrRanges, "Adding range %llx - %llx for default\n", + iter->start, iter->end); + } + } else { - // Clean out any previously existent ids - for (portIter = portList.begin(); portIter != portList.end(); ) { - if (portIter->portId == id) - portIter = portList.erase(portIter); - else - portIter++; - } + assert((id < interfaces.size() && id >= 0) || id == -1); + Port *port = interfaces[id]; + std::vector<DevMap>::iterator portIter; + + // Clean out any previously existent ids + for (portIter = portList.begin(); portIter != portList.end(); ) { + if (portIter->portId == id) + portIter = portList.erase(portIter); + else + portIter++; + } - port->getPeerAddressRanges(ranges, snoops); + port->getPeerAddressRanges(ranges, snoops); - // not dealing with snooping yet either - assert(snoops.size() == 0); - for(iter = ranges.begin(); iter != ranges.end(); iter++) { - DevMap dm; - dm.portId = id; - dm.range = *iter; + // not dealing with snooping yet either + assert(snoops.size() == 0); + for(iter = ranges.begin(); iter != ranges.end(); iter++) { + DevMap dm; + dm.portId = id; + dm.range = *iter; - DPRINTF(BusAddrRanges, "Adding range %llx - %llx for id %d\n", - dm.range.start, dm.range.end, id); - portList.push_back(dm); + DPRINTF(BusAddrRanges, "Adding range %llx - %llx for id %d\n", + dm.range.start, dm.range.end, id); + portList.push_back(dm); + } } DPRINTF(MMU, "port list has %d entries\n", portList.size()); @@ -196,19 +230,47 @@ Bus::recvStatusChange(Port::Status status, int id) for (x = 0; x < interfaces.size(); x++) if (x != id) interfaces[x]->sendStatusChange(Port::RangeChange); + + if (id != defaultId && defaultPort) + defaultPort->sendStatusChange(Port::RangeChange); } void Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) { std::vector<DevMap>::iterator portIter; + AddrRangeIter dflt_iter; + bool subset; resp.clear(); snoop.clear(); DPRINTF(BusAddrRanges, "received address range request, returning:\n"); + + for (dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end(); + dflt_iter++) { + resp.push_back(*dflt_iter); + DPRINTF(BusAddrRanges, " -- %#llX : %#llX\n",dflt_iter->start, + dflt_iter->end); + } for (portIter = portList.begin(); portIter != portList.end(); portIter++) { - if (portIter->portId != id) { + subset = false; + for (dflt_iter = defaultRange.begin(); dflt_iter != defaultRange.end(); + dflt_iter++) { + if ((portIter->range.start < dflt_iter->start && + portIter->range.end >= dflt_iter->start) || + (portIter->range.start < dflt_iter->end && + portIter->range.end >= dflt_iter->end)) + fatal("Devices can not set ranges that itersect the default set\ + but are not a subset of the default set.\n"); + if (portIter->range.start >= dflt_iter->start && + portIter->range.end <= dflt_iter->end) { + subset = true; + DPRINTF(BusAddrRanges, " -- %#llX : %#llX is a SUBSET\n", + portIter->range.start, portIter->range.end); + } + } + if (portIter->portId != id && !subset) { resp.push_back(portIter->range); DPRINTF(BusAddrRanges, " -- %#llX : %#llX\n", portIter->range.start, portIter->range.end); diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 9c7054b94..3a2896886 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -51,19 +51,22 @@ class Bus : public MemObject /** a globally unique id for this bus. */ int busId; + static const int defaultId = -1; + struct DevMap { int portId; Range<Addr> range; }; std::vector<DevMap> portList; + AddrRangeList defaultRange; /** Function called by the port when the bus is recieving a Timing - transaction.*/ + transaction.*/ bool recvTiming(Packet *pkt); /** Function called by the port when the bus is recieving a Atomic - transaction.*/ + transaction.*/ Tick recvAtomic(Packet *pkt); /** Function called by the port when the bus is recieving a Functional @@ -159,6 +162,9 @@ class Bus : public MemObject * original send failed for whatever reason.*/ std::list<Port*> retryList; + /** Port that handles requests that don't match any of the interfaces.*/ + Port *defaultPort; + public: /** A function used to return the port associated with this bus object. */ @@ -167,7 +173,7 @@ class Bus : public MemObject virtual void init(); Bus(const std::string &n, int bus_id) - : MemObject(n), busId(bus_id) {} + : MemObject(n), busId(bus_id), defaultPort(NULL) {} }; |