diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 03fcc87ab0..b3deaecc4b 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -151,7 +151,7 @@ setThreadAreaFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr addr) return 0; } -SyscallDescABI MipsLinuxProcess::syscallDescs[] = { +SyscallDescABI MipsLinuxProcess::syscallDescs[] = { /* 0 */ { "syscall" }, /* 1 */ { "exit", exitFunc }, /* 2 */ { "fork" }, diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh index fa54701e78..239b88b2a5 100644 --- a/src/arch/mips/linux/process.hh +++ b/src/arch/mips/linux/process.hh @@ -52,7 +52,7 @@ class MipsLinuxProcess : public MipsProcess void syscall(ThreadContext *tc, Fault *fault) override; /// Array of syscall descriptors, indexed by call number. - static SyscallDescABI syscallDescs[]; + static SyscallDescABI syscallDescs[]; const int Num_Syscall_Descs; }; diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index b9385337b4..93b64ffa3f 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -211,3 +211,7 @@ MipsProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret) if (sysret.count() > 1) tc->setIntReg(SyscallPseudoReturnReg, sysret.value2()); } + +const std::vector MipsProcess::SyscallABI::ArgumentRegs = { + 4, 5, 6, 7, 8, 9 +}; diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index 8b093d37b2..c153979447 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -34,6 +34,7 @@ #include "mem/page_table.hh" #include "sim/process.hh" +#include "sim/syscall_abi.hh" class ObjectFile; @@ -52,6 +53,39 @@ class MipsProcess : public Process /// Explicitly import the otherwise hidden getSyscallArg using Process::getSyscallArg; void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); + + struct SyscallABI : public GenericSyscallABI64 + { + static const std::vector ArgumentRegs; + }; }; +namespace GuestABI +{ + +template <> +struct Result +{ + static void + store(ThreadContext *tc, const SyscallReturn &ret) + { + if (ret.suppressed() || ret.needsRetry()) + return; + + if (ret.successful()) { + // no error + tc->setIntReg(MipsISA::SyscallSuccessReg, 0); + tc->setIntReg(MipsISA::ReturnValueReg, ret.returnValue()); + } else { + // got an error, return details + tc->setIntReg(MipsISA::SyscallSuccessReg, (uint32_t)(-1)); + tc->setIntReg(MipsISA::ReturnValueReg, ret.errnoValue()); + } + if (ret.count() > 1) + tc->setIntReg(MipsISA::SyscallPseudoReturnReg, ret.value2()); + } +}; + +} // namespace GuestABI + #endif // __MIPS_PROCESS_HH__