diff options
author | Gabe Black <gabeblack@google.com> | 2019-11-22 18:05:23 -0800 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2019-12-10 23:58:14 +0000 |
commit | 8bb10463f4a7483bb84d71a293e38c4a172f68fa (patch) | |
tree | 60da19a8b9bc43060daf74cebef728284a524023 | |
parent | 78016fdd9831516ec441d147202dae249c09cb1c (diff) | |
download | gem5-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>
-rw-r--r-- | src/sim/syscall_desc.hh | 60 |
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__ |