Added fastmem option.

Lets CPU accesses to physical memory bypass Bus.

--HG--
extra : convert_revision : e56e3879de47ee10951a19bfcd8b62b6acdfb30c
This commit is contained in:
Vincentius Robby 2007-08-08 18:43:12 -04:00
parent 1caed14654
commit ec4000e0e2
7 changed files with 46 additions and 8 deletions

View file

@ -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("-n", "--num_cpus", type="int", default=1)
parser.add_option("--caches", action="store_true") parser.add_option("--caches", action="store_true")
parser.add_option("--l2cache", action="store_true") parser.add_option("--l2cache", action="store_true")
parser.add_option("--fastmem", action="store_true")
# Run duration options # Run duration options
parser.add_option("-m", "--maxtick", type="int") parser.add_option("-m", "--maxtick", type="int")

View file

@ -132,6 +132,9 @@ for i in xrange(np):
else: else:
test_sys.cpu[i].connectMemPorts(test_sys.membus) 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 len(bm) == 2:
if m5.build_env['TARGET_ISA'] == 'alpha': if m5.build_env['TARGET_ISA'] == 'alpha':
drive_sys = makeLinuxAlphaSystem(drive_mem_mode, bm[1]) 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 = makeSparcSystem(drive_mem_mode, bm[1])
drive_sys.cpu = DriveCPUClass(cpu_id=0) drive_sys.cpu = DriveCPUClass(cpu_id=0)
drive_sys.cpu.connectMemPorts(drive_sys.membus) 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: if options.kernel is not None:
drive_sys.kernel = binary(options.kernel) drive_sys.kernel = binary(options.kernel)

View file

@ -114,6 +114,9 @@ for i in xrange(np):
system.cpu[i].connectMemPorts(system.membus) system.cpu[i].connectMemPorts(system.membus)
system.cpu[i].workload = process system.cpu[i].workload = process
if options.fastmem:
system.cpu[0].physmem_port = system.physmem.port
root = Root(system = system) root = Root(system = system)
Simulation.run(options, root, system, FutureClass) Simulation.run(options, root, system, FutureClass)

View file

@ -93,10 +93,11 @@ class BaseCPU(SimObject):
def connectMemPorts(self, bus): def connectMemPorts(self, bus):
for p in self._mem_ports: 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): 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.icache = ic
self.dcache = dc self.dcache = dc
self.icache_port = ic.cpu_side self.icache_port = ic.cpu_side

View file

@ -40,4 +40,5 @@ class AtomicSimpleCPU(BaseCPU):
profile = Param.Latency('0ns', "trace the kernel stack") profile = Param.Latency('0ns', "trace the kernel stack")
icache_port = Port("Instruction Port") icache_port = Port("Instruction Port")
dcache_port = Port("Data 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']

View file

@ -67,6 +67,10 @@ AtomicSimpleCPU::getPort(const std::string &if_name, int idx)
return &dcachePort; return &dcachePort;
else if (if_name == "icache_port") else if (if_name == "icache_port")
return &icachePort; return &icachePort;
else if (if_name == "physmem_port") {
hasPhysMemPort = true;
return &physmemPort;
}
else else
panic("No Such Port\n"); panic("No Such Port\n");
} }
@ -83,6 +87,12 @@ AtomicSimpleCPU::init()
TheISA::initCPU(tc, tc->readCpuId()); TheISA::initCPU(tc, tc->readCpuId());
} }
#endif #endif
if (hasPhysMemPort) {
bool snoop = false;
AddrRangeList pmAddrList;
physmemPort.getPeerAddressRanges(pmAddrList, snoop);
physMemAddr = *pmAddrList.begin();
}
} }
bool bool
@ -141,7 +151,8 @@ AtomicSimpleCPU::DcachePort::setPeer(Port *port)
AtomicSimpleCPU::AtomicSimpleCPU(Params *p) AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
: BaseSimpleCPU(p), tickEvent(this), : BaseSimpleCPU(p), tickEvent(this),
width(p->width), simulate_stalls(p->simulate_stalls), 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; _status = Idle;
@ -293,8 +304,12 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
if (req->isMmapedIpr()) if (req->isMmapedIpr())
dcache_latency = TheISA::handleIprRead(thread->getTC(), &pkt); dcache_latency = TheISA::handleIprRead(thread->getTC(), &pkt);
else else {
dcache_latency = dcachePort.sendAtomic(&pkt); if (hasPhysMemPort && pkt.getAddr() == physMemAddr)
dcache_latency = physmemPort.sendAtomic(&pkt);
else
dcache_latency = dcachePort.sendAtomic(&pkt);
}
dcache_access = true; dcache_access = true;
assert(!pkt.isError()); 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); dcache_latency = TheISA::handleIprWrite(thread->getTC(), &pkt);
} else { } else {
data = htog(data); 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; dcache_access = true;
assert(!pkt.isError()); assert(!pkt.isError());
@ -513,7 +531,12 @@ AtomicSimpleCPU::tick()
Packet::Broadcast); Packet::Broadcast);
ifetch_pkt.dataStatic(&inst); 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 // ifetch_req is initialized to read the instruction directly
// into the CPU object's inst field. // into the CPU object's inst field.
//} //}

View file

@ -121,6 +121,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
}; };
DcachePort dcachePort; DcachePort dcachePort;
CpuPort physmemPort;
bool hasPhysMemPort;
Request ifetch_req; Request ifetch_req;
Request data_read_req; Request data_read_req;
Request data_write_req; Request data_write_req;
@ -128,6 +130,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
bool dcache_access; bool dcache_access;
Tick dcache_latency; Tick dcache_latency;
Range<Addr> physMemAddr;
public: public:
virtual Port *getPort(const std::string &if_name, int idx = -1); virtual Port *getPort(const std::string &if_name, int idx = -1);