diff options
Diffstat (limited to 'src/arch/sparc/process.cc')
-rw-r--r-- | src/arch/sparc/process.cc | 145 |
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); + } +} |