summaryrefslogtreecommitdiff
path: root/src/arch/sparc/process.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc/process.cc')
-rw-r--r--src/arch/sparc/process.cc145
1 files changed, 106 insertions, 39 deletions
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 6e490e05e..b2b539816 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -46,6 +46,9 @@
using namespace std;
using namespace SparcISA;
+static const int FirstArgumentReg = 8;
+static const int ReturnValueReg = 8;
+
SparcLiveProcess::SparcLiveProcess(LiveProcessParams * params,
ObjectFile *objFile, Addr _StackBias)
@@ -112,44 +115,45 @@ SparcLiveProcess::startup()
{
Process::startup();
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//From the SPARC ABI
//Setup default FP state
- threadContexts[0]->setMiscRegNoEffect(MISCREG_FSR, 0);
+ tc->setMiscRegNoEffect(MISCREG_FSR, 0);
- threadContexts[0]->setMiscRegNoEffect(MISCREG_TICK, 0);
+ tc->setMiscRegNoEffect(MISCREG_TICK, 0);
/*
* Register window management registers
*/
//No windows contain info from other programs
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
- threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0);
+ //tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
+ tc->setIntReg(NumIntArchRegs + 6, 0);
//There are no windows to pop
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
- threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0);
+ //tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
+ tc->setIntReg(NumIntArchRegs + 4, 0);
//All windows are available to save into
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
- threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2);
+ //tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
+ tc->setIntReg(NumIntArchRegs + 3, NWindows - 2);
//All windows are "clean"
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
- threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows);
+ //tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
+ tc->setIntReg(NumIntArchRegs + 5, NWindows);
//Start with register window 0
- threadContexts[0]->setMiscRegNoEffect(MISCREG_CWP, 0);
+ tc->setMiscRegNoEffect(MISCREG_CWP, 0);
//Always use spill and fill traps 0
- //threadContexts[0]->setMiscRegNoEffect(MISCREG_WSTATE, 0);
- threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0);
+ //tc->setMiscRegNoEffect(MISCREG_WSTATE, 0);
+ tc->setIntReg(NumIntArchRegs + 7, 0);
//Set the trap level to 0
- threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0);
+ tc->setMiscRegNoEffect(MISCREG_TL, 0);
//Set the ASI register to something fixed
- threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
+ tc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
/*
* T1 specific registers
*/
//Turn on the icache, dcache, dtb translation, and itb translation.
- threadContexts[0]->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);
+ tc->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);
}
void
@@ -160,8 +164,9 @@ Sparc32LiveProcess::startup()
SparcLiveProcess::startup();
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//The process runs in user mode with 32 bit addresses
- threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x0a);
+ tc->setMiscReg(MISCREG_PSTATE, 0x0a);
argsInit(32 / 8, VMPageSize);
}
@@ -174,8 +179,9 @@ Sparc64LiveProcess::startup()
SparcLiveProcess::startup();
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//The process runs in user mode
- threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x02);
+ tc->setMiscReg(MISCREG_PSTATE, 0x02);
argsInit(sizeof(IntReg), VMPageSize);
}
@@ -186,7 +192,7 @@ SparcLiveProcess::argsInit(int pageSize)
{
int intSize = sizeof(IntType);
- typedef M5_auxv_t<IntType> auxv_t;
+ typedef AuxVector<IntType> auxv_t;
std::vector<auxv_t> auxv;
@@ -335,18 +341,18 @@ SparcLiveProcess::argsInit(int pageSize)
IntType window_save_base = argc_base - window_save_size;
#endif
- DPRINTF(Sparc, "The addresses of items on the initial stack:\n");
- DPRINTF(Sparc, "%#x - sentry NULL\n", sentry_base);
- DPRINTF(Sparc, "filename = %s\n", filename);
- DPRINTF(Sparc, "%#x - file name\n", file_name_base);
- DPRINTF(Sparc, "%#x - env data\n", env_data_base);
- DPRINTF(Sparc, "%#x - arg data\n", arg_data_base);
- DPRINTF(Sparc, "%#x - auxv array\n", auxv_array_base);
- DPRINTF(Sparc, "%#x - envp array\n", envp_array_base);
- DPRINTF(Sparc, "%#x - argv array\n", argv_array_base);
- DPRINTF(Sparc, "%#x - argc \n", argc_base);
- DPRINTF(Sparc, "%#x - window save\n", window_save_base);
- DPRINTF(Sparc, "%#x - stack min\n", stack_min);
+ DPRINTF(Stack, "The addresses of items on the initial stack:\n");
+ DPRINTF(Stack, "%#x - sentry NULL\n", sentry_base);
+ DPRINTF(Stack, "filename = %s\n", filename);
+ DPRINTF(Stack, "%#x - file name\n", file_name_base);
+ DPRINTF(Stack, "%#x - env data\n", env_data_base);
+ DPRINTF(Stack, "%#x - arg data\n", arg_data_base);
+ DPRINTF(Stack, "%#x - auxv array\n", auxv_array_base);
+ DPRINTF(Stack, "%#x - envp array\n", envp_array_base);
+ DPRINTF(Stack, "%#x - argv array\n", argv_array_base);
+ DPRINTF(Stack, "%#x - argc \n", argc_base);
+ DPRINTF(Stack, "%#x - window save\n", window_save_base);
+ DPRINTF(Stack, "%#x - stack min\n", stack_min);
assert(window_save_base == stack_min);
@@ -354,7 +360,7 @@ SparcLiveProcess::argsInit(int pageSize)
// figure out argc
IntType argc = argv.size();
- IntType guestArgc = TheISA::htog(argc);
+ IntType guestArgc = SparcISA::htog(argc);
//Write out the sentry void *
uint64_t sentry_NULL = 0;
@@ -391,20 +397,21 @@ SparcLiveProcess::argsInit(int pageSize)
fillStart = stack_base;
spillStart = fillStart + sizeof(MachInst) * numFillInsts;
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
//Set up the thread context to start running the process
//assert(NumArgumentRegs >= 2);
- //threadContexts[0]->setIntReg(ArgumentReg[0], argc);
- //threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
- threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias);
+ //tc->setIntReg(ArgumentReg[0], argc);
+ //tc->setIntReg(ArgumentReg[1], argv_array_base);
+ tc->setIntReg(StackPointerReg, stack_min - StackBias);
// %g1 is a pointer to a function that should be run at exit. Since we
// don't have anything like that, it should be set to 0.
- threadContexts[0]->setIntReg(1, 0);
+ tc->setIntReg(1, 0);
Addr prog_entry = objFile->entryPoint();
- threadContexts[0]->setPC(prog_entry);
- threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
- threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
+ tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
//Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);
@@ -505,3 +512,63 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc)
tc->setIntReg(NumIntArchRegs + 4, Canrestore);
tc->setMiscReg(MISCREG_CWP, origCWP);
}
+
+IntReg
+Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+ assert(i < 6);
+ return bits(tc->readIntReg(FirstArgumentReg + i), 31, 0);
+}
+
+void
+Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val)
+{
+ assert(i < 6);
+ tc->setIntReg(FirstArgumentReg + i, bits(val, 31, 0));
+}
+
+IntReg
+Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int i)
+{
+ assert(i < 6);
+ return tc->readIntReg(FirstArgumentReg + i);
+}
+
+void
+Sparc64LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val)
+{
+ assert(i < 6);
+ tc->setIntReg(FirstArgumentReg + i, val);
+}
+
+void
+SparcLiveProcess::setSyscallReturn(ThreadContext *tc,
+ SyscallReturn return_value)
+{
+ // check for error condition. SPARC syscall convention is to
+ // indicate success/failure in reg the carry bit of the ccr
+ // and put the return value itself in the standard return value reg ().
+ if (return_value.successful()) {
+ // no error, clear XCC.C
+ tc->setIntReg(NumIntArchRegs + 2,
+ tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
+ //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE);
+ IntReg val = return_value.value();
+ if (bits(tc->readMiscRegNoEffect(
+ SparcISA::MISCREG_PSTATE), 3, 3)) {
+ val = bits(val, 31, 0);
+ }
+ tc->setIntReg(ReturnValueReg, val);
+ } else {
+ // got an error, set XCC.C
+ tc->setIntReg(NumIntArchRegs + 2,
+ tc->readIntReg(NumIntArchRegs + 2) | 0x11);
+ //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11);
+ IntReg val = -return_value.value();
+ if (bits(tc->readMiscRegNoEffect(
+ SparcISA::MISCREG_PSTATE), 3, 3)) {
+ val = bits(val, 31, 0);
+ }
+ tc->setIntReg(ReturnValueReg, val);
+ }
+}