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>
This commit is contained in:
@@ -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__
|
||||
|
||||
Reference in New Issue
Block a user