summaryrefslogtreecommitdiff
path: root/src/arch/alpha/process.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-02-27 09:22:14 -0800
committerGabe Black <gblack@eecs.umich.edu>2009-02-27 09:22:14 -0800
commit9a000c51736d97c1109be296ea7d1fd41d84debb (patch)
tree9fbc6648a69d4f6156c4259d7f1e32bd7732405e /src/arch/alpha/process.cc
parent60aab03e854c0d955127d12c63f4c99a36d19d80 (diff)
downloadgem5-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.cc40
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());
+ }
+}