From 60579e8d74cecea5737a4502599ccf77e9e6a35e Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sun, 10 Jul 2011 12:56:08 -0500 Subject: [PATCH] O3: Make sure fetch doesn't go off into the weeds during speculation. --- src/cpu/o3/cpu.cc | 6 +----- src/cpu/o3/cpu.hh | 2 -- src/cpu/o3/fetch.hh | 3 ++- src/cpu/o3/fetch_impl.hh | 16 ++++++++++++++++ src/python/m5/params.py | 2 +- src/sim/System.py | 3 ++- src/sim/system.cc | 21 +++++++++++++++++++++ src/sim/system.hh | 8 ++++++++ 8 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index b19e4f460..cd4a3e867 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -46,10 +46,10 @@ #include "enums/MemoryMode.hh" #include "sim/core.hh" #include "sim/stat_control.hh" +#include "sim/system.hh" #if FULL_SYSTEM #include "cpu/quiesce_event.hh" -#include "sim/system.hh" #else #include "sim/process.hh" #endif @@ -204,9 +204,7 @@ FullO3CPU::FullO3CPU(DerivO3CPUParams *params) params->activity), globalSeqNum(1), -#if FULL_SYSTEM system(params->system), -#endif // FULL_SYSTEM drainCount(0), deferRegistration(params->defer_registration) { @@ -1105,9 +1103,7 @@ FullO3CPU::resume() if (_status == SwitchedOut || _status == Idle) return; -#if FULL_SYSTEM assert(system->getMemoryMode() == Enums::timing); -#endif if (!tickEvent.scheduled()) schedule(tickEvent, nextCycle()); diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 7e9c33717..43a2b100d 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -652,10 +652,8 @@ class FullO3CPU : public BaseO3CPU Checker *checker; #endif -#if FULL_SYSTEM /** Pointer to the system. */ System *system; -#endif /** Event to call process() on once draining has completed. */ Event *drainEvent; diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 92affc6db..90fe5334a 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -172,7 +172,8 @@ class DefaultFetch ItlbWait, IcacheWaitResponse, IcacheWaitRetry, - IcacheAccessComplete + IcacheAccessComplete, + NoGoodAddr }; /** Fetching Policy, Add new policies here.*/ diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index 8b1797f11..118f132ca 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -633,6 +633,18 @@ DefaultFetch::finishTranslation(Fault fault, RequestPtr mem_req) // If translation was successful, attempt to read the icache block. if (fault == NoFault) { + // Check that we're not going off into random memory + // If we have, just wait around for commit to squash something and put + // us on the right track + if (!cpu->system->isMemory(mem_req->getPaddr())) { + warn("Address %#x is outside of physical memory, stopping fetch\n", + mem_req->getPaddr()); + fetchStatus[tid] = NoGoodAddr; + delete mem_req; + memReq[tid] = NULL; + return; + } + // Build packet here. PacketPtr data_pkt = new Packet(mem_req, MemCmd::ReadReq, Packet::Broadcast); @@ -1162,9 +1174,13 @@ DefaultFetch::fetch(bool &status_change) } else if (fetchStatus[tid] == TrapPending) { DPRINTF(Fetch, "[tid:%i]: Fetch is waiting for a pending trap\n", tid); + } else if (fetchStatus[tid] == NoGoodAddr) { + DPRINTF(Fetch, "[tid:%i]: Fetch predicted non-executable address\n", + tid); } + // Status is Idle, Squashing, Blocked, ItlbWait or IcacheWaitResponse // so fetch should do nothing. return; diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 4dd879783..1b5fbf226 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -184,7 +184,7 @@ class VectorParamValue(list): return [ v.getValue() for v in self ] def unproxy(self, base): - if len(self) == 1 and isinstance(self[0], AllProxy): + if len(self) == 1 and isinstance(self[0], proxy.AllProxy): return self[0].unproxy(base) else: return [v.unproxy(base) for v in self] diff --git a/src/sim/System.py b/src/sim/System.py index fd707c353..a6897d834 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -44,8 +44,9 @@ class System(SimObject): def swig_objdecls(cls, code): code('%include "python/swig/system.i"') - physmem = Param.PhysicalMemory(Parent.any, "physical memory") + physmem = Param.PhysicalMemory("Physical Memory") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") + memories = VectorParam.PhysicalMemory(Self.all, "All memories is the system") work_item_id = Param.Int(-1, "specific work item id") work_begin_cpu_id_exit = Param.Int(-1, diff --git a/src/sim/system.cc b/src/sim/system.cc index bb8eccf14..81a8a0574 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -83,6 +83,16 @@ System::System(Params *p) // add self to global system list systemList.push_back(this); + /** Keep track of all memories we can execute code out of + * in our system + */ + for (int x = 0; x < p->memories.size(); x++) { + if (!p->memories[x]) + continue; + memRanges.push_back(RangeSize(p->memories[x]->start(), + p->memories[x]->size())); + } + #if FULL_SYSTEM kernelSymtab = new SymbolTable; if (!debugSymbolTable) @@ -288,6 +298,17 @@ System::freeMemSize() #endif +bool +System::isMemory(const Addr addr) const +{ + std::list >::const_iterator i; + for (i = memRanges.begin(); i != memRanges.end(); i++) { + if (*i == addr) + return true; + } + return false; +} + void System::resume() { diff --git a/src/sim/system.hh b/src/sim/system.hh index 0be16247f..a6bc47fc0 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -105,6 +105,14 @@ class System : public SimObject * system. These threads could be Active or Suspended. */ int numRunningContexts(); + /** List to store ranges of memories in this system */ + AddrRangeList memRanges; + + /** check if an address points to valid system memory + * and thus we can fetch instructions out of it + */ + bool isMemory(const Addr addr) const; + #if FULL_SYSTEM Platform *platform; uint64_t init_param; -- 2.30.2