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 | |
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')
28 files changed, 254 insertions, 352 deletions
diff --git a/src/arch/SConscript b/src/arch/SConscript index 2b0af2816..b85ffbd89 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -56,7 +56,6 @@ isa_switch_hdrs = Split(''' regfile.hh remote_gdb.hh stacktrace.hh - syscallreturn.hh tlb.hh types.hh utility.hh diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc index f2ea1b587..e541b260c 100644 --- a/src/arch/alpha/freebsd/system.cc +++ b/src/arch/alpha/freebsd/system.cc @@ -74,9 +74,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc) Addr ppc_vaddr = 0; Addr timer_vaddr = 0; - assert(NumArgumentRegs >= 3); - ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg[1]); - timer_vaddr = (Addr)tc->readIntReg(ArgumentReg[2]); + ppc_vaddr = (Addr)tc->readIntReg(17); + timer_vaddr = (Addr)tc->readIntReg(18); virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency); virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY); diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index e5e4542a7..d37a769ea 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -152,12 +152,9 @@ const int ReturnAddressReg = 26; const int ReturnValueReg = 0; const int FramePointerReg = 15; -const int ArgumentReg[] = {16, 17, 18, 19, 20, 21}; -const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); - -const int SyscallNumReg = ReturnValueReg; -const int SyscallPseudoReturnReg = ArgumentReg[4]; -const int SyscallSuccessReg = 19; +const int SyscallNumReg = 0; +const int FirstArgumentReg = 16; +const int SyscallPseudoReturnReg = 20; const int LogVMPageSize = 13; // 8K bytes const int VMPageSize = (1 << LogVMPageSize); diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 605e40627..1e4f75790 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -48,7 +48,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"); @@ -67,13 +67,13 @@ static SyscallReturn osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -94,13 +94,13 @@ static SyscallReturn osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " 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()); + } +} diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index 65c4624ae..6d083c5ac 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -42,6 +42,11 @@ class AlphaLiveProcess : public LiveProcess void startup(); void argsInit(int intSize, int pageSize); + + public: + AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val); + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; #endif // __ARCH_ALPHA_PROCESS_HH__ diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/syscallreturn.hh deleted file mode 100644 index 776f34fbf..000000000 --- a/src/arch/alpha/syscallreturn.hh +++ /dev/null @@ -1,59 +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: Steve Reinhardt - * Gabe Black - */ - -#ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__ -#define __ARCH_ALPHA_SYSCALLRETURN_HH__ - -#include "cpu/thread_context.hh" -#include "sim/syscallreturn.hh" - -namespace AlphaISA { - -static inline void -setSyscallReturn(SyscallReturn return_value, ThreadContext *tc) -{ - // 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()); - } -} - -} // namespace AlphaISA - -#endif // __ARCH_ALPHA_SYSCALLRETURN_HH__ diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index b84dfb286..8fa3cdeda 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -45,7 +45,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<AlphaTru64::utsname> name(tc->getSyscallArg(0)); + TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "OSF1"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -62,34 +62,35 @@ static SyscallReturn getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case AlphaTru64::GSI_MAX_CPU: { - TypedBufferArg<uint32_t> max_cpu(tc->getSyscallArg(1)); + TypedBufferArg<uint32_t> max_cpu(process->getSyscallArg(tc, 1)); *max_cpu = htog((uint32_t)process->numCpus()); max_cpu.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPUS_IN_BOX: { - TypedBufferArg<uint32_t> cpus_in_box(tc->getSyscallArg(1)); + TypedBufferArg<uint32_t> cpus_in_box(process->getSyscallArg(tc, 1)); *cpus_in_box = htog((uint32_t)process->numCpus()); cpus_in_box.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PHYSMEM: { - TypedBufferArg<uint64_t> physmem(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> physmem(process->getSyscallArg(tc, 1)); *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPU_INFO: { - TypedBufferArg<AlphaTru64::cpu_info> infop(tc->getSyscallArg(1)); + TypedBufferArg<AlphaTru64::cpu_info> + infop(process->getSyscallArg(tc, 1)); infop->current_cpu = htog(0); infop->cpus_in_box = htog(process->numCpus()); @@ -106,14 +107,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_PROC_TYPE: { - TypedBufferArg<uint64_t> proc_type(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> proc_type(process->getSyscallArg(tc, 1)); *proc_type = htog((uint64_t)11); proc_type.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PLATFORM_NAME: { - BufferArg bufArg(tc->getSyscallArg(1), nbytes); + BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes); strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); @@ -122,7 +123,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_CLK_TCK: { - TypedBufferArg<uint64_t> clk_hz(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> clk_hz(process->getSyscallArg(tc, 1)); *clk_hz = htog((uint64_t)1024); clk_hz.copyOut(tc->getMemPort()); return 1; @@ -141,12 +142,12 @@ static SyscallReturn setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); + unsigned op = process->getSyscallArg(tc, 0); switch (op) { case AlphaTru64::SSI_IEEE_FP_CONTROL: warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", - tc->getSyscallArg(1)); + process->getSyscallArg(tc, 1)); break; default: @@ -164,17 +165,17 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { using namespace std; - int id = tc->getSyscallArg(0); // table ID - int index = tc->getSyscallArg(1); // index into table + int id = process->getSyscallArg(tc, 0); // table ID + int index = process->getSyscallArg(tc, 1); // index into table // arg 2 is buffer pointer; type depends on table ID - int nel = tc->getSyscallArg(3); // number of elements - int lel = tc->getSyscallArg(4); // expected element size + int nel = process->getSyscallArg(tc, 3); // number of elements + int lel = process->getSyscallArg(tc, 4); // expected element size switch (id) { case AlphaTru64::TBL_SYSINFO: { if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) return -EINVAL; - TypedBufferArg<Tru64::tbl_sysinfo> elp(tc->getSyscallArg(2)); + TypedBufferArg<Tru64::tbl_sysinfo> elp(process->getSyscallArg(tc, 2)); const int clk_hz = one_million; elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc index 2cf64b799..763da0d4f 100644 --- a/src/arch/alpha/utility.cc +++ b/src/arch/alpha/utility.cc @@ -42,11 +42,12 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) { #if FULL_SYSTEM + const int NumArgumentRegs = 6; if (number < NumArgumentRegs) { if (fp) - return tc->readFloatRegBits(ArgumentReg[number]); + return tc->readFloatRegBits(16 + number); else - return tc->readIntReg(ArgumentReg[number]); + return tc->readIntReg(16 + number); } else { Addr sp = tc->readIntReg(StackPointerReg); VirtualPort *vp = tc->getVirtPort(); diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh index 3450c273e..ed4ed9877 100644 --- a/src/arch/mips/isa_traits.hh +++ b/src/arch/mips/isa_traits.hh @@ -190,13 +190,6 @@ namespace MipsISA // semantically meaningful register indices const int ZeroReg = 0; const int AssemblerReg = 1; - const int ReturnValueReg = 2; - const int ReturnValueReg1 = 2; - const int ReturnValueReg2 = 3; - const int ArgumentReg0 = 4; - const int ArgumentReg1 = 5; - const int ArgumentReg2 = 6; - const int ArgumentReg3 = 7; const int KernelReg0 = 26; const int KernelReg1 = 27; const int GlobalPointerReg = 28; @@ -204,12 +197,7 @@ namespace MipsISA const int FramePointerReg = 30; const int ReturnAddressReg = 31; - const int ArgumentReg[] = {4, 5, 6, 7}; - const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); - - const int SyscallNumReg = ReturnValueReg1; - const int SyscallPseudoReturnReg = ReturnValueReg2; - const int SyscallSuccessReg = ArgumentReg3; + const int SyscallPseudoReturnReg = 3; const int LogVMPageSize = 13; // 8K bytes const int VMPageSize = (1 << LogVMPageSize); diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 9d9d33325..dc3b84ced 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -51,7 +51,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"); @@ -70,13 +70,13 @@ static SyscallReturn sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -97,13 +97,13 @@ static SyscallReturn sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): " diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index b7bd22d78..784ddfe33 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -40,6 +40,10 @@ using namespace std; using namespace MipsISA; +static const int SyscallSuccessReg = 7; +static const int FirstArgumentReg = 4; +static const int ReturnValueReg = 2; + MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile) : LiveProcess(params, objFile) @@ -64,3 +68,33 @@ MipsLiveProcess::startup() { argsInit(MachineBytes, VMPageSize); } + +MipsISA::IntReg +MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 6); + return tc->readIntReg(FirstArgumentReg + i); +} + +void +MipsLiveProcess::setSyscallArg(ThreadContext *tc, + int i, MipsISA::IntReg val) +{ + assert(i < 6); + tc->setIntReg(FirstArgumentReg + i, val); +} + +void +MipsLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + 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()); + } +} diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index 18bf289b8..87c62330f 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -47,6 +47,10 @@ class MipsLiveProcess : public LiveProcess virtual void startup(); + public: + MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val); + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/mips/syscallreturn.hh b/src/arch/mips/syscallreturn.hh deleted file mode 100644 index 24a40ddcc..000000000 --- a/src/arch/mips/syscallreturn.hh +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2007 MIPS Technologies, Inc. - * 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 - * Korey Sewell - */ - -#ifndef __ARCH_MIPS_SYSCALLRETURN_HH__ -#define __ARCH_MIPS_SYSCALLRETURN_HH__ - -#include "sim/syscallreturn.hh" -#include "cpu/thread_context.hh" - -namespace MipsISA -{ - static inline void setSyscallReturn(SyscallReturn return_value, - ThreadContext *tc) - { - if (return_value.successful()) { - // no error - tc->setIntReg(SyscallSuccessReg, 0); - tc->setIntReg(ReturnValueReg1, return_value.value()); - } else { - // got an error, return details - tc->setIntReg(SyscallSuccessReg, (IntReg) -1); - tc->setIntReg(ReturnValueReg1, -return_value.value()); - } - } -} - -#endif 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(); diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh index abb7694ed..d25e0eb70 100644 --- a/src/arch/x86/isa_traits.hh +++ b/src/arch/x86/isa_traits.hh @@ -106,19 +106,7 @@ namespace X86ISA const int StackPointerReg = INTREG_RSP; //X86 doesn't seem to have a link register const int ReturnAddressReg = 0; - const int ReturnValueReg = INTREG_RAX; const int FramePointerReg = INTREG_RBP; - const int ArgumentReg[] = { - INTREG_RDI, - INTREG_RSI, - INTREG_RDX, - //This argument register is r10 for syscalls and rcx for C. - INTREG_R10W, - //INTREG_RCX, - INTREG_R8W, - INTREG_R9W - }; - const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); // Some OS syscalls use a second register (rdx) to return a second // value diff --git a/src/arch/x86/linux/process.hh b/src/arch/x86/linux/process.hh index 2f37692e3..ca3606ef0 100644 --- a/src/arch/x86/linux/process.hh +++ b/src/arch/x86/linux/process.hh @@ -60,7 +60,6 @@ #include "sim/process.hh" #include "arch/x86/linux/linux.hh" -#include "arch/x86/syscallreturn.hh" #include "arch/x86/process.hh" namespace X86ISA { diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 324749366..e4e0fa234 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -68,7 +68,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"); @@ -94,8 +94,8 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, }; //First argument is the code, second is the address - int code = tc->getSyscallArg(0); - uint64_t addr = tc->getSyscallArg(1); + int code = process->getSyscallArg(tc, 0); + uint64_t addr = process->getSyscallArg(tc, 1); uint64_t fsBase, gsBase; TranslatingPort *p = tc->getMemPort(); switch(code) diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 800dd44ef..7d7978a35 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -104,6 +104,18 @@ using namespace std; using namespace X86ISA; +static const int ReturnValueReg = INTREG_RAX; +static const int ArgumentReg[] = { + INTREG_RDI, + INTREG_RSI, + INTREG_RDX, + //This argument register is r10 for syscalls and rcx for C. + INTREG_R10W, + //INTREG_RCX, + INTREG_R8W, + INTREG_R9W +}; +static const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); X86LiveProcess::X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs) : @@ -574,3 +586,35 @@ I386LiveProcess::argsInit(int intSize, int pageSize) { X86LiveProcess::argsInit<uint32_t>(pageSize); } + +void +X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value) +{ + tc->setIntReg(INTREG_RAX, return_value.value()); +} + +X86ISA::IntReg +X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < NumArgumentRegs); + return tc->readIntReg(ArgumentReg[i]); +} + +void +X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) +{ + assert(i < NumArgumentRegs); + return tc->setIntReg(ArgumentReg[i], val); +} + +X86ISA::IntReg +I386LiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + panic("32 bit getSyscallArg not implemented.\n"); +} + +void +I386LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) +{ + panic("32 bit setSyscallArg not implemented.\n"); +} diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index 8d77bd79d..e337e589e 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -81,6 +81,8 @@ namespace X86ISA public: SyscallDesc* getDesc(int callnum); + + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; class X86_64LiveProcess : public X86LiveProcess @@ -92,6 +94,9 @@ namespace X86ISA public: void argsInit(int intSize, int pageSize); void startup(); + + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; class I386LiveProcess : public X86LiveProcess @@ -103,6 +108,9 @@ namespace X86ISA public: void argsInit(int intSize, int pageSize); void startup(); + + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; } diff --git a/src/arch/x86/syscallreturn.hh b/src/arch/x86/syscallreturn.hh deleted file mode 100644 index 6a7fdba58..000000000 --- a/src/arch/x86/syscallreturn.hh +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2007 The Hewlett-Packard Development Company - * All rights reserved. - * - * Redistribution and use of this software in source and binary forms, - * with or without modification, are permitted provided that the - * following conditions are met: - * - * The software must be used only for Non-Commercial Use which means any - * use which is NOT directed to receiving any direct monetary - * compensation for, or commercial advantage from such use. Illustrative - * examples of non-commercial use are academic research, personal study, - * teaching, education and corporate research & development. - * Illustrative examples of commercial use are distributing products for - * commercial advantage and providing services using the software for - * commercial advantage. - * - * If you wish to use this software or functionality therein that may be - * covered by patents for commercial use, please contact: - * Director of Intellectual Property Licensing - * Office of Strategy and Technology - * Hewlett-Packard Company - * 1501 Page Mill Road - * Palo Alto, California 94304 - * - * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. No right of - * sublicense is granted herewith. Derivatives of the software and - * output created using the software may be prepared, but only for - * Non-Commercial Uses. Derivatives of the software may be shared with - * others provided: (i) the others agree to abide by the list of - * conditions herein which includes the Non-Commercial Use restrictions; - * and (ii) such Derivatives of the software include the above copyright - * notice to acknowledge the contribution from this software where - * applicable, this list of conditions and the disclaimer below. - * - * 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_X86_SYSCALLRETURN_HH__ -#define __ARCH_X86_SYSCALLRETURN_HH__ - -#include "base/misc.hh" -#include "cpu/thread_context.hh" -#include "sim/syscallreturn.hh" - -namespace X86ISA -{ - static inline void setSyscallReturn(SyscallReturn return_value, - ThreadContext * tc) - { - tc->setIntReg(INTREG_RAX, return_value.value()); - } -}; - -#endif // __ARCH_X86_SYSCALLRETURN_HH__ |