diff --git a/configs/example/gpufs/system/system.py b/configs/example/gpufs/system/system.py index be4dd570ab..4ec36186ac 100644 --- a/configs/example/gpufs/system/system.py +++ b/configs/example/gpufs/system/system.py @@ -75,6 +75,9 @@ def makeGpuFSSystem(args): voltage_domain = system.cpu_voltage_domain) + # Setup VGA ROM region + system.shadow_rom_ranges = [AddrRange(0xc0000, size = Addr('128kB'))] + # Create specified number of CPUs. GPUFS really only needs one. system.cpu = [TestCPUClass(clk_domain=system.cpu_clk_domain, cpu_id=i) for i in range(args.num_cpus)] diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index 110ed3b4a5..741a41023f 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -606,12 +606,28 @@ RubyPort::PioResponsePort::getAddrRanges() const return ranges; } +bool +RubyPort::MemResponsePort::isShadowRomAddress(Addr addr) const +{ + RubyPort *ruby_port = static_cast(&owner); + AddrRangeList ranges = ruby_port->system->getShadowRomRanges(); + + for (auto it = ranges.begin(); it != ranges.end(); ++it) { + if (it->contains(addr)) { + return true; + } + } + + return false; +} + bool RubyPort::MemResponsePort::isPhysMemAddress(PacketPtr pkt) const { RubyPort *ruby_port = static_cast(&owner); - return ruby_port->system->isMemAddr(pkt->getAddr()) - || ruby_port->system->isDeviceMemAddr(pkt); + Addr addr = pkt->getAddr(); + return (ruby_port->system->isMemAddr(addr) && !isShadowRomAddress(addr)) + || ruby_port->system->isDeviceMemAddr(pkt); } void diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index 1d25ae9a25..e28dc6e41c 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -99,6 +99,7 @@ class RubyPort : public ClockedObject void addToRetryList(); private: + bool isShadowRomAddress(Addr addr) const; bool isPhysMemAddress(PacketPtr pkt) const; }; diff --git a/src/sim/System.py b/src/sim/System.py index a2f6056049..224a31885e 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -83,6 +83,10 @@ class System(SimObject): # I/O bridge or cache mem_ranges = VectorParam.AddrRange([], "Ranges that constitute main memory") + # The ranges backed by a shadowed ROM + shadow_rom_ranges = VectorParam.AddrRange([], "Ranges backed by a " \ + "shadowed ROM") + shared_backstore = Param.String("", "backstore's shmem segment filename, " "use to directly address the backstore from another host-OS process. " "Leave this empty to unset the MAP_SHARED flag.") diff --git a/src/sim/system.cc b/src/sim/system.cc index 57ae62f997..3c244d822d 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -202,6 +202,8 @@ System::System(const Params &p) #endif physmem(name() + ".physmem", p.memories, p.mmap_using_noreserve, p.shared_backstore), + ShadowRomRanges(p.shadow_rom_ranges.begin(), + p.shadow_rom_ranges.end()), memoryMode(p.mem_mode), _cacheLineSize(p.cache_line_size), numWorkIds(p.num_work_ids), diff --git a/src/sim/system.hh b/src/sim/system.hh index 6beba1f472..09798c3855 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -378,6 +378,13 @@ class System : public SimObject, public PCEventScope */ AbstractMemory *getDeviceMemory(RequestorID _id) const; + /* + * Return the list of address ranges backed by a shadowed ROM. + * + * @return List of address ranges backed by a shadowed ROM + */ + AddrRangeList getShadowRomRanges() const { return ShadowRomRanges; } + /** * Get the architecture. */ @@ -413,6 +420,8 @@ class System : public SimObject, public PCEventScope PhysicalMemory physmem; + AddrRangeList ShadowRomRanges; + enums::MemoryMode memoryMode; const unsigned int _cacheLineSize;