sparc: Implement an SE workload for Linux and Solaris.
authorGabe Black <gabe.black@gmail.com>
Wed, 21 Oct 2020 00:36:57 +0000 (17:36 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 27 Oct 2020 09:17:46 +0000 (09:17 +0000)
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 <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
16 files changed:
src/arch/sparc/SConscript
src/arch/sparc/SparcSeWorkload.py [new file with mode: 0644]
src/arch/sparc/faults.cc
src/arch/sparc/linux/process.cc [deleted file]
src/arch/sparc/linux/process.hh [deleted file]
src/arch/sparc/linux/se_workload.cc [new file with mode: 0644]
src/arch/sparc/linux/se_workload.hh [new file with mode: 0644]
src/arch/sparc/linux/syscalls.cc
src/arch/sparc/process.cc
src/arch/sparc/process.hh
src/arch/sparc/se_workload.cc [new file with mode: 0644]
src/arch/sparc/se_workload.hh [new file with mode: 0644]
src/arch/sparc/solaris/process.cc [deleted file]
src/arch/sparc/solaris/process.hh [deleted file]
src/arch/sparc/solaris/se_workload.cc [new file with mode: 0644]
src/arch/sparc/solaris/se_workload.hh [new file with mode: 0644]

index 4c855ba4d4ca2b92b018fa1e55e7ca001f23f617..7ba6d10b044a4253f77efc27feee2391321e1b83 100644 (file)
@@ -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 (file)
index 0000000..03d4b73
--- /dev/null
@@ -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'
index 34a0d52b24b7b474bdc058a870e796a0ffd114e7..33ba921db69f790915c650685e88547222289001 100644 (file)
@@ -30,8 +30,8 @@
 
 #include <algorithm>
 
-#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<SparcProcess *>(p);
     assert(sp);
 
-    sp->handleTrap(_n, tc);
+    auto *workload = dynamic_cast<SEWorkload *>(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 (file)
index 37205c7..0000000
+++ /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 &params, ::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 &params,
-                                         ::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 &params,
-                                         ::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 (file)
index c1ade86..0000000
+++ /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<Sparc64Process::SyscallABI> syscallDescs;
-
-    /// 32 bit compatibility syscall descriptors, indexed by call number.
-    static SyscallDescTable<Sparc32Process::SyscallABI> syscall32Descs;
-};
-
-/// A process with emulated SPARC/Linux syscalls.
-class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32Process
-{
-  public:
-    /// Constructor.
-    Sparc32LinuxProcess(const ProcessParams &params,
-                        ::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 &params,
-                        ::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 (file)
index 0000000..7b652ff
--- /dev/null
@@ -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 <sys/syscall.h>
+
+#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 &params, ::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 (file)
index 0000000..a5022d6
--- /dev/null
@@ -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<SEWorkload::SyscallABI64> syscallDescs;
+
+    /// 32 bit compatibility syscall descriptors, indexed by call number.
+    static SyscallDescTable<SEWorkload::SyscallABI32> syscall32Descs;
+
+    void syscall64(ThreadContext *tc);
+    void syscall32(ThreadContext *tc);
+
+  public:
+    const Params &params() 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__
index 304f2cfdb6760c7151bbe50dd64691e786157aea..a00f60e599e6c452041c4c5dc733462e9a4c2838 100644 (file)
  * 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<Linux::utsname> 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<Sparc32Process::SyscallABI>
-    SparcLinuxProcess::syscall32Descs = {
+SyscallDescTable<SEWorkload::SyscallABI32> EmuLinux::syscall32Descs = {
     {   0, "restart_syscall" },
     {   1, "exit", exitFunc }, // 32 bit
     {   2, "fork" },
@@ -382,8 +382,7 @@ SyscallDescTable<Sparc32Process::SyscallABI>
     { 299, "unshare" }
 };
 
-SyscallDescTable<Sparc64Process::SyscallABI>
-    SparcLinuxProcess::syscallDescs = {
+SyscallDescTable<SEWorkload::SyscallABI64> EmuLinux::syscallDescs = {
     {  0, "restart_syscall" },
     {  1, "exit", exitFunc },
     {  2, "fork" },
index 8f3509f8a90bdd3ae8a022c9b9d237cea232cf94..b292c86a8d40847c6f5fe7116abcea3e5bc36f3a 100644 (file)
 using namespace std;
 using namespace SparcISA;
 
-const std::vector<int> SparcProcess::SyscallABI::ArgumentRegs = {
-    INTREG_O0, INTREG_O1, INTREG_O2, INTREG_O3, INTREG_O4, INTREG_O5
-};
-
 SparcProcess::SparcProcess(const ProcessParams &params,
                            ::Loader::ObjectFile *objFile, Addr _StackBias)
     : Process(params,
@@ -65,47 +61,6 @@ SparcProcess::SparcProcess(const ProcessParams &params,
     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 *)&regVal, 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 *)&regVal, 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);
-}
index 593854a0d9b8194fb11ad6d71829a9d85682c8c7..4d3ebfe4bac1b2403cc41fe86f877ab2642a9848 100644 (file)
 #include <vector>
 
 #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<int> ArgumentRegs;
-    };
-};
-
-namespace GuestABI
-{
-
-template <typename ABI>
-struct Result<ABI, SyscallReturn,
-    typename std::enable_if_t<std::is_base_of<
-        SparcProcess::SyscallABI, ABI>::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 &params, ::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 <typename Arg>
-struct Argument<Sparc32Process::SyscallABI, Arg,
-    typename std::enable_if_t<Sparc32Process::SyscallABI::IsWide<Arg>::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 &params, ::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 (file)
index 0000000..19a4e2b
--- /dev/null
@@ -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<int> SEWorkload::BaseSyscallABI::ArgumentRegs = {
+    INTREG_O0, INTREG_O1, INTREG_O2, INTREG_O3, INTREG_O4, INTREG_O5
+};
+
+bool
+SEWorkload::is64(ThreadContext *tc)
+{
+    return dynamic_cast<Sparc64Process *>(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<uint64_t>(tc->readIntReg(index));
+                memcpy(bytes, &regVal, reg_bytes);
+            } else {
+                uint32_t regVal = htobe<uint32_t>(tc->readIntReg(index));
+                memcpy(bytes, &regVal, 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 (file)
index 0000000..e39261d
--- /dev/null
@@ -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 <vector>
+
+#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<int> ArgumentRegs;
+    };
+
+    struct SyscallABI32 : public GenericSyscallABI32,
+                          public BaseSyscallABI
+    {};
+
+    struct SyscallABI64 : public GenericSyscallABI64,
+                          public BaseSyscallABI
+    {};
+};
+
+} // namespace SparcISA
+
+namespace GuestABI
+{
+
+template <typename ABI>
+struct Result<ABI, SyscallReturn,
+    typename std::enable_if_t<std::is_base_of<
+        SparcISA::SEWorkload::BaseSyscallABI, ABI>::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 <typename Arg>
+struct Argument<SparcISA::SEWorkload::SyscallABI32, Arg,
+    typename std::enable_if_t<
+        SparcISA::SEWorkload::SyscallABI32::IsWide<Arg>::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 (file)
index 442e984..0000000
+++ /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 &params, ::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<Solaris::utsname> 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<Sparc64Process::SyscallABI>
-    SparcSolarisProcess::syscallDescs = {
-    { 0, "syscall" },
-    { 1, "exit", exitFunc },
-    { 2, "fork" },
-    { 3, "read", readFunc<SparcSolaris> },
-    { 4, "write", writeFunc<SparcSolaris> },
-    { 5, "open", openFunc<SparcSolaris> },
-    { 6, "close", closeFunc },
-    { 7, "wait" },
-    { 8, "creat" },
-    { 9, "link" },
-    { 10, "unlink", unlinkFunc },
-    { 11, "exec" },
-    { 12, "chdir" },
-    { 13, "time" },
-    { 14, "mknod" },
-    { 15, "chmod", chmodFunc<Solaris> },
-    { 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<SparcSolaris> },
-    { 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<SparcSolaris> },
-    { 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 &params,
-                                         ::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 (file)
index bd1860d..0000000
+++ /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 &params,
-                        ::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<Sparc64Process::SyscallABI> 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 (file)
index 0000000..9372f15
--- /dev/null
@@ -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 <sys/syscall.h>
+
+#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 &params, ::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<Solaris::utsname> 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<SEWorkload::SyscallABI64> EmuSolaris::syscallDescs = {
+    { 0, "syscall" },
+    { 1, "exit", exitFunc },
+    { 2, "fork" },
+    { 3, "read", readFunc<SparcSolaris> },
+    { 4, "write", writeFunc<SparcSolaris> },
+    { 5, "open", openFunc<SparcSolaris> },
+    { 6, "close", closeFunc },
+    { 7, "wait" },
+    { 8, "creat" },
+    { 9, "link" },
+    { 10, "unlink", unlinkFunc },
+    { 11, "exec" },
+    { 12, "chdir" },
+    { 13, "time" },
+    { 14, "mknod" },
+    { 15, "chmod", chmodFunc<Solaris> },
+    { 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<SparcSolaris> },
+    { 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<SparcSolaris> },
+    { 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 (file)
index 0000000..3faf20f
--- /dev/null
@@ -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<SEWorkload::SyscallABI64> syscallDescs;
+
+  public:
+    const Params &params() 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__