diff options
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/bus.cc | 116 | ||||
-rw-r--r-- | src/mem/bus.hh | 12 | ||||
-rw-r--r-- | src/mem/cache/base_cache.cc | 31 | ||||
-rw-r--r-- | src/mem/cache/base_cache.hh | 32 | ||||
-rw-r--r-- | src/mem/cache/cache.hh | 13 |
5 files changed, 152 insertions, 52 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) {} }; diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index aaaf1bdef..15a21efa1 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -98,6 +98,37 @@ BaseCache::CachePort::clearBlocked() blocked = false; } +BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort) + : Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort) +{ + this->setFlags(AutoDelete); + pkt = NULL; +} + +BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort, Packet *_pkt) + : Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort), pkt(_pkt) +{ + this->setFlags(AutoDelete); +} + +void +BaseCache::CacheEvent::process() +{ + if (!pkt) + { + if (!cachePort->isCpuSide) + pkt = cachePort->cache->getPacket(); + //Else get coherence req + } + cachePort->sendTiming(pkt); +} + +const char * +BaseCache::CacheEvent::description() +{ + return "timing event\n"; +} + Port* BaseCache::getPort(const std::string &if_name, int idx) { diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index 2754fab5a..5370a73c8 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -79,9 +79,9 @@ class BaseCache : public MemObject { class CachePort : public Port { + public: BaseCache *cache; - public: CachePort(const std::string &_name, BaseCache *_cache, bool _isCpuSide); protected: @@ -110,10 +110,11 @@ class BaseCache : public MemObject struct CacheEvent : public Event { - Packet *pkt; CachePort *cachePort; + Packet *pkt; - CacheEvent(Packet *pkt, CachePort *cachePort); + CacheEvent(CachePort *_cachePort); + CacheEvent(CachePort *_cachePort, Packet *_pkt); void process(); const char *description(); }; @@ -147,6 +148,11 @@ class BaseCache : public MemObject fatal("No implementation"); } + virtual Packet *getPacket() + { + fatal("No implementation"); + } + /** * Bit vector of the blocking reasons for the access path. * @sa #BlockedCause @@ -388,7 +394,6 @@ class BaseCache : public MemObject if (!isBlockedForSnoop()) { memSidePort->clearBlocked(); } - } /** @@ -407,10 +412,13 @@ class BaseCache : public MemObject */ void setMasterRequest(RequestCause cause, Tick time) { + if (!doMasterRequest()) + { + BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(memSidePort); + reqCpu->schedule(time); + } uint8_t flag = 1<<cause; masterRequests |= flag; - assert("Implement\n" && 0); -// mi->pktuest(time); } /** @@ -462,8 +470,10 @@ class BaseCache : public MemObject */ void respond(Packet *pkt, Tick time) { - assert("Implement\n" && 0); -// si->respond(pkt,time); + pkt->makeTimingResponse(); + pkt->result = Packet::Success; + CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); + reqCpu->schedule(time); } /** @@ -476,8 +486,10 @@ class BaseCache : public MemObject if (!pkt->req->isUncacheable()) { missLatency[pkt->cmdToIndex()][pkt->req->getThreadNum()] += time - pkt->time; } - assert("Implement\n" && 0); -// si->respond(pkt,time); + pkt->makeTimingResponse(); + pkt->result = Packet::Success; + CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); + reqCpu->schedule(time); } /** diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 1243c9d9e..2e77444a0 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -168,7 +168,7 @@ class Cache : public BaseCache * Selects a request to send on the bus. * @return The memory request to service. */ - Packet * getPacket(); + virtual Packet * getPacket(); /** * Was the request was sent successfully? @@ -242,17 +242,6 @@ class Cache : public BaseCache } /** - * Send a response to the slave interface. - * @param req The request being responded to. - * @param time The time the response is ready. - */ - void respond(Packet * &pkt, Tick time) - { - //si->respond(pkt,time); - cpuSidePort->sendAtomic(pkt); - } - - /** * Perform the access specified in the request and return the estimated * time of completion. This function can either update the hierarchy state * or just perform the access wherever the data is found depending on the |