power: Implement an SE workload for Linux.
Change-Id: Ie242698b7f9e6ffffd4abdcbb483ee81d64802d9
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/34157
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Sandipan Das <sandipan@linux.ibm.com>
diff --git a/src/arch/power/PowerSeWorkload.py b/src/arch/power/PowerSeWorkload.py
new file mode 100644
index 0000000..2d3d3cb
--- /dev/null
+++ b/src/arch/power/PowerSeWorkload.py
@@ -0,0 +1,44 @@
+# Copyright 2020 Google Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from m5.params import *
+
+from m5.objects.Workload import SEWorkload
+
+class PowerSEWorkload(SEWorkload):
+ type = 'PowerSEWorkload'
+ cxx_header = "arch/power/se_workload.hh"
+ cxx_class = 'PowerISA::SEWorkload'
+ abstract = True
+
+class PowerEmuLinux(PowerSEWorkload):
+ type = 'PowerEmuLinux'
+ cxx_header = "arch/power/linux/se_workload.hh"
+ cxx_class = 'PowerISA::EmuLinux'
+
+ @classmethod
+ def _is_compatible_with(cls, obj):
+ return obj.get_arch() == 'power' and \
+ obj.get_op_sys() in ('linux', 'unknown')
diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript
index 1df33d3..1ae43f2 100644
--- a/src/arch/power/SConscript
+++ b/src/arch/power/SConscript
@@ -42,18 +42,20 @@
Source('insts/static_inst.cc')
Source('interrupts.cc')
Source('linux/linux.cc')
- Source('linux/process.cc')
+ Source('linux/se_workload.cc')
Source('mmu.cc')
Source('isa.cc')
Source('pagetable.cc')
Source('process.cc')
Source('remote_gdb.cc')
+ Source('se_workload.cc')
Source('tlb.cc')
Source('utility.cc')
SimObject('PowerInterrupts.py')
SimObject('PowerISA.py')
SimObject('PowerMMU.py')
+ SimObject('PowerSeWorkload.py')
SimObject('PowerTLB.py')
DebugFlag('Power')
diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/se_workload.cc
similarity index 90%
rename from src/arch/power/linux/process.cc
rename to src/arch/power/linux/se_workload.cc
index 75fff89..869b140 100644
--- a/src/arch/power/linux/process.cc
+++ b/src/arch/power/linux/se_workload.cc
@@ -1,8 +1,5 @@
/*
- * Copyright (c) 2003-2005 The Regents of The University of Michigan
- * Copyright (c) 2007-2008 The Florida State University
- * Copyright (c) 2009 The University of Edinburgh
- * All rights reserved.
+ * Copyright 2020 Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,35 +25,29 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "arch/power/linux/process.hh"
+#include "arch/power/linux/se_workload.hh"
-#include "arch/power/isa_traits.hh"
-#include "arch/power/linux/linux.hh"
+#include <sys/syscall.h>
+
+#include "arch/power/process.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"
-#include "sim/system.hh"
-
-using namespace std;
-using namespace PowerISA;
namespace
{
-class PowerLinuxObjectFileLoader : public Process::Loader
+class LinuxLoader : public Process::Loader
{
public:
Process *
- load(const ProcessParams ¶ms, ::Loader::ObjectFile *obj_file) override
+ load(const ProcessParams ¶ms, ::Loader::ObjectFile *obj) override
{
- if (obj_file->getArch() != ::Loader::Power)
+ if (obj->getArch() != ::Loader::Power)
return nullptr;
- auto opsys = obj_file->getOpSys();
+ auto opsys = obj->getOpSys();
if (opsys == ::Loader::UnknownOpSys) {
warn("Unknown operating system; assuming Linux.");
@@ -66,14 +57,28 @@
if (opsys != ::Loader::Linux)
return nullptr;
- return new PowerLinuxProcess(params, obj_file);
+ return new PowerProcess(params, obj);
}
};
-PowerLinuxObjectFileLoader loader;
+LinuxLoader loader;
} // anonymous namespace
+namespace PowerISA
+{
+
+void
+EmuLinux::syscall(ThreadContext *tc)
+{
+ Process *process = tc->getProcessPtr();
+ // Call the syscall function in the base Process class to update stats.
+ // This will move into the base SEWorkload function at some point.
+ process->Process::syscall(tc);
+
+ syscallDescs.get(tc->readIntReg(0))->doSyscall(tc);
+}
+
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<Linux::utsname> name)
@@ -89,7 +94,7 @@
return 0;
}
-SyscallDescTable<PowerProcess::SyscallABI> PowerLinuxProcess::syscallDescs = {
+SyscallDescTable<PowerISA::SEWorkload::SyscallABI> EmuLinux::syscallDescs = {
{ 0, "syscall" },
{ 1, "exit", exitFunc },
{ 2, "fork" },
@@ -439,20 +444,10 @@
{ 346, "epoll_pwait" },
};
-PowerLinuxProcess::PowerLinuxProcess(const ProcessParams ¶ms,
- ::Loader::ObjectFile *objFile) :
- PowerProcess(params, objFile)
-{}
+} // namespace PowerISA
-void
-PowerLinuxProcess::initState()
+PowerISA::EmuLinux *
+PowerEmuLinuxParams::create() const
{
- PowerProcess::initState();
-}
-
-void
-PowerLinuxProcess::syscall(ThreadContext *tc)
-{
- PowerProcess::syscall(tc);
- syscallDescs.get(tc->readIntReg(0))->doSyscall(tc);
+ return new PowerISA::EmuLinux(*this);
}
diff --git a/src/arch/power/linux/process.hh b/src/arch/power/linux/se_workload.hh
similarity index 72%
rename from src/arch/power/linux/process.hh
rename to src/arch/power/linux/se_workload.hh
index eca3da1d..c306b99 100644
--- a/src/arch/power/linux/process.hh
+++ b/src/arch/power/linux/se_workload.hh
@@ -1,7 +1,5 @@
/*
- * Copyright (c) 2007-2008 The Florida State University
- * Copyright (c) 2009 The University of Edinburgh
- * All rights reserved.
+ * Copyright 2020 Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -27,26 +25,36 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __POWER_LINUX_PROCESS_HH__
-#define __POWER_LINUX_PROCESS_HH__
+#ifndef __ARCH_POWER_LINUX_SE_WORKLOAD_HH__
+#define __ARCH_POWER_LINUX_SE_WORKLOAD_HH__
-#include "arch/power/process.hh"
-
+#include "arch/power/linux/linux.hh"
+#include "arch/power/se_workload.hh"
+#include "params/PowerEmuLinux.hh"
#include "sim/syscall_desc.hh"
-/// A process with emulated PPC/Linux syscalls.
-class PowerLinuxProcess : public PowerProcess
+namespace PowerISA
+{
+
+class EmuLinux : public SEWorkload
{
public:
- PowerLinuxProcess(const ProcessParams ¶ms,
- ::Loader::ObjectFile *objFile);
+ using Params = PowerEmuLinuxParams;
- void initState() override;
-
- void syscall(ThreadContext *tc) override;
+ protected:
+ const Params &_params;
/// Syscall descriptors, indexed by call number.
- static SyscallDescTable<SyscallABI> syscallDescs;
+ static SyscallDescTable<SEWorkload::SyscallABI> syscallDescs;
+
+ public:
+ const Params ¶ms() const { return _params; }
+
+ EmuLinux(const Params &p) : SEWorkload(p), _params(p) {}
+
+ void syscall(ThreadContext *tc) override;
};
-#endif // __POWER_LINUX_PROCESS_HH__
+} // namespace PowerISA
+
+#endif // __ARCH_POWER_LINUX_SE_WORKLOAD_HH__
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index 1b7f58f..9e8d2ad 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -277,7 +277,3 @@
//Align the "stack_min" to a page boundary.
memState->setStackMin(roundDown(stack_min, pageSize));
}
-
-const std::vector<int> PowerProcess::SyscallABI::ArgumentRegs = {
- 3, 4, 5, 6, 7, 8
-};
diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh
index 1d64176..5e5a503 100644
--- a/src/arch/power/process.hh
+++ b/src/arch/power/process.hh
@@ -30,12 +30,7 @@
#ifndef __POWER_PROCESS_HH__
#define __POWER_PROCESS_HH__
-#include <string>
-#include <vector>
-
-#include "mem/page_table.hh"
#include "sim/process.hh"
-#include "sim/syscall_abi.hh"
namespace Loader
{
@@ -45,43 +40,13 @@
class PowerProcess : public Process
{
protected:
- PowerProcess(const ProcessParams ¶ms, ::Loader::ObjectFile *objFile);
-
void initState() override;
public:
+ PowerProcess(const ProcessParams ¶ms, ::Loader::ObjectFile *objFile);
+
void argsInit(int intSize, int pageSize);
-
- struct SyscallABI : public GenericSyscallABI64
- {
- static const std::vector<int> ArgumentRegs;
- };
};
-namespace GuestABI
-{
-
-template <>
-struct Result<PowerProcess::SyscallABI, SyscallReturn>
-{
- static void
- store(ThreadContext *tc, const SyscallReturn &ret)
- {
- if (ret.suppressed() || ret.needsRetry())
- return;
-
- PowerISA::Cr cr = tc->readIntReg(PowerISA::INTREG_CR);
- if (ret.successful()) {
- cr.cr0.so = 0;
- } else {
- cr.cr0.so = 1;
- }
- tc->setIntReg(PowerISA::INTREG_CR, cr);
- tc->setIntReg(PowerISA::ReturnValueReg, ret.encodedValue());
- }
-};
-
-} // namespace GuestABI
-
#endif // __POWER_PROCESS_HH__
diff --git a/src/arch/power/linux/process.hh b/src/arch/power/se_workload.cc
similarity index 67%
copy from src/arch/power/linux/process.hh
copy to src/arch/power/se_workload.cc
index eca3da1d..31ff243 100644
--- a/src/arch/power/linux/process.hh
+++ b/src/arch/power/se_workload.cc
@@ -1,7 +1,5 @@
/*
- * Copyright (c) 2007-2008 The Florida State University
- * Copyright (c) 2009 The University of Edinburgh
- * All rights reserved.
+ * Copyright 2020 Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -27,26 +25,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __POWER_LINUX_PROCESS_HH__
-#define __POWER_LINUX_PROCESS_HH__
+#include "arch/power/se_workload.hh"
-#include "arch/power/process.hh"
-
-#include "sim/syscall_desc.hh"
-
-/// A process with emulated PPC/Linux syscalls.
-class PowerLinuxProcess : public PowerProcess
+namespace PowerISA
{
- public:
- PowerLinuxProcess(const ProcessParams ¶ms,
- ::Loader::ObjectFile *objFile);
- void initState() override;
-
- void syscall(ThreadContext *tc) override;
-
- /// Syscall descriptors, indexed by call number.
- static SyscallDescTable<SyscallABI> syscallDescs;
+const std::vector<int> SEWorkload::SyscallABI::ArgumentRegs = {
+ 3, 4, 5, 6, 7, 8
};
-#endif // __POWER_LINUX_PROCESS_HH__
+} // namespace PowerISA
diff --git a/src/arch/power/se_workload.hh b/src/arch/power/se_workload.hh
new file mode 100644
index 0000000..5f3630c
--- /dev/null
+++ b/src/arch/power/se_workload.hh
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ARCH_POWER_SE_WORKLOAD_HH__
+#define __ARCH_POWER_SE_WORKLOAD_HH__
+
+#include "arch/power/registers.hh"
+#include "params/PowerSEWorkload.hh"
+#include "sim/se_workload.hh"
+#include "sim/syscall_abi.hh"
+#include "sim/syscall_desc.hh"
+
+namespace PowerISA
+{
+
+class SEWorkload : public ::SEWorkload
+{
+ public:
+ using Params = PowerSEWorkloadParams;
+
+ protected:
+ const Params &_params;
+
+ public:
+ const Params ¶ms() const { return _params; }
+
+ SEWorkload(const Params &p) : ::SEWorkload(p), _params(p) {}
+
+ ::Loader::Arch getArch() const override { return ::Loader::Power; }
+
+ struct SyscallABI : public GenericSyscallABI64
+ {
+ static const std::vector<int> ArgumentRegs;
+ };
+};
+
+} // namespace PowerISA
+
+namespace GuestABI
+{
+
+template <>
+struct Result<PowerISA::SEWorkload::SyscallABI, SyscallReturn>
+{
+ static void
+ store(ThreadContext *tc, const SyscallReturn &ret)
+ {
+ if (ret.suppressed() || ret.needsRetry())
+ return;
+
+ PowerISA::Cr cr = tc->readIntReg(PowerISA::INTREG_CR);
+ if (ret.successful()) {
+ cr.cr0.so = 0;
+ } else {
+ cr.cr0.so = 1;
+ }
+ tc->setIntReg(PowerISA::INTREG_CR, cr);
+ tc->setIntReg(PowerISA::ReturnValueReg, ret.encodedValue());
+ }
+};
+
+} // namespace GuestABI
+
+#endif // __ARCH_POWER_SE_WORKLOAD_HH__