summaryrefslogtreecommitdiff
path: root/configs
diff options
context:
space:
mode:
authorCurtis Dunham <Curtis.Dunham@arm.com>2015-04-08 15:56:06 -0500
committerCurtis Dunham <Curtis.Dunham@arm.com>2015-04-08 15:56:06 -0500
commitc3268f882029c7501867540ccf04db054fdff084 (patch)
tree6c31899946f53d46a0b7bbbfe7fd5dc782dfde2c /configs
parentf05cb84ed1a61f81c26e4ea22f98454d12f069aa (diff)
downloadgem5-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.py49
-rw-r--r--configs/common/FSConfig.py34
-rw-r--r--configs/common/MemConfig.py8
-rw-r--r--configs/common/Options.py2
-rw-r--r--configs/example/fs.py5
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