From 8bb10463f4a7483bb84d71a293e38c4a172f68fa Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 22 Nov 2019 18:05:23 -0800 Subject: 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 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/sim/syscall_desc.hh | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'src/sim') 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 #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 +class SyscallDescABI : public SyscallDesc +{ + private: + // Aliases to make the code below a little more concise. + template + using SyscallABIExecutor = + std::function; + + template + 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 + static inline SyscallExecutor + buildExecutor(SyscallABIExecutor 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(tc, + std::function( + partial)); + }; + } + + + public: + // Constructors which plumb in buildExecutor. + template + SyscallDescABI(const char *name, SyscallABIExecutor target) : + SyscallDesc(name, buildExecutor(target)) + {} + + template + SyscallDescABI(const char *name, SyscallABIExecutorPtr target) : + SyscallDescABI(name, SyscallABIExecutor(target)) + {} + + using SyscallDesc::SyscallDesc; +}; + #endif // __SIM_SYSCALL_DESC_HH__ -- cgit v1.2.3