From 73fdc2eb57dded37c2e0d93c1cdb179d1faa6679 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 28 Oct 2019 18:55:02 -0700 Subject: [PATCH] config,arch,cpu,kern,sim: Extract kernel information from System. Information about what kernel to load and how to load it was built into the System object and its subclasses. That overloaded the System object and made it responsible for too many things, and also was somewhat awkward when working with SE mode which doesn't have a kernel. This change extracts the kernel and information related to it from the System object and puts into into a OsKernel or Workload object. Currently the idea of a "Workload" to run and a kernel are a bit muddled, an unfortunate carry-over from the original code. It's also an implication of trying not to make too sweeping of a change, and to minimize the number of times configs need to change, ie avoiding creating a "kernel" parameter which would shortly thereafter be renamed to "workload". In future changes, the ideas of a kernel and a workload will be disentangled, and workloads will be expanded to include emulated operating systems which shephard and contain Process-es for syscall emulation. This change was originally split into pieces to make reviewing it easier. Those reviews are here: https: //gem5-review.googlesource.com/c/public/gem5/+/22243 https: //gem5-review.googlesource.com/c/public/gem5/+/24144 https: //gem5-review.googlesource.com/c/public/gem5/+/24145 https: //gem5-review.googlesource.com/c/public/gem5/+/24146 https: //gem5-review.googlesource.com/c/public/gem5/+/24147 https: //gem5-review.googlesource.com/c/public/gem5/+/24286 Change-Id: Ia3d863db276a023b6a2c7ee7a656d8142ff75589 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26466 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- configs/common/FSConfig.py | 90 +++-- configs/common/MemConfig.py | 4 +- configs/example/arm/baremetal.py | 5 +- configs/example/arm/fs_bigLITTLE.py | 15 +- configs/example/arm/starter_fs.py | 16 +- configs/example/fs.py | 8 +- configs/example/se.py | 4 +- src/arch/arm/ArmFsWorkload.py | 90 +++++ src/arch/arm/ArmSystem.py | 55 +-- src/arch/arm/SConscript | 6 +- .../arm/freebsd/{system.cc => fs_workload.cc} | 74 ++-- .../arm/freebsd/{system.hh => fs_workload.hh} | 44 +-- src/arch/arm/fs_workload.cc | 149 +++++++ src/arch/arm/fs_workload.hh | 97 +++++ .../arm/linux/{system.cc => fs_workload.cc} | 186 +++++---- .../arm/linux/{system.hh => fs_workload.hh} | 48 ++- src/arch/arm/stacktrace.cc | 2 +- src/arch/arm/system.cc | 160 ++------ src/arch/arm/system.hh | 79 +--- src/arch/generic/linux/threadinfo.hh | 2 +- src/arch/mips/MipsSystem.py | 1 - src/arch/riscv/RiscvFsWorkload.py | 51 +++ src/arch/riscv/RiscvSystem.py | 11 - src/arch/riscv/SConscript | 3 +- src/arch/riscv/bare_metal/fs_workload.cc | 64 +++ src/arch/riscv/bare_metal/fs_workload.hh | 54 +++ src/arch/riscv/faults.cc | 5 +- src/arch/riscv/fs_workload.hh | 62 +++ src/arch/riscv/system.cc | 33 -- src/arch/riscv/system.hh | 46 +-- src/arch/riscv/tlb.cc | 9 +- src/arch/sparc/SConscript | 2 + src/arch/sparc/SparcFsWorkload.py | 62 +++ src/arch/sparc/SparcSystem.py | 40 -- src/arch/sparc/fs_workload.cc | 207 ++++++++++ src/arch/sparc/fs_workload.hh | 124 ++++++ src/arch/sparc/system.cc | 172 -------- src/arch/sparc/system.hh | 94 +---- src/arch/x86/SConscript | 4 +- src/arch/x86/X86FsWorkload.py | 66 ++++ src/arch/x86/X86System.py | 24 -- src/arch/x86/fs_workload.cc | 373 ++++++++++++++++++ src/arch/x86/fs_workload.hh | 109 +++++ .../x86/linux/{system.cc => fs_workload.cc} | 45 ++- .../x86/linux/{system.hh => fs_workload.hh} | 29 +- src/arch/x86/process.cc | 1 + src/arch/x86/pseudo_inst.cc | 3 +- src/arch/x86/stacktrace.cc | 4 +- src/arch/x86/system.cc | 330 ---------------- src/arch/x86/system.hh | 67 +--- src/cpu/o3/thread_state.hh | 2 +- src/cpu/simple_thread.cc | 2 +- src/dev/arm/RealView.py | 6 +- src/kern/linux/helpers.cc | 2 +- src/sim/OsKernel.py | 47 +++ src/sim/SConscript | 2 + src/sim/System.py | 13 +- src/sim/os_kernel.cc | 171 ++++++++ src/sim/os_kernel.hh | 189 +++++++++ src/sim/pseudo_inst.cc | 4 +- src/sim/system.cc | 128 +----- src/sim/system.hh | 154 +------- tests/configs/arm_generic.py | 11 +- 63 files changed, 2309 insertions(+), 1651 deletions(-) create mode 100644 src/arch/arm/ArmFsWorkload.py rename src/arch/arm/freebsd/{system.cc => fs_workload.cc} (66%) rename src/arch/arm/freebsd/{system.hh => fs_workload.hh} (78%) create mode 100644 src/arch/arm/fs_workload.cc create mode 100644 src/arch/arm/fs_workload.hh rename src/arch/arm/linux/{system.cc => fs_workload.cc} (79%) rename src/arch/arm/linux/{system.hh => fs_workload.hh} (84%) create mode 100644 src/arch/riscv/RiscvFsWorkload.py create mode 100644 src/arch/riscv/bare_metal/fs_workload.cc create mode 100644 src/arch/riscv/bare_metal/fs_workload.hh create mode 100644 src/arch/riscv/fs_workload.hh create mode 100644 src/arch/sparc/SparcFsWorkload.py create mode 100644 src/arch/sparc/fs_workload.cc create mode 100644 src/arch/sparc/fs_workload.hh create mode 100644 src/arch/x86/X86FsWorkload.py create mode 100644 src/arch/x86/fs_workload.cc create mode 100644 src/arch/x86/fs_workload.hh rename src/arch/x86/linux/{system.cc => fs_workload.cc} (80%) rename src/arch/x86/linux/{system.hh => fs_workload.hh} (84%) create mode 100644 src/sim/OsKernel.py create mode 100644 src/sim/os_kernel.cc create mode 100644 src/sim/os_kernel.hh diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index 691a04a27..b58c27380 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -123,10 +123,6 @@ def makeSparcSystem(mem_mode, mdesc=None, cmdline=None): AddrRange(Addr('2GB'), size ='256MB')] self.bridge.master = self.iobus.slave self.bridge.slave = self.membus.master - self.rom.port = self.membus.master - self.nvram.port = self.membus.master - self.hypervisor_desc.port = self.membus.master - self.partition_desc.port = self.membus.master self.intrctrl = IntrControl() self.disk0 = CowMmDisk() self.disk0.childImage(mdesc.disks()[0]) @@ -150,15 +146,37 @@ def makeSparcSystem(mem_mode, mdesc=None, cmdline=None): AddrRange(self.t1000.hvuart.pio_addr, self.t1000.hvuart.pio_addr + uart_pio_size - 1) ] - self.reset_bin = binary('reset_new.bin') - self.hypervisor_bin = binary('q_new.bin') - self.openboot_bin = binary('openboot_new.bin') - self.nvram_bin = binary('nvram1') - self.hypervisor_desc_bin = binary('1up-hv.bin') - self.partition_desc_bin = binary('1up-md.bin') + + workload = SparcFsWorkload( + reset_bin=binary('reset_new.bin'), + hypervisor_bin=binary('q_new.bin'), + openboot_bin=binary('openboot_new.bin'), + nvram_bin=binary('nvram1'), + hypervisor_desc_bin=binary('1up-hv.bin'), + partition_desc_bin=binary('1up-md.bin'), + ) + + # ROM for OBP/Reset/Hypervisor + self.rom = SimpleMemory(range=AddrRange(workload._rom_base, size='8MB')) + # nvram + self.nvram = SimpleMemory( + range=AddrRange(workload._nvram_base, size='8kB')) + # hypervisor description + self.hypervisor_desc = SimpleMemory( + range=AddrRange(workload._hypervisor_desc_base, size='8kB')) + # partition description + self.partition_desc = SimpleMemory( + range=AddrRange(workload._partition_desc_base, size='8kB')) + + self.rom.port = self.membus.master + self.nvram.port = self.membus.master + self.hypervisor_desc.port = self.membus.master + self.partition_desc.port = self.membus.master self.system_port = self.membus.slave + self.workload = workload + return self def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, @@ -169,10 +187,7 @@ def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, pci_devices = [] - if bare_metal: - self = ArmSystem() - else: - self = LinuxArmSystem() + self = ArmSystem() if not mdesc: # generic system @@ -242,11 +257,13 @@ def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, # EOT character on UART will end the simulation self.realview.uart[0].end_on_eot = True else: + workload = ArmFsLinux() + if dtb_filename: - self.dtb_filename = binary(dtb_filename) + workload.dtb_filename = binary(dtb_filename) - self.machine_type = machine_type if machine_type in ArmMachineType.map \ - else "DTOnly" + workload.machine_type = \ + machine_type if machine_type in ArmMachineType.map else "DTOnly" # Ensure that writes to the UART actually go out early in the boot if not cmdline: @@ -254,8 +271,6 @@ 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, binary, bootloader) - if hasattr(self.realview.gic, 'cpu_addr'): self.gic_cpu_addr = self.realview.gic.cpu_addr @@ -292,7 +307,11 @@ def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, "androidboot.selinux=permissive " + \ "video=Virtual-1:1920x1080-16" - self.boot_osflags = fillInCmdline(mdesc, cmdline) + workload.command_line = fillInCmdline(mdesc, cmdline) + + self.workload = workload + + self.realview.setupBootLoader(self, binary) if external_memory: # I/O traffic enters iobus @@ -381,7 +400,7 @@ def makeLinuxMipsSystem(mem_mode, mdesc=None, cmdline=None): self.console = binary('mips/console') if not cmdline: cmdline = 'root=/dev/hda1 console=ttyS0' - self.boot_osflags = fillInCmdline(mdesc, cmdline) + self.workload = OsKernel(command_line=fillInCmdline(mdesc, cmdline)) self.system_port = self.membus.slave @@ -445,9 +464,12 @@ def connectX86RubySystem(x86_sys): x86_sys.pc.attachIO(x86_sys.iobus, x86_sys._dma_ports) -def makeX86System(mem_mode, numCPUs=1, mdesc=None, self=None, Ruby=False): - if self == None: - self = X86System() +def makeX86System(mem_mode, numCPUs=1, mdesc=None, workload=None, Ruby=False): + self = X86System() + + if workload is None: + workload = X86FsWorkload() + self.workload = workload if not mdesc: # generic system @@ -489,7 +511,7 @@ def makeX86System(mem_mode, numCPUs=1, mdesc=None, self=None, Ruby=False): # Add in a Bios information structure. structures = [X86SMBiosBiosInformation()] - self.smbios_table.structures = structures + workload.smbios_table.structures = structures # Set up the Intel MP table base_entries = [] @@ -509,8 +531,8 @@ def makeX86System(mem_mode, numCPUs=1, mdesc=None, self=None, Ruby=False): self.pc.south_bridge.io_apic.apic_id = io_apic.id base_entries.append(io_apic) # In gem5 Pc::calcPciConfigAddr(), it required "assert(bus==0)", - # but linux kernel cannot config PCI device if it was not connected to PCI bus, - # so we fix PCI bus id to 0, and ISA bus id to 1. + # but linux kernel cannot config PCI device if it was not connected to + # PCI bus, so we fix PCI bus id to 0, and ISA bus id to 1. pci_bus = X86IntelMPBus(bus_id = 0, bus_type='PCI ') base_entries.append(pci_bus) isa_bus = X86IntelMPBus(bus_id = 1, bus_type='ISA ') @@ -550,15 +572,15 @@ def makeX86System(mem_mode, numCPUs=1, mdesc=None, self=None, Ruby=False): assignISAInt(1, 1) for i in range(3, 15): assignISAInt(i, i) - self.intel_mp_table.base_entries = base_entries - self.intel_mp_table.ext_entries = ext_entries + workload.intel_mp_table.base_entries = base_entries + workload.intel_mp_table.ext_entries = ext_entries + + return self def makeLinuxX86System(mem_mode, numCPUs=1, mdesc=None, Ruby=False, cmdline=None): - self = LinuxX86System() - # Build up the x86 system and then specialize it for Linux - makeX86System(mem_mode, numCPUs, mdesc, self, Ruby) + self = makeX86System(mem_mode, numCPUs, mdesc, X86FsLinux(), Ruby) # We assume below that there's at least 1MB of memory. We'll require 2 # just to avoid corner cases. @@ -596,12 +618,12 @@ def makeLinuxX86System(mem_mode, numCPUs=1, mdesc=None, Ruby=False, entries.append(X86E820Entry(addr = 0x100000000, size = '%dB' % (self.mem_ranges[1].size()), range_type = 1)) - self.e820_table.entries = entries + self.workload.e820_table.entries = entries # Command line if not cmdline: cmdline = 'earlyprintk=ttyS0 console=ttyS0 lpj=7999923 root=/dev/hda1' - self.boot_osflags = fillInCmdline(mdesc, cmdline) + self.workload.command_line = fillInCmdline(mdesc, cmdline) return self diff --git a/configs/common/MemConfig.py b/configs/common/MemConfig.py index 85494d3f3..d1cc6558a 100644 --- a/configs/common/MemConfig.py +++ b/configs/common/MemConfig.py @@ -125,7 +125,7 @@ def config_mem(options, system): port_data=opt_tlm_memory, port=system.membus.master, addr_ranges=system.mem_ranges) - system.kernel_addr_check = False + system.workload.addr_check = False return if opt_external_memory_system: @@ -133,7 +133,7 @@ def config_mem(options, system): port_type=opt_external_memory_system, port_data="init_mem0", port=xbar.master, addr_ranges=system.mem_ranges) - subsystem.kernel_addr_check = False + subsystem.workload.addr_check = False return nbr_mem_ctrls = opt_mem_channels diff --git a/configs/example/arm/baremetal.py b/configs/example/arm/baremetal.py index 109370b43..c1628934b 100644 --- a/configs/example/arm/baremetal.py +++ b/configs/example/arm/baremetal.py @@ -98,7 +98,8 @@ def create(args): args.mem_size, platform=VExpress_GEM5_V2(), mem_mode=mem_mode, - kernel=args.kernel, + workload=ArmFsWorkload( + object_file=args.kernel), readfile=args.readfile) MemConfig.config_mem(args, system) @@ -215,7 +216,7 @@ def main(): if args.dtb_gen: # No run, autogenerate DTB and exit - root.system.generateDtb(m5.options.outdir, 'system.dtb') + root.system.generateDtb(os.path.join(m5.options.outdir, 'system.dtb')) else: run(args) diff --git a/configs/example/arm/fs_bigLITTLE.py b/configs/example/arm/fs_bigLITTLE.py index cc3e748c8..b7e794d58 100644 --- a/configs/example/arm/fs_bigLITTLE.py +++ b/configs/example/arm/fs_bigLITTLE.py @@ -118,9 +118,10 @@ def createSystem(caches, kernel, bootscript, machine_type="VExpress_GEM5", platform = ObjectList.platform_list.get(machine_type) m5.util.inform("Simulated platform: %s", platform.__name__) - sys = devices.simpleSystem(LinuxArmSystem, + sys = devices.simpleSystem(ArmSystem, caches, mem_size, platform(), - kernel=SysPaths.binary(kernel), + workload=ArmFsLinux( + object_file=SysPaths.binary(kernel)), readfile=bootscript) sys.mem_ctrls = [ SimpleMemory(range=r, port=sys.membus.master) @@ -243,9 +244,9 @@ def build(options): root.system = system if options.kernel_cmd: - system.boot_osflags = options.kernel_cmd + system.workload.command_line = options.kernel_cmd else: - system.boot_osflags = " ".join(kernel_cmd) + system.workload.command_line = " ".join(kernel_cmd) if options.big_cpus + options.little_cpus == 0: m5.util.panic("Empty CPU clusters") @@ -287,9 +288,11 @@ def build(options): # Linux device tree if options.dtb is not None: - system.dtb_filename = SysPaths.binary(options.dtb) + system.workload.dtb_filename = SysPaths.binary(options.dtb) else: - system.generateDtb(m5.options.outdir, 'system.dtb') + system.workload.dtb_filename = \ + os.path.join(m5.options.outdir, 'system.dtb') + system.generateDtb(system.workload.dtb_filename) if devices.have_fastmodel and issubclass(big_model, FastmodelCluster): from m5 import arm_fast_model as fm, systemc as sc diff --git a/configs/example/arm/starter_fs.py b/configs/example/arm/starter_fs.py index ee67cb0b4..7a202807e 100644 --- a/configs/example/arm/starter_fs.py +++ b/configs/example/arm/starter_fs.py @@ -99,11 +99,13 @@ def create(args): # Only simulate caches when using a timing CPU (e.g., the HPI model) want_caches = True if mem_mode == "timing" else False - system = devices.simpleSystem(LinuxArmSystem, + system = devices.simpleSystem(ArmSystem, want_caches, args.mem_size, mem_mode=mem_mode, - kernel=SysPaths.binary(args.kernel), + workload=ArmFsLinux( + object_file= + SysPaths.binary(args.kernel)), readfile=args.script) MemConfig.config_mem(args, system) @@ -146,10 +148,12 @@ def create(args): system.realview.setupBootLoader(system, SysPaths.binary) if args.dtb: - system.dtb_filename = args.dtb + system.workload.dtb_filename = args.dtb else: # No DTB specified: autogenerate DTB - system.generateDtb(m5.options.outdir, 'system.dtb') + system.workload.dtb_filename = \ + os.path.join(m5.options.outdir, 'system.dtb') + system.generateDtb(system.workload.dtb_filename) # Linux boot command flags kernel_cmd = [ @@ -161,13 +165,13 @@ def create(args): # memory layout. "norandmaps", # Tell Linux where to find the root disk image. - "root=/dev/vda1", + "root=/dev/vda", # Mount the root disk read-write by default. "rw", # Tell Linux about the amount of physical memory present. "mem=%s" % args.mem_size, ] - system.boot_osflags = " ".join(kernel_cmd) + system.workload.command_line = " ".join(kernel_cmd) return system diff --git a/configs/example/fs.py b/configs/example/fs.py index bf6832548..5264aa568 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -124,7 +124,7 @@ def build_test_system(np): test_sys.cpu_voltage_domain) if options.kernel is not None: - test_sys.kernel = binary(options.kernel) + test_sys.workload.object_file = binary(options.kernel) if options.script is not None: test_sys.readfile = options.script @@ -269,7 +269,7 @@ def build_drive_system(np): drive_sys.cpu.createInterruptController() drive_sys.cpu.connectAllPorts(drive_sys.membus) if options.kernel is not None: - drive_sys.kernel = binary(options.kernel) + drive_sys.workload.object_file = binary(options.kernel) if ObjectList.is_kvm_cpu(DriveCPUClass): drive_sys.kvm_vm = KvmVM() @@ -369,7 +369,9 @@ if buildEnv['TARGET_ISA'] == "arm" and not options.bare_metal \ for sysname in ('system', 'testsys', 'drivesys'): if hasattr(root, sysname): sys = getattr(root, sysname) - sys.generateDtb(m5.options.outdir, '%s.dtb' % sysname) + sys.workload.dtb_filename = \ + os.path.join(m5.options.outdir, '%s.dtb' % sysname) + sys.generateDtb(sys.workload.dtb_filename) Simulation.setWorkCountOptions(test_sys, options) Simulation.run(options, root, test_sys, FutureClass) diff --git a/configs/example/se.py b/configs/example/se.py index 25c148882..a3cd6f14d 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -50,6 +50,7 @@ import os import m5 from m5.defines import buildEnv from m5.objects import * +from m5.params import NULL from m5.util import addToPath, fatal, warn addToPath('../') @@ -171,7 +172,8 @@ np = options.num_cpus system = System(cpu = [CPUClass(cpu_id=i) for i in range(np)], mem_mode = test_mem_mode, mem_ranges = [AddrRange(options.mem_size)], - cache_line_size = options.cacheline_size) + cache_line_size = options.cacheline_size, + workload = NULL) if numThreads > 1: system.multi_thread = True diff --git a/src/arch/arm/ArmFsWorkload.py b/src/arch/arm/ArmFsWorkload.py new file mode 100644 index 000000000..6064d81e9 --- /dev/null +++ b/src/arch/arm/ArmFsWorkload.py @@ -0,0 +1,90 @@ +# Copyright (c) 2009, 2012-2013, 2015-2019 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.params import * +from m5.options import * +from m5.SimObject import * +from m5.objects.OsKernel import OsKernel + +class ArmMachineType(Enum): + map = { + 'VExpress_EMM' : 2272, + 'VExpress_EMM64' : 2272, + 'DTOnly' : -1, + } + +class ArmFsWorkload(OsKernel): + type = 'ArmFsWorkload' + cxx_header = "arch/arm/fs_workload.hh" + cxx_class = "ArmISA::FsWorkload" + + load_addr_mask = 0 + + boot_loader = VectorParam.String([], + "File that contains the boot loader code. Zero or more files may be " + "specified. The first boot loader that matches the kernel's " + "architecture will be used.") + + dtb_filename = Param.String("", + "File that contains the Device Tree Blob. Don't use DTB if empty.") + + machine_type = Param.ArmMachineType('DTOnly', + "Machine id from http://www.arm.linux.org.uk/developer/machines/") + atags_addr = Param.Addr("Address where default atags structure should " \ + "be written") + early_kernel_symbols = Param.Bool(False, + "enable early kernel symbol tables before MMU") + enable_context_switch_stats_dump = Param.Bool(False, + "enable stats/task info dumping at context switch boundaries") + + panic_on_panic = Param.Bool(False, "Trigger a gem5 panic if the " \ + "guest kernel panics") + panic_on_oops = Param.Bool(False, "Trigger a gem5 panic if the " \ + "guest kernel oopses") + +class ArmFsLinux(ArmFsWorkload): + type = 'ArmFsLinux' + cxx_header = "arch/arm/linux/fs_workload.hh" + cxx_class = "ArmISA::FsLinux" + + @cxxMethod + def dumpDmesg(self): + """Dump dmesg from the simulated kernel to standard out""" + pass + +class ArmFsFreebsd(ArmFsWorkload): + type = 'ArmFsFreebsd' + cxx_header = "arch/arm/freebsd/fs_workload.hh" + cxx_class = "ArmISA::FsFreebsd" diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py index 5f4061feb..1b5fc907d 100644 --- a/src/arch/arm/ArmSystem.py +++ b/src/arch/arm/ArmSystem.py @@ -41,23 +41,12 @@ from m5.util.fdthelper import * from m5.objects.System import System from m5.objects.ArmSemihosting import ArmSemihosting -class ArmMachineType(Enum): - map = { - 'VExpress_EMM' : 2272, - 'VExpress_EMM64' : 2272, - 'DTOnly' : -1, - } - class SveVectorLength(UInt8): min = 1; max = 16 class ArmSystem(System): type = 'ArmSystem' cxx_header = "arch/arm/system.hh" multi_proc = Param.Bool(True, "Multiprocessor system?") - boot_loader = VectorParam.String([], - "File that contains the boot loader code. Zero or more files may be " - "specified. The first boot loader that matches the kernel's " - "architecture will be used.") gic_cpu_addr = Param.Addr(0, "Addres of the GIC CPU interface") flags_addr = Param.Addr(0, "Address of the flags register for MP booting") have_security = Param.Bool(False, @@ -90,10 +79,11 @@ class ArmSystem(System): semihosting = Param.ArmSemihosting(NULL, "Enable support for the Arm semihosting by settings this parameter") - dtb_filename = Param.String("", - "File that contains the Device Tree Blob. Don't use DTB if empty.") + m5ops_base = Param.Addr(0, + "Base of the 64KiB PA range used for memory-mapped m5ops. Set to 0 " + "to disable.") - def generateDtb(self, outdir, filename): + def generateDtb(self, filename): """ Autogenerate DTB. Arguments are the folder where the DTB will be stored, and the name of the DTB file. @@ -103,8 +93,7 @@ class ArmSystem(System): fdt = Fdt() fdt.add_rootnode(rootNode) - dtb_filename = os.path.join(outdir, filename) - self.dtb_filename = fdt.writeDtbFile(dtb_filename) + fdt.writeDtbFile(filename) def generateDeviceTree(self, state): @@ -139,37 +128,3 @@ class ArmSystem(System): root.append(node) return root - -class GenericArmSystem(ArmSystem): - type = 'GenericArmSystem' - cxx_header = "arch/arm/system.hh" - machine_type = Param.ArmMachineType('DTOnly', - "Machine id from http://www.arm.linux.org.uk/developer/machines/") - atags_addr = Param.Addr("Address where default atags structure should " \ - "be written") - early_kernel_symbols = Param.Bool(False, - "enable early kernel symbol tables before MMU") - enable_context_switch_stats_dump = Param.Bool(False, - "enable stats/task info dumping at context switch boundaries") - - panic_on_panic = Param.Bool(False, "Trigger a gem5 panic if the " \ - "guest kernel panics") - panic_on_oops = Param.Bool(False, "Trigger a gem5 panic if the " \ - "guest kernel oopses") - -class LinuxArmSystem(GenericArmSystem): - type = 'LinuxArmSystem' - cxx_header = "arch/arm/linux/system.hh" - - @cxxMethod - def dumpDmesg(self): - """Dump dmesg from the simulated kernel to standard out""" - pass - - # Have Linux systems for ARM auto-calc their load_addr_mask for proper - # kernel relocation. - load_addr_mask = 0x0 - -class FreebsdArmSystem(GenericArmSystem): - type = 'FreebsdArmSystem' - cxx_header = "arch/arm/freebsd/system.hh" diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index b4e9bba8e..409e287db 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -67,10 +67,11 @@ if env['TARGET_ISA'] == 'arm': Source('isa_device.cc') Source('linux/linux.cc') Source('linux/process.cc') - Source('linux/system.cc') + Source('linux/fs_workload.cc') Source('freebsd/freebsd.cc') Source('freebsd/process.cc') - Source('freebsd/system.cc') + Source('freebsd/fs_workload.cc') + Source('fs_workload.cc') Source('miscregs.cc') Source('nativetrace.cc') Source('pauth_helpers.cc') @@ -89,6 +90,7 @@ if env['TARGET_ISA'] == 'arm': Source('utility.cc') Source('vtophys.cc') + SimObject('ArmFsWorkload.py') SimObject('ArmInterrupts.py') SimObject('ArmISA.py') SimObject('ArmNativeTrace.py') diff --git a/src/arch/arm/freebsd/system.cc b/src/arch/arm/freebsd/fs_workload.cc similarity index 66% rename from src/arch/arm/freebsd/system.cc rename to src/arch/arm/freebsd/fs_workload.cc index b77126790..c248ff617 100644 --- a/src/arch/arm/freebsd/system.cc +++ b/src/arch/arm/freebsd/fs_workload.cc @@ -30,7 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/arm/freebsd/system.hh" +#include "arch/arm/freebsd/fs_workload.hh" #include "arch/arm/isa_traits.hh" #include "arch/arm/utility.hh" @@ -47,13 +47,13 @@ #include "mem/physical.hh" #include "sim/stat_control.hh" -using namespace ArmISA; using namespace FreeBSD; -FreebsdArmSystem::FreebsdArmSystem(Params *p) - : GenericArmSystem(p), - enableContextSwitchStatsDump(p->enable_context_switch_stats_dump), - taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr) +namespace ArmISA +{ + +FsFreebsd::FsFreebsd(Params *p) : ArmISA::FsWorkload(p), + enableContextSwitchStatsDump(p->enable_context_switch_stats_dump) { if (p->panic_on_panic) { kernelPanicEvent = addKernelFuncEventOrPanic( @@ -74,36 +74,24 @@ FreebsdArmSystem::FreebsdArmSystem(Params *p) } void -FreebsdArmSystem::initState() +FsFreebsd::initState() { - // Moved from the constructor to here since it relies on the - // address map being resolved in the interconnect - - // Call the initialisation of the super class - GenericArmSystem::initState(); + ArmISA::FsWorkload::initState(); // Load symbols at physical address, we might not want // to do this permanently, for but early bootup work // it is helpful. if (params()->early_kernel_symbols) { - kernel->loadGlobalSymbols(kernelSymtab, 0, 0, loadAddrMask); - kernel->loadGlobalSymbols(debugSymbolTable, 0, 0, loadAddrMask); + obj->loadGlobalSymbols(symtab, 0, 0, loadAddrMask); + obj->loadGlobalSymbols(debugSymbolTable, 0, 0, loadAddrMask); } - // Setup boot data structure - Addr addr = 0; - // Check if the kernel image has a symbol that tells us it supports // device trees. - bool kernel_has_fdt_support = - kernelSymtab->findAddress("fdt_get_range", addr); - bool dtb_file_specified = params()->dtb_filename != ""; - - if (!dtb_file_specified) - fatal("dtb file is not specified\n"); - - if (!kernel_has_fdt_support) - fatal("kernel must have fdt support\n"); + Addr addr; + fatal_if(!symtab->findAddress("fdt_get_range", addr), + "Kernel must have fdt support."); + fatal_if(params()->dtb_filename == "", "dtb file is not specified."); // Kernel supports flattened device tree and dtb file specified. // Using Device Tree Blob to describe system configuration. @@ -112,38 +100,36 @@ FreebsdArmSystem::initState() DtbFile *dtb_file = new DtbFile(params()->dtb_filename); - if (!dtb_file->addBootCmdLine(params()->boot_osflags.c_str(), - params()->boot_osflags.size())) { - warn("couldn't append bootargs to DTB file: %s\n", - params()->dtb_filename); - } + warn_if(!dtb_file->addBootCmdLine(commandLine.c_str(), commandLine.size()), + "Couldn't append bootargs to DTB file: %s", + params()->dtb_filename); Addr ra = dtb_file->findReleaseAddr(); if (ra) bootReleaseAddr = ra & ~ULL(0x7F); dtb_file->buildImage(). - offset(params()->atags_addr + loadAddrOffset).write(physProxy); + offset(params()->atags_addr + loadAddrOffset). + write(system->physProxy); delete dtb_file; // Kernel boot requirements to set up r0, r1 and r2 in ARMv7 - for (int i = 0; i < threadContexts.size(); i++) { - threadContexts[i]->setIntReg(0, 0); - threadContexts[i]->setIntReg(1, params()->machine_type); - threadContexts[i]->setIntReg(2, params()->atags_addr + loadAddrOffset); + for (auto tc: system->threadContexts) { + tc->setIntReg(0, 0); + tc->setIntReg(1, params()->machine_type); + tc->setIntReg(2, params()->atags_addr + loadAddrOffset); } } -FreebsdArmSystem::~FreebsdArmSystem() +FsFreebsd::~FsFreebsd() { - if (uDelaySkipEvent) - delete uDelaySkipEvent; - if (constUDelaySkipEvent) - delete constUDelaySkipEvent; + delete uDelaySkipEvent; } -FreebsdArmSystem * -FreebsdArmSystemParams::create() +} // namespace ArmISA + +ArmISA::FsFreebsd * +ArmFsFreebsdParams::create() { - return new FreebsdArmSystem(this); + return new ArmISA::FsFreebsd(this); } diff --git a/src/arch/arm/freebsd/system.hh b/src/arch/arm/freebsd/fs_workload.hh similarity index 78% rename from src/arch/arm/freebsd/system.hh rename to src/arch/arm/freebsd/fs_workload.hh index f4f19a326..7f0ac083f 100644 --- a/src/arch/arm/freebsd/system.hh +++ b/src/arch/arm/freebsd/fs_workload.hh @@ -30,29 +30,27 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __ARCH_ARM_FREEBSD_SYSTEM_HH__ -#define __ARCH_ARM_FREEBSD_SYSTEM_HH__ +#ifndef __ARCH_ARM_FREEBSD_FS_WORKLOAD_HH__ +#define __ARCH_ARM_FREEBSD_FS_WORKLOAD_HH__ -#include #include -#include -#include -#include "arch/arm/system.hh" -#include "base/output.hh" +#include "arch/arm/fs_workload.hh" #include "kern/freebsd/events.hh" -#include "params/FreebsdArmSystem.hh" -#include "sim/core.hh" +#include "params/ArmFsFreebsd.hh" -class FreebsdArmSystem : public GenericArmSystem +namespace ArmISA +{ + +class FsFreebsd : public ArmISA::FsWorkload { public: /** Boilerplate params code */ - typedef FreebsdArmSystemParams Params; + typedef ArmFsFreebsdParams Params; const Params * params() const { - return dynamic_cast(_params); + return dynamic_cast(&_params); } /** When enabled, dump stats/task info on context switches for @@ -69,10 +67,10 @@ class FreebsdArmSystem : public GenericArmSystem * mappings between taskIds and OS process IDs */ std::ostream* taskFile; - FreebsdArmSystem(Params *p); - ~FreebsdArmSystem(); + FsFreebsd(Params *p); + ~FsFreebsd(); - void initState(); + void initState() override; /** This function creates a new task Id for the given pid. * @param tc thread context that is currentyl executing */ @@ -80,24 +78,17 @@ class FreebsdArmSystem : public GenericArmSystem private: /** Event to halt the simulator if the kernel calls panic() */ - PCEvent *kernelPanicEvent; + PCEvent *kernelPanicEvent = nullptr; /** Event to halt the simulator if the kernel calls oopses */ - PCEvent *kernelOopsEvent; + PCEvent *kernelOopsEvent = nullptr; /** * PC based event to skip udelay(