From da4f5726be6c58f697d7f1d20759b511c641e6b0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Jan 2020 17:21:32 -0800 Subject: [PATCH] arch,sim,kern,dev,cpu: Create a Workload SimObject. This generalized Workload SimObject is not geared towards FS or SE simulations, although currently it's only used in FS. This gets rid of the ARM specific highestELIs64 property (from the workload, not the system) and replaces it with a generic getArch. The old globally accessible kernel symtab has been replaced with a symtab accessor which takes a ThreadContext *. The parameter isn't used for anything for now, but in cases where there might be multiple symbol tables to choose from (kernel vs. current user space?) the method will now be able to distinguish which to use. This also makes it possible for the workload to manage its symbol table with whatever policy makes sense for it. That method returns a const SymbolTable * since most of the time the symbol table doesn't need to be modified. In the one case where an external entity needs to modify the table, two pseudo instructions, the table to modify isn't necessarily the one that's currently active. For instance, the pseudo instruction will likely execute in user space, but might be intended to add a symbol to the kernel in case something like a module was loaded. To support that usage, the workload has a generic "insertSymbol" method which will insert the symbol in the table that "makes sense". There is a lot of ambiguity what that means, but it's no less ambiguous than today where we're only saved by the fact that there is generally only one active symbol table to worry about. This change also introduces a KernelWorkload SimObject class which inherits from Workload and adds in kernel related members for cases where the kernel is specified in the config and loaded by gem5 itself. That's the common case, but the base Workload class would be used directly when, for instance, doing a baremetal simulation or if the kernel is loaded by software within the simulation as is the case for SPARC FS. Because a given architecture specific workload class needs to inherit from either Workload or KernelWorkload, this change removes the ability to boot ARM without a kernel. This ability should be restored in the future. To make having or not having a kernel more flexible, the kernel specific members of the KernelWorkload should be factored out into their own object which can then be attached to a workload through a (potentially unused) property rather than inheritance. Change-Id: Idf72615260266d7b4478d20d4035ed5a1e7aa241 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24283 Reviewed-by: Giacomo Travaglini Maintainer: Gabe Black Tested-by: kokoro --- configs/common/FSConfig.py | 2 +- src/arch/arm/ArmFsWorkload.py | 4 +- src/arch/arm/freebsd/fs_workload.cc | 12 +- src/arch/arm/fs_workload.cc | 43 ++---- src/arch/arm/fs_workload.hh | 39 ++--- src/arch/arm/linux/fs_workload.cc | 25 ++-- src/arch/arm/stacktrace.cc | 2 +- src/arch/arm/system.cc | 18 +-- src/arch/generic/linux/threadinfo.hh | 2 +- src/arch/riscv/RiscvFsWorkload.py | 4 +- src/arch/riscv/bare_metal/fs_workload.cc | 7 + src/arch/riscv/bare_metal/fs_workload.hh | 16 ++ src/arch/riscv/bare_metal/system.cc | 72 --------- src/arch/riscv/fs_workload.hh | 8 +- src/arch/sparc/SparcFsWorkload.py | 6 +- src/arch/sparc/fs_workload.cc | 2 +- src/arch/sparc/fs_workload.hh | 31 +++- src/arch/x86/X86FsWorkload.py | 4 +- src/arch/x86/fs_workload.cc | 10 +- src/arch/x86/fs_workload.hh | 4 +- src/arch/x86/stacktrace.cc | 4 +- src/cpu/o3/thread_state.hh | 2 +- src/cpu/simple_thread.cc | 2 +- src/kern/linux/helpers.cc | 2 +- src/sim/SConscript | 5 +- src/sim/System.py | 2 +- src/sim/{OsKernel.py => Workload.py} | 11 +- src/sim/debug.cc | 1 + src/sim/{os_kernel.cc => kernel_workload.cc} | 107 ++++++------- src/sim/{os_kernel.hh => kernel_workload.hh} | 140 ++++++------------ src/sim/pseudo_inst.cc | 4 +- src/sim/system.hh | 4 +- .../bare_metal/system.hh => sim/workload.cc} | 29 +--- src/sim/workload.hh | 102 +++++++++++++ 34 files changed, 358 insertions(+), 368 deletions(-) delete mode 100644 src/arch/riscv/bare_metal/system.cc rename src/sim/{OsKernel.py => Workload.py} (91%) rename src/sim/{os_kernel.cc => kernel_workload.cc} (58%) rename src/sim/{os_kernel.hh => kernel_workload.hh} (53%) rename src/{arch/riscv/bare_metal/system.hh => sim/workload.cc} (73%) create mode 100644 src/sim/workload.hh diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index a424a30ce..b3e248e6a 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -388,7 +388,7 @@ def makeLinuxMipsSystem(mem_mode, mdesc=None, cmdline=None): self.console = binary('mips/console') if not cmdline: cmdline = 'root=/dev/hda1 console=ttyS0' - self.workload = OsKernel(command_line=fillInCmdline(mdesc, cmdline)) + self.workload = KernelWorkload(command_line=fillInCmdline(mdesc, cmdline)) self.system_port = self.membus.slave diff --git a/src/arch/arm/ArmFsWorkload.py b/src/arch/arm/ArmFsWorkload.py index 459f83095..bc27c6d79 100644 --- a/src/arch/arm/ArmFsWorkload.py +++ b/src/arch/arm/ArmFsWorkload.py @@ -36,7 +36,7 @@ from m5.params import * from m5.options import * from m5.SimObject import * -from m5.objects.OsKernel import OsKernel +from m5.objects.Workload import KernelWorkload class ArmMachineType(Enum): map = { @@ -45,7 +45,7 @@ class ArmMachineType(Enum): 'DTOnly' : -1, } -class ArmFsWorkload(OsKernel): +class ArmFsWorkload(KernelWorkload): type = 'ArmFsWorkload' cxx_header = "arch/arm/fs_workload.hh" cxx_class = "ArmISA::FsWorkload" diff --git a/src/arch/arm/freebsd/fs_workload.cc b/src/arch/arm/freebsd/fs_workload.cc index dbadb4b2a..4eff04d74 100644 --- a/src/arch/arm/freebsd/fs_workload.cc +++ b/src/arch/arm/freebsd/fs_workload.cc @@ -81,21 +81,21 @@ FsFreebsd::initState() // to do this permanently, for but early bootup work // it is helpful. if (params()->early_kernel_symbols) { - obj->loadGlobalSymbols(symtab, 0, 0, loadAddrMask); - obj->loadGlobalSymbols(debugSymbolTable, 0, 0, loadAddrMask); + kernelObj->loadGlobalSymbols(kernelSymtab, 0, 0, _loadAddrMask); + kernelObj->loadGlobalSymbols(debugSymbolTable, 0, 0, _loadAddrMask); } // Check if the kernel image has a symbol that tells us it supports // device trees. Addr addr; - fatal_if(!symtab->findAddress("fdt_get_range", addr), + fatal_if(!kernelSymtab->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. inform("Loading DTB file: %s at address %#x\n", params()->dtb_filename, - params()->atags_addr + loadAddrOffset); + params()->atags_addr + _loadAddrOffset); DtbFile *dtb_file = new DtbFile(params()->dtb_filename); @@ -108,7 +108,7 @@ FsFreebsd::initState() bootReleaseAddr = ra & ~ULL(0x7F); dtb_file->buildImage(). - offset(params()->atags_addr + loadAddrOffset). + offset(params()->atags_addr + _loadAddrOffset). write(system->physProxy); delete dtb_file; @@ -116,7 +116,7 @@ FsFreebsd::initState() for (auto tc: system->threadContexts) { tc->setIntReg(0, 0); tc->setIntReg(1, params()->machine_type); - tc->setIntReg(2, params()->atags_addr + loadAddrOffset); + tc->setIntReg(2, params()->atags_addr + _loadAddrOffset); } } diff --git a/src/arch/arm/fs_workload.cc b/src/arch/arm/fs_workload.cc index 8f40293eb..50a3213d5 100644 --- a/src/arch/arm/fs_workload.cc +++ b/src/arch/arm/fs_workload.cc @@ -69,9 +69,8 @@ SkipFunc::returnFromFuncIn(ThreadContext *tc) } } -FsWorkload::FsWorkload(Params *p) - : OsKernel(*p), - kernelEntry((entry & loadAddrMask) + loadAddrOffset) +FsWorkload::FsWorkload(Params *p) : KernelWorkload(*p), + kernelEntry((kernelObj->entryPoint() & loadAddrMask()) + loadAddrOffset()) { bootLoaders.reserve(p->boot_loader.size()); for (const auto &bl : p->boot_loader) { @@ -82,29 +81,19 @@ FsWorkload::FsWorkload(Params *p) bootLoaders.emplace_back(std::move(bl_obj)); } - if (obj) { - bootldr = getBootLoader(obj); - } else if (!bootLoaders.empty()) { - // No kernel specified, default to the first boot loader - bootldr = bootLoaders[0].get(); - } + bootldr = getBootLoader(kernelObj); fatal_if(!bootLoaders.empty() && !bootldr, "Can't find a matching boot loader / kernel combination!"); - if (bootldr) { + if (bootldr) bootldr->loadGlobalSymbols(debugSymbolTable); - - _highestELIs64 = (bootldr->getArch() == ObjectFile::Arm64); - } else if (obj) { - _highestELIs64 = (obj->getArch() == ObjectFile::Arm64); - } } void FsWorkload::initState() { - OsKernel::initState(); + KernelWorkload::initState(); // Reset CP15?? What does that mean -- ali @@ -144,31 +133,25 @@ FsWorkload::initState() } else { // Set the initial PC to be at start of the kernel code if (!arm_sys->highestELIs64()) - arm_sys->threadContexts[0]->pcState(entry); + arm_sys->threadContexts[0]->pcState(kernelObj->entryPoint()); } } ObjectFile * FsWorkload::getBootLoader(ObjectFile *const obj) { - for (auto &bl : bootLoaders) { - if (bl->getArch() == obj->getArch()) - return bl.get(); + if (obj) { + for (auto &bl : bootLoaders) { + if (bl->getArch() == obj->getArch()) + return bl.get(); + } + } else if (!bootLoaders.empty()) { + return bootLoaders[0].get(); } return nullptr; } -Addr -FsWorkload::resetAddr() const -{ - if (bootldr) { - return bootldr->entryPoint(); - } else { - return kernelEntry; - } -} - } // namespace ArmISA ArmISA::FsWorkload * diff --git a/src/arch/arm/fs_workload.hh b/src/arch/arm/fs_workload.hh index 6e1af08ee..d6e375cd0 100644 --- a/src/arch/arm/fs_workload.hh +++ b/src/arch/arm/fs_workload.hh @@ -46,7 +46,7 @@ #include "kern/linux/events.hh" #include "params/ArmFsWorkload.hh" -#include "sim/os_kernel.hh" +#include "sim/kernel_workload.hh" #include "sim/sim_object.hh" namespace ArmISA @@ -59,7 +59,7 @@ class SkipFunc : public SkipFuncBase void returnFromFuncIn(ThreadContext *tc) override; }; -class FsWorkload : public OsKernel +class FsWorkload : public KernelWorkload { protected: /** Bootloaders */ @@ -70,11 +70,6 @@ class FsWorkload : public OsKernel */ ObjectFile *bootldr = nullptr; - /** - * Whether the highest exception level in software is 64 it. - */ - bool _highestELIs64 = true; - /** * This differs from entry since it takes into account where * the kernel is loaded in memory (with loadAddrMask and @@ -99,19 +94,29 @@ class FsWorkload : public OsKernel return dynamic_cast(&_params); } - FsWorkload(Params *p); + Addr + getEntry() const override + { + if (bootldr) + return bootldr->entryPoint(); + else + return kernelEntry; + } - void initState() override; + ObjectFile::Arch + getArch() const override + { + if (bootldr) + return bootldr->getArch(); + else if (kernelObj) + return kernelObj->getArch(); + else + return ObjectFile::Arm64; + } - /** - * Returns the reset address to be used by an ArmSystem. - * It the workload is using a bootloader, it will return - * the bootloader entry point. - * @returns Arm reset address - */ - Addr resetAddr() const; + FsWorkload(Params *p); - bool highestELIs64() const { return _highestELIs64; } + void initState() override; }; } // namespace ArmISA diff --git a/src/arch/arm/linux/fs_workload.cc b/src/arch/arm/linux/fs_workload.cc index fe023cc4e..65f067598 100644 --- a/src/arch/arm/linux/fs_workload.cc +++ b/src/arch/arm/linux/fs_workload.cc @@ -76,8 +76,8 @@ FsLinux::initState() // to do this permanently, for but early bootup work // it is helpful. if (params()->early_kernel_symbols) { - obj->loadGlobalSymbols(symtab, 0, 0, loadAddrMask); - obj->loadGlobalSymbols(debugSymbolTable, 0, 0, loadAddrMask); + kernelObj->loadGlobalSymbols(kernelSymtab, 0, 0, _loadAddrMask); + kernelObj->loadGlobalSymbols(debugSymbolTable, 0, 0, _loadAddrMask); } // Setup boot data structure @@ -85,14 +85,14 @@ FsLinux::initState() // Check if the kernel image has a symbol that tells us it supports // device trees. bool kernel_has_fdt_support = - symtab->findAddress("unflatten_device_tree", addr); + kernelSymtab->findAddress("unflatten_device_tree", addr); bool dtb_file_specified = params()->dtb_filename != ""; if (kernel_has_fdt_support && dtb_file_specified) { // Kernel supports flattened device tree and dtb file specified. // Using Device Tree Blob to describe system configuration. inform("Loading DTB file: %s at address %#x\n", params()->dtb_filename, - params()->atags_addr + loadAddrOffset); + params()->atags_addr + _loadAddrOffset); DtbFile *dtb_file = new DtbFile(params()->dtb_filename); @@ -103,7 +103,7 @@ FsLinux::initState() } dtb_file->buildImage(). - offset(params()->atags_addr + loadAddrOffset). + offset(params()->atags_addr + _loadAddrOffset). write(system->physProxy); delete dtb_file; } else { @@ -152,7 +152,7 @@ FsLinux::initState() DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2); DDUMP(Loader, boot_data, size << 2); - system->physProxy.writeBlob(params()->atags_addr + loadAddrOffset, + system->physProxy.writeBlob(params()->atags_addr + _loadAddrOffset, boot_data, size << 2); delete[] boot_data; @@ -162,7 +162,7 @@ FsLinux::initState() for (auto tc: system->threadContexts) { tc->setIntReg(0, 0); tc->setIntReg(1, params()->machine_type); - tc->setIntReg(2, params()->atags_addr + loadAddrOffset); + tc->setIntReg(2, params()->atags_addr + _loadAddrOffset); } } @@ -183,19 +183,18 @@ FsLinux::startup() { FsWorkload::startup(); - auto *arm_sys = dynamic_cast(system); if (enableContextSwitchStatsDump) { - if (!arm_sys->highestELIs64()) - dumpStats = addKernelFuncEvent("__switch_to"); - else + if (getArch() == ObjectFile::Arm64) dumpStats = addKernelFuncEvent("__switch_to"); + else + dumpStats = addKernelFuncEvent("__switch_to"); panic_if(!dumpStats, "dumpStats not created!"); std::string task_filename = "tasks.txt"; taskFile = simout.create(name() + "." + task_filename); - for (const auto tc : arm_sys->threadContexts) { + for (const auto tc : system->threadContexts) { uint32_t pid = tc->getCpuPtr()->getPid(); if (pid != BaseCPU::invldPid) { mapPid(tc, pid); @@ -238,7 +237,7 @@ FsLinux::startup() "__const_udelay", "__const_udelay", 1000, 107374); } - if (highestELIs64()) { + if (getArch() == ObjectFile::Arm64) { debugPrintk = addKernelFuncEvent< DebugPrintk>("dprintk"); } else { diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc index b5a9976cf..df3f6a21a 100644 --- a/src/arch/arm/stacktrace.cc +++ b/src/arch/arm/stacktrace.cc @@ -45,7 +45,7 @@ static int32_t readSymbol(ThreadContext *tc, const std::string name) { PortProxy &vp = tc->getVirtProxy(); - SymbolTable *symtab = tc->getSystemPtr()->workload->symtab; + const SymbolTable *symtab = tc->getSystemPtr()->workload->symtab(tc); Addr addr; if (!symtab->findAddress(name, addr)) diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc index b03f0f5ae..dd3b9a557 100644 --- a/src/arch/arm/system.cc +++ b/src/arch/arm/system.cc @@ -73,25 +73,21 @@ ArmSystem::ArmSystem(Params *p) semihosting(p->semihosting), multiProc(p->multi_proc) { - auto *arm_workload = dynamic_cast(p->workload); - panic_if(!arm_workload, - "Workload was not the expected type (ArmISA::FsWorkload)."); - if (p->auto_reset_addr) { - _resetAddr = arm_workload->resetAddr(); + _resetAddr = workload->getEntry(); } else { _resetAddr = p->reset_addr; - warn_if(arm_workload->resetAddr() != _resetAddr, + warn_if(workload->getEntry() != _resetAddr, "Workload entry point %#x and reset address %#x are different", - arm_workload->resetAddr(), _resetAddr); + workload->getEntry(), _resetAddr); } - if (arm_workload->highestELIs64() != _highestELIs64) { + bool wl_is_64 = (workload->getArch() == ObjectFile::Arm64); + if (wl_is_64 != _highestELIs64) { warn("Highest ARM exception-level set to AArch%d but the workload " "is for AArch%d. Assuming you wanted these to match.", - _highestELIs64 ? 64 : 32, - arm_workload->highestELIs64() ? 64 : 32); - _highestELIs64 = arm_workload->highestELIs64(); + _highestELIs64 ? 64 : 32, wl_is_64 ? 64 : 32); + _highestELIs64 = wl_is_64; } if (_highestELIs64 && ( diff --git a/src/arch/generic/linux/threadinfo.hh b/src/arch/generic/linux/threadinfo.hh index 971211371..83e41b97a 100644 --- a/src/arch/generic/linux/threadinfo.hh +++ b/src/arch/generic/linux/threadinfo.hh @@ -47,7 +47,7 @@ class ThreadInfo get_data(const char *symbol, T &data) { Addr addr = 0; - if (!sys->workload->symtab->findAddress(symbol, addr)) { + if (!sys->workload->symtab(tc)->findAddress(symbol, addr)) { warn_once("Unable to find kernel symbol %s\n", symbol); warn_once("Kernel not compiled with task_struct info; can't get " "currently executing task/process/thread name/ids!\n"); diff --git a/src/arch/riscv/RiscvFsWorkload.py b/src/arch/riscv/RiscvFsWorkload.py index 5d1db987e..93e8fcea3 100644 --- a/src/arch/riscv/RiscvFsWorkload.py +++ b/src/arch/riscv/RiscvFsWorkload.py @@ -30,9 +30,9 @@ from m5.params import * from m5.objects.System import System -from m5.objects.OsKernel import OsKernel +from m5.objects.Workload import Workload -class RiscvFsWorkload(OsKernel): +class RiscvFsWorkload(Workload): type = 'RiscvFsWorkload' cxx_class = 'RiscvISA::FsWorkload' cxx_header = 'arch/riscv/fs_workload.hh' diff --git a/src/arch/riscv/bare_metal/fs_workload.cc b/src/arch/riscv/bare_metal/fs_workload.cc index 5c031282c..41fefe933 100644 --- a/src/arch/riscv/bare_metal/fs_workload.cc +++ b/src/arch/riscv/bare_metal/fs_workload.cc @@ -28,6 +28,7 @@ #include "arch/riscv/bare_metal/fs_workload.hh" +#include "arch/riscv/faults.hh" #include "base/loader/object_file.hh" #include "sim/system.hh" @@ -51,6 +52,12 @@ void BareMetal::initState() { RiscvISA::FsWorkload::initState(); + + for (auto *tc: system->threadContexts) { + RiscvISA::Reset().invoke(tc); + tc->activate(); + } + warn_if(!bootloader->buildImage().write(system->physProxy), "Could not load sections to memory."); } diff --git a/src/arch/riscv/bare_metal/fs_workload.hh b/src/arch/riscv/bare_metal/fs_workload.hh index 722806d22..37bffcfe9 100644 --- a/src/arch/riscv/bare_metal/fs_workload.hh +++ b/src/arch/riscv/bare_metal/fs_workload.hh @@ -47,6 +47,22 @@ class BareMetal : public RiscvISA::FsWorkload ~BareMetal(); void initState() override; + + ObjectFile::Arch + getArch() const override + { + return bootloader->getArch(); + } + const SymbolTable * + symtab(ThreadContext *tc) override + { + return bootloaderSymtab; + } + bool + insertSymbol(Addr address, const std::string &symbol) override + { + return bootloaderSymtab->insert(address, symbol); + } }; } // namespace RiscvISA diff --git a/src/arch/riscv/bare_metal/system.cc b/src/arch/riscv/bare_metal/system.cc deleted file mode 100644 index 1ca8ed9b9..000000000 --- a/src/arch/riscv/bare_metal/system.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2018 TU Dresden - * All rights reserved - * - * 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. - */ - -#include "arch/riscv/bare_metal/system.hh" - -#include "arch/riscv/faults.hh" -#include "base/loader/object_file.hh" - -BareMetalRiscvSystem::BareMetalRiscvSystem(Params *p) - : RiscvSystem(p), - bootloader(createObjectFile(p->bootloader)) -{ - if (bootloader == NULL) { - fatal("Could not load bootloader file %s", p->bootloader); - } - - _resetVect = bootloader->entryPoint(); -} - -BareMetalRiscvSystem::~BareMetalRiscvSystem() -{ - delete bootloader; -} - -void -BareMetalRiscvSystem::initState() -{ - // Call the initialisation of the super class - RiscvSystem::initState(); - - for (auto *tc: threadContexts) { - RiscvISA::Reset().invoke(tc); - tc->activate(); - } - - // load program sections into memory - if (!bootloader->buildImage().write(physProxy)) { - warn("could not load sections to memory"); - } -} - -BareMetalRiscvSystem * -BareMetalRiscvSystemParams::create() -{ - return new BareMetalRiscvSystem(this); -} - diff --git a/src/arch/riscv/fs_workload.hh b/src/arch/riscv/fs_workload.hh index aaa9d0f58..0fbd7170d 100644 --- a/src/arch/riscv/fs_workload.hh +++ b/src/arch/riscv/fs_workload.hh @@ -31,13 +31,13 @@ #define __ARCH_RISCV_FS_WORKLOAD_HH__ #include "params/RiscvFsWorkload.hh" -#include "sim/os_kernel.hh" #include "sim/sim_object.hh" +#include "sim/workload.hh" namespace RiscvISA { -class FsWorkload : public OsKernel +class FsWorkload : public Workload { protected: // checker for bare metal application @@ -46,7 +46,7 @@ class FsWorkload : public OsKernel Addr _resetVect; public: - FsWorkload(RiscvFsWorkloadParams *p) : OsKernel(*p), + FsWorkload(RiscvFsWorkloadParams *p) : Workload(p), _isBareMetal(p->bare_metal), _resetVect(p->reset_vect) {} @@ -55,6 +55,8 @@ class FsWorkload : public OsKernel // return bare metal checker bool isBareMetal() const { return _isBareMetal; } + + Addr getEntry() const override { return _resetVect; } }; } // namespace RiscvISA diff --git a/src/arch/sparc/SparcFsWorkload.py b/src/arch/sparc/SparcFsWorkload.py index 6244882b9..ffc3f2b2c 100644 --- a/src/arch/sparc/SparcFsWorkload.py +++ b/src/arch/sparc/SparcFsWorkload.py @@ -26,11 +26,9 @@ from m5.params import * -from m5.objects.OsKernel import OsKernel +from m5.objects.Workload import Workload -class SparcFsWorkload(OsKernel): +class SparcFsWorkload(Workload): type = 'SparcFsWorkload' cxx_header = 'arch/sparc/fs_workload.hh' cxx_class = 'SparcISA::FsWorkload' - - load_addr_mask = 0xffffffffff diff --git a/src/arch/sparc/fs_workload.cc b/src/arch/sparc/fs_workload.cc index e0fa8e41a..71c3b4514 100644 --- a/src/arch/sparc/fs_workload.cc +++ b/src/arch/sparc/fs_workload.cc @@ -38,7 +38,7 @@ namespace SparcISA void FsWorkload::initState() { - OsKernel::initState(); + Workload::initState(); if (system->threadContexts.empty()) return; diff --git a/src/arch/sparc/fs_workload.hh b/src/arch/sparc/fs_workload.hh index 2ffc06a64..d97b9225b 100644 --- a/src/arch/sparc/fs_workload.hh +++ b/src/arch/sparc/fs_workload.hh @@ -29,17 +29,42 @@ #ifndef __ARCH_SPARC_FS_WORKLOAD_HH__ #define __ARCH_SPARC_FS_WORKLOAD_HH__ +#include "arch/sparc/faults.hh" #include "params/SparcFsWorkload.hh" -#include "sim/os_kernel.hh" +#include "sim/workload.hh" namespace SparcISA { -class FsWorkload : public OsKernel +class FsWorkload : public Workload { + protected: + SymbolTable defaultSymtab; + public: - FsWorkload(SparcFsWorkloadParams *p) : OsKernel(*p) {} + FsWorkload(SparcFsWorkloadParams *params) : Workload(params) {} void initState() override; + + Addr + getEntry() const override + { + Addr pc, npc; + getREDVector(0x001, pc, npc); + return pc; + } + ObjectFile::Arch getArch() const override { return ObjectFile::SPARC64; } + + const SymbolTable * + symtab(ThreadContext *tc) override + { + return &defaultSymtab; + } + + bool + insertSymbol(Addr address, const std::string &symbol) override + { + return defaultSymtab.insert(address, symbol); + } }; } // namespace SparcISA diff --git a/src/arch/x86/X86FsWorkload.py b/src/arch/x86/X86FsWorkload.py index 3628c941e..1a4248f6e 100644 --- a/src/arch/x86/X86FsWorkload.py +++ b/src/arch/x86/X86FsWorkload.py @@ -39,9 +39,9 @@ from m5.objects.E820 import X86E820Table, X86E820Entry from m5.objects.SMBios import X86SMBiosSMBiosTable from m5.objects.IntelMP import X86IntelMPFloatingPointer, X86IntelMPConfigTable from m5.objects.ACPI import X86ACPIRSDP -from m5.objects.OsKernel import OsKernel +from m5.objects.Workload import KernelWorkload -class X86FsWorkload(OsKernel): +class X86FsWorkload(KernelWorkload): type = 'X86FsWorkload' cxx_header = 'arch/x86/fs_workload.hh' cxx_class = 'X86ISA::FsWorkload' diff --git a/src/arch/x86/fs_workload.cc b/src/arch/x86/fs_workload.cc index c38fc9b51..6ad42db04 100644 --- a/src/arch/x86/fs_workload.cc +++ b/src/arch/x86/fs_workload.cc @@ -50,7 +50,7 @@ namespace X86ISA { -FsWorkload::FsWorkload(Params *p) : OsKernel(*p), +FsWorkload::FsWorkload(Params *p) : KernelWorkload(*p), smbiosTable(p->smbios_table), mpFloatingPointer(p->intel_mp_pointer), mpConfigTable(p->intel_mp_table), @@ -104,7 +104,7 @@ installSegDesc(ThreadContext *tc, SegmentRegIndex seg, void FsWorkload::initState() { - OsKernel::initState(); + KernelWorkload::initState(); for (auto *tc: system->threadContexts) { X86ISA::InitInterrupt(0).invoke(tc); @@ -119,9 +119,9 @@ FsWorkload::initState() } } - fatal_if(!obj, "No kernel to load."); + fatal_if(!kernelObj, "No kernel to load."); - fatal_if(obj->getArch() == ObjectFile::I386, + fatal_if(kernelObj->getArch() == ObjectFile::I386, "Loading a 32 bit x86 kernel is not supported."); ThreadContext *tc = system->threadContexts[0]; @@ -304,7 +304,7 @@ FsWorkload::initState() cr0.pg = 1; tc->setMiscReg(MISCREG_CR0, cr0); - tc->pcState(entry); + tc->pcState(kernelObj->entryPoint()); // We should now be in long mode. Yay! diff --git a/src/arch/x86/fs_workload.hh b/src/arch/x86/fs_workload.hh index 5b972ec80..7080feb40 100644 --- a/src/arch/x86/fs_workload.hh +++ b/src/arch/x86/fs_workload.hh @@ -46,7 +46,7 @@ #include "base/types.hh" #include "cpu/thread_context.hh" #include "params/X86FsWorkload.hh" -#include "sim/os_kernel.hh" +#include "sim/kernel_workload.hh" namespace X86ISA { @@ -79,7 +79,7 @@ const Addr MMIORegionPhysAddr = 0xffff0000; void installSegDesc(ThreadContext *tc, SegmentRegIndex seg, SegDescriptor desc, bool longmode); -class FsWorkload : public OsKernel +class FsWorkload : public KernelWorkload { public: typedef X86FsWorkloadParams Params; diff --git a/src/arch/x86/stacktrace.cc b/src/arch/x86/stacktrace.cc index 64f2d4b1d..677ab65d5 100644 --- a/src/arch/x86/stacktrace.cc +++ b/src/arch/x86/stacktrace.cc @@ -45,7 +45,7 @@ static int32_t readSymbol(ThreadContext *tc, const std::string name) { PortProxy &vp = tc->getVirtProxy(); - SymbolTable *symtab = tc->getSystemPtr()->workload->symtab; + const SymbolTable *symtab = tc->getSystemPtr()->workload->symtab(tc); Addr addr; if (!symtab->findAddress(name, addr)) @@ -189,7 +189,7 @@ void StackTrace::dump() { StringWrap name(tc->getCpuPtr()->name()); - SymbolTable *symtab = tc->getSystemPtr()->workload->symtab; + const SymbolTable *symtab = tc->getSystemPtr()->workload->symtab(tc); DPRINTFN("------ Stack ------\n"); diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh index b1814dbc6..030dc4ba2 100644 --- a/src/cpu/o3/thread_state.hh +++ b/src/cpu/o3/thread_state.hh @@ -104,7 +104,7 @@ struct O3ThreadState : public ThreadState { if (cpu->params()->profile) { profile = new FunctionProfile( - cpu->params()->system->workload->symtab); + cpu->params()->system->workload->symtab(tc)); Callback *cb = new MakeCallback(this); diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 9e2e55e8e..ef8e074e0 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -98,7 +98,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, clearArchRegs(); if (baseCpu->params()->profile) { - profile = new FunctionProfile(system->workload->symtab); + profile = new FunctionProfile(system->workload->symtab(this)); Callback *cb = new MakeCallback(this); diff --git a/src/kern/linux/helpers.cc b/src/kern/linux/helpers.cc index 559844004..548ae0fe0 100644 --- a/src/kern/linux/helpers.cc +++ b/src/kern/linux/helpers.cc @@ -93,7 +93,7 @@ Linux::dumpDmesg(ThreadContext *tc, std::ostream &os) { System *system = tc->getSystemPtr(); const ByteOrder bo = system->getGuestByteOrder(); - const SymbolTable *symtab = system->workload->symtab; + const SymbolTable *symtab = system->workload->symtab(tc); PortProxy &proxy = tc->getVirtProxy(); Addr addr_lb = 0, addr_lb_len = 0, addr_first = 0, addr_next = 0; diff --git a/src/sim/SConscript b/src/sim/SConscript index 9687796ab..0057d28cf 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -30,7 +30,7 @@ Import('*') SimObject('ClockedObject.py') SimObject('TickedObject.py') -SimObject('OsKernel.py') +SimObject('Workload.py') SimObject('Root.py') SimObject('ClockDomain.py') SimObject('VoltageDomain.py') @@ -53,7 +53,8 @@ Source('global_event.cc') Source('init.cc', add_tags='python') Source('init_signals.cc') Source('main.cc', tags='main') -Source('os_kernel.cc') +Source('workload.cc') +Source('kernel_workload.cc') Source('port.cc') Source('python.cc', add_tags='python') Source('redirect_path.cc') diff --git a/src/sim/System.py b/src/sim/System.py index 0d1f73055..61fbe0e02 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -99,7 +99,7 @@ class System(SimObject): work_cpus_ckpt_count = Param.Counter(0, "create checkpoint when active cpu count value is reached") - workload = Param.OsKernel(NULL, "Operating system kernel") + workload = Param.Workload(NULL, "Operating system kernel") init_param = Param.UInt64(0, "numerical value to pass into simulator") readfile = Param.String("", "file to read startup script from") symbolfile = Param.String("", "file to get the symbols from") diff --git a/src/sim/OsKernel.py b/src/sim/Workload.py similarity index 91% rename from src/sim/OsKernel.py rename to src/sim/Workload.py index 93cb74fe9..1e35abec1 100644 --- a/src/sim/OsKernel.py +++ b/src/sim/Workload.py @@ -28,9 +28,14 @@ from m5.SimObject import SimObject from m5.objects.SimpleMemory import * -class OsKernel(SimObject): - type = 'OsKernel' - cxx_header = "sim/os_kernel.hh" +class Workload(SimObject): + type = 'Workload' + cxx_header = "sim/workload.hh" + abstract = True + +class KernelWorkload(Workload): + type = 'KernelWorkload' + cxx_header = "sim/kernel_workload.hh" object_file = Param.String("", "File that contains the kernel code") extras = VectorParam.String([], "Additional object files to load") diff --git a/src/sim/debug.cc b/src/sim/debug.cc index bf46a51b2..484d4a670 100644 --- a/src/sim/debug.cc +++ b/src/sim/debug.cc @@ -35,6 +35,7 @@ #include "cpu/pc_event.hh" #include "sim/eventq_impl.hh" #include "sim/global_event.hh" +#include "sim/kernel_workload.hh" #include "sim/sim_events.hh" #include "sim/sim_exit.hh" #include "sim/system.hh" diff --git a/src/sim/os_kernel.cc b/src/sim/kernel_workload.cc similarity index 58% rename from src/sim/os_kernel.cc rename to src/sim/kernel_workload.cc index 317f4d39f..3d9a5dc48 100644 --- a/src/sim/os_kernel.cc +++ b/src/sim/kernel_workload.cc @@ -25,59 +25,52 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "sim/os_kernel.hh" +#include "sim/kernel_workload.hh" -#include "base/loader/object_file.hh" -#include "base/loader/symtab.hh" #include "debug/Loader.hh" -#include "params/OsKernel.hh" +#include "params/KernelWorkload.hh" #include "sim/system.hh" -OsKernel::OsKernel(const Params &p) : SimObject(&p), _params(p), - commandLine(p.command_line), symtab(new SymbolTable), - loadAddrMask(p.load_addr_mask), loadAddrOffset(p.load_addr_offset) +KernelWorkload::KernelWorkload(const Params &p) : Workload(&p), _params(p), + _loadAddrMask(p.load_addr_mask), _loadAddrOffset(p.load_addr_offset), + kernelSymtab(new SymbolTable), commandLine(p.command_line) { if (!debugSymbolTable) debugSymbolTable = new SymbolTable; - if (params().object_file == "") { - inform("No kernel set for full system simulation. " - "Assuming you know what you're doing."); - } else { - obj = createObjectFile(params().object_file); - inform("kernel located at: %s", params().object_file); + kernelObj = createObjectFile(params().object_file); + inform("kernel located at: %s", params().object_file); - fatal_if(!obj, "Could not load kernel file %s", params().object_file); + fatal_if(!kernelObj, + "Could not load kernel file %s", params().object_file); - image = obj->buildImage(); + image = kernelObj->buildImage(); - start = image.minAddr(); - end = image.maxAddr(); - entry = obj->entryPoint(); + _start = image.minAddr(); + _end = image.maxAddr(); - // If load_addr_mask is set to 0x0, then calculate the smallest mask to - // cover all kernel addresses so gem5 can relocate the kernel to a new - // offset. - if (loadAddrMask == 0) - loadAddrMask = mask(findMsbSet(end - start) + 1); + // If load_addr_mask is set to 0x0, then calculate the smallest mask to + // cover all kernel addresses so gem5 can relocate the kernel to a new + // offset. + if (_loadAddrMask == 0) + _loadAddrMask = mask(findMsbSet(_end - _start) + 1); - image.move([this](Addr a) { - return (a & loadAddrMask) + loadAddrOffset; - }); + image.move([this](Addr a) { + return (a & _loadAddrMask) + _loadAddrOffset; + }); - // load symbols - fatal_if(!obj->loadGlobalSymbols(symtab), - "Could not load kernel symbols."); + // load symbols + fatal_if(!kernelObj->loadGlobalSymbols(kernelSymtab), + "Could not load kernel symbols."); - fatal_if(!obj->loadLocalSymbols(symtab), - "Could not load kernel local symbols."); + fatal_if(!kernelObj->loadLocalSymbols(kernelSymtab), + "Could not load kernel local symbols."); - fatal_if(!obj->loadGlobalSymbols(debugSymbolTable), - "Could not load kernel symbols."); + fatal_if(!kernelObj->loadGlobalSymbols(debugSymbolTable), + "Could not load kernel symbols."); - fatal_if(!obj->loadLocalSymbols(debugSymbolTable), - "Could not load kernel local symbols."); - } + fatal_if(!kernelObj->loadLocalSymbols(debugSymbolTable), + "Could not load kernel local symbols."); // Loading only needs to happen once and after memory system is // connected so it will happen in initState() @@ -97,42 +90,36 @@ OsKernel::OsKernel(const Params &p) : SimObject(&p), _params(p), } } -Addr -OsKernel::fixFuncEventAddr(Addr addr) -{ - return system->fixFuncEventAddr(addr); -} - -OsKernel::~OsKernel() +KernelWorkload::~KernelWorkload() { - delete symtab; + delete kernelSymtab; } void -OsKernel::initState() +KernelWorkload::initState() { auto &phys_mem = system->physProxy; /** * Load the kernel code into memory. */ auto mapper = [this](Addr a) { - return (a & loadAddrMask) + loadAddrOffset; + return (a & _loadAddrMask) + _loadAddrOffset; }; if (params().object_file != "") { if (params().addr_check) { // Validate kernel mapping before loading binary - fatal_if(!system->isMemAddr(mapper(start)) || - !system->isMemAddr(mapper(end)), + fatal_if(!system->isMemAddr(mapper(_start)) || + !system->isMemAddr(mapper(_end)), "Kernel is mapped to invalid location (not memory). " "start (%#x) - end (%#x) %#x:%#x\n", - start, end, mapper(start), mapper(end)); + _start, _end, mapper(_start), mapper(_end)); } // Load program sections into memory image.write(phys_mem); - DPRINTF(Loader, "Kernel start = %#x\n", start); - DPRINTF(Loader, "Kernel end = %#x\n", end); - DPRINTF(Loader, "Kernel entry = %#x\n", entry); + DPRINTF(Loader, "Kernel start = %#x\n", _start); + DPRINTF(Loader, "Kernel end = %#x\n", _end); + DPRINTF(Loader, "Kernel entry = %#x\n", kernelObj->entryPoint()); DPRINTF(Loader, "Kernel loaded...\n"); } @@ -151,21 +138,19 @@ OsKernel::initState() } void -OsKernel::serialize(CheckpointOut &cp) const +KernelWorkload::serialize(CheckpointOut &cp) const { - symtab->serialize("symtab", cp); - serializeSymtab(cp); + kernelSymtab->serialize("symtab", cp); } void -OsKernel::unserialize(CheckpointIn &cp) +KernelWorkload::unserialize(CheckpointIn &cp) { - symtab->unserialize("symtab", cp); - unserializeSymtab(cp); + kernelSymtab->unserialize("symtab", cp); } -OsKernel * -OsKernelParams::create() +KernelWorkload * +KernelWorkloadParams::create() { - return new OsKernel(*this); + return new KernelWorkload(*this); } diff --git a/src/sim/os_kernel.hh b/src/sim/kernel_workload.hh similarity index 53% rename from src/sim/os_kernel.hh rename to src/sim/kernel_workload.hh index b1238a199..b45a0d98c 100644 --- a/src/sim/os_kernel.hh +++ b/src/sim/kernel_workload.hh @@ -25,114 +25,83 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __SIM_OS_KERNEL_HH__ -#define __SIM_OS_KERNEL_HH__ +#ifndef __SIM_KERNEL_WORKLOAD_HH__ +#define __SIM_KERNEL_WORKLOAD_HH__ -#include "base/loader/memory_image.hh" -#include "base/loader/symtab.hh" -#include "params/OsKernel.hh" -#include "sim/sim_object.hh" +#include +#include + +#include "base/loader/object_file.hh" +#include "base/types.hh" +#include "params/KernelWorkload.hh" +#include "sim/workload.hh" -class ObjectFile; class SymbolTable; class System; -class OsKernel : public SimObject +class KernelWorkload : public Workload { public: - using Params = OsKernelParams; + using Params = KernelWorkloadParams; protected: const Params &_params; - Addr fixFuncEventAddr(Addr); - - public: - OsKernel(const Params &p); - ~OsKernel(); - - const Params ¶ms() { return _params; } - - void initState() override; - - const std::string commandLine; - - void serialize(CheckpointOut &cp) const override; - void unserialize(CheckpointIn &cp) override; - - System *system = nullptr; - - ObjectFile *obj = nullptr; - SymbolTable *symtab = nullptr; - MemoryImage image; - Addr start = 0; - Addr end = MaxAddr; - Addr entry = 0; - /** Mask that should be anded for binary/symbol loading. * This allows one two different OS requirements for the same ISA to be * handled. Some OSes are compiled for a virtual address and need to be * loaded into physical memory that starts at address 0, while other * bare metal tools generate images that start at address 0. */ - Addr loadAddrMask; + Addr _loadAddrMask; /** Offset that should be used for binary/symbol loading. * This further allows more flexibility than the loadAddrMask allows alone * in loading kernels and similar. The loadAddrOffset is applied after the * loadAddrMask. */ - Addr loadAddrOffset; + Addr _loadAddrOffset; + + Addr _start, _end; std::vector extras; - /** @{ */ - /** - * Add a function-based event to the given function, to be looked - * up in the specified symbol table. - * - * The ...OrPanic flavor of the method causes the simulator to - * panic if the symbol can't be found. - * - * @param symtab Symbol table to use for look up. - * @param lbl Function to hook the event to. - * @param desc Description to be passed to the event. - * @param args Arguments to be forwarded to the event constructor. - */ - template - T * - addFuncEvent(const SymbolTable *symtab, const char *lbl, - const std::string &desc, Args... args) - { - Addr addr M5_VAR_USED = 0; // initialize only to avoid compiler warning + ObjectFile *kernelObj = nullptr; + SymbolTable *kernelSymtab = nullptr; - if (symtab->findAddress(lbl, addr)) { - return new T(system, desc, fixFuncEventAddr(addr), - std::forward(args)...); - } + const std::string commandLine; - return nullptr; - } + public: + const Params ¶ms() const { return _params; } - template - T * - addFuncEvent(const SymbolTable *symtab, const char *lbl) + Addr start() const { return _start; } + Addr end() const { return _end; } + Addr loadAddrMask() const { return _loadAddrMask; } + Addr loadAddrOffset() const { return _loadAddrOffset; } + + KernelWorkload(const Params &p); + ~KernelWorkload(); + + Addr getEntry() const override { return kernelObj->entryPoint(); } + ObjectFile::Arch getArch() const override { return kernelObj->getArch(); } + const SymbolTable * + symtab(ThreadContext *tc) override { - return addFuncEvent(symtab, lbl, lbl); + return kernelSymtab; } - template - T * - addFuncEventOrPanic(const SymbolTable *symtab, const char *lbl, - Args... args) + bool + insertSymbol(Addr address, const std::string &symbol) { - T *e = addFuncEvent(symtab, lbl, std::forward(args)...); - panic_if(!e, "Failed to find symbol '%s'", lbl); - return e; + return kernelSymtab->insert(address, symbol); } - /** @} */ + + void initState() override; + + void serialize(CheckpointOut &cp) const override; + void unserialize(CheckpointIn &cp) override; /** @{ */ /** @@ -153,37 +122,18 @@ class OsKernel : public SimObject T * addKernelFuncEvent(const char *lbl, Args... args) { - return addFuncEvent(symtab, lbl, std::forward(args)...); + return addFuncEvent(kernelSymtab, lbl, std::forward(args)...); } template T * addKernelFuncEventOrPanic(const char *lbl, Args... args) { - T *e(addFuncEvent(symtab, lbl, std::forward(args)...)); - if (!e) - panic("Failed to find kernel symbol '%s'", lbl); + T *e = addFuncEvent(kernelSymtab, lbl, std::forward(args)...); + panic_if(!e, "Failed to find kernel symbol '%s'", lbl); return e; } /** @} */ - - protected: - /** - * If needed, serialize additional symbol table entries for a - * specific subclass of this system. - * - * @param os stream to serialize to - */ - virtual void serializeSymtab(CheckpointOut &os) const {} - - /** - * If needed, unserialize additional symbol table entries for a - * specific subclass of this system. - * - * @param cp checkpoint to unserialize from - * @param section relevant section in the checkpoint - */ - virtual void unserializeSymtab(CheckpointIn &cp) {} }; -#endif // __SIM_OS_KERNEL_HH__ +#endif // __SIM_KERNEL_WORKLOAD_HH__ diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index e30738720..802b30423 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -217,7 +217,7 @@ loadsymbol(ThreadContext *tc) if (!to_number(address, addr)) continue; - if (!tc->getSystemPtr()->workload->symtab->insert(addr, symbol)) + if (!tc->getSystemPtr()->workload->insertSymbol(addr, symbol)) continue; @@ -239,7 +239,7 @@ addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); - tc->getSystemPtr()->workload->symtab->insert(addr,symbol); + tc->getSystemPtr()->workload->insertSymbol(addr, symbol); debugSymbolTable->insert(addr,symbol); } diff --git a/src/sim/system.hh b/src/sim/system.hh index f9a437bec..09ba7b430 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -60,10 +60,10 @@ #include "mem/port_proxy.hh" #include "params/System.hh" #include "sim/futex_map.hh" -#include "sim/os_kernel.hh" #include "sim/redirect_path.hh" #include "sim/se_signal.hh" #include "sim/sim_object.hh" +#include "sim/workload.hh" class BaseRemoteGDB; class KvmVM; @@ -211,7 +211,7 @@ class System : public SimObject, public PCEventScope PortProxy physProxy; /** OS kernel */ - OsKernel *workload = nullptr; + Workload *workload = nullptr; public: /** diff --git a/src/arch/riscv/bare_metal/system.hh b/src/sim/workload.cc similarity index 73% rename from src/arch/riscv/bare_metal/system.hh rename to src/sim/workload.cc index 1f665beb1..06773f996 100644 --- a/src/arch/riscv/bare_metal/system.hh +++ b/src/sim/workload.cc @@ -1,6 +1,5 @@ /* - * Copyright (c) 2018 TU Dresden - * All rights reserved + * Copyright 2019 Google Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -26,25 +25,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __ARCH_RISCV_BARE_METAL_SYSTEM_HH__ -#define __ARCH_RISCV_BARE_METAL_SYSTEM_HH__ +#include "sim/workload.hh" -#include "arch/riscv/system.hh" -#include "params/BareMetalRiscvSystem.hh" +#include "params/Workload.hh" +#include "sim/system.hh" -class BareMetalRiscvSystem : public RiscvSystem +Addr +Workload::fixFuncEventAddr(Addr addr) { - protected: - ObjectFile* bootloader; - - public: - typedef BareMetalRiscvSystemParams Params; - BareMetalRiscvSystem(Params *p); - ~BareMetalRiscvSystem(); - - // initialize the system - virtual void initState(); -}; - -#endif // __ARCH_RISCV_BARE_METAL_SYSTEM_HH__ - + return system->fixFuncEventAddr(addr); +} diff --git a/src/sim/workload.hh b/src/sim/workload.hh new file mode 100644 index 000000000..2dbcaa048 --- /dev/null +++ b/src/sim/workload.hh @@ -0,0 +1,102 @@ +/* + * Copyright 2019 Google Inc. + * + * 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. + */ + +#ifndef __SIM_WORKLOAD_HH__ +#define __SIM_WORKLOAD_HH__ + +#include "base/loader/object_file.hh" +#include "base/loader/symtab.hh" +#include "params/Workload.hh" +#include "sim/sim_object.hh" + +class System; +class ThreadContext; + +class Workload : public SimObject +{ + protected: + Addr fixFuncEventAddr(Addr); + + public: + using SimObject::SimObject; + + System *system = nullptr; + + virtual Addr getEntry() const = 0; + virtual ObjectFile::Arch getArch() const = 0; + + virtual const SymbolTable *symtab(ThreadContext *tc) = 0; + virtual bool insertSymbol(Addr address, const std::string &symbol) = 0; + + /** @{ */ + /** + * Add a function-based event to the given function, to be looked + * up in the specified symbol table. + * + * The ...OrPanic flavor of the method causes the simulator to + * panic if the symbol can't be found. + * + * @param symtab Symbol table to use for look up. + * @param lbl Function to hook the event to. + * @param desc Description to be passed to the event. + * @param args Arguments to be forwarded to the event constructor. + */ + template + T * + addFuncEvent(const SymbolTable *symtab, const char *lbl, + const std::string &desc, Args... args) + { + Addr addr M5_VAR_USED = 0; // initialize only to avoid compiler warning + + if (symtab->findAddress(lbl, addr)) { + return new T(system, desc, fixFuncEventAddr(addr), + std::forward(args)...); + } + + return nullptr; + } + + template + T * + addFuncEvent(const SymbolTable *symtab, const char *lbl) + { + return addFuncEvent(symtab, lbl, lbl); + } + + template + T * + addFuncEventOrPanic(const SymbolTable *symtab, const char *lbl, + Args... args) + { + T *e = addFuncEvent(symtab, lbl, std::forward(args)...); + panic_if(!e, "Failed to find symbol '%s'", lbl); + return e; + } + /** @} */ +}; + +#endif // __SIM_WORKLOAD_HH__ -- 2.30.2