From 024b33a1ef6f83be634f7afe644777f070ccd692 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Wed, 11 Oct 2006 18:44:48 -0400 Subject: some drain changes in timing (kevin's) and some memory mode assertion changes so that when you come out of resume, you only assert if you're really wrong. src/cpu/simple/atomic.cc: memory mode assertion change so that it only goes off if it's supposed to. src/cpu/simple/timing.cc: some drain changes (kevin's) and some changes to memoryMode assertions so that they don't go off when they're not supposed to. --HG-- extra : convert_revision : 007d8610f097e08f01367b905ada49f93cf37ca3 --- src/cpu/simple/atomic.cc | 2 +- src/cpu/simple/timing.cc | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 490be20ae..fe421ae6c 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -182,9 +182,9 @@ AtomicSimpleCPU::unserialize(Checkpoint *cp, const string §ion) void AtomicSimpleCPU::resume() { - assert(system->getMemoryMode() == System::Atomic); changeState(SimObject::Running); if (thread->status() == ThreadContext::Active) { + assert(system->getMemoryMode() == System::Atomic); if (!tickEvent.scheduled()) tickEvent.schedule(curTick); } diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 48362c42a..88aa882e3 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -146,6 +146,8 @@ void TimingSimpleCPU::resume() { if (_status != SwitchedOut && _status != Idle) { + assert(system->getMemoryMode() == System::Timing); + // Delete the old event if it existed. if (fetchEvent) { if (fetchEvent->scheduled()) @@ -159,7 +161,6 @@ TimingSimpleCPU::resume() fetchEvent->schedule(curTick); } - assert(system->getMemoryMode() == System::Timing); changeState(SimObject::Running); } @@ -190,6 +191,10 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU) break; } } + + if (_status != Running) { + _status = Idle; + } } @@ -533,15 +538,6 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt) assert(_status == DcacheWaitResponse); _status = Running; - if (getState() == SimObject::Draining) { - completeDrain(); - - delete pkt->req; - delete pkt; - - return; - } - Fault fault = curStaticInst->completeAcc(pkt, this, traceData); if (pkt->isRead() && pkt->req->isLocked()) { @@ -551,6 +547,13 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt) delete pkt->req; delete pkt; + if (getState() == SimObject::Draining) { + advancePC(fault); + completeDrain(); + + return; + } + postExecute(); advanceInst(fault); } -- cgit v1.2.3 From 8acecfef9b0e9a1c34b338a6862a3cc38b2f490b Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Wed, 11 Oct 2006 18:53:50 -0400 Subject: since memoryMode was put into the System (from SimObject), things got broken - this fixes it so that changeToTiming/changeToAtomic works. src/python/m5/SimObject.py: now that setMemoryMode is a method in System, need to convert the SimObject * _ccObject into a system ptr to call setMemoryMode. src/sim/main.cc: need this conversion now. src/sim/sim_object.hh: put the enum back into SimObject. src/sim/system.hh: memoryMode is now a part of SimObject, need the ::'s --HG-- extra : convert_revision : 0ade06957fa57b497798e1f50c237ca1badc821d --- src/python/m5/SimObject.py | 7 ++++++- src/sim/main.cc | 12 ++++++++++++ src/sim/sim_object.hh | 7 +++++++ src/sim/system.hh | 14 ++++---------- 4 files changed, 29 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index a0d66e643..716f584b0 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -726,7 +726,12 @@ class SimObject(object): child.resume() def changeTiming(self, mode): - if isinstance(self, System): + if isinstance(self, m5.objects.System): + # i don't know if there's a better way to do this - calling + # setMemoryMode directly from self._ccObject results in calling + # SimObject::setMemoryMode, not the System::setMemoryMode +## system_ptr = cc_main.convertToSystemPtr(self._ccObject) +## system_ptr.setMemoryMode(mode) self._ccObject.setMemoryMode(mode) for child in self._children.itervalues(): child.changeTiming(mode) diff --git a/src/sim/main.cc b/src/sim/main.cc index 874d0ac85..8bb0d7aaa 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -66,6 +66,7 @@ #include "sim/sim_events.hh" #include "sim/sim_exit.hh" #include "sim/sim_object.hh" +#include "sim/system.hh" #include "sim/stat_control.hh" #include "sim/stats.hh" #include "sim/root.hh" @@ -440,6 +441,17 @@ convertToBaseCPUPtr(SimObject *obj) return ptr; } +System * +convertToSystemPtr(SimObject *obj) +{ + System *ptr = dynamic_cast(obj); + + if (ptr == NULL) + warn("Casting to System pointer failed"); + return ptr; +} + + /** * Do C++ simulator exit processing. Exported to SWIG to be invoked * when simulator terminates via Python's atexit mechanism. diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index 38f2bdd23..32807b69d 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -64,6 +64,13 @@ class SimObject : public Serializable, protected StartupCallback Draining, Drained }; + + enum MemoryMode { + Invalid=0, + Atomic, + Timing + }; + private: State state; diff --git a/src/sim/system.hh b/src/sim/system.hh index 3ab1d81f2..827fe5c78 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -62,22 +62,16 @@ class RemoteGDB; class System : public SimObject { public: - enum MemoryMode { - Invalid=0, - Atomic, - Timing - }; static const char *MemoryModeStrings[3]; - - MemoryMode getMemoryMode() { assert(memoryMode); return memoryMode; } + SimObject::MemoryMode getMemoryMode() { assert(memoryMode); return memoryMode; } /** Change the memory mode of the system. This should only be called by the * python!! * @param mode Mode to change to (atomic/timing) */ - void setMemoryMode(MemoryMode mode); + void setMemoryMode(SimObject::MemoryMode mode); PhysicalMemory *physmem; PCEventQueue pcEventQueue; @@ -126,7 +120,7 @@ class System : public SimObject protected: - MemoryMode memoryMode; + SimObject::MemoryMode memoryMode; #if FULL_SYSTEM /** @@ -173,7 +167,7 @@ class System : public SimObject { std::string name; PhysicalMemory *physmem; - MemoryMode mem_mode; + SimObject::MemoryMode mem_mode; #if FULL_SYSTEM Tick boot_cpu_frequency; -- cgit v1.2.3 From ba795552f58525e34c26a79224ff24c11145103e Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Wed, 11 Oct 2006 18:54:31 -0400 Subject: System not global object, need to preface it with objects. --HG-- extra : convert_revision : 5e105d7082a8c103fb5d5383c3093734bfd590f5 --- src/python/m5/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index 5717b49b6..03e0508fb 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -144,7 +144,7 @@ def restoreCheckpoint(root, dir): resume(root) def changeToAtomic(system): - if not isinstance(system, objects.Root) and not isinstance(system, System): + if not isinstance(system, objects.Root) and not isinstance(system, objects.System): raise TypeError, "Object is not a root or system object. Checkpoint must be " "called on a root object." doDrain(system) @@ -153,7 +153,7 @@ def changeToAtomic(system): resume(system) def changeToTiming(system): - if not isinstance(system, objects.Root) and not isinstance(system, System): + if not isinstance(system, objects.Root) and not isinstance(system, objects.System): raise TypeError, "Object is not a root or system object. Checkpoint must be " "called on a root object." doDrain(system) @@ -162,6 +162,7 @@ def changeToTiming(system): resume(system) def switchCpus(cpuList): + print "switching cpus" if not isinstance(cpuList, list): raise RuntimeError, "Must pass a list to this function" for i in cpuList: @@ -189,9 +190,9 @@ def switchCpus(cpuList): cc_main.cleanupCountedDrain(drain_event) # Now all of the CPUs are ready to be switched out for old_cpu in old_cpus: + print "switching" old_cpu._ccObject.switchOut() index = 0 - print "Switching CPUs" for new_cpu in new_cpus: new_cpu.takeOverFrom(old_cpus[index]) new_cpu._ccObject.resume() -- cgit v1.2.3 From ba4c224c390916fb489aa7179655c71d7fca1e13 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Thu, 12 Oct 2006 13:33:21 -0400 Subject: Fix problems with unCacheable addresses in timing-coherence src/base/traceflags.py: src/mem/physical.cc: Add debug falgs fro physical memory accesses src/mem/cache/cache_impl.hh: Snoops to uncacheable blocks should not happen src/mem/cache/miss/miss_queue.cc: Set the size properly on unCacheable accesses --HG-- extra : convert_revision : fc78192863afb11fc7c591fba169021b9e127d16 --- src/base/traceflags.py | 1 + src/mem/cache/cache_impl.hh | 5 +++++ src/mem/cache/miss/miss_queue.cc | 2 +- src/mem/physical.cc | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/base/traceflags.py b/src/base/traceflags.py index f871ce35f..c05f9e5b0 100644 --- a/src/base/traceflags.py +++ b/src/base/traceflags.py @@ -122,6 +122,7 @@ baseFlags = [ 'MSHR', 'Mbox', 'MemDepUnit', + 'MemoryAccess', 'O3CPU', 'OzoneCPU', 'OzoneLSQ', diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index a68418f24..150abbe52 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -389,6 +389,11 @@ template void Cache::snoop(Packet * &pkt) { + if (pkt->req->isUncacheable()) { + //Can't get a hit on an uncacheable address + //Revisit this for multi level coherence + return; + } Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1)); BlkType *blk = tags->findBlock(pkt); MSHR *mshr = missQueue->findMSHR(blk_addr); diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc index c7b0e0890..c23b542f5 100644 --- a/src/mem/cache/miss/miss_queue.cc +++ b/src/mem/cache/miss/miss_queue.cc @@ -352,7 +352,7 @@ MissQueue::setPrefetcher(BasePrefetcher *_prefetcher) MSHR* MissQueue::allocateMiss(Packet * &pkt, int size, Tick time) { - MSHR* mshr = mq.allocate(pkt, blkSize); + MSHR* mshr = mq.allocate(pkt, size); mshr->order = order++; if (!pkt->req->isUncacheable() ){//&& !pkt->isNoAllocate()) { // Mark this as a cache line fill diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 7303f278e..f5a0ade15 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -201,12 +201,16 @@ PhysicalMemory::doFunctionalAccess(Packet *pkt) if (pkt->req->isLocked()) { trackLoadLocked(pkt->req); } + DPRINTF(MemoryAccess, "Performing Read of size %i on address 0x%x\n", + pkt->getSize(), pkt->getAddr()); memcpy(pkt->getPtr(), pmemAddr + pkt->getAddr() - params()->addrRange.start, pkt->getSize()); } else if (pkt->isWrite()) { if (writeOK(pkt->req)) { + DPRINTF(MemoryAccess, "Performing Write of size %i on address 0x%x\n", + pkt->getSize(), pkt->getAddr()); memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start, pkt->getPtr(), pkt->getSize()); } -- cgit v1.2.3 From dd18ffe51d7dbef59804e7af3384fe0cc28447a5 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Thu, 12 Oct 2006 13:43:12 -0400 Subject: Fix a memory leak in the memtester --HG-- extra : convert_revision : 93062b0f1a3ba7a5210e2f27099f20ae8f66522b --- src/cpu/memtest/memtest.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc index f42f0f8e2..c44f28f9b 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); /* -- cgit v1.2.3 From 6ffdc7b4d7be6d27be3a1ae83262787565063b36 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Thu, 12 Oct 2006 13:45:28 -0400 Subject: Another memleak in the memtester (need [] with the delete) src/cpu/memtest/memtest.cc: Another memleak in the memtester --HG-- extra : convert_revision : f7ab079e90d578fb6b9d1ff238d049fcce55b01b --- src/cpu/memtest/memtest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc index c44f28f9b..024cd7e41 100644 --- a/src/cpu/memtest/memtest.cc +++ b/src/cpu/memtest/memtest.cc @@ -400,7 +400,7 @@ MemTest::tick() //This means we assume CPU does write forwarding to reads that alias something //in the cpu store buffer. if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) { - delete result; + delete [] result; delete req; return; } -- cgit v1.2.3 From f89b56b61ad9cb4605d0c3297b5d563672812ce9 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Thu, 12 Oct 2006 13:59:03 -0400 Subject: Check the response queue on functional accesses. The response queue is not tying up an MSHR, should we change that or assume infinite storage for responses? src/mem/cache/base_cache.cc: src/mem/tport.cc: Add in functional check of retry queued packets. --HG-- extra : convert_revision : 0cb40b3a96d37a5e9eec95312d660ec6a9ce526a --- src/mem/cache/base_cache.cc | 36 ++++++++++++++++++++++++++++++++++++ src/mem/tport.cc | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) (limited to 'src') 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::iterator i = drainList.begin(); + list::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(); + write_data = target->getPtr() + 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() + offset; + write_data = target->getPtr(); + 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/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::iterator i = transmitList.begin(); + std::list::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(); + write_data = target->getPtr() + 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() + offset; + write_data = target->getPtr(); + 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); } -- cgit v1.2.3 From 3ba2ed6aef5a67e2bc66b100680b61f5bca818c8 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 12 Oct 2006 14:15:09 -0400 Subject: add a traceflag for functional accesses implement fix packet and add the ability to print a packet to a ostream remove tabs in packet.hh (Could people stop inserting them??!?!?!) mark const functions in packet.hh as such src/base/traceflags.py: add a traceflag for functional accesses src/mem/packet.cc: implement fix packet and add the ability to print a packet to a ostream src/mem/packet.hh: add the ability to print a packet to an ostream remove tabs in file mark const functions as such --HG-- extra : convert_revision : 4297bce5e1d3abbab48be5bd9eb9e982b751fc7c --- src/base/traceflags.py | 1 + src/mem/packet.cc | 93 +++++++++++++++++++++++++++++++++++++++++++++++++- src/mem/packet.hh | 57 ++++++++++++++++++------------- 3 files changed, 126 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/base/traceflags.py b/src/base/traceflags.py index f871ce35f..e8b17c960 100644 --- a/src/base/traceflags.py +++ b/src/base/traceflags.py @@ -94,6 +94,7 @@ baseFlags = [ 'Flow', 'FreeList', 'FullCPU', + 'FunctionalAccess', 'GDBAcc', 'GDBExtra', 'GDBMisc', diff --git a/src/mem/packet.cc b/src/mem/packet.cc index 7b8fa4a96..cc88827e3 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -34,8 +34,11 @@ * Definition of the Packet Class, a packet is a transaction occuring * between a single level of the memory heirarchy (ie L1->L2). */ + +#include #include "base/misc.hh" #include "mem/packet.hh" +#include "base/trace.hh" static const std::string ReadReqString("ReadReq"); static const std::string WriteReqString("WriteReq"); @@ -112,5 +115,93 @@ Packet::intersect(Packet *p) bool fixPacket(Packet *func, Packet *timing) { - panic("Need to implement!"); + 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)); + + if (DTRACE(FunctionalAccess)) { + DebugOut() << func; + DebugOut() << timing; + } + + // this packet can't solve our problem, continue on + if (!timing->hasData()) + return true; + + if (func->isRead()) { + if (funcStart >= timingStart && funcEnd <= timingEnd) { + func->allocate(); + memcpy(func->getPtr(), timing->getPtr() + + funcStart - timingStart, func->getSize()); + func->result = Packet::Success; + return false; + } else { + // In this case the timing packet only partially satisfies the + // requset, so we would need more information to make this work. + // Like bytes valid in the packet or something, so the request could + // continue and get this bit of possibly newer data along with the + // older data not written to yet. + panic("Timing packet only partially satisfies the functional" + "request. Now what?"); + } + } else if (func->isWrite()) { + if (funcStart >= timingStart) { + memcpy(timing->getPtr() + (funcStart - timingStart), + func->getPtr(), + funcStart - std::min(funcEnd, timingEnd)); + } else { // timingStart > funcStart + memcpy(timing->getPtr(), + func->getPtr() + (timingStart - funcStart), + timingStart - std::min(funcEnd, timingEnd)); + } + // we always want to keep going with a write + return true; + } else + panic("Don't know how to handle command type %#x\n", + func->cmdToIndex()); + +} + + +std::ostream & +operator<<(std::ostream &o, const Packet &p) +{ + + o << "[0x"; + o.setf(std::ios_base::hex, std::ios_base::showbase); + o << p.getAddr(); + o.unsetf(std::ios_base::hex| std::ios_base::showbase); + o << ":"; + o.setf(std::ios_base::hex, std::ios_base::showbase); + o << p.getAddr() + p.getSize() - 1 << "] "; + o.unsetf(std::ios_base::hex| std::ios_base::showbase); + + if (p.result == Packet::Success) + o << "Successful "; + if (p.result == Packet::BadAddress) + o << "BadAddress "; + if (p.result == Packet::Nacked) + o << "Nacked "; + if (p.result == Packet::Unknown) + o << "Inflight "; + + if (p.isRead()) + o << "Read "; + if (p.isWrite()) + o << "Read "; + if (p.isInvalidate()) + o << "Read "; + if (p.isRequest()) + o << "Request "; + if (p.isResponse()) + o << "Response "; + if (p.hasData()) + o << "w/Data "; + + o << std::endl; + return o; } + diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 3a7286a69..0bb51e924 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -171,17 +171,17 @@ class Packet // as well. enum CommandAttribute { - IsRead = 1 << 0, - IsWrite = 1 << 1, - IsPrefetch = 1 << 2, - IsInvalidate = 1 << 3, - IsRequest = 1 << 4, - IsResponse = 1 << 5, - NeedsResponse = 1 << 6, + IsRead = 1 << 0, + IsWrite = 1 << 1, + IsPrefetch = 1 << 2, + IsInvalidate = 1 << 3, + IsRequest = 1 << 4, + IsResponse = 1 << 5, + NeedsResponse = 1 << 6, IsSWPrefetch = 1 << 7, IsHWPrefetch = 1 << 8, IsUpgrade = 1 << 9, - HasData = 1 << 10 + HasData = 1 << 10 }; public: @@ -189,18 +189,18 @@ class Packet enum Command { InvalidCmd = 0, - ReadReq = IsRead | IsRequest | NeedsResponse, - WriteReq = IsWrite | IsRequest | NeedsResponse | HasData, - WriteReqNoAck = IsWrite | IsRequest | HasData, - ReadResp = IsRead | IsResponse | NeedsResponse | HasData, - WriteResp = IsWrite | IsResponse | NeedsResponse, + ReadReq = IsRead | IsRequest | NeedsResponse, + WriteReq = IsWrite | IsRequest | NeedsResponse | HasData, + WriteReqNoAck = IsWrite | IsRequest | HasData, + ReadResp = IsRead | IsResponse | NeedsResponse | HasData, + WriteResp = IsWrite | IsResponse | NeedsResponse, Writeback = IsWrite | IsRequest | HasData, SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse, HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse, SoftPFResp = IsRead | IsResponse | IsSWPrefetch | NeedsResponse | HasData, HardPFResp = IsRead | IsResponse | IsHWPrefetch - | NeedsResponse | HasData, + | NeedsResponse | HasData, InvalidateReq = IsInvalidate | IsRequest, WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest | HasData, UpgradeReq = IsInvalidate | IsRequest | IsUpgrade, @@ -222,17 +222,17 @@ class Packet /** The command field of the packet. */ Command cmd; - bool isRead() { return (cmd & IsRead) != 0; } - bool isWrite() { return (cmd & IsWrite) != 0; } - bool isRequest() { return (cmd & IsRequest) != 0; } - bool isResponse() { return (cmd & IsResponse) != 0; } - bool needsResponse() { return (cmd & NeedsResponse) != 0; } - bool isInvalidate() { return (cmd & IsInvalidate) != 0; } - bool hasData() { return (cmd & HasData) != 0; } + bool isRead() const { return (cmd & IsRead) != 0; } + bool isWrite() const { return (cmd & IsWrite) != 0; } + bool isRequest() const { return (cmd & IsRequest) != 0; } + bool isResponse() const { return (cmd & IsResponse) != 0; } + bool needsResponse() const { return (cmd & NeedsResponse) != 0; } + bool isInvalidate() const { return (cmd & IsInvalidate) != 0; } + bool hasData() const { return (cmd & HasData) != 0; } - bool isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; } - bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; } - bool isCompressed() { return (flags & COMPRESSED) != 0; } + bool isCacheFill() const { return (flags & CACHE_LINE_FILL) != 0; } + bool isNoAllocate() const { return (flags & NO_ALLOCATE) != 0; } + bool isCompressed() const { return (flags & COMPRESSED) != 0; } bool nic_pkt() { assert("Unimplemented\n" && 0); return false; } @@ -397,5 +397,14 @@ class Packet bool intersect(Packet *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 + * traverse the memory hierarchy or not. + */ bool fixPacket(Packet *func, Packet *timing); + +std::ostream & operator<<(std::ostream &o, const Packet &p); + #endif //__MEM_PACKET_HH -- cgit v1.2.3 From fe230ddb8ff2f3339ffaa20d30c01bb5b00185b6 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Thu, 12 Oct 2006 14:21:25 -0400 Subject: Remove bus and top level parameters from cache src/mem/cache/base_cache.hh: Remove top level param from cache src/mem/cache/coherence/uni_coherence.cc: Remove top level parameters from the cache --HG-- extra : convert_revision : 4437aeedc20866869de7f9ab123dfa7baeebedf0 --- src/mem/cache/base_cache.hh | 27 ++------------------------- src/mem/cache/cache_impl.hh | 9 ++------- src/mem/cache/coherence/uni_coherence.cc | 14 ++++++-------- 3 files changed, 10 insertions(+), 40 deletions(-) (limited to 'src') 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 @@ -357,15 +353,6 @@ class BaseCache : public MemObject return blkSize; } - /** - * 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. */ @@ -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::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) { -- cgit v1.2.3 From 0615d92d33ffc2c47b95caeebf3a49c4626fe681 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 12 Oct 2006 15:02:25 -0400 Subject: small bus updates for functional accesses --HG-- extra : convert_revision : c7a6b199c74ed4b4ffab14bbffb51e72d75b7742 --- src/mem/bus.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 75ffed0d2..b11b6de58 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -320,7 +320,7 @@ Bus::functionalSnoop(Packet *pkt) { std::vector ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc()); - while (!ports.empty()) + while (!ports.empty() && pkt->result != Packet::Success) { interfaces[ports.back()]->sendFunctional(pkt); ports.pop_back(); @@ -367,7 +367,10 @@ Bus::recvFunctional(Packet *pkt) pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); assert(pkt->getDest() == Packet::Broadcast); functionalSnoop(pkt); - findPort(pkt->getAddr(), pkt->getSrc())->sendFunctional(pkt); + + // If the snooping found what we were looking for, we're done. + if (pkt->result != Packet::Success) + findPort(pkt->getAddr(), pkt->getSrc())->sendFunctional(pkt); } /** Function called by the port when the bus is receiving a status change.*/ -- cgit v1.2.3 From eddbb6801f6f9666d81cb5491b4ceedd3955f996 Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Thu, 12 Oct 2006 15:02:56 -0400 Subject: Fix CSHR retrys --HG-- extra : convert_revision : caa7664f6c945396fa38ce62fbda018ebed4eaa6 --- src/mem/cache/base_cache.cc | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 4a4a81f73..3f7a52fab 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -189,7 +189,6 @@ BaseCache::CachePort::recvRetry() { DPRINTF(CachePort, "%s has more requests\n", name()); //Still more to issue, rerequest in 1 cycle - pkt = NULL; BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); reqCpu->schedule(curTick + 1); } @@ -202,12 +201,13 @@ BaseCache::CachePort::recvRetry() pkt = cshrRetry; bool success = sendTiming(pkt); waitingOnRetry = !success; - if (success && cache->doSlaveRequest()) + if (success) { - //Still more to issue, rerequest in 1 cycle - pkt = NULL; - BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); - reqCpu->schedule(curTick + 1); + if (cache->doSlaveRequest()) { + //Still more to issue, rerequest in 1 cycle + BaseCache::CacheEvent * reqCpu = new BaseCache::CacheEvent(this); + reqCpu->schedule(curTick + 1); + } cshrRetry = NULL; } } @@ -305,20 +305,28 @@ BaseCache::CacheEvent::process() } else { - assert(cachePort->cache->doSlaveRequest()); //CSHR - pkt = cachePort->cache->getCoherencePacket(); + if (!cachePort->cshrRetry) { + assert(cachePort->cache->doSlaveRequest()); + pkt = cachePort->cache->getCoherencePacket(); + } + else { + pkt = cachePort->cshrRetry; + } bool success = cachePort->sendTiming(pkt); if (!success) { //Need to send on a retry cachePort->cshrRetry = pkt; cachePort->waitingOnRetry = true; } - else if (cachePort->cache->doSlaveRequest()) + else { - //Still more to issue, rerequest in 1 cycle - pkt = NULL; - this->schedule(curTick+1); + cachePort->cshrRetry = NULL; + if (cachePort->cache->doSlaveRequest()) { + //Still more to issue, rerequest in 1 cycle + pkt = NULL; + this->schedule(curTick+1); + } } } return; -- cgit v1.2.3 From 3d2764acf3a05a65c32e93bd18c8fe9a6e0d9ecc Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 12 Oct 2006 15:30:30 -0400 Subject: replace functional code in tport with fixPacket(). fixPacket() should be used anywhere a functional packet and timing packet are found to have the same address. --HG-- extra : convert_revision : 783ec438271b24ddb0ae742b4efd1ed7d6be93f3 --- src/mem/tport.cc | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/mem/tport.cc b/src/mem/tport.cc index 50aab31c4..21907c0ca 100644 --- a/src/mem/tport.cc +++ b/src/mem/tport.cc @@ -36,41 +36,19 @@ SimpleTimingPort::recvFunctional(Packet *pkt) //First check queued events std::list::iterator i = transmitList.begin(); std::list::iterator end = transmitList.end(); - for (; i != end; ++i) { + bool cont = true; + + while (i != end && cont) { 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(); - write_data = target->getPtr() + 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() + offset; - write_data = target->getPtr(); - data_size = pkt->getSize() - offset; - assert(data_size > pkt->getSize()); - if (data_size > target->getSize()) - data_size = target->getSize(); - } + if (target->intersect(pkt)) + fixPacket(pkt, target); - 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); + if (cont) + recvAtomic(pkt); } bool -- cgit v1.2.3 From ca4063ac00202b80e11312be62abbe4283cfae7b Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 13 Oct 2006 14:28:46 -0400 Subject: fix a bug in CopyStringOut. dprintk appears to work again. --HG-- extra : convert_revision : cd0d13a85ddc7599308db8604a8f63a48679cc05 --- src/arch/alpha/vtophys.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/arch/alpha/vtophys.cc b/src/arch/alpha/vtophys.cc index f7fd92c15..fd8f781e4 100644 --- a/src/arch/alpha/vtophys.cc +++ b/src/arch/alpha/vtophys.cc @@ -141,12 +141,12 @@ void AlphaISA::CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen) { int len = 0; + char *start = dst; VirtualPort *vp = tc->getVirtPort(tc); do { vp->readBlob(vaddr++, (uint8_t*)dst++, 1); - len++; - } while (len < maxlen && dst[len] != 0 ); + } while (len < maxlen && start[len++] != 0 ); tc->delVirtPort(vp); dst[len] = 0; -- cgit v1.2.3 From a50e83c1340de76f61ca8cf16fccb0ba09393580 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Fri, 13 Oct 2006 17:35:23 -0400 Subject: Fix assertion. I haven't tested it fully (I can't reproduce Lisa's error) but I believe it should fix what she's running into (which was definitely a bug). src/cpu/o3/fetch_impl.hh: Move assertion to area where it should really always be true. Sometimes you might recvRetry and not necessarily be blocked (if there was a squash). --HG-- extra : convert_revision : 76ad35357e7f4c44fa544ffed071096a62053018 --- src/cpu/o3/fetch_impl.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 32210f1cd..07d4ebb42 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -1285,8 +1285,8 @@ template void DefaultFetch::recvRetry() { - assert(cacheBlocked); if (retryPkt != NULL) { + assert(cacheBlocked); assert(retryTid != -1); assert(fetchStatus[retryTid] == IcacheWaitRetry); -- cgit v1.2.3 From 9202422d6ebb7a17936bee1b9aaa427541156d13 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 14 Oct 2006 02:09:05 -0400 Subject: Get rid of unused CacheBlk << output operator. --HG-- extra : convert_revision : d5c0aadc35edf5c9495afcd3375f1f64716ef845 --- src/mem/cache/cache_blk.hh | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'src') diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index a75c9611d..078c82d82 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -38,8 +38,6 @@ #include "sim/root.hh" // for Tick #include "arch/isa_traits.hh" // for Addr -#include - /** * Cache block status bit assignments */ @@ -180,21 +178,4 @@ class CacheBlk }; -/** - * Output a CacheBlk to the given ostream. - * @param out The stream for the output. - * @param blk The cache block to print. - * - * @return The output stream. - */ -inline std::ostream & -operator<<(std::ostream &out, const CacheBlk &blk) -{ - out << std::hex << std::endl; - out << " Tag: " << blk.tag << std::endl; - out << " Status: " << blk.status << std::endl; - - return(out << std::dec); -} - #endif //__CACHE_BLK_HH__ -- cgit v1.2.3