From: Gabe Black Date: Wed, 21 Oct 2020 00:36:57 +0000 (-0700) Subject: sparc: Implement an SE workload for Linux and Solaris. X-Git-Tag: develop-gem5-snapshot~559 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=175355f71e18e8e8ed401bd267646aa850dc900e;p=gem5.git sparc: Implement an SE workload for Linux and Solaris. I don't have a binary to test Solaris SE mode, but this *should* still work. Change-Id: Iaacc2ddd5193d7341bc65b9fdd5657c26d231cf1 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/33995 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index 4c855ba4d..7ba6d10b0 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -36,14 +36,15 @@ if env['TARGET_ISA'] == 'sparc': Source('interrupts.cc') Source('isa.cc') Source('linux/linux.cc') - Source('linux/process.cc') + Source('linux/se_workload.cc') Source('linux/syscalls.cc') Source('mmu.cc') Source('nativetrace.cc') Source('pagetable.cc') Source('process.cc') Source('remote_gdb.cc') - Source('solaris/process.cc') + Source('se_workload.cc') + Source('solaris/se_workload.cc') Source('solaris/solaris.cc') Source('tlb.cc') Source('ua2005.cc') @@ -54,6 +55,7 @@ if env['TARGET_ISA'] == 'sparc': SimObject('SparcISA.py') SimObject('SparcMMU.py') SimObject('SparcNativeTrace.py') + SimObject('SparcSeWorkload.py') SimObject('SparcTLB.py') DebugFlag('Sparc', "Generic SPARC ISA stuff") diff --git a/src/arch/sparc/SparcSeWorkload.py b/src/arch/sparc/SparcSeWorkload.py new file mode 100644 index 000000000..03d4b7301 --- /dev/null +++ b/src/arch/sparc/SparcSeWorkload.py @@ -0,0 +1,54 @@ +# 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 SparcSEWorkload(SEWorkload): + type = 'SparcSEWorkload' + cxx_header = "arch/sparc/se_workload.hh" + cxx_class = 'SparcISA::SEWorkload' + abstract = True + +class SparcEmuLinux(SparcSEWorkload): + type = 'SparcEmuLinux' + cxx_header = "arch/sparc/linux/se_workload.hh" + cxx_class = 'SparcISA::EmuLinux' + + @classmethod + def _is_compatible_with(cls, obj): + return obj.get_arch() in ('sparc64', 'sparc32') and \ + obj.get_op_sys() in ('linux', 'unknown') + +class SparcEmuSolaris(SparcSEWorkload): + type = 'SparcEmuSolaris' + cxx_header = "arch/sparc/solaris/se_workload.hh" + cxx_class = 'SparcISA::EmuSolaris' + + @classmethod + def _is_compatible_with(cls, obj): + return obj.get_arch() in ('sparc64', 'sparc32') and \ + obj.get_op_sys() == 'solaris' diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 34a0d52b2..33ba921db 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -30,8 +30,8 @@ #include -#include "arch/sparc/isa_traits.hh" #include "arch/sparc/process.hh" +#include "arch/sparc/se_workload.hh" #include "arch/sparc/tlb.hh" #include "arch/sparc/types.hh" #include "base/bitfield.hh" @@ -815,7 +815,8 @@ TrapInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst) SparcProcess *sp = dynamic_cast(p); assert(sp); - sp->handleTrap(_n, tc); + auto *workload = dynamic_cast(tc->getSystemPtr()->workload); + workload->handleTrap(tc, _n); // We need to explicitly advance the pc, since that's not done for us // on a faulting instruction diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc deleted file mode 100644 index 37205c765..000000000 --- a/src/arch/sparc/linux/process.cc +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2003-2005 The Regents of The University of Michigan - * 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/sparc/linux/process.hh" - -#include "arch/sparc/isa_traits.hh" -#include "arch/sparc/registers.hh" -#include "base/loader/object_file.hh" -#include "base/trace.hh" -#include "cpu/thread_context.hh" -#include "kern/linux/linux.hh" -#include "sim/process.hh" -#include "sim/syscall_desc.hh" -#include "sim/syscall_emul.hh" - -using namespace std; -using namespace SparcISA; - -namespace -{ - -class SparcLinuxObjectFileLoader : public Process::Loader -{ - public: - Process * - load(const ProcessParams ¶ms, ::Loader::ObjectFile *obj_file) override - { - auto arch = obj_file->getArch(); - auto opsys = obj_file->getOpSys(); - - if (arch != ::Loader::SPARC64 && arch != ::Loader::SPARC32) - return nullptr; - - if (opsys == ::Loader::UnknownOpSys) { - warn("Unknown operating system; assuming Linux."); - opsys = ::Loader::Linux; - } - - if (opsys != ::Loader::Linux) - return nullptr; - - if (arch == ::Loader::SPARC64) - return new Sparc64LinuxProcess(params, obj_file); - else - return new Sparc32LinuxProcess(params, obj_file); - } -}; - -SparcLinuxObjectFileLoader loader; - -} // anonymous namespace - -Sparc32LinuxProcess::Sparc32LinuxProcess(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile) - : Sparc32Process(params, objFile) -{} - -void -Sparc32LinuxProcess::syscall(ThreadContext *tc) -{ - Sparc32Process::syscall(tc); - syscall32Descs.get(tc->readIntReg(1))->doSyscall(tc); -} - -void -Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc) -{ - switch (trapNum) { - case 0x10: //Linux 32 bit syscall trap - tc->getSystemPtr()->workload->syscall(tc); - break; - default: - SparcProcess::handleTrap(trapNum, tc); - } -} - -Sparc64LinuxProcess::Sparc64LinuxProcess(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile) - : Sparc64Process(params, objFile) -{} - -void -Sparc64LinuxProcess::syscall(ThreadContext *tc) -{ - Sparc64Process::syscall(tc); - syscallDescs.get(tc->readIntReg(1))->doSyscall(tc); -} - -void -Sparc64LinuxProcess::getContext(ThreadContext *tc) -{ - warn("The getcontext trap is not implemented on SPARC"); -} - -void -Sparc64LinuxProcess::setContext(ThreadContext *tc) -{ - panic("The setcontext trap is not implemented on SPARC"); -} - -void -Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc) -{ - switch (trapNum) { - // case 0x10: // Linux 32 bit syscall trap - case 0x6d: // Linux 64 bit syscall trap - tc->getSystemPtr()->workload->syscall(tc); - break; - case 0x6e: // Linux 64 bit getcontext trap - getContext(tc); - break; - case 0x6f: // Linux 64 bit setcontext trap - setContext(tc); - break; - default: - SparcProcess::handleTrap(trapNum, tc); - } -} diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh deleted file mode 100644 index c1ade86d0..000000000 --- a/src/arch/sparc/linux/process.hh +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2003-2004 The Regents of The University of Michigan - * 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. - */ - -#ifndef __SPARC_LINUX_PROCESS_HH__ -#define __SPARC_LINUX_PROCESS_HH__ - -#include "arch/sparc/linux/linux.hh" -#include "arch/sparc/process.hh" -#include "sim/process.hh" -#include "sim/syscall_desc.hh" - -namespace SparcISA { - -// This contains all of the common elements of a SPARC Linux process which -// are not shared by other operating systems. The rest come from the common -// SPARC process class. -class SparcLinuxProcess -{ - public: - /// 64 bit syscall descriptors, indexed by call number. - static SyscallDescTable syscallDescs; - - /// 32 bit compatibility syscall descriptors, indexed by call number. - static SyscallDescTable syscall32Descs; -}; - -/// A process with emulated SPARC/Linux syscalls. -class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32Process -{ - public: - /// Constructor. - Sparc32LinuxProcess(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile); - - void syscall(ThreadContext *tc) override; - - void handleTrap(int trapNum, ThreadContext *tc) override; -}; - -/// A process with emulated 32 bit SPARC/Linux syscalls. -class Sparc64LinuxProcess : public SparcLinuxProcess, public Sparc64Process -{ - public: - /// Constructor. - Sparc64LinuxProcess(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile); - - void syscall(ThreadContext *tc) override; - - void getContext(ThreadContext *tc); - void setContext(ThreadContext *tc); - - void handleTrap(int trapNum, ThreadContext *tc) override; -}; - -SyscallReturn getresuidFunc(SyscallDesc *desc, ThreadContext *tc, - Addr ruid, Addr euid, Addr suid); - -} // namespace SparcISA -#endif // __SPARC_LINUX_PROCESS_HH__ diff --git a/src/arch/sparc/linux/se_workload.cc b/src/arch/sparc/linux/se_workload.cc new file mode 100644 index 000000000..7b652ff01 --- /dev/null +++ b/src/arch/sparc/linux/se_workload.cc @@ -0,0 +1,144 @@ +/* + * 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/sparc/linux/se_workload.hh" + +#include + +#include "arch/sparc/process.hh" +#include "base/loader/object_file.hh" +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "sim/syscall_desc.hh" + +namespace +{ + +class LinuxLoader : public Process::Loader +{ + public: + Process * + load(const ProcessParams ¶ms, ::Loader::ObjectFile *obj) override + { + auto arch = obj->getArch(); + auto opsys = obj->getOpSys(); + + if (arch != ::Loader::SPARC64 && arch != ::Loader::SPARC32) + return nullptr; + + if (opsys == ::Loader::UnknownOpSys) { + warn("Unknown operating system; assuming Linux."); + opsys = ::Loader::Linux; + } + + if (opsys != ::Loader::Linux) + return nullptr; + + if (arch == ::Loader::SPARC64) + return new Sparc64Process(params, obj); + else + return new Sparc32Process(params, obj); + } +}; + +LinuxLoader loader; + +} // anonymous namespace + +namespace SparcISA +{ + +EmuLinux::EmuLinux(const Params &p) : SEWorkload(p), _params(p) +{} + +void +EmuLinux::handleTrap(ThreadContext *tc, int trapNum) +{ + if (is64(tc)) { + switch (trapNum) { + // case 0x10: // Linux 32 bit syscall trap + case 0x6d: // Linux 64 bit syscall trap + syscall64(tc); + return; + case 0x6e: // Linux 64 bit getcontext trap + warn("The getcontext trap is not implemented on SPARC"); + return; + case 0x6f: // Linux 64 bit setcontext trap + panic("The setcontext trap is not implemented on SPARC"); + default: + break; + } + } else { + switch (trapNum) { + case 0x10: //Linux 32 bit syscall trap + syscall32(tc); + return; + default: + break; + } + } + SEWorkload::handleTrap(tc, trapNum); +} + +void +EmuLinux::syscall32(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); + + syscall32Descs.get(tc->readIntReg(1))->doSyscall(tc); +} + +void +EmuLinux::syscall64(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); + + syscallDescs.get(tc->readIntReg(1))->doSyscall(tc); +} + +void +EmuLinux::syscall(ThreadContext *tc) +{ + if (is64(tc)) + syscall64(tc); + else + syscall32(tc); +} + +} // namespace SparcISA + +SparcISA::EmuLinux * +SparcEmuLinuxParams::create() const +{ + return new SparcISA::EmuLinux(*this); +} diff --git a/src/arch/sparc/linux/se_workload.hh b/src/arch/sparc/linux/se_workload.hh new file mode 100644 index 000000000..a5022d6f9 --- /dev/null +++ b/src/arch/sparc/linux/se_workload.hh @@ -0,0 +1,69 @@ +/* + * 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_SPARC_LINUX_SE_WORKLOAD_HH__ +#define __ARCH_SPARC_LINUX_SE_WORKLOAD_HH__ + +#include "arch/sparc/linux/linux.hh" +#include "arch/sparc/se_workload.hh" +#include "params/SparcEmuLinux.hh" +#include "sim/syscall_desc.hh" + +namespace SparcISA +{ + +class EmuLinux : public SEWorkload +{ + public: + using Params = SparcEmuLinuxParams; + + protected: + const Params &_params; + + /// 64 bit syscall descriptors, indexed by call number. + static SyscallDescTable syscallDescs; + + /// 32 bit compatibility syscall descriptors, indexed by call number. + static SyscallDescTable syscall32Descs; + + void syscall64(ThreadContext *tc); + void syscall32(ThreadContext *tc); + + public: + const Params ¶ms() const { return _params; } + + EmuLinux(const Params &p); + + ::Loader::Arch getArch() const override { return ::Loader::SPARC64; } + + void handleTrap(ThreadContext *tc, int trapNum) override; + void syscall(ThreadContext *tc) override; +}; + +} // namespace SparcISA + +#endif // __ARCH_SPARC_LINUX_SE_WORKLOAD_HH__ diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 304f2cfdb..a00f60e59 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -26,14 +26,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/sparc/linux/process.hh" +#include "arch/sparc/linux/se_workload.hh" #include "sim/syscall_desc.hh" #include "sim/syscall_emul.hh" class Process; class ThreadContext; -namespace SparcISA { +namespace SparcISA +{ /// Target uname() handler. static SyscallReturn @@ -51,7 +52,7 @@ unameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr name) } -SyscallReturn +static SyscallReturn getresuidFunc(SyscallDesc *desc, ThreadContext *tc, Addr ruid, Addr euid, Addr suid) { @@ -78,8 +79,7 @@ getresuidFunc(SyscallDesc *desc, ThreadContext *tc, return 0; } -SyscallDescTable - SparcLinuxProcess::syscall32Descs = { +SyscallDescTable EmuLinux::syscall32Descs = { { 0, "restart_syscall" }, { 1, "exit", exitFunc }, // 32 bit { 2, "fork" }, @@ -382,8 +382,7 @@ SyscallDescTable { 299, "unshare" } }; -SyscallDescTable - SparcLinuxProcess::syscallDescs = { +SyscallDescTable EmuLinux::syscallDescs = { { 0, "restart_syscall" }, { 1, "exit", exitFunc }, { 2, "fork" }, diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 8f3509f8a..b292c86a8 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -48,10 +48,6 @@ using namespace std; using namespace SparcISA; -const std::vector SparcProcess::SyscallABI::ArgumentRegs = { - INTREG_O0, INTREG_O1, INTREG_O2, INTREG_O3, INTREG_O4, INTREG_O5 -}; - SparcProcess::SparcProcess(const ProcessParams ¶ms, ::Loader::ObjectFile *objFile, Addr _StackBias) : Process(params, @@ -65,47 +61,6 @@ SparcProcess::SparcProcess(const ProcessParams ¶ms, spillStart = 0; } -void -SparcProcess::handleTrap(int trapNum, ThreadContext *tc) -{ - PCState pc = tc->pcState(); - switch (trapNum) { - case 0x01: // Software breakpoint - warn("Software breakpoint encountered at pc %#x.\n", pc.pc()); - break; - case 0x02: // Division by zero - warn("Software signaled a division by zero at pc %#x.\n", pc.pc()); - break; - case 0x03: // Flush window trap - flushWindows(tc); - break; - case 0x04: // Clean windows - warn("Ignoring process request for clean register " - "windows at pc %#x.\n", pc.pc()); - break; - case 0x05: // Range check - warn("Software signaled a range check at pc %#x.\n", pc.pc()); - break; - case 0x06: // Fix alignment - warn("Ignoring process request for os assisted unaligned accesses " - "at pc %#x.\n", pc.pc()); - break; - case 0x07: // Integer overflow - warn("Software signaled an integer overflow at pc %#x.\n", pc.pc()); - break; - case 0x32: // Get integer condition codes - warn("Ignoring process request to get the integer condition codes " - "at pc %#x.\n", pc.pc()); - break; - case 0x33: // Set integer condition codes - warn("Ignoring process request to set the integer condition codes " - "at pc %#x.\n", pc.pc()); - break; - default: - panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum); - } -} - void SparcProcess::initState() { @@ -433,72 +388,3 @@ Sparc32Process::argsInit(int intSize, int pageSize) initVirtMem->writeBlob(spillStart, spillHandler32, sizeof(MachInst) * numSpillInsts); } - -void Sparc32Process::flushWindows(ThreadContext *tc) -{ - RegVal Cansave = tc->readIntReg(INTREG_CANSAVE); - RegVal Canrestore = tc->readIntReg(INTREG_CANRESTORE); - RegVal Otherwin = tc->readIntReg(INTREG_OTHERWIN); - RegVal CWP = tc->readMiscReg(MISCREG_CWP); - RegVal origCWP = CWP; - CWP = (CWP + Cansave + 2) % NWindows; - while (NWindows - 2 - Cansave != 0) { - if (Otherwin) { - panic("Otherwin non-zero.\n"); - } else { - tc->setMiscReg(MISCREG_CWP, CWP); - // Do the stores - RegVal sp = tc->readIntReg(StackPointerReg); - for (int index = 16; index < 32; index++) { - uint32_t regVal = tc->readIntReg(index); - regVal = htobe(regVal); - if (!tc->getVirtProxy().tryWriteBlob( - sp + (index - 16) * 4, (uint8_t *)®Val, 4)) { - warn("Failed to save register to the stack when " - "flushing windows.\n"); - } - } - Canrestore--; - Cansave++; - CWP = (CWP + 1) % NWindows; - } - } - tc->setIntReg(INTREG_CANSAVE, Cansave); - tc->setIntReg(INTREG_CANRESTORE, Canrestore); - tc->setMiscReg(MISCREG_CWP, origCWP); -} - -void -Sparc64Process::flushWindows(ThreadContext *tc) -{ - RegVal Cansave = tc->readIntReg(INTREG_CANSAVE); - RegVal Canrestore = tc->readIntReg(INTREG_CANRESTORE); - RegVal Otherwin = tc->readIntReg(INTREG_OTHERWIN); - RegVal CWP = tc->readMiscReg(MISCREG_CWP); - RegVal origCWP = CWP; - CWP = (CWP + Cansave + 2) % NWindows; - while (NWindows - 2 - Cansave != 0) { - if (Otherwin) { - panic("Otherwin non-zero.\n"); - } else { - tc->setMiscReg(MISCREG_CWP, CWP); - // Do the stores - RegVal sp = tc->readIntReg(StackPointerReg); - for (int index = 16; index < 32; index++) { - RegVal regVal = tc->readIntReg(index); - regVal = htobe(regVal); - if (!tc->getVirtProxy().tryWriteBlob( - sp + 2047 + (index - 16) * 8, (uint8_t *)®Val, 8)) { - warn("Failed to save register to the stack when " - "flushing windows.\n"); - } - } - Canrestore--; - Cansave++; - CWP = (CWP + 1) % NWindows; - } - } - tc->setIntReg(INTREG_CANSAVE, Cansave); - tc->setIntReg(INTREG_CANRESTORE, Canrestore); - tc->setMiscReg(MISCREG_CWP, origCWP); -} diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index 593854a0d..4d3ebfe4b 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -34,12 +34,9 @@ #include #include "arch/sparc/isa_traits.hh" -#include "arch/sparc/miscregs.hh" #include "base/loader/object_file.hh" #include "mem/page_table.hh" -#include "sim/byteswap.hh" #include "sim/process.hh" -#include "sim/syscall_abi.hh" class SparcProcess : public Process { @@ -60,63 +57,18 @@ class SparcProcess : public Process public: - // Handles traps which request services from the operating system - virtual void handleTrap(int trapNum, ThreadContext *tc); - Addr readFillStart() { return fillStart; } Addr readSpillStart() { return spillStart; } - - virtual void flushWindows(ThreadContext *tc) = 0; - - struct SyscallABI - { - static const std::vector ArgumentRegs; - }; -}; - -namespace GuestABI -{ - -template -struct Result::value>> -{ - static void - store(ThreadContext *tc, const SyscallReturn &ret) - { - if (ret.suppressed() || ret.needsRetry()) - return; - - // check for error condition. SPARC syscall convention is to - // indicate success/failure in reg the carry bit of the ccr - // and put the return value itself in the standard return value reg. - SparcISA::PSTATE pstate = - tc->readMiscRegNoEffect(SparcISA::MISCREG_PSTATE); - SparcISA::CCR ccr = tc->readIntReg(SparcISA::INTREG_CCR); - RegVal val; - if (ret.successful()) { - ccr.xcc.c = ccr.icc.c = 0; - val = ret.returnValue(); - } else { - ccr.xcc.c = ccr.icc.c = 1; - val = ret.errnoValue(); - } - tc->setIntReg(SparcISA::INTREG_CCR, ccr); - if (pstate.am) - val = bits(val, 31, 0); - tc->setIntReg(SparcISA::ReturnValueReg, val); - if (ret.count() == 2) - tc->setIntReg(SparcISA::SyscallPseudoReturnReg, ret.value2()); - } }; -} // namespace GuestABI - class Sparc32Process : public SparcProcess { protected: + void initState() override; + + public: + Sparc32Process(const ProcessParams ¶ms, ::Loader::ObjectFile *objFile) : SparcProcess(params, objFile, 0) { @@ -142,44 +94,15 @@ class Sparc32Process : public SparcProcess mmap_end); } - void initState() override; - - public: - void argsInit(int intSize, int pageSize); - - void flushWindows(ThreadContext *tc) override; - - struct SyscallABI : public GenericSyscallABI32, - public SparcProcess::SyscallABI - {}; -}; - -namespace GuestABI -{ - -template -struct Argument::value>> -{ - using ABI = Sparc32Process::SyscallABI; - - static Arg - get(ThreadContext *tc, typename ABI::State &state) - { - panic_if(state + 1 >= ABI::ArgumentRegs.size(), - "Ran out of syscall argument registers."); - auto high = ABI::ArgumentRegs[state++]; - auto low = ABI::ArgumentRegs[state++]; - return (Arg)ABI::mergeRegs(tc, low, high); - } }; -} // namespace GuestABI - class Sparc64Process : public SparcProcess { protected: + void initState() override; + + public: Sparc64Process(const ProcessParams ¶ms, ::Loader::ObjectFile *objFile) : SparcProcess(params, objFile, 2047) @@ -205,17 +128,7 @@ class Sparc64Process : public SparcProcess mmap_end); } - void initState() override; - - public: - void argsInit(int intSize, int pageSize); - - void flushWindows(ThreadContext *tc) override; - - struct SyscallABI : public GenericSyscallABI64, - public SparcProcess::SyscallABI - {}; }; #endif // __SPARC_PROCESS_HH__ diff --git a/src/arch/sparc/se_workload.cc b/src/arch/sparc/se_workload.cc new file mode 100644 index 000000000..19a4e2b4f --- /dev/null +++ b/src/arch/sparc/se_workload.cc @@ -0,0 +1,137 @@ +/* + * 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/sparc/se_workload.hh" + +#include "arch/sparc/process.hh" +#include "arch/sparc/registers.hh" +#include "arch/sparc/types.hh" +#include "base/logging.hh" +#include "cpu/thread_context.hh" + +namespace SparcISA +{ + +const std::vector SEWorkload::BaseSyscallABI::ArgumentRegs = { + INTREG_O0, INTREG_O1, INTREG_O2, INTREG_O3, INTREG_O4, INTREG_O5 +}; + +bool +SEWorkload::is64(ThreadContext *tc) +{ + return dynamic_cast(tc->getProcessPtr()); +} + +void +SEWorkload::handleTrap(ThreadContext *tc, int trapNum) +{ + PCState pc = tc->pcState(); + switch (trapNum) { + case 0x01: // Software breakpoint + warn("Software breakpoint encountered at pc %#x.", pc.pc()); + break; + case 0x02: // Division by zero + warn("Software signaled a division by zero at pc %#x.", pc.pc()); + break; + case 0x03: // Flush window trap + flushWindows(tc); + break; + case 0x04: // Clean windows + warn("Ignoring process request for clean register " + "windows at pc %#x.", pc.pc()); + break; + case 0x05: // Range check + warn("Software signaled a range check at pc %#x.", pc.pc()); + break; + case 0x06: // Fix alignment + warn("Ignoring process request for os assisted unaligned accesses " + "at pc %#x.", pc.pc()); + break; + case 0x07: // Integer overflow + warn("Software signaled an integer overflow at pc %#x.", pc.pc()); + break; + case 0x32: // Get integer condition codes + warn("Ignoring process request to get the integer condition codes " + "at pc %#x.", pc.pc()); + break; + case 0x33: // Set integer condition codes + warn("Ignoring process request to set the integer condition codes " + "at pc %#x.", pc.pc()); + break; + default: + panic("Unimplemented trap to operating system: trap number %#x.", + trapNum); + } +} + +void +SEWorkload::flushWindows(ThreadContext *tc) +{ + RegVal Cansave = tc->readIntReg(INTREG_CANSAVE); + RegVal Canrestore = tc->readIntReg(INTREG_CANRESTORE); + RegVal Otherwin = tc->readIntReg(INTREG_OTHERWIN); + RegVal CWP = tc->readMiscReg(MISCREG_CWP); + RegVal origCWP = CWP; + + const bool is_64 = is64(tc); + const size_t reg_bytes = is_64 ? 8 : 4; + uint8_t bytes[8]; + + CWP = (CWP + Cansave + 2) % NWindows; + while (NWindows - 2 - Cansave != 0) { + panic_if(Otherwin, "Otherwin non-zero."); + + tc->setMiscReg(MISCREG_CWP, CWP); + // Do the stores + RegVal sp = tc->readIntReg(StackPointerReg); + + Addr addr = is_64 ? sp + 2047 : sp; + for (int index = 16; index < 32; index++) { + if (is_64) { + uint64_t regVal = htobe(tc->readIntReg(index)); + memcpy(bytes, ®Val, reg_bytes); + } else { + uint32_t regVal = htobe(tc->readIntReg(index)); + memcpy(bytes, ®Val, reg_bytes); + } + if (!tc->getVirtProxy().tryWriteBlob(addr, bytes, reg_bytes)) { + warn("Failed to save register to the stack when " + "flushing windows."); + } + addr += reg_bytes; + } + Canrestore--; + Cansave++; + CWP = (CWP + 1) % NWindows; + } + + tc->setIntReg(INTREG_CANSAVE, Cansave); + tc->setIntReg(INTREG_CANRESTORE, Canrestore); + tc->setMiscReg(MISCREG_CWP, origCWP); +} + +} // namespace SparcISA diff --git a/src/arch/sparc/se_workload.hh b/src/arch/sparc/se_workload.hh new file mode 100644 index 000000000..e39261dc5 --- /dev/null +++ b/src/arch/sparc/se_workload.hh @@ -0,0 +1,125 @@ +/* + * 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_SPARC_SE_WORKLOAD_HH__ +#define __ARCH_SPARC_SE_WORKLOAD_HH__ + +#include + +#include "arch/sparc/miscregs.hh" +#include "base/loader/object_file.hh" +#include "cpu/thread_context.hh" +#include "sim/se_workload.hh" +#include "sim/syscall_abi.hh" + +namespace SparcISA +{ + +class SEWorkload : public ::SEWorkload +{ + public: + using ::SEWorkload::SEWorkload; + + virtual void handleTrap(ThreadContext *tc, int trapNum); + virtual void flushWindows(ThreadContext *tc); + + bool is64(ThreadContext *tc); + + struct BaseSyscallABI + { + static const std::vector ArgumentRegs; + }; + + struct SyscallABI32 : public GenericSyscallABI32, + public BaseSyscallABI + {}; + + struct SyscallABI64 : public GenericSyscallABI64, + public BaseSyscallABI + {}; +}; + +} // namespace SparcISA + +namespace GuestABI +{ + +template +struct Result::value>> +{ + static void + store(ThreadContext *tc, const SyscallReturn &ret) + { + if (ret.suppressed() || ret.needsRetry()) + return; + + // check for error condition. SPARC syscall convention is to + // indicate success/failure in reg the carry bit of the ccr + // and put the return value itself in the standard return value reg. + SparcISA::PSTATE pstate = + tc->readMiscRegNoEffect(SparcISA::MISCREG_PSTATE); + SparcISA::CCR ccr = tc->readIntReg(SparcISA::INTREG_CCR); + RegVal val; + if (ret.successful()) { + ccr.xcc.c = ccr.icc.c = 0; + val = ret.returnValue(); + } else { + ccr.xcc.c = ccr.icc.c = 1; + val = ret.errnoValue(); + } + tc->setIntReg(SparcISA::INTREG_CCR, ccr); + if (pstate.am) + val = bits(val, 31, 0); + tc->setIntReg(SparcISA::ReturnValueReg, val); + if (ret.count() == 2) + tc->setIntReg(SparcISA::SyscallPseudoReturnReg, ret.value2()); + } +}; + +template +struct Argument::value>> +{ + using ABI = SparcISA::SEWorkload::SyscallABI32; + + static Arg + get(ThreadContext *tc, typename ABI::State &state) + { + panic_if(state + 1 >= ABI::ArgumentRegs.size(), + "Ran out of syscall argument registers."); + auto high = ABI::ArgumentRegs[state++]; + auto low = ABI::ArgumentRegs[state++]; + return (Arg)ABI::mergeRegs(tc, low, high); + } +}; + +} // namespace GuestABI + +#endif // __ARCH_SPARC_SE_WORKLOAD_HH__ diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc deleted file mode 100644 index 442e984d8..000000000 --- a/src/arch/sparc/solaris/process.cc +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (c) 2003-2005 The Regents of The University of Michigan - * 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/sparc/solaris/process.hh" - -#include "arch/sparc/isa_traits.hh" -#include "arch/sparc/registers.hh" -#include "base/loader/object_file.hh" -#include "base/trace.hh" -#include "cpu/thread_context.hh" -#include "kern/solaris/solaris.hh" -#include "sim/process.hh" -#include "sim/syscall_desc.hh" -#include "sim/syscall_emul.hh" - -using namespace std; -using namespace SparcISA; - -namespace -{ - -class SparcSolarisObjectFileLoader : public Process::Loader -{ - public: - Process * - load(const ProcessParams ¶ms, ::Loader::ObjectFile *obj_file) override - { - auto arch = obj_file->getArch(); - auto opsys = obj_file->getOpSys(); - - if (arch != ::Loader::SPARC64 && arch != ::Loader::SPARC32) - return nullptr; - - if (opsys != ::Loader::Solaris) - return nullptr; - - return new SparcSolarisProcess(params, obj_file); - } -}; - -SparcSolarisObjectFileLoader loader; - -} // anonymous namespace - - -/// Target uname() handler. -static SyscallReturn -unameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr name) -{ - auto process = tc->getProcessPtr(); - - strcpy(name->sysname, "SunOS"); - strcpy(name->nodename, "m5.eecs.umich.edu"); - strcpy(name->release, process->release.c_str()); - strcpy(name->version, "Generic_118558-21"); - strcpy(name->machine, "sun4u"); - - return 0; -} - - -SyscallDescTable - SparcSolarisProcess::syscallDescs = { - { 0, "syscall" }, - { 1, "exit", exitFunc }, - { 2, "fork" }, - { 3, "read", readFunc }, - { 4, "write", writeFunc }, - { 5, "open", openFunc }, - { 6, "close", closeFunc }, - { 7, "wait" }, - { 8, "creat" }, - { 9, "link" }, - { 10, "unlink", unlinkFunc }, - { 11, "exec" }, - { 12, "chdir" }, - { 13, "time" }, - { 14, "mknod" }, - { 15, "chmod", chmodFunc }, - { 16, "chown", chownFunc }, - { 17, "brk", brkFunc }, - { 18, "stat" }, - { 19, "lseek", lseekFunc }, - { 20, "getpid", getpidFunc }, - { 21, "mount" }, - { 22, "umount" }, - { 23, "setuid", ignoreFunc }, - { 24, "getuid", getuidFunc }, - { 25, "stime" }, - { 26, "pcsample" }, - { 27, "alarm" }, - { 28, "fstat", fstatFunc }, - { 29, "pause" }, - { 30, "utime" }, - { 31, "stty" }, - { 32, "gtty" }, - { 33, "access" }, - { 34, "nice" }, - { 35, "statfs" }, - { 36, "sync" }, - { 37, "kill" }, - { 38, "fstatfs" }, - { 39, "pgrpsys" }, - { 40, "xenix" }, - { 41, "dup" }, - { 42, "pipe", pipePseudoFunc }, - { 43, "times" }, - { 44, "profil" }, - { 45, "plock" }, - { 46, "setgid" }, - { 47, "getgid", getgidFunc }, - { 48, "signal" }, - { 49, "msgsys" }, - { 50, "syssun" }, - { 51, "acct" }, - { 52, "shmsys" }, - { 53, "semsys" }, - { 54, "ioctl" }, - { 55, "uadmin" }, - { 56, "RESERVED" }, - { 57, "utssys" }, - { 58, "fdsync" }, - { 59, "execve" }, - { 60, "umask", umaskFunc }, - { 61, "chroot" }, - { 62, "fcntl" }, - { 63, "ulimit" }, - { 64, "reserved_64" }, - { 65, "reserved_65" }, - { 66, "reserved_66" }, - { 67, "reserved_67" }, - { 68, "reserved_68" }, - { 69, "reserved_69" }, - { 70, "tasksys" }, - { 71, "acctctl" }, - { 72, "reserved_72" }, - { 73, "getpagesizes" }, - { 74, "rctlsys" }, - { 75, "issetugid" }, - { 76, "fsat" }, - { 77, "lwp_park" }, - { 78, "sendfilev" }, - { 79, "rmdir" }, - { 80, "mkdir" }, - { 81, "getdents" }, - { 82, "reserved_82" }, - { 83, "reserved_83" }, - { 84, "sysfs" }, - { 85, "getmsg" }, - { 86, "putmsg" }, - { 87, "poll" }, - { 88, "lstat" }, - { 89, "symlink" }, - { 90, "readlink", readlinkFunc }, - { 91, "setgroups" }, - { 92, "getgroups" }, - { 93, "fchmod" }, - { 94, "fchown" }, - { 95, "sigprocmask" }, - { 96, "sigsuspend" }, - { 97, "sigaltstack" }, - { 98, "sigaction" }, - { 99, "sigpending" }, - { 100, "context" }, - { 101, "evsys" }, - { 102, "evtrapret" }, - { 103, "statvfs" }, - { 104, "fstatvfs" }, - { 105, "getloadavg" }, - { 106, "nfssys" }, - { 107, "waitsys" }, - { 108, "sigsendsys" }, - { 109, "hrtsys" }, - { 110, "acancel" }, - { 111, "async" }, - { 112, "priocntlsys" }, - { 113, "pathconf" }, - { 114, "mincore" }, - { 115, "mmap", mmapFunc }, - { 116, "mprotect" }, - { 117, "munmap", munmapFunc }, - { 118, "fpathconf" }, - { 119, "vfork" }, - { 120, "fchdir" }, - { 121, "readv" }, - { 122, "writev" }, - { 123, "xstat" }, - { 124, "lxstat" }, - { 125, "fxstat" }, - { 126, "xmknod" }, - { 127, "clocal" }, - { 128, "setrlimit" }, - { 129, "getrlimit" }, - { 130, "lchown" }, - { 131, "memcntl" }, - { 132, "getpmsg" }, - { 133, "putpmsg" }, - { 134, "rename" }, - { 135, "uname", unameFunc }, - { 136, "setegid" }, - { 137, "sysconfig" }, - { 138, "adjtime" }, - { 139, "systeminfo" }, - { 140, "reserved_140" }, - { 141, "seteuid" }, - { 142, "vtrace" }, - { 143, "fork1" }, - { 144, "sigtimedwait" }, - { 145, "lwp_info" }, - { 146, "yield" }, - { 147, "lwp_sema_wait" }, - { 148, "lwp_sema_post" }, - { 149, "lwp_sema_trywait" }, - { 150, "lwp_detach" }, - { 151, "corectl" }, - { 152, "modctl" }, - { 153, "fchroot" }, - { 154, "utimes" }, - { 155, "vhangup" }, - { 156, "gettimeofday" }, - { 157, "getitimer" }, - { 158, "setitimer" }, - { 159, "lwp_create" }, - { 160, "lwp_exit" }, - { 161, "lwp_suspend" }, - { 162, "lwp_continue" }, - { 163, "lwp_kill" }, - { 164, "lwp_self" }, - { 165, "lwp_setprivate" }, - { 166, "lwp_getprivate" }, - { 167, "lwp_wait" }, - { 168, "lwp_mutex_wakeup" }, - { 169, "lwp_mutex_lock" }, - { 170, "lwp_cond_wait" }, - { 171, "lwp_cond_signal" }, - { 172, "lwp_cond_broadcast" }, - { 173, "pread" }, - { 174, "pwrite" }, - { 175, "llseek" }, - { 176, "inst_sync" }, - { 177, "srmlimitsys" }, - { 178, "kaio" }, - { 179, "cpc" }, - { 180, "lgrpsys_meminfosys" }, - { 181, "rusagesys" }, - { 182, "reserved_182" }, - { 183, "reserved_183" }, - { 184, "tsolsys" }, - { 185, "acl" }, - { 186, "auditsys" }, - { 187, "processor_bind" }, - { 188, "processor_info" }, - { 189, "p_online" }, - { 190, "sigqueue" }, - { 191, "clock_gettime" }, - { 192, "clock_settime" }, - { 193, "clock_getres" }, - { 194, "timer_create" }, - { 195, "timer_delete" }, - { 196, "timer_settime" }, - { 197, "timer_gettime" }, - { 198, "timer_getoverrun" }, - { 199, "nanosleep" }, - { 200, "facl" }, - { 201, "door" }, - { 202, "setreuid" }, - { 203, "setregid" }, - { 204, "install_utrap" }, - { 205, "signotify" }, - { 206, "schedctl" }, - { 207, "pset" }, - { 208, "sparc_utrap_install" }, - { 209, "resolvepath" }, - { 210, "signotifywait" }, - { 211, "lwp_sigredirect" }, - { 212, "lwp_alarm" }, - { 213, "getdents64" }, - { 214, "mmap64" }, - { 215, "stat64" }, - { 216, "lstat64" }, - { 217, "fstat64" }, - { 218, "statvfs64" }, - { 219, "fstatvfs64" }, - { 220, "setrlimit64" }, - { 221, "getrlimit64" }, - { 222, "pread64" }, - { 223, "pwrite64" }, - { 224, "creat64" }, - { 225, "open64" }, - { 226, "rpcsys" }, - { 227, "reserved_227" }, - { 228, "reserved_228" }, - { 229, "reserved_229" }, - { 230, "so_socket" }, - { 231, "so_socketpair" }, - { 232, "bind" }, - { 233, "listen" }, - { 234, "accept" }, - { 235, "connect" }, - { 236, "shutdown" }, - { 237, "recv" }, - { 238, "recvfrom" }, - { 239, "recvmsg" }, - { 240, "send" }, - { 241, "sendmsg" }, - { 242, "sendto" }, - { 243, "getpeername" }, - { 244, "getsockname" }, - { 245, "getsockopt" }, - { 246, "setsockopt" }, - { 247, "sockconfig" }, - { 248, "ntp_gettime" }, - { 249, "ntp_adjtime" }, - { 250, "lwp_mutex_unlock" }, - { 251, "lwp_mutex_trylock" }, - { 252, "lwp_mutex_init" }, - { 253, "cladm" }, - { 254, "lwp_sigtimedwait" }, - { 255, "umount2" } -}; - -SparcSolarisProcess::SparcSolarisProcess(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile) : - Sparc64Process(params, objFile) -{} - -void -SparcSolarisProcess::syscall(ThreadContext *tc) -{ - Sparc64Process::syscall(tc); - syscallDescs.get(tc->readIntReg(1))->doSyscall(tc); -} diff --git a/src/arch/sparc/solaris/process.hh b/src/arch/sparc/solaris/process.hh deleted file mode 100644 index bd1860d85..000000000 --- a/src/arch/sparc/solaris/process.hh +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2003-2004 The Regents of The University of Michigan - * 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. - */ - -#ifndef __SPARC_SOLARIS_PROCESS_HH__ -#define __SPARC_SOLARIS_PROCESS_HH__ - -#include "arch/sparc/solaris/solaris.hh" -#include "arch/sparc/process.hh" -#include "sim/process.hh" -#include "sim/syscall_desc.hh" - -namespace SparcISA { - -/// A process with emulated SPARC/Solaris syscalls. -class SparcSolarisProcess : public Sparc64Process -{ - public: - /// Constructor. - SparcSolarisProcess(const ProcessParams ¶ms, - ::Loader::ObjectFile *objFile); - - /// The target system's hostname. - static const char *hostname; - - void syscall(ThreadContext *tc) override; - - /// Array of syscall descriptors, indexed by call number. - static SyscallDescTable syscallDescs; -}; - - -} // namespace SparcISA -#endif // __SPARC_SOLARIS_PROCESS_HH__ diff --git a/src/arch/sparc/solaris/se_workload.cc b/src/arch/sparc/solaris/se_workload.cc new file mode 100644 index 000000000..9372f15b0 --- /dev/null +++ b/src/arch/sparc/solaris/se_workload.cc @@ -0,0 +1,364 @@ +/* + * 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/sparc/solaris/se_workload.hh" + +#include + +#include "arch/sparc/process.hh" +#include "base/loader/object_file.hh" +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "sim/proxy_ptr.hh" +#include "sim/syscall_desc.hh" +#include "sim/syscall_emul.hh" + +namespace +{ + +class SolarisLoader : public Process::Loader +{ + public: + Process * + load(const ProcessParams ¶ms, ::Loader::ObjectFile *obj) override + { + auto arch = obj->getArch(); + auto opsys = obj->getOpSys(); + + if (arch != ::Loader::SPARC64) + return nullptr; + + if (opsys != ::Loader::Solaris) + return nullptr; + + return new Sparc64Process(params, obj); + } +}; + +SolarisLoader loader; + +} // anonymous namespace + +namespace SparcISA +{ + +EmuSolaris::EmuSolaris(const Params &p) : SEWorkload(p), _params(p) +{} + +void +EmuSolaris::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); + + syscallDescs.get(tc->readIntReg(1))->doSyscall(tc); +} + +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr name) +{ + auto process = tc->getProcessPtr(); + + strcpy(name->sysname, "SunOS"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, process->release.c_str()); + strcpy(name->version, "Generic_118558-21"); + strcpy(name->machine, "sun4u"); + + return 0; +} + + +SyscallDescTable EmuSolaris::syscallDescs = { + { 0, "syscall" }, + { 1, "exit", exitFunc }, + { 2, "fork" }, + { 3, "read", readFunc }, + { 4, "write", writeFunc }, + { 5, "open", openFunc }, + { 6, "close", closeFunc }, + { 7, "wait" }, + { 8, "creat" }, + { 9, "link" }, + { 10, "unlink", unlinkFunc }, + { 11, "exec" }, + { 12, "chdir" }, + { 13, "time" }, + { 14, "mknod" }, + { 15, "chmod", chmodFunc }, + { 16, "chown", chownFunc }, + { 17, "brk", brkFunc }, + { 18, "stat" }, + { 19, "lseek", lseekFunc }, + { 20, "getpid", getpidFunc }, + { 21, "mount" }, + { 22, "umount" }, + { 23, "setuid", ignoreFunc }, + { 24, "getuid", getuidFunc }, + { 25, "stime" }, + { 26, "pcsample" }, + { 27, "alarm" }, + { 28, "fstat", fstatFunc }, + { 29, "pause" }, + { 30, "utime" }, + { 31, "stty" }, + { 32, "gtty" }, + { 33, "access" }, + { 34, "nice" }, + { 35, "statfs" }, + { 36, "sync" }, + { 37, "kill" }, + { 38, "fstatfs" }, + { 39, "pgrpsys" }, + { 40, "xenix" }, + { 41, "dup" }, + { 42, "pipe", pipePseudoFunc }, + { 43, "times" }, + { 44, "profil" }, + { 45, "plock" }, + { 46, "setgid" }, + { 47, "getgid", getgidFunc }, + { 48, "signal" }, + { 49, "msgsys" }, + { 50, "syssun" }, + { 51, "acct" }, + { 52, "shmsys" }, + { 53, "semsys" }, + { 54, "ioctl" }, + { 55, "uadmin" }, + { 56, "RESERVED" }, + { 57, "utssys" }, + { 58, "fdsync" }, + { 59, "execve" }, + { 60, "umask", umaskFunc }, + { 61, "chroot" }, + { 62, "fcntl" }, + { 63, "ulimit" }, + { 64, "reserved_64" }, + { 65, "reserved_65" }, + { 66, "reserved_66" }, + { 67, "reserved_67" }, + { 68, "reserved_68" }, + { 69, "reserved_69" }, + { 70, "tasksys" }, + { 71, "acctctl" }, + { 72, "reserved_72" }, + { 73, "getpagesizes" }, + { 74, "rctlsys" }, + { 75, "issetugid" }, + { 76, "fsat" }, + { 77, "lwp_park" }, + { 78, "sendfilev" }, + { 79, "rmdir" }, + { 80, "mkdir" }, + { 81, "getdents" }, + { 82, "reserved_82" }, + { 83, "reserved_83" }, + { 84, "sysfs" }, + { 85, "getmsg" }, + { 86, "putmsg" }, + { 87, "poll" }, + { 88, "lstat" }, + { 89, "symlink" }, + { 90, "readlink", readlinkFunc }, + { 91, "setgroups" }, + { 92, "getgroups" }, + { 93, "fchmod" }, + { 94, "fchown" }, + { 95, "sigprocmask" }, + { 96, "sigsuspend" }, + { 97, "sigaltstack" }, + { 98, "sigaction" }, + { 99, "sigpending" }, + { 100, "context" }, + { 101, "evsys" }, + { 102, "evtrapret" }, + { 103, "statvfs" }, + { 104, "fstatvfs" }, + { 105, "getloadavg" }, + { 106, "nfssys" }, + { 107, "waitsys" }, + { 108, "sigsendsys" }, + { 109, "hrtsys" }, + { 110, "acancel" }, + { 111, "async" }, + { 112, "priocntlsys" }, + { 113, "pathconf" }, + { 114, "mincore" }, + { 115, "mmap", mmapFunc }, + { 116, "mprotect" }, + { 117, "munmap", munmapFunc }, + { 118, "fpathconf" }, + { 119, "vfork" }, + { 120, "fchdir" }, + { 121, "readv" }, + { 122, "writev" }, + { 123, "xstat" }, + { 124, "lxstat" }, + { 125, "fxstat" }, + { 126, "xmknod" }, + { 127, "clocal" }, + { 128, "setrlimit" }, + { 129, "getrlimit" }, + { 130, "lchown" }, + { 131, "memcntl" }, + { 132, "getpmsg" }, + { 133, "putpmsg" }, + { 134, "rename" }, + { 135, "uname", unameFunc }, + { 136, "setegid" }, + { 137, "sysconfig" }, + { 138, "adjtime" }, + { 139, "systeminfo" }, + { 140, "reserved_140" }, + { 141, "seteuid" }, + { 142, "vtrace" }, + { 143, "fork1" }, + { 144, "sigtimedwait" }, + { 145, "lwp_info" }, + { 146, "yield" }, + { 147, "lwp_sema_wait" }, + { 148, "lwp_sema_post" }, + { 149, "lwp_sema_trywait" }, + { 150, "lwp_detach" }, + { 151, "corectl" }, + { 152, "modctl" }, + { 153, "fchroot" }, + { 154, "utimes" }, + { 155, "vhangup" }, + { 156, "gettimeofday" }, + { 157, "getitimer" }, + { 158, "setitimer" }, + { 159, "lwp_create" }, + { 160, "lwp_exit" }, + { 161, "lwp_suspend" }, + { 162, "lwp_continue" }, + { 163, "lwp_kill" }, + { 164, "lwp_self" }, + { 165, "lwp_setprivate" }, + { 166, "lwp_getprivate" }, + { 167, "lwp_wait" }, + { 168, "lwp_mutex_wakeup" }, + { 169, "lwp_mutex_lock" }, + { 170, "lwp_cond_wait" }, + { 171, "lwp_cond_signal" }, + { 172, "lwp_cond_broadcast" }, + { 173, "pread" }, + { 174, "pwrite" }, + { 175, "llseek" }, + { 176, "inst_sync" }, + { 177, "srmlimitsys" }, + { 178, "kaio" }, + { 179, "cpc" }, + { 180, "lgrpsys_meminfosys" }, + { 181, "rusagesys" }, + { 182, "reserved_182" }, + { 183, "reserved_183" }, + { 184, "tsolsys" }, + { 185, "acl" }, + { 186, "auditsys" }, + { 187, "processor_bind" }, + { 188, "processor_info" }, + { 189, "p_online" }, + { 190, "sigqueue" }, + { 191, "clock_gettime" }, + { 192, "clock_settime" }, + { 193, "clock_getres" }, + { 194, "timer_create" }, + { 195, "timer_delete" }, + { 196, "timer_settime" }, + { 197, "timer_gettime" }, + { 198, "timer_getoverrun" }, + { 199, "nanosleep" }, + { 200, "facl" }, + { 201, "door" }, + { 202, "setreuid" }, + { 203, "setregid" }, + { 204, "install_utrap" }, + { 205, "signotify" }, + { 206, "schedctl" }, + { 207, "pset" }, + { 208, "sparc_utrap_install" }, + { 209, "resolvepath" }, + { 210, "signotifywait" }, + { 211, "lwp_sigredirect" }, + { 212, "lwp_alarm" }, + { 213, "getdents64" }, + { 214, "mmap64" }, + { 215, "stat64" }, + { 216, "lstat64" }, + { 217, "fstat64" }, + { 218, "statvfs64" }, + { 219, "fstatvfs64" }, + { 220, "setrlimit64" }, + { 221, "getrlimit64" }, + { 222, "pread64" }, + { 223, "pwrite64" }, + { 224, "creat64" }, + { 225, "open64" }, + { 226, "rpcsys" }, + { 227, "reserved_227" }, + { 228, "reserved_228" }, + { 229, "reserved_229" }, + { 230, "so_socket" }, + { 231, "so_socketpair" }, + { 232, "bind" }, + { 233, "listen" }, + { 234, "accept" }, + { 235, "connect" }, + { 236, "shutdown" }, + { 237, "recv" }, + { 238, "recvfrom" }, + { 239, "recvmsg" }, + { 240, "send" }, + { 241, "sendmsg" }, + { 242, "sendto" }, + { 243, "getpeername" }, + { 244, "getsockname" }, + { 245, "getsockopt" }, + { 246, "setsockopt" }, + { 247, "sockconfig" }, + { 248, "ntp_gettime" }, + { 249, "ntp_adjtime" }, + { 250, "lwp_mutex_unlock" }, + { 251, "lwp_mutex_trylock" }, + { 252, "lwp_mutex_init" }, + { 253, "cladm" }, + { 254, "lwp_sigtimedwait" }, + { 255, "umount2" } +}; + +} // namespace SparcISA + +SparcISA::EmuSolaris * +SparcEmuSolarisParams::create() const +{ + return new SparcISA::EmuSolaris(*this); +} diff --git a/src/arch/sparc/solaris/se_workload.hh b/src/arch/sparc/solaris/se_workload.hh new file mode 100644 index 000000000..3faf20f94 --- /dev/null +++ b/src/arch/sparc/solaris/se_workload.hh @@ -0,0 +1,62 @@ +/* + * 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_SPARC_SOLARIS_SE_WORKLOAD_HH__ +#define __ARCH_SPARC_SOLARIS_SE_WORKLOAD_HH__ + +#include "arch/sparc/se_workload.hh" +#include "arch/sparc/solaris/solaris.hh" +#include "params/SparcEmuSolaris.hh" +#include "sim/syscall_desc.hh" + +namespace SparcISA +{ + +class EmuSolaris : public SEWorkload +{ + public: + using Params = SparcEmuSolarisParams; + + protected: + const Params &_params; + + /// Array of syscall descriptors, indexed by call number. + static SyscallDescTable syscallDescs; + + public: + const Params ¶ms() const { return _params; } + + EmuSolaris(const Params &p); + + ::Loader::Arch getArch() const override { return ::Loader::SPARC64; } + + void syscall(ThreadContext *tc) override; +}; + +} // namespace SparcISA + +#endif // __ARCH_SPARC_SOLARIS_SE_WORKLOAD_HH__