diff options
Diffstat (limited to 'src/mem')
54 files changed, 889 insertions, 1017 deletions
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index 9c14e7ee2..38dcfd2e8 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -89,7 +89,7 @@ Bridge::init() /** Function called by the port when the bus is receiving a Timing * transaction.*/ bool -Bridge::BridgePort::recvTiming(Packet *pkt) +Bridge::BridgePort::recvTiming(PacketPtr pkt) { DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n", pkt->getSrc(), pkt->getDest(), pkt->getAddr()); @@ -99,7 +99,7 @@ Bridge::BridgePort::recvTiming(Packet *pkt) bool -Bridge::BridgePort::queueForSendTiming(Packet *pkt) +Bridge::BridgePort::queueForSendTiming(PacketPtr pkt) { if (queueFull()) return false; @@ -148,11 +148,12 @@ Bridge::BridgePort::trySend() assert(buf->ready <= curTick); - Packet *pkt = buf->pkt; + PacketPtr pkt = buf->pkt; DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", buf->origSrc, pkt->getDest(), pkt->getAddr()); + pkt->flags &= ~SNOOP_COMMIT; //CLear it if it was set if (sendTiming(pkt)) { // send successful sendQueue.pop_front(); @@ -197,7 +198,7 @@ Bridge::BridgePort::recvRetry() /** Function called by the port when the bus is receiving a Atomic * transaction.*/ Tick -Bridge::BridgePort::recvAtomic(Packet *pkt) +Bridge::BridgePort::recvAtomic(PacketPtr pkt) { return otherPort->sendAtomic(pkt) + delay; } @@ -205,7 +206,7 @@ Bridge::BridgePort::recvAtomic(Packet *pkt) /** Function called by the port when the bus is receiving a Functional * transaction.*/ void -Bridge::BridgePort::recvFunctional(Packet *pkt) +Bridge::BridgePort::recvFunctional(PacketPtr pkt) { std::list<PacketBuffer*>::iterator i; bool pktContinue = true; diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index 2ab9799c7..f7d0d12d0 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -70,12 +70,12 @@ class Bridge : public MemObject public: Tick ready; - Packet *pkt; + PacketPtr pkt; Packet::SenderState *origSenderState; short origSrc; bool expectResponse; - PacketBuffer(Packet *_pkt, Tick t) + PacketBuffer(PacketPtr _pkt, Tick t) : ready(t), pkt(_pkt), origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()), expectResponse(_pkt->needsResponse()) @@ -84,7 +84,7 @@ class Bridge : public MemObject pkt->senderState = this; } - void fixResponse(Packet *pkt) + void fixResponse(PacketPtr pkt) { assert(pkt->senderState == this); pkt->setDest(origSrc); @@ -109,7 +109,7 @@ class Bridge : public MemObject */ bool queueFull() { return (sendQueue.size() == queueLimit); } - bool queueForSendTiming(Packet *pkt); + bool queueForSendTiming(PacketPtr pkt); void finishSend(PacketBuffer *buf); @@ -146,7 +146,7 @@ class Bridge : public MemObject /** When receiving a timing request from the peer port, pass it to the bridge. */ - virtual bool recvTiming(Packet *pkt); + virtual bool recvTiming(PacketPtr pkt); /** When receiving a retry request from the peer port, pass it to the bridge. */ @@ -154,11 +154,11 @@ class Bridge : public MemObject /** When receiving a Atomic requestfrom the peer port, pass it to the bridge. */ - virtual Tick recvAtomic(Packet *pkt); + virtual Tick recvAtomic(PacketPtr pkt); /** When receiving a Functional request from the peer port, pass it to the bridge. */ - virtual void recvFunctional(Packet *pkt); + virtual void recvFunctional(PacketPtr pkt); /** When receiving a status changefrom the peer port, pass it to the bridge. */ diff --git a/src/mem/bus.cc b/src/mem/bus.cc index b11b6de58..86a148f87 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -138,7 +138,7 @@ void Bus::occupyBus(PacketPtr pkt) /** Function called by the port when the bus is receiving a Timing * transaction.*/ bool -Bus::recvTiming(Packet *pkt) +Bus::recvTiming(PacketPtr pkt) { Port *port; DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n", @@ -160,9 +160,12 @@ Bus::recvTiming(Packet *pkt) short dest = pkt->getDest(); if (dest == Packet::Broadcast) { if (timingSnoop(pkt)) { + bool success; + pkt->flags |= SNOOP_COMMIT; - bool success = timingSnoop(pkt); + success = timingSnoop(pkt); assert(success); + if (pkt->flags & SATISFIED) { //Cache-Cache transfer occuring if (inRetry) { @@ -298,7 +301,7 @@ Bus::findSnoopPorts(Addr addr, int id) } Tick -Bus::atomicSnoop(Packet *pkt) +Bus::atomicSnoop(PacketPtr pkt) { std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); Tick response_time = 0; @@ -316,7 +319,7 @@ Bus::atomicSnoop(Packet *pkt) } void -Bus::functionalSnoop(Packet *pkt) +Bus::functionalSnoop(PacketPtr pkt) { std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); @@ -328,7 +331,7 @@ Bus::functionalSnoop(Packet *pkt) } bool -Bus::timingSnoop(Packet *pkt) +Bus::timingSnoop(PacketPtr pkt) { std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); bool success = true; @@ -346,7 +349,7 @@ Bus::timingSnoop(Packet *pkt) /** Function called by the port when the bus is receiving a Atomic * transaction.*/ Tick -Bus::recvAtomic(Packet *pkt) +Bus::recvAtomic(PacketPtr pkt) { DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n", pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); @@ -361,7 +364,7 @@ Bus::recvAtomic(Packet *pkt) /** Function called by the port when the bus is receiving a Functional * transaction.*/ void -Bus::recvFunctional(Packet *pkt) +Bus::recvFunctional(PacketPtr pkt) { DPRINTF(Bus, "recvFunctional: packet src %d dest %d addr 0x%x cmd %s\n", pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 509b8cf9b..9fb33b7c3 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -71,15 +71,15 @@ class Bus : public MemObject /** Function called by the port when the bus is recieving a Timing transaction.*/ - bool recvTiming(Packet *pkt); + bool recvTiming(PacketPtr pkt); /** Function called by the port when the bus is recieving a Atomic transaction.*/ - Tick recvAtomic(Packet *pkt); + Tick recvAtomic(PacketPtr pkt); /** Function called by the port when the bus is recieving a Functional transaction.*/ - void recvFunctional(Packet *pkt); + void recvFunctional(PacketPtr pkt); /** Timing function called by port when it is once again able to process * requests. */ @@ -107,16 +107,16 @@ class Bus : public MemObject std::vector<int> findSnoopPorts(Addr addr, int id); /** Snoop all relevant ports atomicly. */ - Tick atomicSnoop(Packet *pkt); + Tick atomicSnoop(PacketPtr pkt); /** Snoop all relevant ports functionally. */ - void functionalSnoop(Packet *pkt); + void functionalSnoop(PacketPtr pkt); /** Call snoop on caches, be sure to set SNOOP_COMMIT bit if you want * the snoop to happen * @return True if succeds. */ - bool timingSnoop(Packet *pkt); + bool timingSnoop(PacketPtr pkt); /** Process address range request. * @param resp addresses that we can respond to @@ -157,17 +157,17 @@ class Bus : public MemObject /** When reciving a timing request from the peer port (at id), pass it to the bus. */ - virtual bool recvTiming(Packet *pkt) + virtual bool recvTiming(PacketPtr pkt) { pkt->setSrc(id); return bus->recvTiming(pkt); } /** When reciving a Atomic requestfrom the peer port (at id), pass it to the bus. */ - virtual Tick recvAtomic(Packet *pkt) + virtual Tick recvAtomic(PacketPtr pkt) { pkt->setSrc(id); return bus->recvAtomic(pkt); } /** When reciving a Functional requestfrom the peer port (at id), pass it to the bus. */ - virtual void recvFunctional(Packet *pkt) + virtual void recvFunctional(PacketPtr pkt) { pkt->setSrc(id); bus->recvFunctional(pkt); } /** When reciving a status changefrom the peer port (at id), diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 3f7a52fab..0694aae6e 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -33,9 +33,10 @@ * Definition of BaseCache functions. */ -#include "mem/cache/base_cache.hh" -#include "cpu/smt.hh" #include "cpu/base.hh" +#include "cpu/smt.hh" +#include "mem/cache/base_cache.hh" +#include "mem/cache/miss/mshr.hh" using namespace std; @@ -44,7 +45,6 @@ BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache, : Port(_name), cache(_cache), isCpuSide(_isCpuSide) { blocked = false; - cshrRetry = NULL; waitingOnRetry = false; //Start ports at null if more than one is created we should panic //cpuSidePort = NULL; @@ -71,7 +71,7 @@ BaseCache::CachePort::deviceBlockSize() } bool -BaseCache::CachePort::recvTiming(Packet *pkt) +BaseCache::CachePort::recvTiming(PacketPtr pkt) { if (isCpuSide && !pkt->req->isUncacheable() @@ -99,48 +99,23 @@ BaseCache::CachePort::recvTiming(Packet *pkt) } Tick -BaseCache::CachePort::recvAtomic(Packet *pkt) +BaseCache::CachePort::recvAtomic(PacketPtr pkt) { return cache->doAtomicAccess(pkt, isCpuSide); } void -BaseCache::CachePort::recvFunctional(Packet *pkt) +BaseCache::CachePort::recvFunctional(PacketPtr pkt) { //Check storage here first - list<Packet *>::iterator i = drainList.begin(); - list<Packet *>::iterator end = drainList.end(); + list<PacketPtr>::iterator i = drainList.begin(); + list<PacketPtr>::iterator end = drainList.end(); for (; i != end; ++i) { - Packet * target = *i; + PacketPtr target = *i; // If the target contains data, and it overlaps the // probed request, need to update data if (target->intersect(pkt)) { - uint8_t* pkt_data; - uint8_t* write_data; - int data_size; - if (target->getAddr() < pkt->getAddr()) { - int offset = pkt->getAddr() - target->getAddr(); - pkt_data = pkt->getPtr<uint8_t>(); - write_data = target->getPtr<uint8_t>() + offset; - data_size = target->getSize() - offset; - assert(data_size > 0); - if (data_size > pkt->getSize()) - data_size = pkt->getSize(); - } else { - int offset = target->getAddr() - pkt->getAddr(); - pkt_data = pkt->getPtr<uint8_t>() + offset; - write_data = target->getPtr<uint8_t>(); - data_size = pkt->getSize() - offset; - assert(data_size > pkt->getSize()); - if (data_size > target->getSize()) - data_size = target->getSize(); - } - - if (pkt->isWrite()) { - memcpy(pkt_data, write_data, data_size); - } else { - memcpy(write_data, pkt_data, data_size); - } + fixPacket(pkt, target); } } cache->doFunctionalAccess(pkt, isCpuSide); @@ -149,7 +124,7 @@ BaseCache::CachePort::recvFunctional(Packet *pkt) void BaseCache::CachePort::recvRetry() { - Packet *pkt; + PacketPtr pkt; assert(waitingOnRetry); if (!drainList.empty()) { DPRINTF(CachePort, "%s attempting to send a retry for response\n", name()); @@ -179,12 +154,23 @@ BaseCache::CachePort::recvRetry() return; } pkt = cache->getPacket(); - MSHR* mshr = (MSHR*)pkt->senderState; + MSHR* mshr = (MSHR*) pkt->senderState; + //Copy the packet, it may be modified/destroyed elsewhere + PacketPtr copyPkt = new Packet(*pkt); + copyPkt->dataStatic<uint8_t>(pkt->getPtr<uint8_t>()); + mshr->pkt = copyPkt; + bool success = sendTiming(pkt); DPRINTF(Cache, "Address %x was %s in sending the timing request\n", pkt->getAddr(), success ? "succesful" : "unsuccesful"); - cache->sendResult(pkt, mshr, success); + waitingOnRetry = !success; + if (waitingOnRetry) { + DPRINTF(CachePort, "%s now waiting on a retry\n", name()); + } + + cache->sendResult(pkt, mshr, success); + if (success && cache->doMasterRequest()) { DPRINTF(CachePort, "%s has more requests\n", name()); @@ -195,20 +181,20 @@ BaseCache::CachePort::recvRetry() } else { - assert(cshrRetry); + assert(cache->doSlaveRequest()); //pkt = cache->getCoherencePacket(); //We save the packet, no reordering on CSHRS - pkt = cshrRetry; + pkt = cache->getCoherencePacket(); + MSHR* cshr = (MSHR*)pkt->senderState; bool success = sendTiming(pkt); + cache->sendCoherenceResult(pkt, cshr, success); waitingOnRetry = !success; - if (success) + if (success && cache->doSlaveRequest()) { - if (cache->doSlaveRequest()) { - //Still more to issue, rerequest in 1 cycle - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); - reqCpu->schedule(curTick + 1); - } - cshrRetry = NULL; + DPRINTF(CachePort, "%s has more requests\n", name()); + //Still more to issue, rerequest in 1 cycle + BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); + reqCpu->schedule(curTick + 1); } } if (waitingOnRetry) DPRINTF(CachePort, "%s STILL Waiting on retry\n", name()); @@ -246,7 +232,7 @@ BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort) pkt = NULL; } -BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort, Packet *_pkt) +BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort, PacketPtr _pkt) : Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort), pkt(_pkt) { this->setFlags(AutoDelete); @@ -289,15 +275,25 @@ BaseCache::CacheEvent::process() pkt = cachePort->cache->getPacket(); MSHR* mshr = (MSHR*) pkt->senderState; + //Copy the packet, it may be modified/destroyed elsewhere + PacketPtr copyPkt = new Packet(*pkt); + copyPkt->dataStatic<uint8_t>(pkt->getPtr<uint8_t>()); + mshr->pkt = copyPkt; + bool success = cachePort->sendTiming(pkt); DPRINTF(Cache, "Address %x was %s in sending the timing request\n", pkt->getAddr(), success ? "succesful" : "unsuccesful"); - cachePort->cache->sendResult(pkt, mshr, success); + cachePort->waitingOnRetry = !success; - if (cachePort->waitingOnRetry) DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); + if (cachePort->waitingOnRetry) { + DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); + } + + cachePort->cache->sendResult(pkt, mshr, success); if (success && cachePort->cache->doMasterRequest()) { - DPRINTF(CachePort, "%s still more MSHR requests to send\n", cachePort->name()); + DPRINTF(CachePort, "%s still more MSHR requests to send\n", + cachePort->name()); //Still more to issue, rerequest in 1 cycle pkt = NULL; this->schedule(curTick+1); @@ -306,27 +302,21 @@ BaseCache::CacheEvent::process() else { //CSHR - if (!cachePort->cshrRetry) { - assert(cachePort->cache->doSlaveRequest()); - pkt = cachePort->cache->getCoherencePacket(); - } - else { - pkt = cachePort->cshrRetry; - } + assert(cachePort->cache->doSlaveRequest()); + pkt = cachePort->cache->getCoherencePacket(); + MSHR* cshr = (MSHR*) pkt->senderState; bool success = cachePort->sendTiming(pkt); - if (!success) { - //Need to send on a retry - cachePort->cshrRetry = pkt; - cachePort->waitingOnRetry = true; - } - else + cachePort->cache->sendCoherenceResult(pkt, cshr, success); + cachePort->waitingOnRetry = !success; + if (cachePort->waitingOnRetry) + DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name()); + if (success && cachePort->cache->doSlaveRequest()) { - cachePort->cshrRetry = NULL; - if (cachePort->cache->doSlaveRequest()) { - //Still more to issue, rerequest in 1 cycle - pkt = NULL; - this->schedule(curTick+1); - } + DPRINTF(CachePort, "%s still more CSHR requests to send\n", + cachePort->name()); + //Still more to issue, rerequest in 1 cycle + pkt = NULL; + this->schedule(curTick+1); } } return; diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index 455e13d9c..565280aef 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -58,7 +58,6 @@ enum BlockedCause{ Blocked_NoTargets, Blocked_NoWBBuffers, Blocked_Coherence, - Blocked_Copy, NUM_BLOCKED_CAUSES }; @@ -86,11 +85,11 @@ class BaseCache : public MemObject CachePort(const std::string &_name, BaseCache *_cache, bool _isCpuSide); protected: - virtual bool recvTiming(Packet *pkt); + virtual bool recvTiming(PacketPtr pkt); - virtual Tick recvAtomic(Packet *pkt); + virtual Tick recvAtomic(PacketPtr pkt); - virtual void recvFunctional(Packet *pkt); + virtual void recvFunctional(PacketPtr pkt); virtual void recvStatusChange(Status status); @@ -114,24 +113,25 @@ class BaseCache : public MemObject bool waitingOnRetry; - std::list<Packet *> drainList; + std::list<PacketPtr> drainList; - Packet *cshrRetry; }; struct CacheEvent : public Event { CachePort *cachePort; - Packet *pkt; + PacketPtr pkt; CacheEvent(CachePort *_cachePort); - CacheEvent(CachePort *_cachePort, Packet *_pkt); + CacheEvent(CachePort *_cachePort, PacketPtr _pkt); void process(); const char *description(); }; - protected: + public: //Made public so coherence can get at it. CachePort *cpuSidePort; + + protected: CachePort *memSidePort; bool snoopRangesSent; @@ -141,17 +141,17 @@ class BaseCache : public MemObject private: //To be defined in cache_impl.hh not in base class - virtual bool doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide) + virtual bool doTimingAccess(PacketPtr pkt, CachePort *cachePort, bool isCpuSide) { fatal("No implementation"); } - virtual Tick doAtomicAccess(Packet *pkt, bool isCpuSide) + virtual Tick doAtomicAccess(PacketPtr pkt, bool isCpuSide) { fatal("No implementation"); } - virtual void doFunctionalAccess(Packet *pkt, bool isCpuSide) + virtual void doFunctionalAccess(PacketPtr pkt, bool isCpuSide) { fatal("No implementation"); } @@ -172,17 +172,23 @@ class BaseCache : public MemObject } } - virtual Packet *getPacket() + virtual PacketPtr getPacket() { fatal("No implementation"); } - virtual Packet *getCoherencePacket() + virtual PacketPtr getCoherencePacket() { fatal("No implementation"); } - virtual void sendResult(Packet* &pkt, MSHR* mshr, bool success) + virtual void sendResult(PacketPtr &pkt, MSHR* mshr, bool success) + { + + fatal("No implementation"); + } + + virtual void sendCoherenceResult(PacketPtr &pkt, MSHR* mshr, bool success) { fatal("No implementation"); @@ -489,10 +495,13 @@ class BaseCache : public MemObject */ void setSlaveRequest(RequestCause cause, Tick time) { + if (!doSlaveRequest() && !cpuSidePort->waitingOnRetry) + { + BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(cpuSidePort); + reqCpu->schedule(time); + } uint8_t flag = 1<<cause; slaveRequests |= flag; - assert("Implement\n" && 0); -// si->pktuest(time); } /** @@ -510,15 +519,18 @@ class BaseCache : public MemObject * @param pkt The request being responded to. * @param time The time the response is ready. */ - void respond(Packet *pkt, Tick time) + void respond(PacketPtr pkt, Tick time) { if (pkt->needsResponse()) { CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); reqCpu->schedule(time); } else { - if (pkt->cmd == Packet::Writeback) delete pkt->req; - delete pkt; + if (pkt->cmd != Packet::UpgradeReq) + { + delete pkt->req; + delete pkt; + } } } @@ -527,7 +539,7 @@ class BaseCache : public MemObject * @param pkt The request to respond to. * @param time The time the response is ready. */ - void respondToMiss(Packet *pkt, Tick time) + void respondToMiss(PacketPtr pkt, Tick time) { if (!pkt->req->isUncacheable()) { missLatency[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] += time - pkt->time; @@ -537,8 +549,11 @@ class BaseCache : public MemObject reqCpu->schedule(time); } else { - if (pkt->cmd == Packet::Writeback) delete pkt->req; - delete pkt; + if (pkt->cmd != Packet::UpgradeReq) + { + delete pkt->req; + delete pkt; + } } } @@ -546,7 +561,7 @@ class BaseCache : public MemObject * Suppliess the data if cache to cache transfers are enabled. * @param pkt The bus transaction to fulfill. */ - void respondToSnoop(Packet *pkt, Tick time) + void respondToSnoop(PacketPtr pkt, Tick time) { assert (pkt->needsResponse()); CacheEvent *reqMem = new CacheEvent(memSidePort, pkt); diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 41b270030..1f3b087bb 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -75,12 +75,6 @@ class Cache : public BaseCache /** Prefetcher */ Prefetcher<TagStore, Buffering> *prefetcher; - /** Do fast copies in this cache. */ - bool doCopy; - - /** Block on a delayed copy. */ - bool blockOnCopy; - /** * The clock ratio of the outgoing bus. * Used for calculating critical word first. @@ -102,21 +96,9 @@ class Cache : public BaseCache * A permanent mem req to always be used to cause invalidations. * Used to append to target list, to cause an invalidation. */ - Packet * invalidatePkt; + PacketPtr invalidatePkt; Request *invalidateReq; - /** - * Temporarily move a block into a MSHR. - * @todo Remove this when LSQ/SB are fixed and implemented in memtest. - */ - void pseudoFill(Addr addr); - - /** - * Temporarily move a block into an existing MSHR. - * @todo Remove this when LSQ/SB are fixed and implemented in memtest. - */ - void pseudoFill(MSHR *mshr); - public: class Params @@ -125,19 +107,17 @@ class Cache : public BaseCache TagStore *tags; Buffering *missQueue; Coherence *coherence; - bool doCopy; - bool blockOnCopy; BaseCache::Params baseParams; Prefetcher<TagStore, Buffering> *prefetcher; bool prefetchAccess; int hitLatency; Params(TagStore *_tags, Buffering *mq, Coherence *coh, - bool do_copy, BaseCache::Params params, + BaseCache::Params params, Prefetcher<TagStore, Buffering> *_prefetcher, bool prefetch_access, int hit_latency) - : tags(_tags), missQueue(mq), coherence(coh), doCopy(do_copy), - blockOnCopy(false), baseParams(params), + : tags(_tags), missQueue(mq), coherence(coh), + baseParams(params), prefetcher(_prefetcher), prefetchAccess(prefetch_access), hitLatency(hit_latency) { @@ -147,12 +127,12 @@ class Cache : public BaseCache /** Instantiates a basic cache object. */ Cache(const std::string &_name, Params ¶ms); - virtual bool doTimingAccess(Packet *pkt, CachePort *cachePort, + virtual bool doTimingAccess(PacketPtr pkt, CachePort *cachePort, bool isCpuSide); - virtual Tick doAtomicAccess(Packet *pkt, bool isCpuSide); + virtual Tick doAtomicAccess(PacketPtr pkt, bool isCpuSide); - virtual void doFunctionalAccess(Packet *pkt, bool isCpuSide); + virtual void doFunctionalAccess(PacketPtr pkt, bool isCpuSide); virtual void recvStatusChange(Port::Status status, bool isCpuSide); @@ -163,55 +143,47 @@ class Cache : public BaseCache * @param pkt The request to perform. * @return The result of the access. */ - bool access(Packet * &pkt); + bool access(PacketPtr &pkt); /** * Selects a request to send on the bus. * @return The memory request to service. */ - virtual Packet * getPacket(); + virtual PacketPtr getPacket(); /** * Was the request was sent successfully? * @param pkt The request. * @param success True if the request was sent successfully. */ - virtual void sendResult(Packet * &pkt, MSHR* mshr, bool success); + virtual void sendResult(PacketPtr &pkt, MSHR* mshr, bool success); /** - * Handles a response (cache line fill/write ack) from the bus. - * @param pkt The request being responded to. - */ - void handleResponse(Packet * &pkt); - - /** - * Start handling a copy transaction. - * @param pkt The copy request to perform. + * Was the CSHR request was sent successfully? + * @param pkt The request. + * @param success True if the request was sent successfully. */ - void startCopy(Packet * &pkt); + virtual void sendCoherenceResult(PacketPtr &pkt, MSHR* cshr, bool success); /** - * Handle a delayed copy transaction. - * @param pkt The delayed copy request to continue. - * @param addr The address being responded to. - * @param blk The block of the current response. - * @param mshr The mshr being handled. + * Handles a response (cache line fill/write ack) from the bus. + * @param pkt The request being responded to. */ - void handleCopy(Packet * &pkt, Addr addr, BlkType *blk, MSHR *mshr); + void handleResponse(PacketPtr &pkt); /** * Selects a coherence message to forward to lower levels of the hierarchy. * @return The coherence message to forward. */ - virtual Packet * getCoherencePacket(); + virtual PacketPtr getCoherencePacket(); /** * Snoops bus transactions to maintain coherence. * @param pkt The current bus transaction. */ - void snoop(Packet * &pkt); + void snoop(PacketPtr &pkt); - void snoopResponse(Packet * &pkt); + void snoopResponse(PacketPtr &pkt); /** * Invalidates the block containing address if found. @@ -252,7 +224,7 @@ class Cache : public BaseCache * request. * @return The estimated completion time. */ - Tick probe(Packet * &pkt, bool update, CachePort * otherSidePort); + Tick probe(PacketPtr &pkt, bool update, CachePort * otherSidePort); /** * Snoop for the provided request in the cache and return the estimated @@ -263,7 +235,7 @@ class Cache : public BaseCache * request. * @return The estimated completion time. */ - Tick snoopProbe(Packet * &pkt); + Tick snoopProbe(PacketPtr &pkt); }; #endif // __CACHE_HH__ diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index 078c82d82..7b999e4b1 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -35,8 +35,11 @@ #ifndef __CACHE_BLK_HH__ #define __CACHE_BLK_HH__ +#include <list> + #include "sim/root.hh" // for Tick #include "arch/isa_traits.hh" // for Addr +#include "mem/request.hh" /** * Cache block status bit assignments @@ -96,6 +99,35 @@ class CacheBlk /** Number of references to this block since it was brought in. */ int refCount; + protected: + /** + * Represents that the indicated thread context has a "lock" on + * the block, in the LL/SC sense. + */ + class Lock { + public: + int cpuNum; // locking CPU + int threadNum; // locking thread ID within CPU + + // check for matching execution context + bool matchesContext(Request *req) + { + return (cpuNum == req->getCpuNum() && + threadNum == req->getThreadNum()); + } + + Lock(Request *req) + : cpuNum(req->getCpuNum()), threadNum(req->getThreadNum()) + { + } + }; + + /** List of thread contexts that have performed a load-locked (LL) + * on the block since the last store. */ + std::list<Lock> lockList; + + public: + CacheBlk() : asid(-1), tag(0), data(0) ,size(0), status(0), whenReady(0), set(-1), refCount(0) @@ -175,7 +207,58 @@ class CacheBlk return (status & BlkHWPrefetched) != 0; } + /** + * Track the fact that a local locked was issued to the block. If + * multiple LLs get issued from the same context we could have + * redundant records on the list, but that's OK, as they'll all + * get blown away at the next store. + */ + void trackLoadLocked(Request *req) + { + assert(req->isLocked()); + lockList.push_front(Lock(req)); + } + + /** + * Clear the list of valid load locks. Should be called whenever + * block is written to or invalidated. + */ + void clearLoadLocks() { lockList.clear(); } + /** + * Handle interaction of load-locked operations and stores. + * @return True if write should proceed, false otherwise. Returns + * false only in the case of a failed store conditional. + */ + bool checkWrite(Request *req) + { + if (req->isLocked()) { + // it's a store conditional... have to check for matching + // load locked. + bool success = false; + + for (std::list<Lock>::iterator i = lockList.begin(); + i != lockList.end(); ++i) + { + if (i->matchesContext(req)) { + // it's a store conditional, and as far as the memory + // system can tell, the requesting context's lock is + // still valid. + success = true; + break; + } + } + + req->setScResult(success ? 1 : 0); + clearLoadLocks(); + return success; + } else { + // for *all* stores (conditional or otherwise) we have to + // clear the list of load-locks as they're all invalid now. + clearLoadLocks(); + return true; + } + } }; #endif //__CACHE_BLK_HH__ diff --git a/src/mem/cache/cache_builder.cc b/src/mem/cache/cache_builder.cc index 05a149a1c..03646ec2a 100644 --- a/src/mem/cache/cache_builder.cc +++ b/src/mem/cache/cache_builder.cc @@ -113,7 +113,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(BaseCache) Param<bool> prioritizeRequests; // SimObjectParam<Bus *> in_bus; // SimObjectParam<Bus *> out_bus; - Param<bool> do_copy; SimObjectParam<CoherenceProtocol *> protocol; Param<Addr> trace_addr; Param<int> hash_delay; @@ -163,7 +162,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache) /* INIT_PARAM_DFLT(in_bus, "incoming bus object", NULL), INIT_PARAM(out_bus, "outgoing bus object"), */ - INIT_PARAM_DFLT(do_copy, "perform fast copies in the cache", false), INIT_PARAM_DFLT(protocol, "coherence protocol to use in the cache", NULL), INIT_PARAM_DFLT(trace_addr, "address to trace", 0), @@ -228,7 +226,7 @@ END_INIT_SIM_OBJECT_PARAMS(BaseCache) BUILD_NULL_PREFETCHER(t, comp, b); \ } \ Cache<CacheTags<t, comp>, b, c>::Params params(tagStore, mq, coh, \ - do_copy, base_params, \ + base_params, \ /*in_bus, out_bus,*/ pf, \ prefetch_access, hit_latency); \ Cache<CacheTags<t, comp>, b, c> *retval = \ diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 9db79b843..66a9ee554 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -56,7 +56,7 @@ template<class TagStore, class Buffering, class Coherence> bool Cache<TagStore,Buffering,Coherence>:: -doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide) +doTimingAccess(PacketPtr pkt, CachePort *cachePort, bool isCpuSide) { if (isCpuSide) { @@ -82,15 +82,10 @@ doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide) template<class TagStore, class Buffering, class Coherence> Tick Cache<TagStore,Buffering,Coherence>:: -doAtomicAccess(Packet *pkt, bool isCpuSide) +doAtomicAccess(PacketPtr pkt, bool isCpuSide) { if (isCpuSide) { - //Temporary solution to LL/SC - if (pkt->isWrite() && (pkt->req->isLocked())) { - pkt->req->setScResult(1); - } - probe(pkt, true, NULL); //TEMP ALWAYS SUCCES FOR NOW pkt->result = Packet::Success; @@ -109,18 +104,13 @@ doAtomicAccess(Packet *pkt, bool isCpuSide) template<class TagStore, class Buffering, class Coherence> void Cache<TagStore,Buffering,Coherence>:: -doFunctionalAccess(Packet *pkt, bool isCpuSide) +doFunctionalAccess(PacketPtr pkt, bool isCpuSide) { if (isCpuSide) { //TEMP USE CPU?THREAD 0 0 pkt->req->setThreadContext(0,0); - //Temporary solution to LL/SC - if (pkt->isWrite() && (pkt->req->isLocked())) { - assert("Can't handle LL/SC on functional path\n"); - } - probe(pkt, false, memSidePort); //TEMP ALWAYS SUCCESFUL FOR NOW pkt->result = Packet::Success; @@ -148,7 +138,6 @@ Cache(const std::string &_name, prefetchAccess(params.prefetchAccess), tags(params.tags), missQueue(params.missQueue), coherence(params.coherence), prefetcher(params.prefetcher), - doCopy(params.doCopy), blockOnCopy(params.blockOnCopy), hitLatency(params.hitLatency) { tags->setCache(this); @@ -198,7 +187,8 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt) /** @todo make the fast write alloc (wh64) work with coherence. */ /** @todo Do we want to do fast writes for writebacks as well? */ if (!blk && pkt->getSize() >= blkSize && coherence->allowFastWrites() && - (pkt->cmd == Packet::WriteReq || pkt->cmd == Packet::WriteInvalidateReq) ) { + (pkt->cmd == Packet::WriteReq + || pkt->cmd == Packet::WriteInvalidateReq) ) { // not outstanding misses, can do this MSHR* outstanding_miss = missQueue->findMSHR(pkt->getAddr()); if (pkt->cmd == Packet::WriteInvalidateReq || !outstanding_miss) { @@ -248,14 +238,15 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt) template<class TagStore, class Buffering, class Coherence> -Packet * +PacketPtr Cache<TagStore,Buffering,Coherence>::getPacket() { assert(missQueue->havePending()); - Packet * pkt = missQueue->getPacket(); + PacketPtr pkt = missQueue->getPacket(); if (pkt) { if (!pkt->req->isUncacheable()) { - if (pkt->cmd == Packet::HardPFReq) misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++; + if (pkt->cmd == Packet::HardPFReq) + misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++; BlkType *blk = tags->findBlock(pkt); Packet::Command cmd = coherence->getBusCmd(pkt->cmd, (blk)? blk->status : 0); @@ -270,19 +261,29 @@ Cache<TagStore,Buffering,Coherence>::getPacket() template<class TagStore, class Buffering, class Coherence> void -Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, bool success) +Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, + bool success) { - if (success && !(pkt->flags & NACKED_LINE)) { - missQueue->markInService(pkt, mshr); + if (success && !(pkt && (pkt->flags & NACKED_LINE))) { + if (!mshr->pkt->needsResponse() + && !(mshr->pkt->cmd == Packet::UpgradeReq) + && (pkt && (pkt->flags & SATISFIED))) { + //Writeback, clean up the non copy version of the packet + delete pkt; + } + missQueue->markInService(mshr->pkt, mshr); //Temp Hack for UPGRADES - if (pkt->cmd == Packet::UpgradeReq) { + if (mshr->pkt && mshr->pkt->cmd == Packet::UpgradeReq) { + assert(pkt); //Upgrades need to be fixed pkt->flags &= ~CACHE_LINE_FILL; BlkType *blk = tags->findBlock(pkt); CacheBlk::State old_state = (blk) ? blk->status : 0; CacheBlk::State new_state = coherence->getNewState(pkt,old_state); if (old_state != new_state) - DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", - pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); + DPRINTF(Cache, "Block for blk addr %x moving from " + "state %i to %i\n", + pkt->getAddr() & (((ULL(1))<<48)-1), + old_state, new_state); //Set the state on the upgrade memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize); PacketList writebacks; @@ -294,19 +295,28 @@ Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, bool pkt->flags &= ~NACKED_LINE; pkt->flags &= ~SATISFIED; pkt->flags &= ~SNOOP_COMMIT; + +//Rmove copy from mshr + delete mshr->pkt; + mshr->pkt = pkt; + missQueue->restoreOrigCmd(pkt); } } template<class TagStore, class Buffering, class Coherence> void -Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt) +Cache<TagStore,Buffering,Coherence>::handleResponse(PacketPtr &pkt) { BlkType *blk = NULL; if (pkt->senderState) { + //Delete temp copy in MSHR, restore it. + delete ((MSHR*)pkt->senderState)->pkt; + ((MSHR*)pkt->senderState)->pkt = pkt; if (pkt->result == Packet::Nacked) { //pkt->reinitFromRequest(); - warn("NACKs from devices not connected to the same bus not implemented\n"); + warn("NACKs from devices not connected to the same bus " + "not implemented\n"); return; } if (pkt->result == Packet::BadAddress) { @@ -322,8 +332,10 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt) PacketList writebacks; CacheBlk::State new_state = coherence->getNewState(pkt,old_state); if (old_state != new_state) - DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", - pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); + DPRINTF(Cache, "Block for blk addr %x moving from " + "state %i to %i\n", + pkt->getAddr() & (((ULL(1))<<48)-1), + old_state, new_state); blk = tags->handleFill(blk, (MSHR*)pkt->senderState, new_state, writebacks, pkt); while (!writebacks.empty()) { @@ -336,87 +348,70 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt) } template<class TagStore, class Buffering, class Coherence> -void -Cache<TagStore,Buffering,Coherence>::pseudoFill(Addr addr) +PacketPtr +Cache<TagStore,Buffering,Coherence>::getCoherencePacket() { - // Need to temporarily move this blk into MSHRs - MSHR *mshr = missQueue->allocateTargetList(addr); - int lat; - PacketList dummy; - // Read the data into the mshr - BlkType *blk = tags->handleAccess(mshr->pkt, lat, dummy, false); - assert(dummy.empty()); - assert(mshr->pkt->flags & SATISFIED); - // can overload order since it isn't used on non pending blocks - mshr->order = blk->status; - // temporarily remove the block from the cache. - tags->invalidateBlk(addr); + return coherence->getPacket(); } template<class TagStore, class Buffering, class Coherence> void -Cache<TagStore,Buffering,Coherence>::pseudoFill(MSHR *mshr) +Cache<TagStore,Buffering,Coherence>::sendCoherenceResult(PacketPtr &pkt, + MSHR *cshr, + bool success) { - // Need to temporarily move this blk into MSHRs - assert(mshr->pkt->cmd == Packet::ReadReq); - int lat; - PacketList dummy; - // Read the data into the mshr - BlkType *blk = tags->handleAccess(mshr->pkt, lat, dummy, false); - assert(dummy.empty()); - assert(mshr->pkt->flags & SATISFIED); - // can overload order since it isn't used on non pending blocks - mshr->order = blk->status; - // temporarily remove the block from the cache. - tags->invalidateBlk(mshr->pkt->getAddr()); -} - - -template<class TagStore, class Buffering, class Coherence> -Packet * -Cache<TagStore,Buffering,Coherence>::getCoherencePacket() -{ - return coherence->getPacket(); + coherence->sendResult(pkt, cshr, success); } template<class TagStore, class Buffering, class Coherence> void -Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt) +Cache<TagStore,Buffering,Coherence>::snoop(PacketPtr &pkt) { if (pkt->req->isUncacheable()) { //Can't get a hit on an uncacheable address //Revisit this for multi level coherence return; } + + //Send a timing (true) invalidate up if the protocol calls for it + coherence->propogateInvalidate(pkt, true); + Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); BlkType *blk = tags->findBlock(pkt); MSHR *mshr = missQueue->findMSHR(blk_addr); - if (coherence->hasProtocol()) { //@todo Move this into handle bus req - //If we find an mshr, and it is in service, we need to NACK or invalidate + if (coherence->hasProtocol() || pkt->isInvalidate()) { + //@todo Move this into handle bus req + //If we find an mshr, and it is in service, we need to NACK or + //invalidate if (mshr) { if (mshr->inService) { if ((mshr->pkt->isInvalidate() || !mshr->pkt->isCacheFill()) - && (pkt->cmd != Packet::InvalidateReq && pkt->cmd != Packet::WriteInvalidateReq)) { - //If the outstanding request was an invalidate (upgrade,readex,..) - //Then we need to ACK the request until we get the data - //Also NACK if the outstanding request is not a cachefill (writeback) + && (pkt->cmd != Packet::InvalidateReq + && pkt->cmd != Packet::WriteInvalidateReq)) { + //If the outstanding request was an invalidate + //(upgrade,readex,..) Then we need to ACK the request + //until we get the data Also NACK if the outstanding + //request is not a cachefill (writeback) assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; pkt->flags |= NACKED_LINE; ///@todo NACK's from other levels - //warn("NACKs from devices not connected to the same bus not implemented\n"); + //warn("NACKs from devices not connected to the same bus " + //"not implemented\n"); //respondToSnoop(pkt, curTick + hitLatency); return; } else { - //The supplier will be someone else, because we are waiting for - //the data. This should cause this cache to be forced to go to - //the shared state, not the exclusive even though the shared line - //won't be asserted. But for now we will just invlidate ourselves - //and allow the other cache to go into the exclusive state. - //@todo Make it so a read to a pending read doesn't invalidate. - //@todo Make it so that a read to a pending read can't be exclusive now. + //The supplier will be someone else, because we are + //waiting for the data. This should cause this cache to + //be forced to go to the shared state, not the exclusive + //even though the shared line won't be asserted. But for + //now we will just invlidate ourselves and allow the other + //cache to go into the exclusive state. @todo Make it so + //a read to a pending read doesn't invalidate. @todo Make + //it so that a read to a pending read can't be exclusive + //now. //Set the address so find match works //panic("Don't have invalidates yet\n"); @@ -424,7 +419,8 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt) //Append the invalidate on missQueue->addTarget(mshr,invalidatePkt); - DPRINTF(Cache, "Appending Invalidate to blk_addr: %x\n", pkt->getAddr() & (((ULL(1))<<48)-1)); + DPRINTF(Cache, "Appending Invalidate to blk_addr: %x\n", + pkt->getAddr() & (((ULL(1))<<48)-1)); return; } } @@ -432,7 +428,8 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt) //We also need to check the writeback buffers and handle those std::vector<MSHR *> writebacks; if (missQueue->findWrites(blk_addr, writebacks)) { - DPRINTF(Cache, "Snoop hit in writeback to blk_addr: %x\n", pkt->getAddr() & (((ULL(1))<<48)-1)); + DPRINTF(Cache, "Snoop hit in writeback to blk_addr: %x\n", + pkt->getAddr() & (((ULL(1))<<48)-1)); //Look through writebacks for any non-uncachable writes, use that for (int i=0; i<writebacks.size(); i++) { @@ -460,7 +457,8 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt) } if (pkt->isInvalidate()) { - //This must be an upgrade or other cache will take ownership + //This must be an upgrade or other cache will take + //ownership missQueue->markInService(mshr->pkt, mshr); } return; @@ -471,34 +469,36 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt) CacheBlk::State new_state; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); if (satisfy) { - DPRINTF(Cache, "Cache snooped a %s request for addr %x and now supplying data," - "new state is %i\n", + DPRINTF(Cache, "Cache snooped a %s request for addr %x and " + "now supplying data, new state is %i\n", pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state, pkt); respondToSnoop(pkt, curTick + hitLatency); return; } - if (blk) DPRINTF(Cache, "Cache snooped a %s request for addr %x, new state is %i\n", - pkt->cmdString(), blk_addr, new_state); + if (blk) + DPRINTF(Cache, "Cache snooped a %s request for addr %x, " + "new state is %i\n", pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state); } template<class TagStore, class Buffering, class Coherence> void -Cache<TagStore,Buffering,Coherence>::snoopResponse(Packet * &pkt) +Cache<TagStore,Buffering,Coherence>::snoopResponse(PacketPtr &pkt) { //Need to handle the response, if NACKED if (pkt->flags & NACKED_LINE) { //Need to mark it as not in service, and retry for bus assert(0); //Yeah, we saw a NACK come through - //For now this should never get called, we return false when we see a NACK - //instead, by doing this we allow the bus_blocked mechanism to handle the retry - //For now it retrys in just 2 cycles, need to figure out how to change that - //Eventually we will want to also have success come in as a parameter - //Need to make sure that we handle the functionality that happens on successufl - //return of the sendAddr function + //For now this should never get called, we return false when we see a + //NACK instead, by doing this we allow the bus_blocked mechanism to + //handle the retry For now it retrys in just 2 cycles, need to figure + //out how to change that Eventually we will want to also have success + //come in as a parameter Need to make sure that we handle the + //functionality that happens on successufl return of the sendAddr + //function } } @@ -515,7 +515,8 @@ Cache<TagStore,Buffering,Coherence>::invalidateBlk(Addr addr) */ template<class TagStore, class Buffering, class Coherence> Tick -Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort* otherSidePort) +Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, + CachePort* otherSidePort) { // MemDebug::cacheProbe(pkt); if (!pkt->req->isUncacheable()) { @@ -530,6 +531,13 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort } } + if (!update && (pkt->isWrite() || (otherSidePort == cpuSidePort))) { + // Still need to change data in all locations. + otherSidePort->sendFunctional(pkt); + if (pkt->isRead() && pkt->result == Packet::Success) + return 0; + } + PacketList writebacks; int lat; BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update); @@ -538,157 +546,111 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort pkt->getAddr() & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss", pkt->getAddr() & ~((Addr)blkSize - 1)); - if (!blk) { - // Need to check for outstanding misses and writes - Addr blk_addr = pkt->getAddr() & ~(blkSize - 1); - - // There can only be one matching outstanding miss. - MSHR* mshr = missQueue->findMSHR(blk_addr); - - // There can be many matching outstanding writes. - std::vector<MSHR*> writes; - missQueue->findWrites(blk_addr, writes); - - if (!update) { - otherSidePort->sendFunctional(pkt); - - // Check for data in MSHR and writebuffer. - if (mshr) { - warn("Found outstanding miss on an non-update probe"); - MSHR::TargetList *targets = mshr->getTargetList(); - MSHR::TargetList::iterator i = targets->begin(); - MSHR::TargetList::iterator end = targets->end(); - for (; i != end; ++i) { - Packet * target = *i; - // If the target contains data, and it overlaps the - // probed request, need to update data - if (target->isWrite() && target->intersect(pkt)) { - uint8_t* pkt_data; - uint8_t* write_data; - int data_size; - if (target->getAddr() < pkt->getAddr()) { - int offset = pkt->getAddr() - target->getAddr(); - pkt_data = pkt->getPtr<uint8_t>(); - write_data = target->getPtr<uint8_t>() + offset; - data_size = target->getSize() - offset; - assert(data_size > 0); - if (data_size > pkt->getSize()) - data_size = pkt->getSize(); - } else { - int offset = target->getAddr() - pkt->getAddr(); - pkt_data = pkt->getPtr<uint8_t>() + offset; - write_data = target->getPtr<uint8_t>(); - data_size = pkt->getSize() - offset; - assert(data_size > pkt->getSize()); - if (data_size > target->getSize()) - data_size = target->getSize(); - } - - if (pkt->isWrite()) { - memcpy(pkt_data, write_data, data_size); - } else { - memcpy(write_data, pkt_data, data_size); - } - } - } - } - for (int i = 0; i < writes.size(); ++i) { - Packet * write = writes[i]->pkt; - if (write->intersect(pkt)) { - warn("Found outstanding write on an non-update probe"); - uint8_t* pkt_data; - uint8_t* write_data; - int data_size; - if (write->getAddr() < pkt->getAddr()) { - int offset = pkt->getAddr() - write->getAddr(); - pkt_data = pkt->getPtr<uint8_t>(); - write_data = write->getPtr<uint8_t>() + offset; - data_size = write->getSize() - offset; - assert(data_size > 0); - if (data_size > pkt->getSize()) - data_size = pkt->getSize(); - } else { - int offset = write->getAddr() - pkt->getAddr(); - pkt_data = pkt->getPtr<uint8_t>() + offset; - write_data = write->getPtr<uint8_t>(); - data_size = pkt->getSize() - offset; - assert(data_size > pkt->getSize()); - if (data_size > write->getSize()) - data_size = write->getSize(); - } - if (pkt->isWrite()) { - memcpy(pkt_data, write_data, data_size); - } else { - memcpy(write_data, pkt_data, data_size); - } + // Need to check for outstanding misses and writes + Addr blk_addr = pkt->getAddr() & ~(blkSize - 1); + + // There can only be one matching outstanding miss. + MSHR* mshr = missQueue->findMSHR(blk_addr); + // There can be many matching outstanding writes. + std::vector<MSHR*> writes; + missQueue->findWrites(blk_addr, writes); + + if (!update) { + // Check for data in MSHR and writebuffer. + if (mshr) { + MSHR::TargetList *targets = mshr->getTargetList(); + MSHR::TargetList::iterator i = targets->begin(); + MSHR::TargetList::iterator end = targets->end(); + for (; i != end; ++i) { + PacketPtr target = *i; + // If the target contains data, and it overlaps the + // probed request, need to update data + if (target->intersect(pkt)) { + fixPacket(pkt, target); } } - return 0; - } else { - // update the cache state and statistics - if (mshr || !writes.empty()){ - // Can't handle it, return pktuest unsatisfied. - panic("Atomic access ran into outstanding MSHR's or WB's!"); + } + for (int i = 0; i < writes.size(); ++i) { + PacketPtr write = writes[i]->pkt; + if (write->intersect(pkt)) { + fixPacket(pkt, write); } - if (!pkt->req->isUncacheable()) { + } + if (pkt->isRead() + && pkt->result != Packet::Success + && otherSidePort == memSidePort) { + otherSidePort->sendFunctional(pkt); + assert(pkt->result == Packet::Success); + } + return 0; + } else if (!blk) { + // update the cache state and statistics + if (mshr || !writes.empty()){ + // Can't handle it, return pktuest unsatisfied. + panic("Atomic access ran into outstanding MSHR's or WB's!"); + } + if (!pkt->req->isUncacheable()) { // Fetch the cache block to fill - BlkType *blk = tags->findBlock(pkt); - Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd, - (blk)? blk->status : 0); + BlkType *blk = tags->findBlock(pkt); + Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd, + (blk)? blk->status : 0); - Packet * busPkt = new Packet(pkt->req,temp_cmd, -1, blkSize); + PacketPtr busPkt = new Packet(pkt->req,temp_cmd, -1, blkSize); - busPkt->allocate(); + busPkt->allocate(); - busPkt->time = curTick; + busPkt->time = curTick; - DPRINTF(Cache, "Sending a atomic %s for %x blk_addr: %x\n", - busPkt->cmdString(), - busPkt->getAddr() & (((ULL(1))<<48)-1), - busPkt->getAddr() & ~((Addr)blkSize - 1)); + DPRINTF(Cache, "Sending a atomic %s for %x blk_addr: %x\n", + busPkt->cmdString(), + busPkt->getAddr() & (((ULL(1))<<48)-1), + busPkt->getAddr() & ~((Addr)blkSize - 1)); - lat = memSidePort->sendAtomic(busPkt); + lat = memSidePort->sendAtomic(busPkt); - //Be sure to flip the response to a request for coherence - if (busPkt->needsResponse()) { - busPkt->makeAtomicResponse(); - } + //Be sure to flip the response to a request for coherence + if (busPkt->needsResponse()) { + busPkt->makeAtomicResponse(); + } /* if (!(busPkt->flags & SATISFIED)) { - // blocked at a higher level, just return - return 0; - } +// blocked at a higher level, just return +return 0; +} */ misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; - CacheBlk::State old_state = (blk) ? blk->status : 0; - CacheBlk::State new_state = coherence->getNewState(busPkt, old_state); - DPRINTF(Cache, "Receive response:%s for blk addr %x in state %i\n", - busPkt->cmdString(), - busPkt->getAddr() & (((ULL(1))<<48)-1), old_state); - if (old_state != new_state) - DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n", - busPkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state); - - tags->handleFill(blk, busPkt, - new_state, - writebacks, pkt); - //Free the packet - delete busPkt; - - // Handle writebacks if needed - while (!writebacks.empty()){ - Packet *wbPkt = writebacks.front(); - memSidePort->sendAtomic(wbPkt); - writebacks.pop_front(); - delete wbPkt; - } - return lat + hitLatency; - } else { - return memSidePort->sendAtomic(pkt); + CacheBlk::State old_state = (blk) ? blk->status : 0; + CacheBlk::State new_state = + coherence->getNewState(busPkt, old_state); + DPRINTF(Cache, + "Receive response:%s for blk addr %x in state %i\n", + busPkt->cmdString(), + busPkt->getAddr() & (((ULL(1))<<48)-1), old_state); + if (old_state != new_state) + DPRINTF(Cache, "Block for blk addr %x moving from " + "state %i to %i\n", + busPkt->getAddr() & (((ULL(1))<<48)-1), + old_state, new_state); + + tags->handleFill(blk, busPkt, + new_state, + writebacks, pkt); + //Free the packet + delete busPkt; + + // Handle writebacks if needed + while (!writebacks.empty()){ + PacketPtr wbPkt = writebacks.front(); + memSidePort->sendAtomic(wbPkt); + writebacks.pop_front(); + delete wbPkt; } + return lat + hitLatency; + } else { + return memSidePort->sendAtomic(pkt); } } else { // There was a cache hit. @@ -698,12 +660,8 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort writebacks.pop_front(); } - if (update) { - hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; - } else if (pkt->isWrite()) { - // Still need to change data in all locations. - otherSidePort->sendFunctional(pkt); - } + hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; + return hitLatency; } fatal("Probe not handled.\n"); @@ -714,22 +672,27 @@ template<class TagStore, class Buffering, class Coherence> Tick Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt) { - Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); - BlkType *blk = tags->findBlock(pkt); - MSHR *mshr = missQueue->findMSHR(blk_addr); - CacheBlk::State new_state = 0; - bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); - if (satisfy) { - DPRINTF(Cache, "Cache snooped a %s request for addr %x and now supplying data," - "new state is %i\n", - pkt->cmdString(), blk_addr, new_state); + //Send a atomic (false) invalidate up if the protocol calls for it + coherence->propogateInvalidate(pkt, false); + + Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); + BlkType *blk = tags->findBlock(pkt); + MSHR *mshr = missQueue->findMSHR(blk_addr); + CacheBlk::State new_state = 0; + bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); + if (satisfy) { + DPRINTF(Cache, "Cache snooped a %s request for addr %x and " + "now supplying data, new state is %i\n", + pkt->cmdString(), blk_addr, new_state); tags->handleSnoop(blk, new_state, pkt); return hitLatency; - } - if (blk) DPRINTF(Cache, "Cache snooped a %s request for addr %x, new state is %i\n", - pkt->cmdString(), blk_addr, new_state); - tags->handleSnoop(blk, new_state); - return 0; + } + if (blk) + DPRINTF(Cache, "Cache snooped a %s request for addr %x, " + "new state is %i\n", + pkt->cmdString(), blk_addr, new_state); + tags->handleSnoop(blk, new_state); + return 0; } diff --git a/src/mem/cache/coherence/coherence_protocol.cc b/src/mem/cache/coherence/coherence_protocol.cc index e28dda3dc..52beb0880 100644 --- a/src/mem/cache/coherence/coherence_protocol.cc +++ b/src/mem/cache/coherence/coherence_protocol.cc @@ -192,7 +192,7 @@ CoherenceProtocol::regStats() bool -CoherenceProtocol::invalidateTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::invalidateTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) { @@ -203,7 +203,7 @@ CoherenceProtocol::invalidateTrans(BaseCache *cache, Packet * &pkt, bool -CoherenceProtocol::supplyTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::supplyTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state @@ -214,7 +214,7 @@ CoherenceProtocol::supplyTrans(BaseCache *cache, Packet * &pkt, bool -CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -226,7 +226,7 @@ CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, Packet * &pkt, bool -CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -238,7 +238,7 @@ CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, Packet * &pkt, bool -CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -248,7 +248,7 @@ CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, Packet * &pkt, } bool -CoherenceProtocol::assertShared(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::assertShared(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -463,7 +463,7 @@ CoherenceProtocol::getBusCmd(Packet::Command cmdIn, CacheBlk::State state, CacheBlk::State -CoherenceProtocol::getNewState(Packet * &pkt, CacheBlk::State oldState) +CoherenceProtocol::getNewState(PacketPtr &pkt, CacheBlk::State oldState) { CacheBlk::State state = oldState & stateMask; int cmd_idx = pkt->cmdToIndex(); @@ -488,7 +488,7 @@ CoherenceProtocol::getNewState(Packet * &pkt, CacheBlk::State oldState) bool -CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::handleBusRequest(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) @@ -518,7 +518,7 @@ CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt, } bool -CoherenceProtocol::nullTransition(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::nullTransition(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) { @@ -530,7 +530,7 @@ CoherenceProtocol::nullTransition(BaseCache *cache, Packet * &pkt, bool -CoherenceProtocol::invalidTransition(BaseCache *cache, Packet * &pkt, +CoherenceProtocol::invalidTransition(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State & new_state) { diff --git a/src/mem/cache/coherence/coherence_protocol.hh b/src/mem/cache/coherence/coherence_protocol.hh index b5d7d80aa..b30fb053b 100644 --- a/src/mem/cache/coherence/coherence_protocol.hh +++ b/src/mem/cache/coherence/coherence_protocol.hh @@ -89,7 +89,7 @@ class CoherenceProtocol : public SimObject * @param oldState The current block state. * @return The new state. */ - CacheBlk::State getNewState(Packet * &pkt, + CacheBlk::State getNewState(PacketPtr &pkt, CacheBlk::State oldState); /** @@ -101,12 +101,12 @@ class CoherenceProtocol : public SimObject * @param new_state The new coherence state of the block. * @return True if the request should be satisfied locally. */ - bool handleBusRequest(BaseCache *cache, Packet * &pkt, CacheBlk *blk, + bool handleBusRequest(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State &new_state); protected: /** Snoop function type. */ - typedef bool (*SnoopFuncType)(BaseCache *, Packet *&, CacheBlk *, + typedef bool (*SnoopFuncType)(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); // @@ -116,49 +116,49 @@ class CoherenceProtocol : public SimObject /** * Do nothing transition. */ - static bool nullTransition(BaseCache *, Packet *&, CacheBlk *, + static bool nullTransition(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Invalid transition, basically panic. */ - static bool invalidTransition(BaseCache *, Packet *&, CacheBlk *, + static bool invalidTransition(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Invalidate block, move to Invalid state. */ - static bool invalidateTrans(BaseCache *, Packet *&, CacheBlk *, + static bool invalidateTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Supply data, no state transition. */ - static bool supplyTrans(BaseCache *, Packet *&, CacheBlk *, + static bool supplyTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Supply data and go to Shared state. */ - static bool supplyAndGotoSharedTrans(BaseCache *, Packet *&, CacheBlk *, + static bool supplyAndGotoSharedTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Supply data and go to Owned state. */ - static bool supplyAndGotoOwnedTrans(BaseCache *, Packet *&, CacheBlk *, + static bool supplyAndGotoOwnedTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Invalidate block, supply data, and go to Invalid state. */ - static bool supplyAndInvalidateTrans(BaseCache *, Packet *&, CacheBlk *, + static bool supplyAndInvalidateTrans(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** * Assert the shared line for a block that is shared/exclusive. */ - static bool assertShared(BaseCache *, Packet *&, CacheBlk *, + static bool assertShared(BaseCache *, PacketPtr &, CacheBlk *, MSHR *, CacheBlk::State&); /** diff --git a/src/mem/cache/coherence/simple_coherence.hh b/src/mem/cache/coherence/simple_coherence.hh index 71d8f36f4..5316e64b9 100644 --- a/src/mem/cache/coherence/simple_coherence.hh +++ b/src/mem/cache/coherence/simple_coherence.hh @@ -89,18 +89,30 @@ class SimpleCoherence * This policy does not forward invalidates, return NULL. * @return NULL. */ - Packet * getPacket() + PacketPtr getPacket() { return NULL; } /** + * Was the CSHR request was sent successfully? + * @param pkt The request. + * @param success True if the request was sent successfully. + */ + void sendResult(PacketPtr &pkt, MSHR* cshr, bool success) + { + //Don't do coherence + return; + } + + + /** * Return the proper state given the current state and the bus response. * @param pkt The bus response. * @param current The current block state. * @return The new state. */ - CacheBlk::State getNewState(Packet * &pkt, CacheBlk::State current) + CacheBlk::State getNewState(PacketPtr &pkt, CacheBlk::State current) { return protocol->getNewState(pkt, current); } @@ -112,7 +124,7 @@ class SimpleCoherence * @param mshr The MSHR corresponding to the request, if any. * @param new_state Return the new state for the block. */ - bool handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr, + bool handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State &new_state) { // assert(mshr == NULL); @@ -148,6 +160,12 @@ class SimpleCoherence bool allowFastWrites() { return false; } bool hasProtocol() { return true; } + + void propogateInvalidate(PacketPtr pkt, bool isTiming) + { + //For now we do nothing, asssumes simple coherence is top level of cache + return; + } }; #endif //__SIMPLE_COHERENCE_HH__ diff --git a/src/mem/cache/coherence/uni_coherence.cc b/src/mem/cache/coherence/uni_coherence.cc index 0efe393f9..19230e35b 100644 --- a/src/mem/cache/coherence/uni_coherence.cc +++ b/src/mem/cache/coherence/uni_coherence.cc @@ -40,45 +40,67 @@ UniCoherence::UniCoherence() { } -Packet * +PacketPtr UniCoherence::getPacket() { - bool unblock = cshrs.isFull(); - Packet* pkt = cshrs.getReq(); - cshrs.markInService((MSHR*)pkt->senderState); - if (!cshrs.havePending()) { - cache->clearSlaveRequest(Request_Coherence); - } - if (unblock) { - //since CSHRs are always used as buffers, should always get rid of one - assert(!cshrs.isFull()); - cache->clearBlocked(Blocked_Coherence); - } + PacketPtr pkt = cshrs.getReq(); return pkt; } +void +UniCoherence::sendResult(PacketPtr &pkt, MSHR* cshr, bool success) +{ + if (success) + { + bool unblock = cshrs.isFull(); +// cshrs.markInService(cshr); + cshrs.deallocate(cshr); + if (!cshrs.havePending()) { + cache->clearSlaveRequest(Request_Coherence); + } + if (unblock) { + //since CSHRs are always used as buffers, should always get rid of one + assert(!cshrs.isFull()); + cache->clearBlocked(Blocked_Coherence); + } + } +} + + /** * @todo add support for returning slave requests, not doing them here. */ bool -UniCoherence::handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr, +UniCoherence::handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State &new_state) { new_state = 0; if (pkt->isInvalidate()) { - DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n", - pkt->getAddr(), blk); - // Forward to other caches - Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1); - cshrs.allocate(tmp); - cache->setSlaveRequest(Request_Coherence, curTick); - if (cshrs.isFull()) { - cache->setBlockedForSnoop(Blocked_Coherence); + DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n", + pkt->getAddr(), blk); + } + else if (blk) { + new_state = blk->status; + } + return false; +} + +void +UniCoherence::propogateInvalidate(PacketPtr pkt, bool isTiming) +{ + if (pkt->isInvalidate()) { + if (isTiming) { + // Forward to other caches + PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1); + cshrs.allocate(tmp); + cache->setSlaveRequest(Request_Coherence, curTick); + if (cshrs.isFull()) + cache->setBlockedForSnoop(Blocked_Coherence); } - } else { - if (blk) { - new_state = blk->status; + else { + PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1); + cache->cpuSidePort->sendAtomic(tmp); + delete tmp; } } - return false; } diff --git a/src/mem/cache/coherence/uni_coherence.hh b/src/mem/cache/coherence/uni_coherence.hh index 27b6c7fb5..44c752088 100644 --- a/src/mem/cache/coherence/uni_coherence.hh +++ b/src/mem/cache/coherence/uni_coherence.hh @@ -92,7 +92,7 @@ class UniCoherence * @param current The current block state. * @return The new state. */ - CacheBlk::State getNewState(Packet * &pkt, CacheBlk::State current) + CacheBlk::State getNewState(PacketPtr &pkt, CacheBlk::State current) { if (pkt->senderState) //Blocking Buffers don't get mshrs { @@ -108,11 +108,19 @@ class UniCoherence else return BlkValid | BlkWritable; } + /** * Return outstanding invalidate to forward. * @return The next invalidate to forward to lower levels of cache. */ - Packet * getPacket(); + PacketPtr getPacket(); + + /** + * Was the CSHR request was sent successfully? + * @param pkt The request. + * @param success True if the request was sent successfully. + */ + void sendResult(PacketPtr &pkt, MSHR* cshr, bool success); /** * Handle snooped bus requests. @@ -122,7 +130,7 @@ class UniCoherence * @param new_state The new coherence state of the block. * @return True if the request should be satisfied locally. */ - bool handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr, + bool handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr, CacheBlk::State &new_state); /** @@ -131,6 +139,8 @@ class UniCoherence bool allowFastWrites() { return true; } bool hasProtocol() { return false; } + + void propogateInvalidate(PacketPtr pkt, bool isTiming); }; #endif //__UNI_COHERENCE_HH__ diff --git a/src/mem/cache/miss/blocking_buffer.cc b/src/mem/cache/miss/blocking_buffer.cc index f7aacff89..bf741e547 100644 --- a/src/mem/cache/miss/blocking_buffer.cc +++ b/src/mem/cache/miss/blocking_buffer.cc @@ -68,7 +68,7 @@ BlockingBuffer::setPrefetcher(BasePrefetcher *_prefetcher) prefetcher = _prefetcher; } void -BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time) +BlockingBuffer::handleMiss(PacketPtr &pkt, int blk_size, Tick time) { Addr blk_addr = pkt->getAddr() & ~(Addr)(blk_size - 1); if (pkt->isWrite() && (pkt->req->isUncacheable() || !writeAllocate || @@ -98,7 +98,7 @@ BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time) cache->setMasterRequest(Request_MSHR, time); } -Packet * +PacketPtr BlockingBuffer::getPacket() { if (miss.pkt && !miss.inService) { @@ -108,7 +108,7 @@ BlockingBuffer::getPacket() } void -BlockingBuffer::setBusCmd(Packet * &pkt, Packet::Command cmd) +BlockingBuffer::setBusCmd(PacketPtr &pkt, Packet::Command cmd) { MSHR *mshr = (MSHR*) pkt->senderState; mshr->originalCmd = pkt->cmd; @@ -117,13 +117,13 @@ BlockingBuffer::setBusCmd(Packet * &pkt, Packet::Command cmd) } void -BlockingBuffer::restoreOrigCmd(Packet * &pkt) +BlockingBuffer::restoreOrigCmd(PacketPtr &pkt) { pkt->cmdOverride(((MSHR*)(pkt->senderState))->originalCmd); } void -BlockingBuffer::markInService(Packet * &pkt, MSHR* mshr) +BlockingBuffer::markInService(PacketPtr &pkt, MSHR* mshr) { if (!pkt->isCacheFill() && pkt->isWrite()) { // Forwarding a write/ writeback, don't need to change @@ -152,7 +152,7 @@ BlockingBuffer::markInService(Packet * &pkt, MSHR* mshr) } void -BlockingBuffer::handleResponse(Packet * &pkt, Tick time) +BlockingBuffer::handleResponse(PacketPtr &pkt, Tick time) { if (pkt->isCacheFill()) { // targets were handled in the cache tags @@ -163,7 +163,7 @@ BlockingBuffer::handleResponse(Packet * &pkt, Tick time) if (((MSHR*)(pkt->senderState))->hasTargets()) { // Should only have 1 target if we had any assert(((MSHR*)(pkt->senderState))->getNumTargets() == 1); - Packet * target = ((MSHR*)(pkt->senderState))->getTarget(); + PacketPtr target = ((MSHR*)(pkt->senderState))->getTarget(); ((MSHR*)(pkt->senderState))->popTarget(); if (pkt->isRead()) { memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), target->getSize()); @@ -187,7 +187,7 @@ void BlockingBuffer::squash(int threadNum) { if (miss.threadNum == threadNum) { - Packet * target = miss.getTarget(); + PacketPtr target = miss.getTarget(); miss.popTarget(); assert(0/*target->req->getThreadNum()*/ == threadNum); target = NULL; @@ -207,7 +207,7 @@ BlockingBuffer::doWriteback(Addr addr, { // Generate request Request * req = new Request(addr, size, 0); - Packet * pkt = new Packet(req, Packet::Writeback, -1); + PacketPtr pkt = new Packet(req, Packet::Writeback, -1); pkt->allocate(); if (data) { memcpy(pkt->getPtr<uint8_t>(), data, size); @@ -228,7 +228,7 @@ BlockingBuffer::doWriteback(Addr addr, void -BlockingBuffer::doWriteback(Packet * &pkt) +BlockingBuffer::doWriteback(PacketPtr &pkt) { writebacks[0/*pkt->req->getThreadNum()*/]++; diff --git a/src/mem/cache/miss/blocking_buffer.hh b/src/mem/cache/miss/blocking_buffer.hh index f7069696c..4408cfc4f 100644 --- a/src/mem/cache/miss/blocking_buffer.hh +++ b/src/mem/cache/miss/blocking_buffer.hh @@ -111,7 +111,7 @@ public: * @param blk_size The block size of the cache. * @param time The time the miss is detected. */ - void handleMiss(Packet * &pkt, int blk_size, Tick time); + void handleMiss(PacketPtr &pkt, int blk_size, Tick time); /** * Fetch the block for the given address and buffer the given target. @@ -122,7 +122,7 @@ public: * @param target The target for the fetch. */ MSHR* fetchBlock(Addr addr, int blk_size, Tick time, - Packet * &target) + PacketPtr &target) { fatal("Unimplemented"); } @@ -131,20 +131,20 @@ public: * Selects a outstanding pktuest to service. * @return The pktuest to service, NULL if none found. */ - Packet * getPacket(); + PacketPtr getPacket(); /** * Set the command to the given bus command. * @param pkt The request to update. * @param cmd The bus command to use. */ - void setBusCmd(Packet * &pkt, Packet::Command cmd); + void setBusCmd(PacketPtr &pkt, Packet::Command cmd); /** * Restore the original command in case of a bus transmission error. * @param pkt The request to reset. */ - void restoreOrigCmd(Packet * &pkt); + void restoreOrigCmd(PacketPtr &pkt); /** * Marks a pktuest as in service (sent on the bus). This can have side @@ -152,14 +152,14 @@ public: * are successfully sent. * @param pkt The request that was sent on the bus. */ - void markInService(Packet * &pkt, MSHR* mshr); + void markInService(PacketPtr &pkt, MSHR* mshr); /** * Frees the resources of the pktuest and unblock the cache. * @param pkt The request that has been satisfied. * @param time The time when the pktuest is satisfied. */ - void handleResponse(Packet * &pkt, Tick time); + void handleResponse(PacketPtr &pkt, Tick time); /** * Removes all outstanding pktuests for a given thread number. If a request @@ -223,7 +223,7 @@ public: * Perform a writeback pktuest. * @param pkt The writeback request. */ - void doWriteback(Packet * &pkt); + void doWriteback(PacketPtr &pkt); /** * Returns true if there are outstanding pktuests. @@ -239,7 +239,7 @@ public: * @param mshr The mshr to add a target to. * @param pkt The target to add. */ - void addTarget(MSHR *mshr, Packet * &pkt) + void addTarget(MSHR *mshr, PacketPtr &pkt) { fatal("Shouldn't call this on a blocking buffer."); } diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc index c23b542f5..fe467a8ea 100644 --- a/src/mem/cache/miss/miss_queue.cc +++ b/src/mem/cache/miss/miss_queue.cc @@ -350,7 +350,7 @@ MissQueue::setPrefetcher(BasePrefetcher *_prefetcher) } MSHR* -MissQueue::allocateMiss(Packet * &pkt, int size, Tick time) +MissQueue::allocateMiss(PacketPtr &pkt, int size, Tick time) { MSHR* mshr = mq.allocate(pkt, size); mshr->order = order++; @@ -370,7 +370,7 @@ MissQueue::allocateMiss(Packet * &pkt, int size, Tick time) MSHR* -MissQueue::allocateWrite(Packet * &pkt, int size, Tick time) +MissQueue::allocateWrite(PacketPtr &pkt, int size, Tick time) { MSHR* mshr = wb.allocate(pkt,size); mshr->order = order++; @@ -401,7 +401,7 @@ MissQueue::allocateWrite(Packet * &pkt, int size, Tick time) * @todo Remove SW prefetches on mshr hits. */ void -MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time) +MissQueue::handleMiss(PacketPtr &pkt, int blkSize, Tick time) { // if (!cache->isTopLevel()) if (prefetchMiss) prefetcher->handleMiss(pkt, time); @@ -455,7 +455,7 @@ MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time) MSHR* MissQueue::fetchBlock(Addr addr, int blk_size, Tick time, - Packet * &target) + PacketPtr &target) { Addr blkAddr = addr & ~(Addr)(blk_size - 1); assert(mq.findMatch(addr) == NULL); @@ -469,10 +469,10 @@ MissQueue::fetchBlock(Addr addr, int blk_size, Tick time, return mshr; } -Packet * +PacketPtr MissQueue::getPacket() { - Packet * pkt = mq.getReq(); + PacketPtr pkt = mq.getReq(); if (((wb.isFull() && wb.inServiceMSHRs == 0) || !pkt || pkt->time > curTick) && wb.havePending()) { pkt = wb.getReq(); @@ -510,7 +510,7 @@ MissQueue::getPacket() } void -MissQueue::setBusCmd(Packet * &pkt, Packet::Command cmd) +MissQueue::setBusCmd(PacketPtr &pkt, Packet::Command cmd) { assert(pkt->senderState != 0); MSHR * mshr = (MSHR*)pkt->senderState; @@ -528,13 +528,13 @@ MissQueue::setBusCmd(Packet * &pkt, Packet::Command cmd) } void -MissQueue::restoreOrigCmd(Packet * &pkt) +MissQueue::restoreOrigCmd(PacketPtr &pkt) { pkt->cmd = ((MSHR*)(pkt->senderState))->originalCmd; } void -MissQueue::markInService(Packet * &pkt, MSHR* mshr) +MissQueue::markInService(PacketPtr &pkt, MSHR* mshr) { bool unblock = false; BlockedCause cause = NUM_BLOCKED_CAUSES; @@ -583,7 +583,7 @@ MissQueue::markInService(Packet * &pkt, MSHR* mshr) void -MissQueue::handleResponse(Packet * &pkt, Tick time) +MissQueue::handleResponse(PacketPtr &pkt, Tick time) { MSHR* mshr = (MSHR*)pkt->senderState; if (((MSHR*)(pkt->senderState))->originalCmd == Packet::HardPFReq) { @@ -632,7 +632,7 @@ MissQueue::handleResponse(Packet * &pkt, Tick time) if (mshr->hasTargets() && pkt->req->isUncacheable()) { // Should only have 1 target if we had any assert(num_targets == 1); - Packet * target = mshr->getTarget(); + PacketPtr target = mshr->getTarget(); mshr->popTarget(); if (pkt->isRead()) { memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), @@ -645,7 +645,7 @@ MissQueue::handleResponse(Packet * &pkt, Tick time) //Must be a no_allocate with possibly more than one target assert(mshr->pkt->isNoAllocate()); while (mshr->hasTargets()) { - Packet * target = mshr->getTarget(); + PacketPtr target = mshr->getTarget(); mshr->popTarget(); if (pkt->isRead()) { memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), @@ -721,7 +721,7 @@ MissQueue::doWriteback(Addr addr, { // Generate request Request * req = new Request(addr, size, 0); - Packet * pkt = new Packet(req, Packet::Writeback, -1); + PacketPtr pkt = new Packet(req, Packet::Writeback, -1); pkt->allocate(); if (data) { memcpy(pkt->getPtr<uint8_t>(), data, size); @@ -739,7 +739,7 @@ MissQueue::doWriteback(Addr addr, void -MissQueue::doWriteback(Packet * &pkt) +MissQueue::doWriteback(PacketPtr &pkt) { writebacks[0/*pkt->req->getThreadNum()*/]++; allocateWrite(pkt, 0, curTick); diff --git a/src/mem/cache/miss/miss_queue.hh b/src/mem/cache/miss/miss_queue.hh index 179638d2b..2e04802fb 100644 --- a/src/mem/cache/miss/miss_queue.hh +++ b/src/mem/cache/miss/miss_queue.hh @@ -169,7 +169,7 @@ class MissQueue * @param time The time the miss occurs. * @return A pointer to the new MSHR. */ - MSHR* allocateMiss(Packet * &pkt, int size, Tick time); + MSHR* allocateMiss(PacketPtr &pkt, int size, Tick time); /** * Allocate a new WriteBuffer to handle the provided write. @@ -178,7 +178,7 @@ class MissQueue * @param time The time the write occurs. * @return A pointer to the new write buffer. */ - MSHR* allocateWrite(Packet * &pkt, int size, Tick time); + MSHR* allocateWrite(PacketPtr &pkt, int size, Tick time); public: /** @@ -218,7 +218,7 @@ class MissQueue * @param blk_size The block size of the cache. * @param time The time the miss is detected. */ - void handleMiss(Packet * &pkt, int blk_size, Tick time); + void handleMiss(PacketPtr &pkt, int blk_size, Tick time); /** * Fetch the block for the given address and buffer the given target. @@ -229,26 +229,26 @@ class MissQueue * @param target The target for the fetch. */ MSHR* fetchBlock(Addr addr, int blk_size, Tick time, - Packet * &target); + PacketPtr &target); /** * Selects a outstanding pktuest to service. * @return The pktuest to service, NULL if none found. */ - Packet * getPacket(); + PacketPtr getPacket(); /** * Set the command to the given bus command. * @param pkt The request to update. * @param cmd The bus command to use. */ - void setBusCmd(Packet * &pkt, Packet::Command cmd); + void setBusCmd(PacketPtr &pkt, Packet::Command cmd); /** * Restore the original command in case of a bus transmission error. * @param pkt The request to reset. */ - void restoreOrigCmd(Packet * &pkt); + void restoreOrigCmd(PacketPtr &pkt); /** * Marks a pktuest as in service (sent on the bus). This can have side @@ -256,14 +256,14 @@ class MissQueue * are successfully sent. * @param pkt The request that was sent on the bus. */ - void markInService(Packet * &pkt, MSHR* mshr); + void markInService(PacketPtr &pkt, MSHR* mshr); /** * Collect statistics and free resources of a satisfied pktuest. * @param pkt The request that has been satisfied. * @param time The time when the pktuest is satisfied. */ - void handleResponse(Packet * &pkt, Tick time); + void handleResponse(PacketPtr &pkt, Tick time); /** * Removes all outstanding pktuests for a given thread number. If a request @@ -316,7 +316,7 @@ class MissQueue * Perform the given writeback pktuest. * @param pkt The writeback request. */ - void doWriteback(Packet * &pkt); + void doWriteback(PacketPtr &pkt); /** * Returns true if there are outstanding pktuests. @@ -329,7 +329,7 @@ class MissQueue * @param mshr The mshr to add a target to. * @param pkt The target to add. */ - void addTarget(MSHR *mshr, Packet * &pkt) + void addTarget(MSHR *mshr, PacketPtr &pkt) { mq.allocateTarget(mshr, pkt); } diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc index 455798f15..fc520b4b4 100644 --- a/src/mem/cache/miss/mshr.cc +++ b/src/mem/cache/miss/mshr.cc @@ -55,7 +55,7 @@ MSHR::MSHR() void MSHR::allocate(Packet::Command cmd, Addr _addr, int size, - Packet * &target) + PacketPtr &target) { addr = _addr; if (target) @@ -85,7 +85,7 @@ MSHR::allocate(Packet::Command cmd, Addr _addr, int size, * @todo When we have a "global" data flag, might want to copy data here. */ void -MSHR::allocateAsBuffer(Packet * &target) +MSHR::allocateAsBuffer(PacketPtr &target) { addr = target->getAddr(); threadNum = 0/*target->req->getThreadNum()*/; @@ -111,13 +111,13 @@ MSHR::deallocate() * Adds a target to an MSHR */ void -MSHR::allocateTarget(Packet * &target) +MSHR::allocateTarget(PacketPtr &target) { //If we append an invalidate and we issued a read to the bus, //but now have some pending writes, we need to move //the invalidate to before the first non-read if (inService && pkt->isRead() && target->isInvalidate()) { - std::list<Packet *> temp; + std::list<PacketPtr> temp; while (!targets.empty()) { if (!targets.front()->isRead()) break; diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh index 028259b35..d92aa8a85 100644 --- a/src/mem/cache/miss/mshr.hh +++ b/src/mem/cache/miss/mshr.hh @@ -49,9 +49,9 @@ class MSHR; class MSHR { public: /** Defines the Data structure of the MSHR targetlist. */ - typedef std::list<Packet *> TargetList; + typedef std::list<PacketPtr> TargetList; /** Target list iterator. */ - typedef std::list<Packet *>::iterator TargetListIterator; + typedef std::list<PacketPtr>::iterator TargetListIterator; /** A list of MSHRs. */ typedef std::list<MSHR *> List; /** MSHR list iterator. */ @@ -68,7 +68,7 @@ class MSHR { /** Thread number of the miss. */ int threadNum; /** The pktuest that is forwarded to the next level of the hierarchy. */ - Packet * pkt; + PacketPtr pkt; /** The number of currently allocated targets. */ short ntargets; /** The original pktuesting command. */ @@ -101,13 +101,13 @@ public: * @param pkt The original miss. */ void allocate(Packet::Command cmd, Addr addr, int size, - Packet * &pkt); + PacketPtr &pkt); /** * Allocate this MSHR as a buffer for the given pktuest. * @param target The memory pktuest to buffer. */ - void allocateAsBuffer(Packet * &target); + void allocateAsBuffer(PacketPtr &target); /** * Mark this MSHR as free. @@ -118,7 +118,7 @@ public: * Add a pktuest to the list of targets. * @param target The target. */ - void allocateTarget(Packet * &target); + void allocateTarget(PacketPtr &target); /** A simple constructor. */ MSHR(); @@ -147,7 +147,7 @@ public: * Returns a reference to the first target. * @return A pointer to the first target. */ - Packet * getTarget() + PacketPtr getTarget() { return targets.front(); } diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc index 1876a8987..d3a7a7933 100644 --- a/src/mem/cache/miss/mshr_queue.cc +++ b/src/mem/cache/miss/mshr_queue.cc @@ -88,7 +88,7 @@ MSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const } MSHR* -MSHRQueue::findPending(Packet * &pkt) const +MSHRQueue::findPending(PacketPtr &pkt) const { MSHR::ConstIterator i = pendingList.begin(); MSHR::ConstIterator end = pendingList.end(); @@ -103,29 +103,12 @@ MSHRQueue::findPending(Packet * &pkt) const return mshr; } } - - //need to check destination address for copies. - //TEMP NOT DOING COPIES -#if 0 - if (mshr->pkt->cmd == Copy) { - Addr dest = mshr->pkt->dest; - if (dest < pkt->addr) { - if (dest + mshr->pkt->size > pkt->addr) { - return mshr; - } - } else { - if (pkt->addr + pkt->size > dest) { - return mshr; - } - } - } -#endif } return NULL; } MSHR* -MSHRQueue::allocate(Packet * &pkt, int size) +MSHRQueue::allocate(PacketPtr &pkt, int size) { Addr aligned_addr = pkt->getAddr() & ~((Addr)size - 1); assert(!freeList.empty()); @@ -148,7 +131,7 @@ MSHRQueue::allocate(Packet * &pkt, int size) } MSHR* -MSHRQueue::allocateFetch(Addr addr, int size, Packet * &target) +MSHRQueue::allocateFetch(Addr addr, int size, PacketPtr &target) { MSHR *mshr = freeList.front(); assert(mshr->getNumTargets() == 0); @@ -167,7 +150,7 @@ MSHRQueue::allocateTargetList(Addr addr, int size) MSHR *mshr = freeList.front(); assert(mshr->getNumTargets() == 0); freeList.pop_front(); - Packet * dummy; + PacketPtr dummy; mshr->allocate(Packet::ReadReq, addr, size, dummy); mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); mshr->inService = true; @@ -213,7 +196,7 @@ void MSHRQueue::markInService(MSHR* mshr) { //assert(mshr == pendingList.front()); - if (!(mshr->pkt->needsResponse() || mshr->pkt->cmd == Packet::UpgradeReq)) { + if (!mshr->pkt->needsResponse() && !(mshr->pkt->cmd == Packet::UpgradeReq)) { assert(mshr->getNumTargets() == 0); if ((mshr->pkt->flags & SATISFIED) && (mshr->pkt->cmd == Packet::Writeback)) { //Writeback hit, so delete it @@ -254,7 +237,7 @@ MSHRQueue::squash(int threadNum) MSHR *mshr = *i; if (mshr->threadNum == threadNum) { while (mshr->hasTargets()) { - Packet * target = mshr->getTarget(); + PacketPtr target = mshr->getTarget(); mshr->popTarget(); assert(0/*target->req->getThreadNum()*/ == threadNum); diff --git a/src/mem/cache/miss/mshr_queue.hh b/src/mem/cache/miss/mshr_queue.hh index ea5f101b7..30397d9a0 100644 --- a/src/mem/cache/miss/mshr_queue.hh +++ b/src/mem/cache/miss/mshr_queue.hh @@ -107,7 +107,7 @@ class MSHRQueue { * @param pkt The request to find. * @return A pointer to the earliest matching MSHR. */ - MSHR* findPending(Packet * &pkt) const; + MSHR* findPending(PacketPtr &pkt) const; /** * Allocates a new MSHR for the pktuest and size. This places the request @@ -118,7 +118,7 @@ class MSHRQueue { * * @pre There are free MSHRs. */ - MSHR* allocate(Packet * &pkt, int size = 0); + MSHR* allocate(PacketPtr &pkt, int size = 0); /** * Allocate a read pktuest for the given address, and places the given @@ -129,7 +129,7 @@ class MSHRQueue { * @param target The first target for the pktuest. * @return Pointer to the new MSHR. */ - MSHR* allocateFetch(Addr addr, int size, Packet * &target); + MSHR* allocateFetch(Addr addr, int size, PacketPtr &target); /** * Allocate a target list for the given address. @@ -153,7 +153,7 @@ class MSHRQueue { * @param mshr The MSHR to allocate the target to. * @param pkt The target request. */ - void allocateTarget(MSHR* mshr, Packet * &pkt) + void allocateTarget(MSHR* mshr, PacketPtr &pkt) { mshr->allocateTarget(pkt); allocatedTargets += 1; @@ -216,7 +216,7 @@ class MSHRQueue { * Returns the pktuest at the head of the pendingList. * @return The next pktuest to service. */ - Packet * getReq() const + PacketPtr getReq() const { if (pendingList.empty()) { return NULL; diff --git a/src/mem/cache/prefetch/base_prefetcher.cc b/src/mem/cache/prefetch/base_prefetcher.cc index 5e50c48bd..a1388fad6 100644 --- a/src/mem/cache/prefetch/base_prefetcher.cc +++ b/src/mem/cache/prefetch/base_prefetcher.cc @@ -102,7 +102,7 @@ BasePrefetcher::regStats(const std::string &name) ; } -Packet * +PacketPtr BasePrefetcher::getPacket() { DPRINTF(HWPrefetch, "%s:Requesting a hw_pf to issue\n", cache->name()); @@ -112,7 +112,7 @@ BasePrefetcher::getPacket() return NULL; } - Packet * pkt; + PacketPtr pkt; bool keepTrying = false; do { pkt = *pf.begin(); @@ -131,7 +131,7 @@ BasePrefetcher::getPacket() } void -BasePrefetcher::handleMiss(Packet * &pkt, Tick time) +BasePrefetcher::handleMiss(PacketPtr &pkt, Tick time) { if (!pkt->req->isUncacheable() && !(pkt->req->isInstRead() && only_data)) { @@ -139,7 +139,7 @@ BasePrefetcher::handleMiss(Packet * &pkt, Tick time) Addr blkAddr = pkt->getAddr() & ~(Addr)(blkSize-1); //Check if miss is in pfq, if so remove it - std::list<Packet *>::iterator iter = inPrefetch(blkAddr); + std::list<PacketPtr>::iterator iter = inPrefetch(blkAddr); if (iter != pf.end()) { DPRINTF(HWPrefetch, "%s:Saw a miss to a queued prefetch, removing it\n", cache->name()); pfRemovedMSHR++; @@ -179,7 +179,7 @@ BasePrefetcher::handleMiss(Packet * &pkt, Tick time) pfIdentified++; //create a prefetch memreq Request * prefetchReq = new Request(*addr, blkSize, 0); - Packet * prefetch; + PacketPtr prefetch; prefetch = new Packet(prefetchReq, Packet::HardPFReq, -1); prefetch->allocate(); prefetch->req->setThreadContext(pkt->req->getCpuNum(), @@ -233,11 +233,11 @@ BasePrefetcher::handleMiss(Packet * &pkt, Tick time) } } -std::list<Packet *>::iterator +std::list<PacketPtr>::iterator BasePrefetcher::inPrefetch(Addr address) { //Guaranteed to only be one match, we always check before inserting - std::list<Packet *>::iterator iter; + std::list<PacketPtr>::iterator iter; for (iter=pf.begin(); iter != pf.end(); iter++) { if (((*iter)->getAddr() & ~(Addr)(blkSize-1)) == address) { return iter; diff --git a/src/mem/cache/prefetch/base_prefetcher.hh b/src/mem/cache/prefetch/base_prefetcher.hh index d7ea41961..781d3ab09 100644 --- a/src/mem/cache/prefetch/base_prefetcher.hh +++ b/src/mem/cache/prefetch/base_prefetcher.hh @@ -45,7 +45,7 @@ class BasePrefetcher protected: /** The Prefetch Queue. */ - std::list<Packet *> pf; + std::list<PacketPtr> pf; // PARAMETERS @@ -93,24 +93,24 @@ class BasePrefetcher void setCache(BaseCache *_cache); - void handleMiss(Packet * &pkt, Tick time); + void handleMiss(PacketPtr &pkt, Tick time); - Packet * getPacket(); + PacketPtr getPacket(); bool havePending() { return !pf.empty(); } - virtual void calculatePrefetch(Packet * &pkt, + virtual void calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses, std::list<Tick> &delays) = 0; - virtual bool inCache(Packet * &pkt) = 0; + virtual bool inCache(PacketPtr &pkt) = 0; virtual bool inMissQueue(Addr address) = 0; - std::list<Packet *>::iterator inPrefetch(Addr address); + std::list<PacketPtr>::iterator inPrefetch(Addr address); }; diff --git a/src/mem/cache/prefetch/ghb_prefetcher.hh b/src/mem/cache/prefetch/ghb_prefetcher.hh index c22b763d1..14f5747df 100644 --- a/src/mem/cache/prefetch/ghb_prefetcher.hh +++ b/src/mem/cache/prefetch/ghb_prefetcher.hh @@ -75,7 +75,7 @@ class GHBPrefetcher : public Prefetcher<TagStore, Buffering> ~GHBPrefetcher() {} - void calculatePrefetch(Packet * &pkt, std::list<Addr> &addresses, + void calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses, std::list<Tick> &delays) { Addr blkAddr = pkt->getAddr() & ~(Addr)(this->blkSize-1); diff --git a/src/mem/cache/prefetch/stride_prefetcher.hh b/src/mem/cache/prefetch/stride_prefetcher.hh index 4a8ee7de4..d6fb8ab66 100644 --- a/src/mem/cache/prefetch/stride_prefetcher.hh +++ b/src/mem/cache/prefetch/stride_prefetcher.hh @@ -92,7 +92,7 @@ class StridePrefetcher : public Prefetcher<TagStore, Buffering> ~StridePrefetcher() {} - void calculatePrefetch(Packet * &pkt, std::list<Addr> &addresses, + void calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses, std::list<Tick> &delays) { // Addr blkAddr = pkt->paddr & ~(Addr)(this->blkSize-1); diff --git a/src/mem/cache/prefetch/tagged_prefetcher.hh b/src/mem/cache/prefetch/tagged_prefetcher.hh index 17f500dd8..b61e57dcc 100644 --- a/src/mem/cache/prefetch/tagged_prefetcher.hh +++ b/src/mem/cache/prefetch/tagged_prefetcher.hh @@ -64,7 +64,7 @@ class TaggedPrefetcher : public Prefetcher<TagStore, Buffering> ~TaggedPrefetcher() {} - void calculatePrefetch(Packet * &pkt, std::list<Addr> &addresses, + void calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses, std::list<Tick> &delays); }; diff --git a/src/mem/cache/prefetch/tagged_prefetcher_impl.hh b/src/mem/cache/prefetch/tagged_prefetcher_impl.hh index e554b3cec..a18de4571 100644 --- a/src/mem/cache/prefetch/tagged_prefetcher_impl.hh +++ b/src/mem/cache/prefetch/tagged_prefetcher_impl.hh @@ -50,7 +50,7 @@ TaggedPrefetcher(int size, bool pageStop, bool serialSquash, template <class TagStore, class Buffering> void TaggedPrefetcher<TagStore, Buffering>:: -calculatePrefetch(Packet * &pkt, std::list<Addr> &addresses, +calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses, std::list<Tick> &delays) { Addr blkAddr = pkt->getAddr() & ~(Addr)(this->blkSize-1); diff --git a/src/mem/cache/tags/fa_lru.cc b/src/mem/cache/tags/fa_lru.cc index 784ba1311..a58ddaff8 100644 --- a/src/mem/cache/tags/fa_lru.cc +++ b/src/mem/cache/tags/fa_lru.cc @@ -203,7 +203,7 @@ FALRU::findBlock(Addr addr, int &lat, int *inCache) } FALRUBlk* -FALRU::findBlock(Packet * &pkt, int &lat, int *inCache) +FALRU::findBlock(PacketPtr &pkt, int &lat, int *inCache) { Addr addr = pkt->getAddr(); @@ -256,7 +256,7 @@ FALRU::findBlock(Addr addr) const } FALRUBlk* -FALRU::findReplacement(Packet * &pkt, PacketList &writebacks, +FALRU::findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks) { FALRUBlk * blk = tail; diff --git a/src/mem/cache/tags/fa_lru.hh b/src/mem/cache/tags/fa_lru.hh index f9d4d7109..2db89d603 100644 --- a/src/mem/cache/tags/fa_lru.hh +++ b/src/mem/cache/tags/fa_lru.hh @@ -198,7 +198,7 @@ public: * @param inCache The FALRUBlk::inCache flags. * @return Pointer to the cache block. */ - FALRUBlk* findBlock(Packet * &pkt, int &lat, int *inCache = 0); + FALRUBlk* findBlock(PacketPtr &pkt, int &lat, int *inCache = 0); /** * Find the block in the cache, do not update the replacement data. @@ -215,7 +215,7 @@ public: * @param compress_blocks List of blocks to compress, for adaptive comp. * @return The block to place the replacement in. */ - FALRUBlk* findReplacement(Packet * &pkt, PacketList & writebacks, + FALRUBlk* findReplacement(PacketPtr &pkt, PacketList & writebacks, BlkList &compress_blocks); /** @@ -322,25 +322,6 @@ public: PacketList &writebacks) { } - - /** - * Unimplemented. Perform a cache block copy from block aligned addresses. - * @param source The block aligned source address. - * @param dest The block aligned destination adddress. - * @param asid The address space ID. - * @param writebacks List for any generated writeback pktuests. - */ - void doCopy(Addr source, Addr dest, PacketList &writebacks) - { - } - - /** - * Unimplemented. - */ - void fixCopy(Packet * &pkt, PacketList &writebacks) - { - } - }; #endif diff --git a/src/mem/cache/tags/iic.cc b/src/mem/cache/tags/iic.cc index 1377c8613..f4e870659 100644 --- a/src/mem/cache/tags/iic.cc +++ b/src/mem/cache/tags/iic.cc @@ -285,7 +285,7 @@ IIC::findBlock(Addr addr, int &lat) } IICTag* -IIC::findBlock(Packet * &pkt, int &lat) +IIC::findBlock(PacketPtr &pkt, int &lat) { Addr addr = pkt->getAddr(); @@ -362,7 +362,7 @@ IIC::findBlock(Addr addr) const IICTag* -IIC::findReplacement(Packet * &pkt, PacketList &writebacks, +IIC::findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks) { DPRINTF(IIC, "Finding Replacement for %x\n", pkt->getAddr()); @@ -423,7 +423,7 @@ IIC::freeReplacementBlock(PacketList & writebacks) tag_ptr->refCount = 0; if (tag_ptr->isModified()) { -/* Packet * writeback = +/* PacketPtr writeback = buildWritebackReq(regenerateBlkAddr(tag_ptr->tag, 0), tag_ptr->req->asid, tag_ptr->xc, blkSize, tag_ptr->data, @@ -431,7 +431,7 @@ IIC::freeReplacementBlock(PacketList & writebacks) */ Request *writebackReq = new Request(regenerateBlkAddr(tag_ptr->tag, 0), blkSize, 0); - Packet *writeback = new Packet(writebackReq, Packet::Writeback, -1); + PacketPtr writeback = new Packet(writebackReq, Packet::Writeback, -1); writeback->allocate(); memcpy(writeback->getPtr<uint8_t>(), tag_ptr->data, blkSize); @@ -711,8 +711,8 @@ IIC::invalidateBlk(Addr addr) } void -IIC::readData(IICTag *blk, uint8_t *data){ -// assert(cache->doData()); +IIC::readData(IICTag *blk, uint8_t *data) +{ assert(blk->size <= trivialSize || blk->numData > 0); int data_size = blk->size; if (data_size > trivialSize) { @@ -729,8 +729,8 @@ IIC::readData(IICTag *blk, uint8_t *data){ void IIC::writeData(IICTag *blk, uint8_t *write_data, int size, - PacketList & writebacks){ -// assert(cache->doData()); + PacketList & writebacks) +{ assert(size < blkSize || !blk->isCompressed()); DPRINTF(IIC, "Writing %d bytes to %x\n", size, blk->tag<<tagShift); @@ -750,10 +750,6 @@ IIC::writeData(IICTag *blk, uint8_t *write_data, int size, // can free data blocks for (int i=num_subs; i < blk->numData; ++i){ // decrement reference count and compare to zero - /** - * @todo - * Make this work with copying. - */ if (--dataReferenceCount[blk->data_ptr[i]] == 0) { freeDataBlock(blk->data_ptr[i]); } @@ -775,96 +771,6 @@ IIC::writeData(IICTag *blk, uint8_t *write_data, int size, } -/** - * @todo This code can break if the src is evicted to get a tag for the dest. - */ -void -IIC::doCopy(Addr source, Addr dest, PacketList &writebacks) -{ -//Copy unsuported now -#if 0 - IICTag *dest_tag = findBlock(dest); - - if (dest_tag) { - for (int i = 0; i < dest_tag->numData; ++i) { - if (--dataReferenceCount[dest_tag->data_ptr[i]] == 0) { - freeDataBlock(dest_tag->data_ptr[i]); - } - } - // Reset replacement entry - } else { - dest_tag = getFreeTag(hash(dest), writebacks); - dest_tag->re = (void*) repl->add(dest_tag - tagStore); - dest_tag->set = hash(dest); - dest_tag->tag = extractTag(dest); - dest_tag->status = BlkValid | BlkWritable; - } - // Find the source tag here since it might move if we need to find a - // tag for the destination. - IICTag *src_tag = findBlock(source); - assert(src_tag); - assert(!cache->doData() || src_tag->size <= trivialSize - || src_tag->numData > 0); - // point dest to source data and inc counter - for (int i = 0; i < src_tag->numData; ++i) { - dest_tag->data_ptr[i] = src_tag->data_ptr[i]; - ++dataReferenceCount[dest_tag->data_ptr[i]]; - } - - // Maintain fast access data. - memcpy(dest_tag->data, src_tag->data, blkSize); - - dest_tag->xc = src_tag->xc; - dest_tag->size = src_tag->size; - dest_tag->numData = src_tag->numData; - if (src_tag->numData == 0) { - // Data is stored in the trivial data, just copy it. - memcpy(dest_tag->trivialData, src_tag->trivialData, src_tag->size); - } - - dest_tag->status |= BlkDirty; - if (dest_tag->size < blkSize) { - dest_tag->status |= BlkCompressed; - } else { - dest_tag->status &= ~BlkCompressed; - } -#endif -} - -void -IIC::fixCopy(Packet * &pkt, PacketList &writebacks) -{ -#if 0 - // if reference counter is greater than 1, do copy - // else do write - Addr blk_addr = blkAlign(pkt->getAddr); - IICTag* blk = findBlock(blk_addr); - - if (blk->numData > 0 && dataReferenceCount[blk->data_ptr[0]] != 1) { - // copy the data - // Mark the block as referenced so it doesn't get replaced. - blk->status |= BlkReferenced; - for (int i = 0; i < blk->numData; ++i){ - unsigned long new_data = getFreeDataBlock(writebacks); - // Need to refresh pointer - /** - * @todo Remove this refetch once we change IIC to pointer based - */ - blk = findBlock(blk_addr); - assert(blk); - if (cache->doData()) { - memcpy(&(dataBlks[new_data][0]), - &(dataBlks[blk->data_ptr[i]][0]), - subSize); - } - dataReferenceCount[blk->data_ptr[i]]--; - dataReferenceCount[new_data]++; - blk->data_ptr[i] = new_data; - } - } -#endif -} - void IIC::cleanupRefs() { diff --git a/src/mem/cache/tags/iic.hh b/src/mem/cache/tags/iic.hh index 2357bdce3..92bd6da1d 100644 --- a/src/mem/cache/tags/iic.hh +++ b/src/mem/cache/tags/iic.hh @@ -458,7 +458,7 @@ class IIC : public BaseTags * @param lat The access latency. * @return A pointer to the block found, if any. */ - IICTag* findBlock(Packet * &pkt, int &lat); + IICTag* findBlock(PacketPtr &pkt, int &lat); /** * Find the block, do not update the replacement data. @@ -475,7 +475,7 @@ class IIC : public BaseTags * @param compress_blocks List of blocks to compress, for adaptive comp. * @return The block to place the replacement in. */ - IICTag* findReplacement(Packet * &pkt, PacketList &writebacks, + IICTag* findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks); /** @@ -498,22 +498,6 @@ class IIC : public BaseTags PacketList & writebacks); /** - * Perform a block aligned copy from the source address to the destination. - * @param source The block-aligned source address. - * @param dest The block-aligned destination address. - * @param asid The address space DI. - * @param writebacks List for any generated writeback pktuests. - */ - void doCopy(Addr source, Addr dest, PacketList &writebacks); - - /** - * If a block is currently marked copy on write, copy it before writing. - * @param pkt The write request. - * @param writebacks List for any generated writeback pktuests. - */ - void fixCopy(Packet * &pkt, PacketList &writebacks); - - /** * Called at end of simulation to complete average block reference stats. */ virtual void cleanupRefs(); diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc index 976bbeff2..31d29aae6 100644 --- a/src/mem/cache/tags/lru.cc +++ b/src/mem/cache/tags/lru.cc @@ -184,7 +184,7 @@ LRU::findBlock(Addr addr, int &lat) } LRUBlk* -LRU::findBlock(Packet * &pkt, int &lat) +LRU::findBlock(PacketPtr &pkt, int &lat) { Addr addr = pkt->getAddr(); @@ -215,7 +215,7 @@ LRU::findBlock(Addr addr) const } LRUBlk* -LRU::findReplacement(Packet * &pkt, PacketList &writebacks, +LRU::findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks) { unsigned set = extractSet(pkt->getAddr()); @@ -246,56 +246,12 @@ LRU::invalidateBlk(Addr addr) if (blk) { blk->status = 0; blk->isTouched = false; + blk->clearLoadLocks(); tagsInUse--; } } void -LRU::doCopy(Addr source, Addr dest, PacketList &writebacks) -{ - assert(source == blkAlign(source)); - assert(dest == blkAlign(dest)); - LRUBlk *source_blk = findBlock(source); - assert(source_blk); - LRUBlk *dest_blk = findBlock(dest); - if (dest_blk == NULL) { - // Need to do a replacement - Request *search = new Request(dest,1,0); - Packet * pkt = new Packet(search, Packet::ReadReq, -1); - BlkList dummy_list; - dest_blk = findReplacement(pkt, writebacks, dummy_list); - if (dest_blk->isValid() && dest_blk->isModified()) { - // Need to writeback data. -/* pkt = buildWritebackReq(regenerateBlkAddr(dest_blk->tag, - dest_blk->set), - dest_blk->req->asid, - dest_blk->xc, - blkSize, - dest_blk->data, - dest_blk->size); -*/ - Request *writebackReq = new Request(regenerateBlkAddr(dest_blk->tag, - dest_blk->set), - blkSize, 0); - Packet *writeback = new Packet(writebackReq, Packet::Writeback, -1); - writeback->allocate(); - memcpy(writeback->getPtr<uint8_t>(),dest_blk->data, blkSize); - writebacks.push_back(writeback); - } - dest_blk->tag = extractTag(dest); - delete search; - delete pkt; - } - /** - * @todo Can't assume the status once we have coherence on copies. - */ - - // Set this block as readable, writeable, and dirty. - dest_blk->status = 7; - memcpy(dest_blk->data, source_blk->data, blkSize); -} - -void LRU::cleanupRefs() { for (int i = 0; i < numSets*assoc; ++i) { diff --git a/src/mem/cache/tags/lru.hh b/src/mem/cache/tags/lru.hh index a3a56a0e6..fed688283 100644 --- a/src/mem/cache/tags/lru.hh +++ b/src/mem/cache/tags/lru.hh @@ -174,7 +174,7 @@ public: * @param lat The access latency. * @return Pointer to the cache block if found. */ - LRUBlk* findBlock(Packet * &pkt, int &lat); + LRUBlk* findBlock(PacketPtr &pkt, int &lat); /** * Finds the given address in the cache and update replacement data. @@ -201,7 +201,7 @@ public: * @param compress_blocks List of blocks to compress, for adaptive comp. * @return The block to place the replacement in. */ - LRUBlk* findReplacement(Packet * &pkt, PacketList &writebacks, + LRUBlk* findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks); /** @@ -303,22 +303,6 @@ public: } /** - * Perform a block aligned copy from the source address to the destination. - * @param source The block-aligned source address. - * @param dest The block-aligned destination address. - * @param asid The address space DI. - * @param writebacks List for any generated writeback pktuests. - */ - void doCopy(Addr source, Addr dest, PacketList &writebacks); - - /** - * No impl. - */ - void fixCopy(Packet * &pkt, PacketList &writebacks) - { - } - - /** * Called at end of simulation to complete average block reference stats. */ virtual void cleanupRefs(); diff --git a/src/mem/cache/tags/split.cc b/src/mem/cache/tags/split.cc index 690eea22e..bc74f0e0f 100644 --- a/src/mem/cache/tags/split.cc +++ b/src/mem/cache/tags/split.cc @@ -267,7 +267,7 @@ Split::probe(Addr addr) const } SplitBlk* -Split::findBlock(Packet * &pkt, int &lat) +Split::findBlock(PacketPtr &pkt, int &lat) { Addr aligned = blkAlign(pkt->getAddr()); @@ -350,7 +350,7 @@ Split::findBlock(Addr addr) const } SplitBlk* -Split::findReplacement(Packet * &pkt, PacketList &writebacks, +Split::findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks) { SplitBlk *blk; @@ -422,19 +422,6 @@ Split::invalidateBlk(Addr addr) } void -Split::doCopy(Addr source, Addr dest, PacketList &writebacks) -{ - if (lru->probe( source)) - lru->doCopy(source, dest, writebacks); - else { - if (lifo && lifo_net) - lifo_net->doCopy(source, dest, writebacks); - else if (lru_net) - lru_net->doCopy(source, dest, writebacks); - } -} - -void Split::cleanupRefs() { lru->cleanupRefs(); diff --git a/src/mem/cache/tags/split.hh b/src/mem/cache/tags/split.hh index f0091e971..748f6fb25 100644 --- a/src/mem/cache/tags/split.hh +++ b/src/mem/cache/tags/split.hh @@ -207,7 +207,7 @@ class Split : public BaseTags * @param lat The access latency. * @return Pointer to the cache block if found. */ - SplitBlk* findBlock(Packet * &pkt, int &lat); + SplitBlk* findBlock(PacketPtr &pkt, int &lat); /** * Finds the given address in the cache, do not update replacement data. @@ -224,7 +224,7 @@ class Split : public BaseTags * @param compress_blocks List of blocks to compress, for adaptive comp. * @return The block to place the replacement in. */ - SplitBlk* findReplacement(Packet * &pkt, PacketList &writebacks, + SplitBlk* findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks); @@ -311,22 +311,6 @@ class Split : public BaseTags } /** - * Perform a block aligned copy from the source address to the destination. - * @param source The block-aligned source address. - * @param dest The block-aligned destination address. - * @param asid The address space DI. - * @param writebacks List for any generated writeback pktuests. - */ - void doCopy(Addr source, Addr dest, PacketList &writebacks); - - /** - * No impl. - */ - void fixCopy(Packet * &pkt, PacketList &writebacks) - { - } - - /** * Called at end of simulation to complete average block reference stats. */ virtual void cleanupRefs(); diff --git a/src/mem/cache/tags/split_lifo.cc b/src/mem/cache/tags/split_lifo.cc index 6fcbf3597..302e2aaeb 100644 --- a/src/mem/cache/tags/split_lifo.cc +++ b/src/mem/cache/tags/split_lifo.cc @@ -255,7 +255,7 @@ SplitLIFO::findBlock(Addr addr, int &lat) } SplitBlk* -SplitLIFO::findBlock(Packet * &pkt, int &lat) +SplitLIFO::findBlock(PacketPtr &pkt, int &lat) { Addr addr = pkt->getAddr(); @@ -291,7 +291,7 @@ SplitLIFO::findBlock(Addr addr) const } SplitBlk* -SplitLIFO::findReplacement(Packet * &pkt, PacketList &writebacks, +SplitLIFO::findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks) { unsigned set = extractSet(pkt->getAddr()); @@ -347,52 +347,6 @@ SplitLIFO::invalidateBlk(Addr addr) } void -SplitLIFO::doCopy(Addr source, Addr dest, PacketList &writebacks) -{ -//Copy Unsuported for now -#if 0 - assert(source == blkAlign(source)); - assert(dest == blkAlign(dest)); - SplitBlk *source_blk = findBlock(source); - assert(source_blk); - SplitBlk *dest_blk = findBlock(dest); - if (dest_blk == NULL) { - // Need to do a replacement - Packet * pkt = new Packet(); - pkt->paddr = dest; - BlkList dummy_list; - dest_blk = findReplacement(pkt, writebacks, dummy_list); - if (dest_blk->isValid() && dest_blk->isModified()) { - // Need to writeback data. - pkt = buildWritebackReq(regenerateBlkAddr(dest_blk->tag, - dest_blk->set), - dest_blk->xc, - blkSize, - (cache->doData())?dest_blk->data:0, - dest_blk->size); - writebacks.push_back(pkt); - } - dest_blk->tag = extractTag(dest); - /** - * @todo Do we need to pass in the execution context, or can we - * assume its the same? - */ - assert(source_blk->xc); - dest_blk->xc = source_blk->xc; - } - /** - * @todo Can't assume the status once we have coherence on copies. - */ - - // Set this block as readable, writeable, and dirty. - dest_blk->status = 7; - if (cache->doData()) { - memcpy(dest_blk->data, source_blk->data, blkSize); - } -#endif -} - -void SplitLIFO::cleanupRefs() { for (int i = 0; i < numBlks; ++i) { diff --git a/src/mem/cache/tags/split_lifo.hh b/src/mem/cache/tags/split_lifo.hh index 355a66162..6c3befe37 100644 --- a/src/mem/cache/tags/split_lifo.hh +++ b/src/mem/cache/tags/split_lifo.hh @@ -207,7 +207,7 @@ public: * @param lat The access latency. * @return Pointer to the cache block if found. */ - SplitBlk* findBlock(Packet * &pkt, int &lat); + SplitBlk* findBlock(PacketPtr &pkt, int &lat); /** * Finds the given address in the cache, do not update replacement data. @@ -224,7 +224,7 @@ public: * @param compress_blocks List of blocks to compress, for adaptive comp. * @return The block to place the replacement in. */ - SplitBlk* findReplacement(Packet * &pkt, PacketList &writebacks, + SplitBlk* findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks); /** @@ -326,22 +326,6 @@ public: } /** - * Perform a block aligned copy from the source address to the destination. - * @param source The block-aligned source address. - * @param dest The block-aligned destination address. - * @param asid The address space DI. - * @param writebacks List for any generated writeback pktuests. - */ - void doCopy(Addr source, Addr dest, PacketList &writebacks); - - /** - * No impl. - */ - void fixCopy(Packet * &pkt, PacketList &writebacks) - { - } - - /** * Called at end of simulation to complete average block reference stats. */ virtual void cleanupRefs(); diff --git a/src/mem/cache/tags/split_lru.cc b/src/mem/cache/tags/split_lru.cc index 4381923bd..11c9a5d64 100644 --- a/src/mem/cache/tags/split_lru.cc +++ b/src/mem/cache/tags/split_lru.cc @@ -203,7 +203,7 @@ SplitLRU::findBlock(Addr addr, int &lat) } SplitBlk* -SplitLRU::findBlock(Packet * &pkt, int &lat) +SplitLRU::findBlock(PacketPtr &pkt, int &lat) { Addr addr = pkt->getAddr(); @@ -234,7 +234,7 @@ SplitLRU::findBlock(Addr addr) const } SplitBlk* -SplitLRU::findReplacement(Packet * &pkt, PacketList &writebacks, +SplitLRU::findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks) { unsigned set = extractSet(pkt->getAddr()); @@ -272,52 +272,6 @@ SplitLRU::invalidateBlk(Addr addr) } void -SplitLRU::doCopy(Addr source, Addr dest, PacketList &writebacks) -{ -//Copy not supported for now -#if 0 - assert(source == blkAlign(source)); - assert(dest == blkAlign(dest)); - SplitBlk *source_blk = findBlock(source); - assert(source_blk); - SplitBlk *dest_blk = findBlock(dest); - if (dest_blk == NULL) { - // Need to do a replacement - Packet * pkt = new Packet(); - pkt->paddr = dest; - BlkList dummy_list; - dest_blk = findReplacement(pkt, writebacks, dummy_list); - if (dest_blk->isValid() && dest_blk->isModified()) { - // Need to writeback data. - pkt = buildWritebackReq(regenerateBlkAddr(dest_blk->tag, - dest_blk->set), - dest_blk->xc, - blkSize, - (cache->doData())?dest_blk->data:0, - dest_blk->size); - writebacks.push_back(pkt); - } - dest_blk->tag = extractTag(dest); - /** - * @todo Do we need to pass in the execution context, or can we - * assume its the same? - */ - assert(source_blk->xc); - dest_blk->xc = source_blk->xc; - } - /** - * @todo Can't assume the status once we have coherence on copies. - */ - - // Set this block as readable, writeable, and dirty. - dest_blk->status = 7; - if (cache->doData()) { - memcpy(dest_blk->data, source_blk->data, blkSize); - } -#endif -} - -void SplitLRU::cleanupRefs() { for (int i = 0; i < numSets*assoc; ++i) { diff --git a/src/mem/cache/tags/split_lru.hh b/src/mem/cache/tags/split_lru.hh index 72aebac9c..6160d59e5 100644 --- a/src/mem/cache/tags/split_lru.hh +++ b/src/mem/cache/tags/split_lru.hh @@ -190,7 +190,7 @@ public: * @param lat The access latency. * @return Pointer to the cache block if found. */ - SplitBlk* findBlock(Packet * &pkt, int &lat); + SplitBlk* findBlock(PacketPtr &pkt, int &lat); /** * Finds the given address in the cache, do not update replacement data. @@ -207,7 +207,7 @@ public: * @param compress_blocks List of blocks to compress, for adaptive comp. * @return The block to place the replacement in. */ - SplitBlk* findReplacement(Packet * &pkt, PacketList &writebacks, + SplitBlk* findReplacement(PacketPtr &pkt, PacketList &writebacks, BlkList &compress_blocks); /** @@ -309,22 +309,6 @@ public: } /** - * Perform a block aligned copy from the source address to the destination. - * @param source The block-aligned source address. - * @param dest The block-aligned destination address. - * @param asid The address space DI. - * @param writebacks List for any generated writeback pktuests. - */ - void doCopy(Addr source, Addr dest, PacketList &writebacks); - - /** - * No impl. - */ - void fixCopy(Packet * &pkt, PacketList &writebacks) - { - } - - /** * Called at end of simulation to complete average block reference stats. */ virtual void cleanupRefs(); diff --git a/src/mem/dram.cc b/src/mem/dram.cc index d7b955975..873ca5b97 100644 --- a/src/mem/dram.cc +++ b/src/mem/dram.cc @@ -359,7 +359,7 @@ DRAMMemory::regStats() static char *mem_access_output=NULL; /* latency of access [CPU cycles]*/ Tick -DRAMMemory::calculateLatency(Packet *pkt) +DRAMMemory::calculateLatency(PacketPtr pkt) { bool cmdIsRead = pkt->isRead(); diff --git a/src/mem/dram.hh b/src/mem/dram.hh index 32d117596..9d2f60ee8 100644 --- a/src/mem/dram.hh +++ b/src/mem/dram.hh @@ -140,7 +140,7 @@ class DRAMMemory : public PhysicalMemory protected: - Tick calculateLatency(Packet *pkt); + Tick calculateLatency(PacketPtr pkt); int prechargeBanksAround(int bank); public: diff --git a/src/mem/packet.cc b/src/mem/packet.cc index 64c65dcca..fa8d82c46 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -36,9 +36,10 @@ */ #include <iostream> + #include "base/misc.hh" -#include "mem/packet.hh" #include "base/trace.hh" +#include "mem/packet.hh" static const std::string ReadReqString("ReadReq"); static const std::string WriteReqString("WriteReq"); @@ -51,6 +52,7 @@ static const std::string HardPFReqString("HardPFReq"); static const std::string HardPFRespString("HardPFResp"); static const std::string InvalidateReqString("InvalidateReq"); static const std::string WriteInvalidateReqString("WriteInvalidateReq"); +static const std::string WriteInvalidateRespString("WriteInvalidateResp"); static const std::string UpgradeReqString("UpgradeReq"); static const std::string ReadExReqString("ReadExReq"); static const std::string ReadExRespString("ReadExResp"); @@ -71,6 +73,7 @@ Packet::cmdString() const case HardPFResp: return HardPFRespString; case InvalidateReq: return InvalidateReqString; case WriteInvalidateReq:return WriteInvalidateReqString; + case WriteInvalidateResp:return WriteInvalidateRespString; case UpgradeReq: return UpgradeReqString; case ReadExReq: return ReadExReqString; case ReadExResp: return ReadExRespString; @@ -93,6 +96,7 @@ Packet::cmdIdxToString(Packet::Command idx) case HardPFResp: return HardPFRespString; case InvalidateReq: return InvalidateReqString; case WriteInvalidateReq:return WriteInvalidateReqString; + case WriteInvalidateResp:return WriteInvalidateRespString; case UpgradeReq: return UpgradeReqString; case ReadExReq: return ReadExReqString; case ReadExResp: return ReadExRespString; @@ -129,7 +133,7 @@ Packet::allocate() /** Do the packet modify the same addresses. */ bool -Packet::intersect(Packet *p) +Packet::intersect(PacketPtr p) { Addr s1 = getAddr(); Addr e1 = getAddr() + getSize() - 1; @@ -140,14 +144,14 @@ Packet::intersect(Packet *p) } bool -fixPacket(Packet *func, Packet *timing) +fixPacket(PacketPtr func, PacketPtr timing) { Addr funcStart = func->getAddr(); Addr funcEnd = func->getAddr() + func->getSize() - 1; Addr timingStart = timing->getAddr(); Addr timingEnd = timing->getAddr() + timing->getSize() - 1; - assert(!(funcStart > timingEnd || timingStart < funcEnd)); + assert(!(funcStart > timingEnd || timingStart > funcEnd)); if (DTRACE(FunctionalAccess)) { DebugOut() << func; diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 48b32ec47..d8ad49bdb 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -38,14 +38,15 @@ #ifndef __MEM_PACKET_HH__ #define __MEM_PACKET_HH__ +#include <cassert> +#include <list> + #include "mem/request.hh" #include "sim/host.hh" #include "sim/root.hh" -#include <list> -#include <cassert> struct Packet; -typedef Packet* PacketPtr; +typedef Packet *PacketPtr; typedef uint8_t* PacketDataPtr; typedef std::list<PacketPtr> PacketList; @@ -102,7 +103,7 @@ class Packet /** Device address (e.g., bus ID) of the source of the * transaction. The source is not responsible for setting this * field; it is set implicitly by the interconnect when the - * packet * is first sent. */ + * packet is first sent. */ short src; /** Device address (e.g., bus ID) of the destination of the @@ -202,7 +203,10 @@ class Packet HardPFResp = IsRead | IsResponse | IsHWPrefetch | NeedsResponse | HasData, InvalidateReq = IsInvalidate | IsRequest, - WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest | HasData, + WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest + | HasData | NeedsResponse, + WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest | NeedsResponse + | IsResponse, UpgradeReq = IsInvalidate | IsRequest | IsUpgrade, ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse, ReadExResp = IsRead | IsInvalidate | IsResponse @@ -339,10 +343,12 @@ class Packet srcValid = false; } - /** Take a request packet and modify it in place to be suitable - * for returning as a response to that request. + /** + * Take a request packet and modify it in place to be suitable for + * returning as a response to that request. */ - void makeAtomicResponse() { + void makeAtomicResponse() + { assert(needsResponse()); assert(isRequest()); int icmd = (int)cmd; @@ -355,50 +361,90 @@ class Packet cmd = (Command)icmd; } - /** Take a request packet that has been returned as NACKED and modify it so - * that it can be sent out again. Only packets that need a response can be - * NACKED, so verify that that is true. */ - void reinitNacked() { + /** + * Take a request packet that has been returned as NACKED and + * modify it so that it can be sent out again. Only packets that + * need a response can be NACKED, so verify that that is true. + */ + void + reinitNacked() + { assert(needsResponse() && result == Nacked); dest = Broadcast; result = Unknown; } - /** Set the data pointer to the following value that should not be freed. */ + /** + * Set the data pointer to the following value that should not be + * freed. + */ template <typename T> - void dataStatic(T *p); + void + dataStatic(T *p) + { + if(dynamicData) + dynamicData = false; + data = (PacketDataPtr)p; + staticData = true; + } - /** Set the data pointer to a value that should have delete [] called on it. + /** + * Set the data pointer to a value that should have delete [] + * called on it. */ template <typename T> - void dataDynamicArray(T *p); + void + dataDynamicArray(T *p) + { + assert(!staticData && !dynamicData); + data = (PacketDataPtr)p; + dynamicData = true; + arrayData = true; + } - /** set the data pointer to a value that should have delete called on it. */ + /** + * set the data pointer to a value that should have delete called + * on it. + */ template <typename T> - void dataDynamic(T *p); + void + dataDynamic(T *p) + { + assert(!staticData && !dynamicData); + data = (PacketDataPtr)p; + dynamicData = true; + arrayData = false; + } - /** return the value of what is pointed to in the packet. */ + /** get a pointer to the data ptr. */ template <typename T> - T get(); + T* + getPtr() + { + assert(staticData || dynamicData); + return (T*)data; + } - /** get a pointer to the data ptr. */ + /** return the value of what is pointed to in the packet. */ template <typename T> - T* getPtr(); + T get(); /** set the value in the data pointer to v. */ template <typename T> void set(T v); - /** delete the data pointed to in the data pointer. Ok to call to matter how - * data was allocted. */ + /** + * delete the data pointed to in the data pointer. Ok to call to + * matter how data was allocted. + */ void deleteData(); /** If there isn't data in the packet, allocate some. */ void allocate(); /** Do the packet modify the same addresses. */ - bool intersect(Packet *p); + bool intersect(PacketPtr p); }; @@ -407,7 +453,7 @@ class Packet * in the timing packet. It returns if the functional packet should continue to * traverse the memory hierarchy or not. */ -bool fixPacket(Packet *func, Packet *timing); +bool fixPacket(PacketPtr func, PacketPtr timing); std::ostream & operator<<(std::ostream &o, const Packet &p); diff --git a/src/mem/packet_access.hh b/src/mem/packet_access.hh new file mode 100644 index 000000000..aac0c3ae5 --- /dev/null +++ b/src/mem/packet_access.hh @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Nathan Binkert + */ + +#include "arch/isa_traits.hh" +#include "mem/packet.hh" +#include "sim/byteswap.hh" + +#ifndef __MEM_PACKET_ACCESS_HH__ +#define __MEM_PACKET_ACCESS_HH__ +// The memory system needs to have an endianness. This is the easiest +// way to deal with it for now. At some point, we will have to remove +// these functions and make the users do their own byte swapping since +// the memory system does not in fact have an endianness. + +/** return the value of what is pointed to in the packet. */ +template <typename T> +inline T +Packet::get() +{ + assert(staticData || dynamicData); + assert(sizeof(T) <= size); + return TheISA::gtoh(*(T*)data); +} + +/** set the value in the data pointer to v. */ +template <typename T> +inline void +Packet::set(T v) +{ + assert(sizeof(T) <= size); + *(T*)data = TheISA::htog(v); +} + +#endif //__MEM_PACKET_ACCESS_HH__ diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index 2b460306f..fe8094b88 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -27,6 +27,7 @@ * * Authors: Steve Reinhardt * Ron Dreslinski + * Ali Saidi */ /** @@ -97,6 +98,8 @@ PageTable::allocate(Addr vaddr, int64_t size) // starting address must be page aligned assert(pageOffset(vaddr) == 0); + DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size); + for (; size > 0; size -= pageSize, vaddr += pageSize) { m5::hash_map<Addr,Addr>::iterator iter = pTable.find(vaddr); @@ -159,3 +162,41 @@ PageTable::translate(RequestPtr &req) req->setPaddr(paddr); return page_check(req->getPaddr(), req->getSize()); } + +void +PageTable::serialize(std::ostream &os) +{ + paramOut(os, "ptable.size", pTable.size()); + + int count = 0; + + m5::hash_map<Addr,Addr>::iterator iter = pTable.begin(); + m5::hash_map<Addr,Addr>::iterator end = pTable.end(); + while (iter != end) { + paramOut(os, csprintf("ptable.entry%dvaddr", count), iter->first); + paramOut(os, csprintf("ptable.entry%dpaddr", count), iter->second); + + ++iter; + ++count; + } + assert(count == pTable.size()); +} + +void +PageTable::unserialize(Checkpoint *cp, const std::string §ion) +{ + int i = 0, count; + paramIn(cp, section, "ptable.size", count); + Addr vaddr, paddr; + + pTable.clear(); + + while(i < count) { + paramIn(cp, section, csprintf("ptable.entry%dvaddr", i), vaddr); + paramIn(cp, section, csprintf("ptable.entry%dpaddr", i), paddr); + pTable[vaddr] = paddr; + ++i; + } + +} + diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index fce063280..0e2b1f58c 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -95,6 +95,8 @@ class PageTable */ Fault translate(RequestPtr &req); + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); }; #endif diff --git a/src/mem/physical.cc b/src/mem/physical.cc index f5a0ade15..0302f7351 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -39,21 +39,17 @@ #include <iostream> #include <string> - +#include "arch/isa_traits.hh" #include "base/misc.hh" #include "config/full_system.hh" -#include "mem/packet_impl.hh" #include "mem/physical.hh" -#include "sim/host.hh" #include "sim/builder.hh" #include "sim/eventq.hh" -#include "arch/isa_traits.hh" - +#include "sim/host.hh" using namespace std; using namespace TheISA; - PhysicalMemory::PhysicalMemory(Params *p) : MemObject(p->name), pmemAddr(NULL), port(NULL), lat(p->latency), _params(p) { @@ -105,7 +101,7 @@ PhysicalMemory::deviceBlockSize() } Tick -PhysicalMemory::calculateLatency(Packet *pkt) +PhysicalMemory::calculateLatency(PacketPtr pkt) { return lat; } @@ -193,7 +189,7 @@ PhysicalMemory::checkLockedAddrList(Request *req) } void -PhysicalMemory::doFunctionalAccess(Packet *pkt) +PhysicalMemory::doFunctionalAccess(PacketPtr pkt) { assert(pkt->getAddr() + pkt->getSize() <= params()->addrRange.size()); @@ -281,14 +277,14 @@ PhysicalMemory::MemoryPort::deviceBlockSize() } Tick -PhysicalMemory::MemoryPort::recvAtomic(Packet *pkt) +PhysicalMemory::MemoryPort::recvAtomic(PacketPtr pkt) { memory->doFunctionalAccess(pkt); return memory->calculateLatency(pkt); } void -PhysicalMemory::MemoryPort::recvFunctional(Packet *pkt) +PhysicalMemory::MemoryPort::recvFunctional(PacketPtr pkt) { // Default implementation of SimpleTimingPort::recvFunctional() // calls recvAtomic() and throws away the latency; we can save a diff --git a/src/mem/physical.hh b/src/mem/physical.hh index 97bea2ec4..045e61612 100644 --- a/src/mem/physical.hh +++ b/src/mem/physical.hh @@ -57,9 +57,9 @@ class PhysicalMemory : public MemObject protected: - virtual Tick recvAtomic(Packet *pkt); + virtual Tick recvAtomic(PacketPtr pkt); - virtual void recvFunctional(Packet *pkt); + virtual void recvFunctional(PacketPtr pkt); virtual void recvStatusChange(Status status); @@ -172,8 +172,8 @@ class PhysicalMemory : public MemObject unsigned int drain(Event *de); protected: - void doFunctionalAccess(Packet *pkt); - virtual Tick calculateLatency(Packet *pkt); + void doFunctionalAccess(PacketPtr pkt); + virtual Tick calculateLatency(PacketPtr pkt); void recvStatusChange(Port::Status status); public: diff --git a/src/mem/port.cc b/src/mem/port.cc index 17924b759..bbc98c160 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -35,7 +35,6 @@ #include "base/chunk_generator.hh" #include "base/trace.hh" -#include "mem/packet_impl.hh" #include "mem/port.hh" void diff --git a/src/mem/port.hh b/src/mem/port.hh index bb3bc1b1b..b6eeb9db3 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -128,13 +128,13 @@ class Port * called by a peer port, never directly by any outside object. */ /** Called to recive a timing call from the peer port. */ - virtual bool recvTiming(Packet *pkt) = 0; + virtual bool recvTiming(PacketPtr pkt) = 0; /** Called to recive a atomic call from the peer port. */ - virtual Tick recvAtomic(Packet *pkt) = 0; + virtual Tick recvAtomic(PacketPtr pkt) = 0; /** Called to recive a functional call from the peer port. */ - virtual void recvFunctional(Packet *pkt) = 0; + virtual void recvFunctional(PacketPtr pkt) = 0; /** Called to recieve a status change from the peer port. */ virtual void recvStatusChange(Status status) = 0; @@ -172,14 +172,14 @@ class Port case a cache has a higher priority request come in while waiting for the bus to arbitrate. */ - bool sendTiming(Packet *pkt) { return peer->recvTiming(pkt); } + bool sendTiming(PacketPtr pkt) { return peer->recvTiming(pkt); } /** Function called by the associated device to send an atomic * access, an access in which the data is moved and the state is * updated in one cycle, without interleaving with other memory * accesses. Returns estimated latency of access. */ - Tick sendAtomic(Packet *pkt) + Tick sendAtomic(PacketPtr pkt) { return peer->recvAtomic(pkt); } /** Function called by the associated device to send a functional access, @@ -187,7 +187,7 @@ class Port memory system, without affecting the current state of any block or moving the block. */ - void sendFunctional(Packet *pkt) + void sendFunctional(PacketPtr pkt) { return peer->recvFunctional(pkt); } /** Called by the associated device to send a status change to the device @@ -252,9 +252,9 @@ class FunctionalPort : public Port {} protected: - virtual bool recvTiming(Packet *pkt) { panic("FuncPort is UniDir"); } - virtual Tick recvAtomic(Packet *pkt) { panic("FuncPort is UniDir"); } - virtual void recvFunctional(Packet *pkt) { panic("FuncPort is UniDir"); } + virtual bool recvTiming(PacketPtr pkt) { panic("FuncPort is UniDir"); } + virtual Tick recvAtomic(PacketPtr pkt) { panic("FuncPort is UniDir"); } + virtual void recvFunctional(PacketPtr pkt) { panic("FuncPort is UniDir"); } virtual void recvStatusChange(Status status) {} public: diff --git a/src/mem/tport.cc b/src/mem/tport.cc index 21907c0ca..55a461a8b 100644 --- a/src/mem/tport.cc +++ b/src/mem/tport.cc @@ -31,28 +31,27 @@ #include "mem/tport.hh" void -SimpleTimingPort::recvFunctional(Packet *pkt) +SimpleTimingPort::recvFunctional(PacketPtr pkt) { - //First check queued events - std::list<Packet *>::iterator i = transmitList.begin(); - std::list<Packet *>::iterator end = transmitList.end(); - bool cont = true; + std::list<PacketPtr>::iterator i = transmitList.begin(); + std::list<PacketPtr>::iterator end = transmitList.end(); - while (i != end && cont) { - Packet * target = *i; + while (i != end) { + PacketPtr target = *i; // If the target contains data, and it overlaps the // probed request, need to update data if (target->intersect(pkt)) fixPacket(pkt, target); } + //Then just do an atomic access and throw away the returned latency - if (cont) + if (pkt->result != Packet::Success) recvAtomic(pkt); } bool -SimpleTimingPort::recvTiming(Packet *pkt) +SimpleTimingPort::recvTiming(PacketPtr pkt) { // If the device is only a slave, it should only be sending // responses, which should never get nacked. There used to be @@ -66,6 +65,13 @@ SimpleTimingPort::recvTiming(Packet *pkt) pkt->makeTimingResponse(); sendTimingLater(pkt, latency); } + else { + if (pkt->cmd != Packet::UpgradeReq) + { + delete pkt->req; + delete pkt; + } + } return true; } diff --git a/src/mem/tport.hh b/src/mem/tport.hh index df6d48196..fbe81c443 100644 --- a/src/mem/tport.hh +++ b/src/mem/tport.hh @@ -60,7 +60,7 @@ class SimpleTimingPort : public Port protected: /** A list of outgoing timing response packets that haven't been * serviced yet. */ - std::list<Packet*> transmitList; + std::list<PacketPtr> transmitList; /** * This class is used to implemented sendTiming() with a delay. When @@ -71,10 +71,10 @@ class SimpleTimingPort : public Port class SendEvent : public Event { SimpleTimingPort *port; - Packet *packet; + PacketPtr packet; public: - SendEvent(SimpleTimingPort *p, Packet *pkt, Tick t) + SendEvent(SimpleTimingPort *p, PacketPtr pkt, Tick t) : Event(&mainEventQueue), port(p), packet(pkt) { setFlags(AutoDelete); schedule(curTick + t); } @@ -95,7 +95,7 @@ class SimpleTimingPort : public Port Event *drainEvent; /** Schedule a sendTiming() event to be called in the future. */ - void sendTimingLater(Packet *pkt, Tick time) + void sendTimingLater(PacketPtr pkt, Tick time) { outTiming++; new SendEvent(this, pkt, time); } /** This function is notification that the device should attempt to send a @@ -103,10 +103,10 @@ class SimpleTimingPort : public Port virtual void recvRetry(); /** Implemented using recvAtomic(). */ - void recvFunctional(Packet *pkt); + void recvFunctional(PacketPtr pkt); /** Implemented using recvAtomic(). */ - bool recvTiming(Packet *pkt); + bool recvTiming(PacketPtr pkt); /** * Simple ports generally don't care about any status |