diff options
author | Curtis Dunham <Curtis.Dunham@arm.com> | 2015-04-08 15:56:06 -0500 |
---|---|---|
committer | Curtis Dunham <Curtis.Dunham@arm.com> | 2015-04-08 15:56:06 -0500 |
commit | c3268f882029c7501867540ccf04db054fdff084 (patch) | |
tree | 6c31899946f53d46a0b7bbbfe7fd5dc782dfde2c /configs | |
parent | f05cb84ed1a61f81c26e4ea22f98454d12f069aa (diff) | |
download | gem5-c3268f882029c7501867540ccf04db054fdff084.tar.xz |
config: Support full-system with SST's memory system
This patch adds an example configuration in ext/sst/tests/ that allows
an SST/gem5 instance to simulate a 4-core AArch64 system with SST's
memHierarchy components providing all the caches and memories.
Diffstat (limited to 'configs')
-rw-r--r-- | configs/common/CacheConfig.py | 49 | ||||
-rw-r--r-- | configs/common/FSConfig.py | 34 | ||||
-rw-r--r-- | configs/common/MemConfig.py | 8 | ||||
-rw-r--r-- | configs/common/Options.py | 2 | ||||
-rw-r--r-- | configs/example/fs.py | 5 |
5 files changed, 91 insertions, 7 deletions
diff --git a/configs/common/CacheConfig.py b/configs/common/CacheConfig.py index 66fe491e1..899090af5 100644 --- a/configs/common/CacheConfig.py +++ b/configs/common/CacheConfig.py @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2013 ARM Limited +# Copyright (c) 2012-2013, 2015 ARM Limited # All rights reserved # # The license below extends only to copyright in the software and shall @@ -46,6 +46,13 @@ from m5.objects import * from Caches import * def config_cache(options, system): + if options.external_memory_system and (options.caches or options.l2cache): + print "External caches and internal caches are exclusive options.\n" + sys.exit(1) + + if options.external_memory_system: + ExternalCache = ExternalCacheFactory(options.external_memory_system) + if options.cpu_type == "arm_detailed": try: from O3_ARM_v7a import * @@ -114,10 +121,50 @@ def config_cache(options, system): system.cpu[i].dcache = dcache_real system.cpu[i].dcache_mon = dcache_mon + elif options.external_memory_system: + # These port names are presented to whatever 'external' system + # gem5 is connecting to. Its configuration will likely depend + # on these names. For simplicity, we would advise configuring + # it to use this naming scheme; if this isn't possible, change + # the names below. + if buildEnv['TARGET_ISA'] in ['x86', 'arm']: + system.cpu[i].addPrivateSplitL1Caches( + ExternalCache("cpu%d.icache" % i), + ExternalCache("cpu%d.dcache" % i), + ExternalCache("cpu%d.itb_walker_cache" % i), + ExternalCache("cpu%d.dtb_walker_cache" % i)) + else: + system.cpu[i].addPrivateSplitL1Caches( + ExternalCache("cpu%d.icache" % i), + ExternalCache("cpu%d.dcache" % i)) + system.cpu[i].createInterruptController() if options.l2cache: system.cpu[i].connectAllPorts(system.tol2bus, system.membus) + elif options.external_memory_system: + system.cpu[i].connectUncachedPorts(system.membus) else: system.cpu[i].connectAllPorts(system.membus) return system + +# ExternalSlave provides a "port", but when that port connects to a cache, +# the connecting CPU SimObject wants to refer to its "cpu_side". +# The 'ExternalCache' class provides this adaptation by rewriting the name, +# eliminating distracting changes elsewhere in the config code. +class ExternalCache(ExternalSlave): + def __getattr__(cls, attr): + if (attr == "cpu_side"): + attr = "port" + return super(ExternalSlave, cls).__getattr__(attr) + + def __setattr__(cls, attr, value): + if (attr == "cpu_side"): + attr = "port" + return super(ExternalSlave, cls).__setattr__(attr, value) + +def ExternalCacheFactory(port_type): + def make(name): + return ExternalCache(port_data=name, port_type=port_type, + addr_ranges=[AllMemory]) + return make diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index cfc156649..17f1f7641 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2012 ARM Limited +# Copyright (c) 2010-2012, 2015 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -203,7 +203,8 @@ def makeSparcSystem(mem_mode, mdesc=None): return self def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, - dtb_filename=None, bare_metal=False, cmdline=None): + dtb_filename=None, bare_metal=False, cmdline=None, + external_memory=""): assert machine_type if bare_metal: @@ -293,7 +294,15 @@ def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, 'lpj=19988480 norandmaps rw loglevel=8 ' + \ 'mem=%(mem)s root=%(rootdev)s' - self.realview.setupBootLoader(self.membus, self, binary) + # When using external memory, gem5 writes the boot loader to nvmem + # and then SST will read from it, but SST can only get to nvmem from + # iobus, as gem5's membus is only used for initialization and + # SST doesn't use it. Attaching nvmem to iobus solves this issue. + # During initialization, system_port -> membus -> iobus -> nvmem. + if external_memory: + self.realview.setupBootLoader(self.iobus, self, binary) + else: + self.realview.setupBootLoader(self.membus, self, binary) self.gic_cpu_addr = self.realview.gic.cpu_addr self.flags_addr = self.realview.realview_io.pio_addr + 0x30 @@ -322,7 +331,24 @@ def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, self.boot_osflags = fillInCmdline(mdesc, cmdline) - self.realview.attachOnChipIO(self.membus, self.bridge) + if external_memory: + # I/O traffic enters iobus + self.external_io = ExternalMaster(port_data="external_io", + port_type=external_memory) + self.external_io.port = self.iobus.slave + + # Ensure iocache only receives traffic destined for (actual) memory. + self.iocache = ExternalSlave(port_data="iocache", + port_type=external_memory, + addr_ranges=self.mem_ranges) + self.iocache.port = self.iobus.master + + # Let system_port get to nvmem and nothing else. + self.bridge.ranges = [self.realview.nvmem.range] + + self.realview.attachOnChipIO(self.iobus) + else: + self.realview.attachOnChipIO(self.membus, self.bridge) self.realview.attachIO(self.iobus) self.intrctrl = IntrControl() self.terminal = Terminal() diff --git a/configs/common/MemConfig.py b/configs/common/MemConfig.py index b0ac44406..5266667ec 100644 --- a/configs/common/MemConfig.py +++ b/configs/common/MemConfig.py @@ -189,6 +189,14 @@ def config_mem(options, system): them. """ + if options.external_memory_system: + system.external_memory = m5.objects.ExternalSlave( + port_type=options.external_memory_system, + port_data="init_mem0", port=system.membus.master, + addr_ranges=system.mem_ranges) + system.kernel_addr_check = False + return + nbr_mem_ctrls = options.mem_channels import math from m5.util import fatal diff --git a/configs/common/Options.py b/configs/common/Options.py index f110f7dfb..a383b40ca 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -104,6 +104,8 @@ def addCommonOptions(parser): parser.add_option("--memchecker", action="store_true") # Cache Options + parser.add_option("--external-memory-system", type="string", + help="use external ports of this port_type for caches") parser.add_option("--caches", action="store_true") parser.add_option("--l2cache", action="store_true") parser.add_option("--fastmem", action="store_true") diff --git a/configs/example/fs.py b/configs/example/fs.py index 98c7db480..70a3b950e 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -98,7 +98,8 @@ def build_test_system(np): test_sys = makeArmSystem(test_mem_mode, options.machine_type, options.num_cpus, bm[0], options.dtb_filename, bare_metal=options.bare_metal, - cmdline=cmdline) + cmdline=cmdline, + external_memory=options.external_memory_system) if options.enable_context_switch_stats_dump: test_sys.enable_context_switch_stats_dump = True else: @@ -185,7 +186,7 @@ def build_test_system(np): test_sys.iocache = IOCache(addr_ranges = test_sys.mem_ranges) test_sys.iocache.cpu_side = test_sys.iobus.master test_sys.iocache.mem_side = test_sys.membus.slave - else: + elif not options.external_memory_system: test_sys.iobridge = Bridge(delay='50ns', ranges = test_sys.mem_ranges) test_sys.iobridge.slave = test_sys.iobus.master test_sys.iobridge.master = test_sys.membus.slave |