diff options
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/cache/base_cache.cc | 92 | ||||
-rw-r--r-- | src/mem/cache/base_cache.hh | 139 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 58 | ||||
-rw-r--r-- | src/mem/cache/miss/mshr_queue.cc | 5 | ||||
-rw-r--r-- | src/mem/packet.cc | 23 | ||||
-rw-r--r-- | src/mem/packet.hh | 14 | ||||
-rw-r--r-- | src/mem/physical.cc | 15 | ||||
-rw-r--r-- | src/mem/tport.cc | 14 |
8 files changed, 297 insertions, 63 deletions
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index c26d7782b..c16cb6945 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -102,21 +102,56 @@ BaseCache::CachePort::recvAtomic(PacketPtr pkt) return cache->doAtomicAccess(pkt, isCpuSide); } -void -BaseCache::CachePort::recvFunctional(PacketPtr pkt) +bool +BaseCache::CachePort::checkFunctional(PacketPtr pkt) { //Check storage here first list<PacketPtr>::iterator i = drainList.begin(); - list<PacketPtr>::iterator end = drainList.end(); - for (; i != end; ++i) { + list<PacketPtr>::iterator iend = drainList.end(); + bool notDone = true; + while (i != iend && notDone) { 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); + DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a drain\n", + pkt->cmdString(), pkt->getAddr() & ~(cache->getBlockSize() - 1)); + notDone = fixPacket(pkt, target); } + i++; } - cache->doFunctionalAccess(pkt, isCpuSide); + //Also check the response not yet ready to be on the list + std::list<std::pair<Tick,PacketPtr> >::iterator j = transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator jend = transmitList.end(); + + while (j != jend && notDone) { + PacketPtr target = j->second; + // If the target contains data, and it overlaps the + // probed request, need to update data + if (target->intersect(pkt)) { + DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a response\n", + pkt->cmdString(), pkt->getAddr() & ~(cache->getBlockSize() - 1)); + notDone = fixDelayedResponsePacket(pkt, target); + } + j++; + } + return notDone; +} + +void +BaseCache::CachePort::recvFunctional(PacketPtr pkt) +{ + bool notDone = checkFunctional(pkt); + if (notDone) + cache->doFunctionalAccess(pkt, isCpuSide); +} + +void +BaseCache::CachePort::checkAndSendFunctional(PacketPtr pkt) +{ + bool notDone = checkFunctional(pkt); + if (notDone) + sendFunctional(pkt); } void @@ -135,7 +170,7 @@ BaseCache::CachePort::recvRetry() isCpuSide && cache->doSlaveRequest()) { DPRINTF(CachePort, "%s has more responses/requests\n", name()); - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); + BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this, false); reqCpu->schedule(curTick + 1); } waitingOnRetry = false; @@ -176,7 +211,7 @@ BaseCache::CachePort::recvRetry() { DPRINTF(CachePort, "%s has more requests\n", name()); //Still more to issue, rerequest in 1 cycle - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); + BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this, false); reqCpu->schedule(curTick + 1); } } @@ -194,7 +229,7 @@ BaseCache::CachePort::recvRetry() { DPRINTF(CachePort, "%s has more requests\n", name()); //Still more to issue, rerequest in 1 cycle - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); + BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this, false); reqCpu->schedule(curTick + 1); } } @@ -226,23 +261,19 @@ BaseCache::CachePort::clearBlocked() } } -BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort) - : Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort) +BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort, bool _newResponse) + : Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort), + newResponse(_newResponse) { - this->setFlags(AutoDelete); + if (!newResponse) + this->setFlags(AutoDelete); pkt = NULL; } -BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort, PacketPtr _pkt) - : Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort), pkt(_pkt) -{ - this->setFlags(AutoDelete); -} - void BaseCache::CacheEvent::process() { - if (!pkt) + if (!newResponse) { if (cachePort->waitingOnRetry) return; //We have some responses to drain first @@ -322,8 +353,16 @@ BaseCache::CacheEvent::process() } return; } - //Response - //Know the packet to send + //Else it's a response + assert(cachePort->transmitList.size()); + assert(cachePort->transmitList.front().first <= curTick); + pkt = cachePort->transmitList.front().second; + cachePort->transmitList.pop_front(); + if (!cachePort->transmitList.empty()) { + Tick time = cachePort->transmitList.front().first; + schedule(time <= curTick ? curTick+1 : time); + } + if (pkt->flags & NACKED_LINE) pkt->result = Packet::Nacked; else @@ -343,7 +382,7 @@ BaseCache::CacheEvent::process() } // Check if we're done draining once this list is empty - if (cachePort->drainList.empty()) + if (cachePort->drainList.empty() && cachePort->transmitList.empty()) cachePort->cache->checkDrain(); } @@ -358,8 +397,10 @@ BaseCache::getPort(const std::string &if_name, int idx) { if (if_name == "") { - if(cpuSidePort == NULL) + if(cpuSidePort == NULL) { cpuSidePort = new CachePort(name() + "-cpu_side_port", this, true); + sendEvent = new CacheEvent(cpuSidePort, true); + } return cpuSidePort; } else if (if_name == "functional") @@ -368,8 +409,10 @@ BaseCache::getPort(const std::string &if_name, int idx) } else if (if_name == "cpu_side") { - if(cpuSidePort == NULL) + if(cpuSidePort == NULL) { cpuSidePort = new CachePort(name() + "-cpu_side_port", this, true); + sendEvent = new CacheEvent(cpuSidePort, true); + } return cpuSidePort; } else if (if_name == "mem_side") @@ -377,6 +420,7 @@ BaseCache::getPort(const std::string &if_name, int idx) if (memSidePort != NULL) panic("Already have a mem side for this cache\n"); memSidePort = new CachePort(name() + "-mem_side_port", this, false); + memSendEvent = new CacheEvent(memSidePort, true); return memSidePort; } else panic("Port name %s unrecognized\n", if_name); diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index ea7544fbb..584c2d5df 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -105,7 +105,11 @@ class BaseCache : public MemObject void clearBlocked(); - bool canDrain() { return drainList.empty(); } + bool checkFunctional(PacketPtr pkt); + + void checkAndSendFunctional(PacketPtr pkt); + + bool canDrain() { return drainList.empty() && transmitList.empty(); } bool blocked; @@ -117,15 +121,16 @@ class BaseCache : public MemObject std::list<PacketPtr> drainList; + std::list<std::pair<Tick,PacketPtr> > transmitList; }; struct CacheEvent : public Event { CachePort *cachePort; PacketPtr pkt; + bool newResponse; - CacheEvent(CachePort *_cachePort); - CacheEvent(CachePort *_cachePort, PacketPtr _pkt); + CacheEvent(CachePort *_cachePort, bool response); void process(); const char *description(); }; @@ -133,6 +138,9 @@ class BaseCache : public MemObject public: //Made public so coherence can get at it. CachePort *cpuSidePort; + CacheEvent *sendEvent; + CacheEvent *memSendEvent; + protected: CachePort *memSidePort; @@ -353,6 +361,12 @@ class BaseCache : public MemObject snoopRangesSent = false; } + ~BaseCache() + { + delete sendEvent; + delete memSendEvent; + } + virtual void init(); /** @@ -467,7 +481,8 @@ class BaseCache : public MemObject { if (!doMasterRequest() && !memSidePort->waitingOnRetry) { - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(memSidePort); + BaseCache::CacheEvent * reqCpu = + new BaseCache::CacheEvent(memSidePort, false); reqCpu->schedule(time); } uint8_t flag = 1<<cause; @@ -503,7 +518,8 @@ class BaseCache : public MemObject { if (!doSlaveRequest() && !cpuSidePort->waitingOnRetry) { - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(cpuSidePort); + BaseCache::CacheEvent * reqCpu = + new BaseCache::CacheEvent(cpuSidePort, false); reqCpu->schedule(time); } uint8_t flag = 1<<cause; @@ -528,9 +544,44 @@ class BaseCache : public MemObject */ void respond(PacketPtr pkt, Tick time) { + assert(time >= curTick); if (pkt->needsResponse()) { - CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); +/* CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); reqCpu->schedule(time); +*/ + if (cpuSidePort->transmitList.empty()) { + assert(!sendEvent->scheduled()); + sendEvent->schedule(time); + cpuSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + + // something is on the list and this belongs at the end + if (time >= cpuSidePort->transmitList.back().first) { + cpuSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + // Something is on the list and this belongs somewhere else + std::list<std::pair<Tick,PacketPtr> >::iterator i = + cpuSidePort->transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator end = + cpuSidePort->transmitList.end(); + bool done = false; + + while (i != end && !done) { + if (time < i->first) { + if (i == cpuSidePort->transmitList.begin()) { + //Inserting at begining, reschedule + sendEvent->reschedule(time); + } + cpuSidePort->transmitList.insert(i,std::pair<Tick,PacketPtr> + (time,pkt)); + done = true; + } + i++; + } } else { if (pkt->cmd != Packet::UpgradeReq) @@ -548,12 +599,48 @@ class BaseCache : public MemObject */ void respondToMiss(PacketPtr pkt, Tick time) { + assert(time >= curTick); if (!pkt->req->isUncacheable()) { - missLatency[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] += time - pkt->time; + missLatency[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] += + time - pkt->time; } if (pkt->needsResponse()) { - CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); +/* CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt); reqCpu->schedule(time); +*/ + if (cpuSidePort->transmitList.empty()) { + assert(!sendEvent->scheduled()); + sendEvent->schedule(time); + cpuSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + + // something is on the list and this belongs at the end + if (time >= cpuSidePort->transmitList.back().first) { + cpuSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + // Something is on the list and this belongs somewhere else + std::list<std::pair<Tick,PacketPtr> >::iterator i = + cpuSidePort->transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator end = + cpuSidePort->transmitList.end(); + bool done = false; + + while (i != end && !done) { + if (time < i->first) { + if (i == cpuSidePort->transmitList.begin()) { + //Inserting at begining, reschedule + sendEvent->reschedule(time); + } + cpuSidePort->transmitList.insert(i,std::pair<Tick,PacketPtr> + (time,pkt)); + done = true; + } + i++; + } } else { if (pkt->cmd != Packet::UpgradeReq) @@ -570,9 +657,43 @@ class BaseCache : public MemObject */ void respondToSnoop(PacketPtr pkt, Tick time) { + assert(time >= curTick); assert (pkt->needsResponse()); - CacheEvent *reqMem = new CacheEvent(memSidePort, pkt); +/* CacheEvent *reqMem = new CacheEvent(memSidePort, pkt); reqMem->schedule(time); +*/ + if (memSidePort->transmitList.empty()) { + assert(!memSendEvent->scheduled()); + memSendEvent->schedule(time); + memSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + + // something is on the list and this belongs at the end + if (time >= memSidePort->transmitList.back().first) { + memSidePort->transmitList.push_back(std::pair<Tick,PacketPtr> + (time,pkt)); + return; + } + // Something is on the list and this belongs somewhere else + std::list<std::pair<Tick,PacketPtr> >::iterator i = + memSidePort->transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator end = + memSidePort->transmitList.end(); + bool done = false; + + while (i != end && !done) { + if (time < i->first) { + if (i == memSidePort->transmitList.begin()) { + //Inserting at begining, reschedule + memSendEvent->reschedule(time); + } + memSidePort->transmitList.insert(i,std::pair<Tick,PacketPtr>(time,pkt)); + done = true; + } + i++; + } } /** diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 9bb72e85c..df59b0a4f 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -53,6 +53,8 @@ #include "sim/sim_exit.hh" // for SimExitEvent +bool SIGNAL_NACK_HACK; + template<class TagStore, class Buffering, class Coherence> bool Cache<TagStore,Buffering,Coherence>:: @@ -242,6 +244,11 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt) missQueue->handleMiss(pkt, size, curTick + hitLatency); } + if (pkt->cmd == Packet::Writeback) { + //Need to clean up the packet on a writeback miss, but leave the request + delete pkt; + } + return true; } @@ -265,6 +272,7 @@ Cache<TagStore,Buffering,Coherence>::getPacket() assert(!doMasterRequest() || missQueue->havePending()); assert(!pkt || pkt->time <= curTick); + SIGNAL_NACK_HACK = false; return pkt; } @@ -273,16 +281,15 @@ void Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, bool success) { - 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; - } + if (success && !(SIGNAL_NACK_HACK)) { + //Remember if it was an upgrade because writeback MSHR's are removed + //in Mark in Service + bool upgrade = (mshr->pkt && mshr->pkt->cmd == Packet::UpgradeReq); + missQueue->markInService(mshr->pkt, mshr); + //Temp Hack for UPGRADES - if (mshr->pkt && mshr->pkt->cmd == Packet::UpgradeReq) { + if (upgrade) { assert(pkt); //Upgrades need to be fixed pkt->flags &= ~CACHE_LINE_FILL; BlkType *blk = tags->findBlock(pkt); @@ -300,6 +307,7 @@ Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, } } else if (pkt && !pkt->req->isUncacheable()) { pkt->flags &= ~NACKED_LINE; + SIGNAL_NACK_HACK = false; pkt->flags &= ~SATISFIED; pkt->flags &= ~SNOOP_COMMIT; @@ -333,6 +341,8 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(PacketPtr &pkt) DPRINTF(Cache, "Handling reponse to %x\n", pkt->getAddr()); if (pkt->isCacheFill() && !pkt->isNoAllocate()) { + DPRINTF(Cache, "Block for addr %x being updated in Cache\n", + pkt->getAddr()); blk = tags->findBlock(pkt); CacheBlk::State old_state = (blk) ? blk->status : 0; PacketList writebacks; @@ -402,6 +412,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(PacketPtr &pkt) assert(!(pkt->flags & SATISFIED)); pkt->flags |= SATISFIED; pkt->flags |= NACKED_LINE; + SIGNAL_NACK_HACK = true; ///@todo NACK's from other levels //warn("NACKs from devices not connected to the same bus " //"not implemented\n"); @@ -474,6 +485,13 @@ Cache<TagStore,Buffering,Coherence>::snoop(PacketPtr &pkt) } CacheBlk::State new_state; bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state); + + if (blk && mshr && !mshr->inService && new_state == 0) { + //There was a outstanding write to a shared block, not need ReadEx + //not update, so change No Allocate param in MSHR + mshr->pkt->flags &= ~NO_ALLOCATE; + } + if (satisfy) { DPRINTF(Cache, "Cache snooped a %s request for addr %x and " "now supplying data, new state is %i\n", @@ -486,6 +504,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(PacketPtr &pkt) 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); } @@ -534,9 +553,9 @@ Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, } } - if (!update && (pkt->isWrite() || (otherSidePort == cpuSidePort))) { + if (!update && (otherSidePort == cpuSidePort)) { // Still need to change data in all locations. - otherSidePort->sendFunctional(pkt); + otherSidePort->checkAndSendFunctional(pkt); if (pkt->isRead() && pkt->result == Packet::Success) return 0; } @@ -560,30 +579,33 @@ Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update, missQueue->findWrites(blk_addr, writes); if (!update) { + bool notDone = !(pkt->flags & SATISFIED); //Hit in cache (was a block) // 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) { + for (; i != end && notDone; ++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); + DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a MSHR\n", + pkt->cmdString(), blk_addr); + notDone = fixPacket(pkt, target); } } } - for (int i = 0; i < writes.size(); ++i) { + for (int i = 0; i < writes.size() && notDone; ++i) { PacketPtr write = writes[i]->pkt; if (write->intersect(pkt)) { - fixPacket(pkt, write); + DPRINTF(Cache, "Functional %s access to blk_addr %x intersects a writeback\n", + pkt->cmdString(), blk_addr); + notDone = fixPacket(pkt, write); } } - if (pkt->isRead() - && pkt->result != Packet::Success - && otherSidePort == memSidePort) { - otherSidePort->sendFunctional(pkt); + if (notDone && otherSidePort == memSidePort) { + otherSidePort->checkAndSendFunctional(pkt); assert(pkt->result == Packet::Success); } return 0; diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc index d3a7a7933..6cb62429d 100644 --- a/src/mem/cache/miss/mshr_queue.cc +++ b/src/mem/cache/miss/mshr_queue.cc @@ -198,11 +198,6 @@ MSHRQueue::markInService(MSHR* mshr) //assert(mshr == pendingList.front()); 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 - //otherwise the consumer will delete it - delete mshr->pkt->req; - } deallocate(mshr); return; } diff --git a/src/mem/packet.cc b/src/mem/packet.cc index a342af634..e2faf4527 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -144,6 +144,24 @@ Packet::intersect(PacketPtr p) } bool +fixDelayedResponsePacket(PacketPtr func, PacketPtr timing) +{ + bool result; + + if (timing->isRead() || timing->isWrite()) { + timing->toggleData(); + result = fixPacket(func, timing); + timing->toggleData(); + } + else { + //Don't toggle if it isn't a read/write response + result = fixPacket(func, timing); + } + + return result; +} + +bool fixPacket(PacketPtr func, PacketPtr timing) { Addr funcStart = func->getAddr(); @@ -168,6 +186,7 @@ fixPacket(PacketPtr func, PacketPtr timing) memcpy(func->getPtr<uint8_t>(), timing->getPtr<uint8_t>() + funcStart - timingStart, func->getSize()); func->result = Packet::Success; + func->flags |= SATISFIED; return false; } else { // In this case the timing packet only partially satisfies the @@ -182,11 +201,11 @@ fixPacket(PacketPtr func, PacketPtr timing) if (funcStart >= timingStart) { memcpy(timing->getPtr<uint8_t>() + (funcStart - timingStart), func->getPtr<uint8_t>(), - std::min(funcEnd, timingEnd) - funcStart); + (std::min(funcEnd, timingEnd) - funcStart) + 1); } else { // timingStart > funcStart memcpy(timing->getPtr<uint8_t>(), func->getPtr<uint8_t>() + (timingStart - funcStart), - std::min(funcEnd, timingEnd) - timingStart); + (std::min(funcEnd, timingEnd) - timingStart) + 1); } // we always want to keep going with a write return true; diff --git a/src/mem/packet.hh b/src/mem/packet.hh index cb97dd036..2bc51bf12 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -344,6 +344,13 @@ class Packet srcValid = false; } + + void toggleData() { + int icmd = (int)cmd; + icmd ^= HasData; + cmd = (Command)icmd; + } + /** * Take a request packet and modify it in place to be suitable for * returning as a response to that request. @@ -448,7 +455,6 @@ class Packet bool intersect(PacketPtr p); }; - /** This function given a functional packet and a timing packet either satisfies * the timing packet, or updates the timing packet to reflect the updated state * in the timing packet. It returns if the functional packet should continue to @@ -456,6 +462,12 @@ class Packet */ bool fixPacket(PacketPtr func, PacketPtr timing); +/** This function is a wrapper for the fixPacket field that toggles the hasData bit + * it is used when a response is waiting in the caches, but hasn't been marked as a + * response yet (so the fixPacket needs to get the correct value for the hasData) + */ +bool fixDelayedResponsePacket(PacketPtr func, PacketPtr timing); + std::ostream & operator<<(std::ostream &o, const Packet &p); #endif //__MEM_PACKET_HH diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 39eb63108..94f60ad80 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -288,6 +288,21 @@ PhysicalMemory::MemoryPort::recvAtomic(PacketPtr pkt) void PhysicalMemory::MemoryPort::recvFunctional(PacketPtr pkt) { + //Since we are overriding the function, make sure to have the impl of the + //check or functional accesses here. + std::list<std::pair<Tick,PacketPtr> >::iterator i = transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator end = transmitList.end(); + bool notDone = true; + + while (i != end && notDone) { + PacketPtr target = i->second; + // If the target contains data, and it overlaps the + // probed request, need to update data + if (target->intersect(pkt)) + notDone = fixPacket(pkt, target); + i++; + } + // Default implementation of SimpleTimingPort::recvFunctional() // calls recvAtomic() and throws away the latency; we can save a // little here by just not calculating the latency. diff --git a/src/mem/tport.cc b/src/mem/tport.cc index 086d91279..c43c9aac0 100644 --- a/src/mem/tport.cc +++ b/src/mem/tport.cc @@ -35,14 +35,14 @@ SimpleTimingPort::recvFunctional(PacketPtr pkt) { std::list<std::pair<Tick,PacketPtr> >::iterator i = transmitList.begin(); std::list<std::pair<Tick,PacketPtr> >::iterator end = transmitList.end(); - bool done = false; + bool notDone = true; - while (i != end && !done) { + while (i != end && notDone) { PacketPtr target = i->second; // If the target contains data, and it overlaps the // probed request, need to update data if (target->intersect(pkt)) - done = fixPacket(pkt, target); + notDone = fixPacket(pkt, target); i++; } @@ -118,8 +118,14 @@ SimpleTimingPort::sendTiming(PacketPtr pkt, Tick time) bool done = false; while (i != end && !done) { - if (time+curTick < i->first) + if (time+curTick < i->first) { + if (i == transmitList.begin()) { + //Inserting at begining, reschedule + sendEvent.reschedule(time+curTick); + } transmitList.insert(i,std::pair<Tick,PacketPtr>(time+curTick,pkt)); + done = true; + } i++; } } |