diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-02-27 09:22:14 -0800 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-02-27 09:22:14 -0800 |
commit | 9a000c51736d97c1109be296ea7d1fd41d84debb (patch) | |
tree | 9fbc6648a69d4f6156c4259d7f1e32bd7732405e /src/arch/alpha/process.cc | |
parent | 60aab03e854c0d955127d12c63f4c99a36d19d80 (diff) | |
download | gem5-9a000c51736d97c1109be296ea7d1fd41d84debb.tar.xz |
Processes: Make getting and setting system call arguments part of a process object.
Diffstat (limited to 'src/arch/alpha/process.cc')
-rw-r--r-- | src/arch/alpha/process.cc | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 004be1ec0..9c6e62815 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -42,6 +42,8 @@ using namespace AlphaISA; using namespace std; +static const int SyscallSuccessReg = 19; + AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile) : LiveProcess(params, objFile) @@ -156,12 +158,10 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize) (uint8_t*)&(auxv[x].a_val), intSize); } - assert(NumArgumentRegs >= 2); - ThreadContext *tc = system->getThreadContext(contextIds[0]); - tc->setIntReg(ArgumentReg[0], argc); - tc->setIntReg(ArgumentReg[1], argv_array_base); + setSyscallArg(tc, 0, argc); + setSyscallArg(tc, 1, argv_array_base); tc->setIntReg(StackPointerReg, stack_min); Addr prog_entry = objFile->entryPoint(); @@ -195,3 +195,35 @@ AlphaLiveProcess::startup() tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57); } +AlphaISA::IntReg +AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 6); + return tc->readIntReg(FirstArgumentReg + i); +} + +void +AlphaLiveProcess::setSyscallArg(ThreadContext *tc, + int i, AlphaISA::IntReg val) +{ + assert(i < 6); + tc->setIntReg(FirstArgumentReg + i, val); +} + +void +AlphaLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + // check for error condition. Alpha syscall convention is to + // indicate success/failure in reg a3 (r19) and put the + // return value itself in the standard return value reg (v0). + if (return_value.successful()) { + // no error + tc->setIntReg(SyscallSuccessReg, 0); + tc->setIntReg(ReturnValueReg, return_value.value()); + } else { + // got an error, return details + tc->setIntReg(SyscallSuccessReg, (IntReg)-1); + tc->setIntReg(ReturnValueReg, -return_value.value()); + } +} |