diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc index 9f16e85c79..0653c3123a 100644 --- a/src/arch/power/linux/process.cc +++ b/src/arch/power/linux/process.cc @@ -91,7 +91,7 @@ unameFunc(SyscallDesc *desc, int callnum, ThreadContext *tc, Addr utsname) return 0; } -SyscallDescABI PowerLinuxProcess::syscallDescs[] = { +SyscallDescABI PowerLinuxProcess::syscallDescs[] = { /* 0 */ { "syscall" }, /* 1 */ { "exit", exitFunc }, /* 2 */ { "fork" }, diff --git a/src/arch/power/linux/process.hh b/src/arch/power/linux/process.hh index 0db1517785..5ff462fc60 100644 --- a/src/arch/power/linux/process.hh +++ b/src/arch/power/linux/process.hh @@ -51,7 +51,7 @@ class PowerLinuxProcess : public PowerProcess using Process::getSyscallArg; /// Array of syscall descriptors, indexed by call number. - static SyscallDescABI syscallDescs[]; + static SyscallDescABI syscallDescs[]; const int Num_Syscall_Descs; }; diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index 7d8dd34e47..d74563b92e 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -288,3 +288,7 @@ PowerProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret) tc->setIntReg(INTREG_CR, cr); tc->setIntReg(ReturnValueReg, sysret.encodedValue()); } + +const std::vector PowerProcess::SyscallABI::ArgumentRegs = { + 3, 4, 5, 6, 7, 8 +}; diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh index 0df6333505..7f6eede192 100644 --- a/src/arch/power/process.hh +++ b/src/arch/power/process.hh @@ -35,6 +35,7 @@ #include "mem/page_table.hh" #include "sim/process.hh" +#include "sim/syscall_abi.hh" class ObjectFile; @@ -52,7 +53,37 @@ class PowerProcess : public Process using Process::getSyscallArg; void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value) override; + + 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; + + PowerISA::Cr cr = tc->readIntReg(PowerISA::INTREG_CR); + if (ret.successful()) { + cr.cr0.so = 0; + } else { + cr.cr0.so = 1; + } + tc->setIntReg(PowerISA::INTREG_CR, cr); + tc->setIntReg(PowerISA::ReturnValueReg, ret.encodedValue()); + } +}; + +} // namespace GuestABI + #endif // __POWER_PROCESS_HH__