diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cpu/memtest/memtest.cc | 13 | ||||
-rw-r--r-- | src/mem/cache/base_cache.cc | 36 | ||||
-rw-r--r-- | src/mem/cache/base_cache.hh | 27 | ||||
-rw-r--r-- | src/mem/cache/cache_impl.hh | 9 | ||||
-rw-r--r-- | src/mem/cache/coherence/uni_coherence.cc | 14 | ||||
-rw-r--r-- | src/mem/tport.cc | 38 |
6 files changed, 94 insertions, 43 deletions
diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc index f42f0f8e2..024cd7e41 100644 --- a/src/cpu/memtest/memtest.cc +++ b/src/cpu/memtest/memtest.cc @@ -360,7 +360,11 @@ MemTest::tick() //For now we only allow one outstanding request per addreess per tester //This means we assume CPU does write forwarding to reads that alias something //in the cpu store buffer. - if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) return; + if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) { + delete result; + delete req; + return; + } else outstandingAddrs.insert(paddr); // ***** NOTE FOR RON: I'm not sure how to access checkMem. - Kevin @@ -395,7 +399,12 @@ MemTest::tick() //For now we only allow one outstanding request per addreess per tester //This means we assume CPU does write forwarding to reads that alias something //in the cpu store buffer. - if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) return; + if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) { + delete [] result; + delete req; + return; + } + else outstandingAddrs.insert(paddr); /* diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 71ea58416..4a4a81f73 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -107,6 +107,42 @@ BaseCache::CachePort::recvAtomic(Packet *pkt) void BaseCache::CachePort::recvFunctional(Packet *pkt) { + //Check storage here first + list<Packet *>::iterator i = drainList.begin(); + list<Packet *>::iterator end = drainList.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->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); + } + } + } cache->doFunctionalAccess(pkt, isCpuSide); } diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index 563b1ca8b..455e13d9c 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -212,10 +212,6 @@ class BaseCache : public MemObject protected: - /** True if this cache is connected to the CPU. */ - bool topLevelCache; - - /** Stores time the cache blocked for statistics. */ Tick blockedCycle; @@ -337,7 +333,7 @@ class BaseCache : public MemObject */ BaseCache(const std::string &name, Params ¶ms) : MemObject(name), blocked(0), blockedSnoop(0), masterRequests(0), - slaveRequests(0), topLevelCache(false), blkSize(params.blkSize), + slaveRequests(0), blkSize(params.blkSize), missCount(params.maxMisses) { //Start ports at null if more than one is created we should panic @@ -358,15 +354,6 @@ class BaseCache : public MemObject } /** - * Returns true if this cache is connect to the CPU. - * @return True if this is a L1 cache. - */ - bool isTopLevel() - { - return topLevelCache; - } - - /** * Returns true if the cache is blocked for accesses. */ bool isBlocked() @@ -561,8 +548,6 @@ class BaseCache : public MemObject */ void respondToSnoop(Packet *pkt, Tick time) { -// assert("Implement\n" && 0); -// mi->respond(pkt,curTick + hitLatency); assert (pkt->needsResponse()); CacheEvent *reqMem = new CacheEvent(memSidePort, pkt); reqMem->schedule(time); @@ -585,15 +570,7 @@ class BaseCache : public MemObject { //This is where snoops get updated AddrRangeList dummy; -// if (!topLevelCache) -// { - cpuSidePort->getPeerAddressRanges(dummy, snoop); -// } -// else -// { -// snoop.push_back(RangeSize(0,-1)); -// } - + cpuSidePort->getPeerAddressRanges(dummy, snoop); return; } } diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 150abbe52..9db79b843 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -151,12 +151,7 @@ Cache(const std::string &_name, doCopy(params.doCopy), blockOnCopy(params.blockOnCopy), hitLatency(params.hitLatency) { -//FIX BUS POINTERS -// if (params.in == NULL) { - topLevelCache = true; -// } -//PLEASE FIX THIS, BUS SIZES NOT BEING USED - tags->setCache(this, blkSize, 1/*params.out->width, params.out->clockRate*/); + tags->setCache(this); tags->setPrefetcher(prefetcher); missQueue->setCache(this); missQueue->setPrefetcher(prefetcher); @@ -397,7 +392,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt) Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); BlkType *blk = tags->findBlock(pkt); MSHR *mshr = missQueue->findMSHR(blk_addr); - if (isTopLevel() && coherence->hasProtocol()) { //@todo Move this into handle bus req + 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 (mshr) { if (mshr->inService) { diff --git a/src/mem/cache/coherence/uni_coherence.cc b/src/mem/cache/coherence/uni_coherence.cc index 5ab706269..0efe393f9 100644 --- a/src/mem/cache/coherence/uni_coherence.cc +++ b/src/mem/cache/coherence/uni_coherence.cc @@ -68,14 +68,12 @@ UniCoherence::handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr, if (pkt->isInvalidate()) { DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n", pkt->getAddr(), blk); - if (!cache->isTopLevel()) { - // 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); - } + // 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); } } else { if (blk) { diff --git a/src/mem/tport.cc b/src/mem/tport.cc index 456878d0a..50aab31c4 100644 --- a/src/mem/tport.cc +++ b/src/mem/tport.cc @@ -33,7 +33,43 @@ void SimpleTimingPort::recvFunctional(Packet *pkt) { - // just do an atomic access and throw away the returned latency + //First check queued events + std::list<Packet *>::iterator i = transmitList.begin(); + std::list<Packet *>::iterator end = transmitList.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->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); + } + } + } + //Then just do an atomic access and throw away the returned latency recvAtomic(pkt); } |