summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2019-11-22 18:05:23 -0800
committerGabe Black <gabeblack@google.com>2019-12-10 23:58:14 +0000
commit8bb10463f4a7483bb84d71a293e38c4a172f68fa (patch)
tree60da19a8b9bc43060daf74cebef728284a524023 /src/sim
parent78016fdd9831516ec441d147202dae249c09cb1c (diff)
downloadgem5-8bb10463f4a7483bb84d71a293e38c4a172f68fa.tar.xz
sim: Add a wrapper/subclass for SyscallDesc which uses GuestABI.
This will let system call implementations take arguments naturally, and centrally defined, potentially complex, and ISA/context specific mechanisms will automatically gather the arguments and store any result. Jira Issue: https://gem5.atlassian.net/browse/GEM5-187 Change-Id: I68d265e0bab5de372ba975e4c7e9bb2d968c80af Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23172 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/syscall_desc.hh60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/sim/syscall_desc.hh b/src/sim/syscall_desc.hh
index 9a2859148..e5adf8bd5 100644
--- a/src/sim/syscall_desc.hh
+++ b/src/sim/syscall_desc.hh
@@ -50,6 +50,7 @@
#include <string>
#include "base/types.hh"
+#include "sim/guest_abi.hh"
#include "sim/syscall_return.hh"
class Process;
@@ -94,4 +95,63 @@ class SyscallDesc {
SyscallExecutor executor;
};
+/*
+ * This SyscallDesc subclass template adapts a given syscall implementation so
+ * that some arguments can come from the simulator (desc, num and tc) while the
+ * rest can come from the guest using the GuestABI mechanism.
+ */
+template <typename ABI>
+class SyscallDescABI : public SyscallDesc
+{
+ private:
+ // Aliases to make the code below a little more concise.
+ template <typename ...Args>
+ using SyscallABIExecutor =
+ std::function<SyscallReturn(SyscallDesc *, int,
+ ThreadContext *, Args...)>;
+
+ template <typename ...Args>
+ using SyscallABIExecutorPtr =
+ SyscallReturn (*)(SyscallDesc *, int, ThreadContext *, Args...);
+
+
+ // Wrap an executor with guest arguments with a normal executor that gets
+ // those additional arguments from the guest context.
+ template <typename ...Args>
+ static inline SyscallExecutor
+ buildExecutor(SyscallABIExecutor<Args...> target)
+ {
+ return [target](SyscallDesc *desc, int num,
+ ThreadContext *tc) -> SyscallReturn {
+ // Create a partial function which will stick desc and num to the
+ // front of the parameter list.
+ auto partial = [target,desc,num](
+ ThreadContext *tc, Args... args) -> SyscallReturn {
+ return target(desc, num, tc, args...);
+ };
+
+ // Use invokeSimcall to gather the other arguments based on the
+ // given ABI and pass them to the syscall implementation.
+ return invokeSimcall<ABI, SyscallReturn, Args...>(tc,
+ std::function<SyscallReturn(ThreadContext *, Args...)>(
+ partial));
+ };
+ }
+
+
+ public:
+ // Constructors which plumb in buildExecutor.
+ template <typename ...Args>
+ SyscallDescABI(const char *name, SyscallABIExecutor<Args...> target) :
+ SyscallDesc(name, buildExecutor<Args...>(target))
+ {}
+
+ template <typename ...Args>
+ SyscallDescABI(const char *name, SyscallABIExecutorPtr<Args...> target) :
+ SyscallDescABI(name, SyscallABIExecutor<Args...>(target))
+ {}
+
+ using SyscallDesc::SyscallDesc;
+};
+
#endif // __SIM_SYSCALL_DESC_HH__