diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index bceed391f8..e20b33b01b 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -674,15 +674,7 @@ AtomicSimpleCPU::tick() //if (decoder.needMoreBytes()) //{ icache_access = true; - Packet ifetch_pkt = Packet(ifetch_req, MemCmd::ReadReq); - ifetch_pkt.dataStatic(&inst); - - icache_latency = sendPacket(icachePort, &ifetch_pkt); - - assert(!ifetch_pkt.isError()); - - // ifetch_req is initialized to read the instruction - // directly into the CPU object's inst field. + icache_latency = fetchInstMem(); //} } @@ -747,6 +739,21 @@ AtomicSimpleCPU::tick() reschedule(tickEvent, curTick() + latency, true); } +Tick +AtomicSimpleCPU::fetchInstMem() +{ + Packet pkt = Packet(ifetch_req, MemCmd::ReadReq); + + // ifetch_req is initialized to read the instruction + // directly into the CPU object's inst field. + pkt.dataStatic(&inst); + + Tick latency = sendPacket(icachePort, &pkt); + assert(!pkt.isError()); + + return latency; +} + void AtomicSimpleCPU::regProbePoints() { diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index 3ff25800a9..febba9eb56 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -57,7 +57,6 @@ class AtomicSimpleCPU : public BaseSimpleCPU void init() override; protected: - EventFunctionWrapper tickEvent; const int width; @@ -102,6 +101,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU bool tryCompleteDrain(); virtual Tick sendPacket(RequestPort &port, const PacketPtr &pkt); + virtual Tick fetchInstMem(); /** * An AtomicCPUPort overrides the default behaviour of the diff --git a/src/cpu/simple/noncaching.cc b/src/cpu/simple/noncaching.cc index 44d57fb94a..28878e2dec 100644 --- a/src/cpu/simple/noncaching.cc +++ b/src/cpu/simple/noncaching.cc @@ -59,10 +59,37 @@ NonCachingSimpleCPU::verifyMemoryMode() const Tick NonCachingSimpleCPU::sendPacket(RequestPort &port, const PacketPtr &pkt) { - if (system->isMemAddr(pkt->getAddr())) { - system->getPhysMem().access(pkt); - return 0; - } else { - return port.sendAtomic(pkt); + MemBackdoorPtr bd = nullptr; + Tick latency = port.sendAtomicBackdoor(pkt, bd); + + // If the target gave us a backdoor for next time and we didn't + // already have it, record it. + if (bd && memBackdoors.insert(bd->range(), bd) != memBackdoors.end()) { + // Install a callback to erase this backdoor if it goes away. + auto callback = [this](const MemBackdoor &backdoor) { + for (auto it = memBackdoors.begin(); + it != memBackdoors.end(); it++) { + if (it->second == &backdoor) { + memBackdoors.erase(it); + return; + } + } + panic("Got invalidation for unknown memory backdoor."); + }; + bd->addInvalidationCallback(callback); } + return latency; +} + +Tick +NonCachingSimpleCPU::fetchInstMem() +{ + auto bd_it = memBackdoors.contains(ifetch_req->getPaddr()); + if (bd_it == memBackdoors.end()) + return AtomicSimpleCPU::fetchInstMem(); + + auto *bd = bd_it->second; + Addr offset = ifetch_req->getPaddr() - bd->range().start(); + memcpy(&inst, bd->ptr() + offset, ifetch_req->getSize()); + return 0; } diff --git a/src/cpu/simple/noncaching.hh b/src/cpu/simple/noncaching.hh index 1bc87184b0..4cb9638bef 100644 --- a/src/cpu/simple/noncaching.hh +++ b/src/cpu/simple/noncaching.hh @@ -38,7 +38,9 @@ #ifndef __CPU_SIMPLE_NONCACHING_HH__ #define __CPU_SIMPLE_NONCACHING_HH__ +#include "base/addr_range_map.hh" #include "cpu/simple/atomic.hh" +#include "mem/backdoor.hh" #include "params/NonCachingSimpleCPU.hh" /** @@ -53,7 +55,10 @@ class NonCachingSimpleCPU : public AtomicSimpleCPU void verifyMemoryMode() const override; protected: + AddrRangeMap memBackdoors; + Tick sendPacket(RequestPort &port, const PacketPtr &pkt) override; + Tick fetchInstMem() override; }; #endif // __CPU_SIMPLE_NONCACHING_HH__