From ec4000e0e284834df0eb1db792074a1b11f21cc8 Mon Sep 17 00:00:00 2001 From: Vincentius Robby Date: Wed, 8 Aug 2007 18:43:12 -0400 Subject: [PATCH] Added fastmem option. Lets CPU accesses to physical memory bypass Bus. --HG-- extra : convert_revision : e56e3879de47ee10951a19bfcd8b62b6acdfb30c --- configs/common/Options.py | 1 + configs/example/fs.py | 5 +++++ configs/example/se.py | 3 +++ src/cpu/BaseCPU.py | 5 +++-- src/cpu/simple/AtomicSimpleCPU.py | 3 ++- src/cpu/simple/atomic.cc | 33 ++++++++++++++++++++++++++----- src/cpu/simple/atomic.hh | 4 ++++ 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/configs/common/Options.py b/configs/common/Options.py index 4f2b317c0..225916840 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -32,6 +32,7 @@ parser.add_option("-t", "--timing", action="store_true") parser.add_option("-n", "--num_cpus", type="int", default=1) parser.add_option("--caches", action="store_true") parser.add_option("--l2cache", action="store_true") +parser.add_option("--fastmem", action="store_true") # Run duration options parser.add_option("-m", "--maxtick", type="int") diff --git a/configs/example/fs.py b/configs/example/fs.py index ca1408970..3a57fe5b8 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -132,6 +132,9 @@ for i in xrange(np): else: test_sys.cpu[i].connectMemPorts(test_sys.membus) + if options.fastmem: + test_sys.cpu[i].physmem_port = test_sys.physmem.port + if len(bm) == 2: if m5.build_env['TARGET_ISA'] == 'alpha': drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1]) @@ -139,6 +142,8 @@ if len(bm) == 2: drive_sys = makeSparcSystem(drive_mem_mode, bm[1]) drive_sys.cpu = DriveCPUClass(cpu_id=0) drive_sys.cpu.connectMemPorts(drive_sys.membus) + if options.fastmem: + drive_sys.cpu.physmem_port = drive_sys.physmem.port if options.kernel is not None: drive_sys.kernel = binary(options.kernel) diff --git a/configs/example/se.py b/configs/example/se.py index 20fe75a21..639bcd7c6 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -114,6 +114,9 @@ for i in xrange(np): system.cpu[i].connectMemPorts(system.membus) system.cpu[i].workload = process + if options.fastmem: + system.cpu[0].physmem_port = system.physmem.port + root = Root(system = system) Simulation.run(options, root, system, FutureClass) diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index 8be84392d..7a51650e6 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -93,10 +93,11 @@ class BaseCPU(SimObject): def connectMemPorts(self, bus): for p in self._mem_ports: - exec('self.%s = bus.port' % p) + if p != 'physmem_port': + exec('self.%s = bus.port' % p) def addPrivateSplitL1Caches(self, ic, dc): - assert(len(self._mem_ports) == 2) + assert(len(self._mem_ports) == 2 or len(self._mem_ports) == 3) self.icache = ic self.dcache = dc self.icache_port = ic.cpu_side diff --git a/src/cpu/simple/AtomicSimpleCPU.py b/src/cpu/simple/AtomicSimpleCPU.py index e97f059c1..bfd1825c2 100644 --- a/src/cpu/simple/AtomicSimpleCPU.py +++ b/src/cpu/simple/AtomicSimpleCPU.py @@ -40,4 +40,5 @@ class AtomicSimpleCPU(BaseCPU): profile = Param.Latency('0ns', "trace the kernel stack") icache_port = Port("Instruction Port") dcache_port = Port("Data Port") - _mem_ports = ['icache_port', 'dcache_port'] + physmem_port = Port("Physical Memory Port") + _mem_ports = ['icache_port', 'dcache_port', 'physmem_port'] diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 704b65f36..e2a7d5938 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -67,6 +67,10 @@ AtomicSimpleCPU::getPort(const std::string &if_name, int idx) return &dcachePort; else if (if_name == "icache_port") return &icachePort; + else if (if_name == "physmem_port") { + hasPhysMemPort = true; + return &physmemPort; + } else panic("No Such Port\n"); } @@ -83,6 +87,12 @@ AtomicSimpleCPU::init() TheISA::initCPU(tc, tc->readCpuId()); } #endif + if (hasPhysMemPort) { + bool snoop = false; + AddrRangeList pmAddrList; + physmemPort.getPeerAddressRanges(pmAddrList, snoop); + physMemAddr = *pmAddrList.begin(); + } } bool @@ -141,7 +151,8 @@ AtomicSimpleCPU::DcachePort::setPeer(Port *port) AtomicSimpleCPU::AtomicSimpleCPU(Params *p) : BaseSimpleCPU(p), tickEvent(this), width(p->width), simulate_stalls(p->simulate_stalls), - icachePort(name() + "-iport", this), dcachePort(name() + "-iport", this) + icachePort(name() + "-iport", this), dcachePort(name() + "-iport", this), + physmemPort(name() + "-iport", this), hasPhysMemPort(false) { _status = Idle; @@ -293,8 +304,12 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) if (req->isMmapedIpr()) dcache_latency = TheISA::handleIprRead(thread->getTC(), &pkt); - else - dcache_latency = dcachePort.sendAtomic(&pkt); + else { + if (hasPhysMemPort && pkt.getAddr() == physMemAddr) + dcache_latency = physmemPort.sendAtomic(&pkt); + else + dcache_latency = dcachePort.sendAtomic(&pkt); + } dcache_access = true; assert(!pkt.isError()); @@ -402,7 +417,10 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) dcache_latency = TheISA::handleIprWrite(thread->getTC(), &pkt); } else { data = htog(data); - dcache_latency = dcachePort.sendAtomic(&pkt); + if (hasPhysMemPort && pkt.getAddr() == physMemAddr) + dcache_latency = physmemPort.sendAtomic(&pkt); + else + dcache_latency = dcachePort.sendAtomic(&pkt); } dcache_access = true; assert(!pkt.isError()); @@ -513,7 +531,12 @@ AtomicSimpleCPU::tick() Packet::Broadcast); ifetch_pkt.dataStatic(&inst); - icache_latency = icachePort.sendAtomic(&ifetch_pkt); + if (hasPhysMemPort && ifetch_pkt.getAddr() == physMemAddr) + icache_latency = physmemPort.sendAtomic(&ifetch_pkt); + else + icache_latency = icachePort.sendAtomic(&ifetch_pkt); + + // ifetch_req is initialized to read the instruction directly // into the CPU object's inst field. //} diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index 28e883b24..96429e5b1 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -121,6 +121,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU }; DcachePort dcachePort; + CpuPort physmemPort; + bool hasPhysMemPort; Request ifetch_req; Request data_read_req; Request data_write_req; @@ -128,6 +130,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU bool dcache_access; Tick dcache_latency; + Range physMemAddr; + public: virtual Port *getPort(const std::string &if_name, int idx = -1);