From a78abf07b7568589a2585397f4c17799626664e8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 20 Oct 2020 17:37:03 -0700 Subject: [PATCH] riscv: Implement an SE workload for Linux. Change-Id: Ieb7058007e56ce0c8d153c1853e4b92237e98ab8 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/34156 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- src/arch/riscv/RiscvSeWorkload.py | 44 ++++++++++ src/arch/riscv/SConscript | 4 +- .../linux/{process.cc => se_workload.cc} | 84 ++++++++---------- .../linux/{process.hh => se_workload.hh} | 60 +++++-------- src/arch/riscv/process.cc | 4 - src/arch/riscv/process.hh | 38 ++------ src/arch/riscv/se_workload.cc | 37 ++++++++ src/arch/riscv/se_workload.hh | 88 +++++++++++++++++++ 8 files changed, 239 insertions(+), 120 deletions(-) create mode 100644 src/arch/riscv/RiscvSeWorkload.py rename src/arch/riscv/linux/{process.cc => se_workload.cc} (93%) rename src/arch/riscv/linux/{process.hh => se_workload.hh} (55%) create mode 100644 src/arch/riscv/se_workload.cc create mode 100644 src/arch/riscv/se_workload.hh diff --git a/src/arch/riscv/RiscvSeWorkload.py b/src/arch/riscv/RiscvSeWorkload.py new file mode 100644 index 000000000..c4f61bf83 --- /dev/null +++ b/src/arch/riscv/RiscvSeWorkload.py @@ -0,0 +1,44 @@ +# Copyright 2020 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. + +from m5.params import * + +from m5.objects.Workload import SEWorkload + +class RiscvSEWorkload(SEWorkload): + type = 'RiscvSEWorkload' + cxx_header = "arch/riscv/se_workload.hh" + cxx_class = 'RiscvISA::SEWorkload' + abstract = True + +class RiscvEmuLinux(RiscvSEWorkload): + type = 'RiscvEmuLinux' + cxx_header = "arch/riscv/linux/se_workload.hh" + cxx_class = 'RiscvISA::EmuLinux' + + @classmethod + def _is_compatible_with(cls, obj): + return obj.get_arch() in ('riscv64', 'riscv32') and \ + obj.get_op_sys() in ('linux', 'unknown') diff --git a/src/arch/riscv/SConscript b/src/arch/riscv/SConscript index 3fddd3123..5f1aedc9b 100644 --- a/src/arch/riscv/SConscript +++ b/src/arch/riscv/SConscript @@ -53,9 +53,10 @@ if env['TARGET_ISA'] == 'riscv': Source('pagetable.cc') Source('pagetable_walker.cc') Source('remote_gdb.cc') + Source('se_workload.cc') Source('tlb.cc') - Source('linux/process.cc') + Source('linux/se_workload.cc') Source('linux/linux.cc') Source('bare_metal/fs_workload.cc') @@ -64,6 +65,7 @@ if env['TARGET_ISA'] == 'riscv': SimObject('RiscvInterrupts.py') SimObject('RiscvISA.py') SimObject('RiscvMMU.py') + SimObject('RiscvSeWorkload.py') SimObject('RiscvTLB.py') DebugFlag('RiscvMisc') diff --git a/src/arch/riscv/linux/process.cc b/src/arch/riscv/linux/se_workload.cc similarity index 93% rename from src/arch/riscv/linux/process.cc rename to src/arch/riscv/linux/se_workload.cc index 5c0624de5..03a61d6d6 100644 --- a/src/arch/riscv/linux/process.cc +++ b/src/arch/riscv/linux/se_workload.cc @@ -1,8 +1,8 @@ /* - * Copyright (c) 2005 The Regents of The University of Michigan - * Copyright (c) 2007 MIPS Technologies, Inc. - * Copyright (c) 2016 The University of Virginia - * All rights reserved. + * Copyright 2005 The Regents of The University of Michigan + * Copyright 2007 MIPS Technologies, Inc. + * Copyright 2016 The University of Virginia + * Copyright 2020 Google Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,37 +28,27 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/riscv/linux/process.hh" +#include "arch/riscv/linux/se_workload.hh" -#include +#include -#include "arch/riscv/isa_traits.hh" -#include "arch/riscv/linux/linux.hh" +#include "arch/riscv/process.hh" #include "base/loader/object_file.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" -#include "debug/SyscallVerbose.hh" -#include "kern/linux/linux.hh" -#include "sim/eventq.hh" -#include "sim/process.hh" -#include "sim/syscall_desc.hh" #include "sim/syscall_emul.hh" -#include "sim/system.hh" - -using namespace std; -using namespace RiscvISA; namespace { -class RiscvLinuxObjectFileLoader : public Process::Loader +class LinuxLoader : public Process::Loader { public: Process * - load(const ProcessParams ¶ms, ::Loader::ObjectFile *obj_file) override + load(const ProcessParams ¶ms, ::Loader::ObjectFile *obj) override { - auto arch = obj_file->getArch(); - auto opsys = obj_file->getOpSys(); + auto arch = obj->getArch(); + auto opsys = obj->getOpSys(); if (arch != ::Loader::Riscv64 && arch != ::Loader::Riscv32) return nullptr; @@ -72,16 +62,34 @@ class RiscvLinuxObjectFileLoader : public Process::Loader return nullptr; if (arch == ::Loader::Riscv64) - return new RiscvLinuxProcess64(params, obj_file); + return new RiscvProcess64(params, obj); else - return new RiscvLinuxProcess32(params, obj_file); + return new RiscvProcess32(params, obj); } }; -RiscvLinuxObjectFileLoader loader; +LinuxLoader loader; } // anonymous namespace +namespace RiscvISA +{ + +void +EmuLinux::syscall(ThreadContext *tc) +{ + Process *process = tc->getProcessPtr(); + // Call the syscall function in the base Process class to update stats. + // This will move into the base SEWorkload function at some point. + process->Process::syscall(tc); + + RegVal num = tc->readIntReg(RiscvISA::SyscallNumReg); + if (dynamic_cast(process)) + syscallDescs64.get(num)->doSyscall(tc); + else + syscallDescs32.get(num)->doSyscall(tc); +} + /// Target uname() handler. static SyscallReturn unameFunc64(SyscallDesc *desc, ThreadContext *tc, VPtr name) @@ -112,8 +120,7 @@ unameFunc32(SyscallDesc *desc, ThreadContext *tc, VPtr name) return 0; } -SyscallDescTable - RiscvLinuxProcess64::syscallDescs = { +SyscallDescTable EmuLinux::syscallDescs64 = { { 0, "io_setup" }, { 1, "io_destroy" }, { 2, "io_submit" }, @@ -444,8 +451,7 @@ SyscallDescTable { 2011, "getmainvars" } }; -SyscallDescTable - RiscvLinuxProcess32::syscallDescs = { +SyscallDescTable EmuLinux::syscallDescs32 = { { 0, "io_setup" }, { 1, "io_destroy" }, { 2, "io_submit" }, @@ -776,24 +782,10 @@ SyscallDescTable { 2011, "getmainvars" } }; -RiscvLinuxProcess64::RiscvLinuxProcess64(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile) : RiscvProcess64(params, objFile) -{} +} // namespace RiscvISA -void -RiscvLinuxProcess64::syscall(ThreadContext *tc) -{ - RiscvProcess64::syscall(tc); - syscallDescs.get(tc->readIntReg(SyscallNumReg))->doSyscall(tc); -} - -RiscvLinuxProcess32::RiscvLinuxProcess32(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile) : RiscvProcess32(params, objFile) -{} - -void -RiscvLinuxProcess32::syscall(ThreadContext *tc) +RiscvISA::EmuLinux * +RiscvEmuLinuxParams::create() const { - RiscvProcess32::syscall(tc); - syscallDescs.get(tc->readIntReg(SyscallNumReg))->doSyscall(tc); + return new RiscvISA::EmuLinux(*this); } diff --git a/src/arch/riscv/linux/process.hh b/src/arch/riscv/linux/se_workload.hh similarity index 55% rename from src/arch/riscv/linux/process.hh rename to src/arch/riscv/linux/se_workload.hh index dd9157cbd..881ba3346 100644 --- a/src/arch/riscv/linux/process.hh +++ b/src/arch/riscv/linux/se_workload.hh @@ -1,7 +1,7 @@ /* - * Copyright (c) 2004 The Regents of The University of Michigan - * Copyright (c) 2016 The University of Virginia - * All rights reserved. + * Copyright 2004 The Regents of The University of Michigan + * Copyright 2016 The University of Virginia + * Copyright 2020 Google Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -27,53 +27,39 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __RISCV_LINUX_PROCESS_HH__ -#define __RISCV_LINUX_PROCESS_HH__ - -#include +#ifndef __ARCH_RISCV_LINUX_SE_WORKLOAD_HH__ +#define __ARCH_RISCV_LINUX_SE_WORKLOAD_HH__ #include "arch/riscv/linux/linux.hh" -#include "arch/riscv/process.hh" -#include "sim/eventq.hh" +#include "arch/riscv/se_workload.hh" +#include "params/RiscvEmuLinux.hh" #include "sim/syscall_desc.hh" -/// A process with emulated Riscv/Linux syscalls. -class RiscvLinuxProcess64 : public RiscvProcess64 +namespace RiscvISA { - public: - /// Constructor. - RiscvLinuxProcess64(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile); - /// The target system's hostname. - static const char *hostname; +class EmuLinux : public SEWorkload +{ + public: + using Params = RiscvEmuLinuxParams; - /// ID of the thread group leader for the process - uint64_t __tgid; + protected: + const Params &_params; - void syscall(ThreadContext *tc) override; + /// 64 bit syscall descriptors, indexed by call number. + static SyscallDescTable syscallDescs64; - /// Syscall descriptors, indexed by call number. - static SyscallDescTable syscallDescs; -}; + /// 32 bit syscall descriptors, indexed by call number. + static SyscallDescTable syscallDescs32; -class RiscvLinuxProcess32 : public RiscvProcess32 -{ public: - /// Constructor. - RiscvLinuxProcess32(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile); - - /// The target system's hostname. - static const char *hostname; + const Params ¶ms() const { return _params; } - /// ID of the thread group leader for the process - uint64_t __tgid; + EmuLinux(const Params &p) : SEWorkload(p), _params(p) {} void syscall(ThreadContext *tc) override; - - /// Array of syscall descriptors, indexed by call number. - static SyscallDescTable syscallDescs; }; -#endif // __RISCV_LINUX_PROCESS_HH__ +} // namespace RiscvISA + +#endif // __ARCH_RISCV_LINUX_SE_WORKLOAD_HH__ diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc index 3dd157a1c..10c1378a5 100644 --- a/src/arch/riscv/process.cc +++ b/src/arch/riscv/process.cc @@ -246,7 +246,3 @@ RiscvProcess::argsInit(int pageSize) memState->setStackMin(roundDown(memState->getStackMin(), pageSize)); } - -const std::vector RiscvProcess::SyscallABI::ArgumentRegs = { - 10, 11, 12, 13, 14, 15, 16 -}; diff --git a/src/arch/riscv/process.hh b/src/arch/riscv/process.hh index 03f106e66..105d1eb7f 100644 --- a/src/arch/riscv/process.hh +++ b/src/arch/riscv/process.hh @@ -53,49 +53,23 @@ class RiscvProcess : public Process public: virtual bool mmapGrowsDown() const override { return false; } - - //FIXME RISCV needs to handle 64 bit arguments in its 32 bit ISA. - struct SyscallABI : public GenericSyscallABI64 - { - static const std::vector ArgumentRegs; - }; -}; - -namespace GuestABI -{ - -template <> -struct Result -{ - static void - store(ThreadContext *tc, const SyscallReturn &ret) - { - if (ret.suppressed() || ret.needsRetry()) - return; - - if (ret.successful()) { - // no error - tc->setIntReg(RiscvISA::ReturnValueReg, ret.returnValue()); - } else { - // got an error, return details - tc->setIntReg(RiscvISA::ReturnValueReg, ret.encodedValue()); - } - } -}; - }; class RiscvProcess64 : public RiscvProcess { - protected: + public: RiscvProcess64(const ProcessParams ¶ms, ::Loader::ObjectFile *objFile); + + protected: void initState() override; }; class RiscvProcess32 : public RiscvProcess { - protected: + public: RiscvProcess32(const ProcessParams ¶ms, ::Loader::ObjectFile *objFile); + + protected: void initState() override; }; diff --git a/src/arch/riscv/se_workload.cc b/src/arch/riscv/se_workload.cc new file mode 100644 index 000000000..ce4679c69 --- /dev/null +++ b/src/arch/riscv/se_workload.cc @@ -0,0 +1,37 @@ +/* + * Copyright 2020 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. + */ + +#include "arch/riscv/se_workload.hh" + +namespace RiscvISA +{ + +const std::vector SEWorkload::SyscallABI::ArgumentRegs = { + 10, 11, 12, 13, 14, 15, 16 +}; + +} // namespace RiscvISA diff --git a/src/arch/riscv/se_workload.hh b/src/arch/riscv/se_workload.hh new file mode 100644 index 000000000..e0be5a14a --- /dev/null +++ b/src/arch/riscv/se_workload.hh @@ -0,0 +1,88 @@ +/* + * Copyright 2020 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 __ARCH_RISCV_SE_WORKLOAD_HH__ +#define __ARCH_RISCV_SE_WORKLOAD_HH__ + +#include "arch/riscv/registers.hh" +#include "params/RiscvSEWorkload.hh" +#include "sim/se_workload.hh" +#include "sim/syscall_abi.hh" +#include "sim/syscall_desc.hh" + +namespace RiscvISA +{ + +class SEWorkload : public ::SEWorkload +{ + public: + using Params = RiscvSEWorkloadParams; + + protected: + const Params &_params; + + public: + const Params ¶ms() const { return _params; } + + SEWorkload(const Params &p) : ::SEWorkload(p), _params(p) {} + + ::Loader::Arch getArch() const override { return ::Loader::Riscv64; } + + //FIXME RISCV needs to handle 64 bit arguments in its 32 bit ISA. + struct SyscallABI : public GenericSyscallABI64 + { + static const std::vector ArgumentRegs; + }; +}; + +} // namespace RiscvISA + +namespace GuestABI +{ + +template <> +struct Result +{ + static void + store(ThreadContext *tc, const SyscallReturn &ret) + { + if (ret.suppressed() || ret.needsRetry()) + return; + + if (ret.successful()) { + // no error + tc->setIntReg(RiscvISA::ReturnValueReg, ret.returnValue()); + } else { + // got an error, return details + tc->setIntReg(RiscvISA::ReturnValueReg, ret.encodedValue()); + } + } +}; + +} // namespace GuestABI + +#endif // __ARCH_RISCV_SE_WORKLOAD_HH__ -- 2.30.2