diff options
Diffstat (limited to 'src/arch/sparc')
-rw-r--r-- | src/arch/sparc/isa_traits.hh | 8 | ||||
-rw-r--r-- | src/arch/sparc/linux/process.hh | 1 | ||||
-rw-r--r-- | src/arch/sparc/linux/syscalls.cc | 9 | ||||
-rw-r--r-- | src/arch/sparc/process.cc | 63 | ||||
-rw-r--r-- | src/arch/sparc/process.hh | 7 | ||||
-rw-r--r-- | src/arch/sparc/solaris/process.cc | 2 | ||||
-rw-r--r-- | src/arch/sparc/syscallreturn.hh | 74 | ||||
-rw-r--r-- | src/arch/sparc/utility.cc | 3 |
8 files changed, 79 insertions, 88 deletions
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 30455792f..501f2f990 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -68,16 +68,12 @@ namespace SparcISA // semantically meaningful register indices const int ZeroReg = 0; // architecturally meaningful // the rest of these depend on the ABI - const int StackPointerReg = 14; const int ReturnAddressReg = 31; // post call, precall is 15 - const int ReturnValueReg = 8; // Post return, 24 is pre-return. + const int StackPointerReg = 14; const int FramePointerReg = 30; - const int ArgumentReg[] = {8, 9, 10, 11, 12, 13}; - const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); - // Some OS syscall use a second register (o1) to return a second value - const int SyscallPseudoReturnReg = ArgumentReg[1]; + const int SyscallPseudoReturnReg = 9; //8K. This value is implmentation specific; and should probably //be somewhere else. diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh index 06eee9235..a76b4b3b2 100644 --- a/src/arch/sparc/linux/process.hh +++ b/src/arch/sparc/linux/process.hh @@ -32,7 +32,6 @@ #define __SPARC_LINUX_PROCESS_HH__ #include "arch/sparc/linux/linux.hh" -#include "arch/sparc/syscallreturn.hh" #include "arch/sparc/process.hh" #include "sim/process.hh" diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 3e8c603cd..8496fca13 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -29,7 +29,6 @@ */ #include "arch/sparc/linux/process.hh" -#include "arch/sparc/syscallreturn.hh" #include "sim/syscall_emul.hh" class LiveProcess; @@ -42,7 +41,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0)); + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -60,9 +59,9 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { const IntReg id = htog(100); - Addr ruid = tc->getSyscallArg(0); - Addr euid = tc->getSyscallArg(1); - Addr suid = tc->getSyscallArg(2); + Addr ruid = p->getSyscallArg(tc, 0); + Addr euid = p->getSyscallArg(tc, 1); + Addr suid = p->getSyscallArg(tc, 2); //Handle the EFAULT case //Set the ruid if(ruid) diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 515389687..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) @@ -509,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); + } +} diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index 95abb93d3..fdb9734ba 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -69,6 +69,7 @@ class SparcLiveProcess : public LiveProcess { return spillStart; } virtual void flushWindows(ThreadContext *tc) = 0; + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; class Sparc32LiveProcess : public SparcLiveProcess @@ -93,6 +94,9 @@ class Sparc32LiveProcess : public SparcLiveProcess void argsInit(int intSize, int pageSize); void flushWindows(ThreadContext *tc); + + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; class Sparc64LiveProcess : public SparcLiveProcess @@ -118,6 +122,9 @@ class Sparc64LiveProcess : public SparcLiveProcess void argsInit(int intSize, int pageSize); void flushWindows(ThreadContext *tc); + + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; #endif // __SPARC_PROCESS_HH__ diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index e4f6b23c8..1a4940b59 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -48,7 +48,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Solaris::utsname> name(tc->getSyscallArg(0)); + TypedBufferArg<Solaris::utsname> name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "SunOS"); strcpy(name->nodename, "m5.eecs.umich.edu"); diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh deleted file mode 100644 index d4e6c7c50..000000000 --- a/src/arch/sparc/syscallreturn.hh +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2003-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - */ - -#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__ -#define __ARCH_SPARC_SYSCALLRETURN_HH__ - -#include <inttypes.h> - -#include "sim/syscallreturn.hh" -#include "arch/sparc/regfile.hh" -#include "cpu/thread_context.hh" - -namespace SparcISA -{ - static inline void setSyscallReturn(SyscallReturn return_value, - ThreadContext * tc) - { - // 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); - } - } -}; - -#endif diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc index 8f5c3e036..d4cc286e6 100644 --- a/src/arch/sparc/utility.cc +++ b/src/arch/sparc/utility.cc @@ -46,8 +46,9 @@ namespace SparcISA { //first 6 arguments which the caller may use but doesn't have to. uint64_t getArgument(ThreadContext *tc, int number, bool fp) { #if FULL_SYSTEM + const int NumArgumentRegs = 6; if (number < NumArgumentRegs) { - return tc->readIntReg(ArgumentReg[number]); + return tc->readIntReg(8 + number); } else { Addr sp = tc->readIntReg(StackPointerReg); VirtualPort *vp = tc->getVirtPort(); |