From acd289b7ef5862bdac391672f0e1ad20fbfadab0 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Tue, 17 Jan 2012 12:55:09 -0600 Subject: [PATCH] MEM: Make the bus default port yet another port This patch removes the idiosyncratic nature of the default bus port and makes it yet another port in the list of interfaces. Rather than having a specific pointer to the default port we merely track the identifier of this port. This change makes future port diversification easier and overall cleans up the bus code. --- src/mem/bus.cc | 97 ++++++++++++++++---------------------------------- src/mem/bus.hh | 63 +++----------------------------- 2 files changed, 35 insertions(+), 125 deletions(-) diff --git a/src/mem/bus.cc b/src/mem/bus.cc index ea1ec7322..a20f90108 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -38,6 +38,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Ali Saidi + * Andreas Hansson */ /** @@ -45,9 +46,6 @@ * Definition of a bus object. */ -#include -#include - #include "base/misc.hh" #include "base/trace.hh" #include "debug/Bus.hh" @@ -58,8 +56,7 @@ Bus::Bus(const BusParams *p) : MemObject(p), busId(p->bus_id), clock(p->clock), headerCycles(p->header_cycles), width(p->width), tickNextIdle(0), - drainEvent(NULL), busIdle(this), inRetry(false), maxId(0), - defaultPort(NULL), + drainEvent(NULL), busIdle(this), inRetry(false), defaultPortId(-1), useDefaultRange(p->use_default_range), defaultBlockSize(p->block_size), cachedBlockSize(0), cachedBlockSizeValid(false) { @@ -70,28 +67,25 @@ Bus::Bus(const BusParams *p) fatal("Bus clock period must be positive\n"); if (headerCycles <= 0) fatal("Number of header cycles must be positive\n"); - clearBusCache(); clearPortCache(); } Port * Bus::getPort(const std::string &if_name, int idx) { + std::string portName; + int id = interfaces.size(); if (if_name == "default") { - if (defaultPort == NULL) { - defaultPort = new BusPort(csprintf("%s-default",name()), this, - defaultId); - cachedBlockSizeValid = false; - return defaultPort; + if (defaultPortId == -1) { + defaultPortId = id; + portName = csprintf("%s-default", name()); } else - fatal("Default port already set\n"); + fatal("Default port already set on %s\n", name()); + } else { + portName = csprintf("%s-p%d", name(), id); } - int id; - // if_name ignored? forced to be empty? - id = maxId++; - assert(maxId < std::numeric_limits::max()); - BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id); - interfaces[id] = bp; + BusPort *bp = new BusPort(portName, this, id); + interfaces.push_back(bp); cachedBlockSizeValid = false; return bp; } @@ -99,16 +93,16 @@ Bus::getPort(const std::string &if_name, int idx) void Bus::init() { - m5::hash_map::iterator intIter; + std::vector::iterator intIter; // iterate over our interfaces and determine which of our neighbours // are snooping and add them as snoopers for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++) { - if (intIter->second->getPeer()->isSnooping()) { + if ((*intIter)->getPeer()->isSnooping()) { DPRINTF(BusAddrRanges, "Adding snooping neighbour %s\n", - intIter->second->getPeer()->name()); - snoopPorts.push_back(intIter->second); + (*intIter)->getPeer()->name()); + snoopPorts.push_back(*intIter); } } } @@ -188,16 +182,7 @@ Bus::recvTiming(PacketPtr pkt) { short src = pkt->getSrc(); - 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); - } - } + BusPort *src_port = interfaces[src]; // If the bus is busy, or other devices are in line ahead of the current // one, put this device on the retry list. @@ -223,8 +208,7 @@ Bus::recvTiming(PacketPtr pkt) if (dest == Packet::Broadcast) { dest_port_id = findPort(pkt->getAddr()); - dest_port = (dest_port_id == defaultId) ? - defaultPort : interfaces[dest_port_id]; + dest_port = interfaces[dest_port_id]; SnoopIter s_end = snoopPorts.end(); for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) { BusPort *p = *s_iter; @@ -235,20 +219,10 @@ Bus::recvTiming(PacketPtr pkt) } } } else { - assert(dest < maxId); + assert(dest < interfaces.size()); 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]; + dest_port = interfaces[dest_port_id]; } if (dest_port_id == src) { @@ -346,7 +320,7 @@ Bus::findPort(Addr addr) for (AddrRangeIter i = defaultRange.begin(); i != a_end; i++) { if (*i == addr) { DPRINTF(Bus, " found addr %#llx on default\n", addr); - return defaultId; + return defaultPortId; } } @@ -355,7 +329,7 @@ Bus::findPort(Addr addr) DPRINTF(Bus, "Unable to find destination for addr %#llx, " "will use default port\n", addr); - return defaultId; + return defaultPortId; } @@ -379,16 +353,7 @@ Bus::recvAtomic(PacketPtr pkt) int orig_src = pkt->getSrc(); int target_port_id = findPort(pkt->getAddr()); - 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); - } - } + BusPort *target_port = interfaces[target_port_id]; SnoopIter s_end = snoopPorts.end(); for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) { @@ -444,7 +409,7 @@ Bus::recvFunctional(PacketPtr pkt) assert(pkt->getDest() == Packet::Broadcast); int port_id = findPort(pkt->getAddr()); - Port *port = (port_id == defaultId) ? defaultPort : interfaces[port_id]; + Port *port = interfaces[port_id]; // The packet may be changed by another bus on snoops, restore the // id after each int src_id = pkt->getSrc(); @@ -491,11 +456,11 @@ Bus::recvRangeChange(int id) DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id); clearPortCache(); - if (id == defaultId) { + if (id == defaultPortId) { defaultRange.clear(); // Only try to update these ranges if the user set a default responder. if (useDefaultRange) { - AddrRangeList ranges = defaultPort->getPeer()->getAddrRanges(); + AddrRangeList ranges = interfaces[id]->getPeer()->getAddrRanges(); for(iter = ranges.begin(); iter != ranges.end(); iter++) { defaultRange.push_back(*iter); DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n", @@ -504,7 +469,7 @@ Bus::recvRangeChange(int id) } } else { - assert((id < maxId && id >= 0) || id == defaultId); + assert(id < interfaces.size() && id >= 0); BusPort *port = interfaces[id]; // Clean out any previously existent ids @@ -533,14 +498,12 @@ Bus::recvRangeChange(int id) // tell all our peers that our address range has changed. // Don't tell the device that caused this change, it already knows - m5::hash_map::iterator intIter; + std::vector::const_iterator intIter; for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++) - if (intIter->first != id) - intIter->second->sendRangeChange(); + if ((*intIter)->getId() != id) + (*intIter)->sendRangeChange(); - if (id != defaultId && defaultPort) - defaultPort->sendRangeChange(); inRecvRangeChange.erase(id); } diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 2ad17cf3b..5b8b373a5 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -39,6 +39,7 @@ * * Authors: Ron Dreslinski * Ali Saidi + * Andreas Hansson */ /** @@ -91,7 +92,7 @@ class Bus : public MemObject void onRetryList(bool newVal) { _onRetryList = newVal; } - int getId() { return id; } + int getId() const { return id; } /** * Determine if this port should be considered a snooper. This @@ -167,9 +168,6 @@ class Bus : public MemObject Event * drainEvent; - - static const int defaultId = -3; //Make it unique from Broadcast - typedef range_map::iterator PortIter; range_map portMap; @@ -297,12 +295,9 @@ class Bus : public MemObject bool inRetry; std::set inRecvRangeChange; - /** max number of bus ids we've handed out so far */ - short maxId; - - /** An array of pointers to the peer port interfaces + /** An ordered vector of pointers to the peer port interfaces connected to this bus.*/ - m5::hash_map interfaces; + std::vector interfaces; /** An array of pointers to ports that retry should be called on because the * original send failed for whatever reason.*/ @@ -331,7 +326,7 @@ class Bus : public MemObject } /** Port that handles requests that don't match any of the interfaces.*/ - BusPort *defaultPort; + short defaultPortId; /** If true, use address range provided by default device. Any address not handled by another port and not in default device's @@ -343,54 +338,6 @@ class Bus : public MemObject unsigned cachedBlockSize; bool cachedBlockSizeValid; - // Cache for the peer port interfaces - struct BusCache { - bool valid; - short id; - BusPort *port; - }; - - BusCache busCache[3]; - - // Checks the peer port interfaces cache for the port id and returns - // a pointer to the matching port - inline BusPort* checkBusCache(short id) { - if (busCache[0].valid && id == busCache[0].id) { - return busCache[0].port; - } - if (busCache[1].valid && id == busCache[1].id) { - return busCache[1].port; - } - if (busCache[2].valid && id == busCache[2].id) { - return busCache[2].port; - } - - return NULL; - } - - // Replaces the earliest entry in the cache with a new entry - inline void updateBusCache(short id, BusPort *port) { - busCache[2].valid = busCache[1].valid; - busCache[2].id = busCache[1].id; - busCache[2].port = busCache[1].port; - - busCache[1].valid = busCache[0].valid; - busCache[1].id = busCache[0].id; - busCache[1].port = busCache[0].port; - - busCache[0].valid = true; - busCache[0].id = id; - busCache[0].port = port; - } - - // Invalidates the cache. Needs to be called in constructor. - inline void clearBusCache() { - busCache[2].valid = false; - busCache[1].valid = false; - busCache[0].valid = false; - } - - public: /** A function used to return the port associated with this bus object. */ -- 2.30.2