diff -r 9955637586ca -r 47a65615576f src/mem/bus.hh --- a/src/mem/bus.hh Thu Jan 05 13:25:34 2012 +0000 +++ b/src/mem/bus.hh Thu Jan 05 13:25:37 2012 +0000 @@ -1,4 +1,16 @@ /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2002-2005 The Regents of The University of Michigan * All rights reserved. * @@ -27,6 +39,7 @@ * * Authors: Ron Dreslinski * Ali Saidi + * Andreas Hansson */ /** @@ -79,7 +92,7 @@ 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 @@ -155,9 +168,6 @@ Event * drainEvent; - - static const int defaultId = -3; //Make it unique from Broadcast - typedef range_map::iterator PortIter; range_map portMap; @@ -285,12 +295,9 @@ 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.*/ @@ -319,7 +326,7 @@ } /** 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 @@ -331,54 +338,6 @@ 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. */ diff -r 9955637586ca -r 47a65615576f src/mem/bus.cc --- a/src/mem/bus.cc Thu Jan 05 13:25:34 2012 +0000 +++ b/src/mem/bus.cc Thu Jan 05 13:25:37 2012 +0000 @@ -1,4 +1,16 @@ /* + * Copyright (c) 2011 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * @@ -26,6 +38,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Ali Saidi + * Andreas Hansson */ /** @@ -33,9 +46,6 @@ * Definition of a bus object. */ -#include -#include - #include "base/misc.hh" #include "base/trace.hh" #include "debug/Bus.hh" @@ -46,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) { @@ -58,28 +67,25 @@ 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; } @@ -87,16 +93,16 @@ 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); } } } @@ -176,16 +182,7 @@ { 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. @@ -211,8 +208,7 @@ 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; @@ -223,20 +219,10 @@ } } } 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) { @@ -334,7 +320,7 @@ 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; } } @@ -343,7 +329,7 @@ DPRINTF(Bus, "Unable to find destination for addr %#llx, " "will use default port\n", addr); - return defaultId; + return defaultPortId; } @@ -367,16 +353,7 @@ 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++) { @@ -439,7 +416,7 @@ 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(); @@ -478,11 +455,11 @@ 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", @@ -491,7 +468,7 @@ } } else { - assert((id < maxId && id >= 0) || id == defaultId); + assert(id < interfaces.size() && id >= 0); BusPort *port = interfaces[id]; // Clean out any previously existent ids @@ -520,14 +497,12 @@ // 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); }