Fixes to SPARC syscall emulation mode.
authorGabe Black <gblack@eecs.umich.edu>
Tue, 18 Apr 2006 13:27:22 +0000 (09:27 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Tue, 18 Apr 2006 13:27:22 +0000 (09:27 -0400)
arch/sparc/isa/base.isa:
    Added a set of abbreviations for the different condition tests.
arch/sparc/isa/decoder.isa:
    Fixes and additions to get syscall emulation closer to working.
arch/sparc/isa/formats/branch.isa:
    Fixed branches so that the immediate version actually uses the immediate value
arch/sparc/isa/formats/integerop.isa:
    Compute the condition codes -before- writing to the state of the machine.
arch/sparc/isa/formats/mem.isa:
    An attempt to fix up the output of the disassembly of loads and stores.
arch/sparc/isa/formats/trap.isa:
    Added code to disassemble a trap instruction. This probably needs to be fixed up so there are immediate and register versions.
arch/sparc/isa/operands.isa:
    Added an R1 operand, and fixed up the numbering
arch/sparc/isa_traits.hh:
    SyscallNumReg is no longer needed, the max number of sources and destinations are fixed up, and the syscall return uses xcc instead of icc.
arch/sparc/linux/process.cc:
arch/sparc/linux/process.hh:
    Added a getresuidFunc syscall implementation. This isn't actually used, but I thought it was and will leave it in.
arch/sparc/process.cc:
arch/sparc/process.hh:
    Fixed up how the initial stack frame is set up.
arch/sparc/regfile.hh:
    Changed the number of windows from 6 to 32 so we don't have to worry about spill and fill traps for now, and commented out the register file setting itself up.
cpu/cpu_exec_context.hh:
cpu/exec_context.hh:
cpu/simple/cpu.hh:
sim/process.cc:
sim/process.hh:
    Changed the syscall mechanism to pass down the syscall number directly.

--HG--
extra : convert_revision : 15723b949a0ddb3d24e68c079343b4dba2439f43

18 files changed:
arch/sparc/isa/base.isa
arch/sparc/isa/decoder.isa
arch/sparc/isa/formats/branch.isa
arch/sparc/isa/formats/integerop.isa
arch/sparc/isa/formats/mem.isa
arch/sparc/isa/formats/trap.isa
arch/sparc/isa/operands.isa
arch/sparc/isa_traits.hh
arch/sparc/linux/process.cc
arch/sparc/linux/process.hh
arch/sparc/process.cc
arch/sparc/process.hh
arch/sparc/regfile.hh
cpu/cpu_exec_context.hh
cpu/exec_context.hh
cpu/simple/cpu.hh
sim/process.cc
sim/process.hh

index 434426ffa525735e752938e4abe93ba2f3595807..cb370a3e7701a7fffc3b7afad363fc252c45151f 100644 (file)
@@ -37,6 +37,8 @@ output header {{
             OverflowSet=0x7
         };
 
+        extern char * CondTestAbbrev[];
+
         /**
          * Base class for all SPARC static instructions.
          */
@@ -65,6 +67,29 @@ output header {{
         }
 }};
 
+output decoder {{
+
+        char * CondTestAbbrev[] =
+        {
+            "nev", //Never
+            "e", //Equal
+            "le", //Less or Equal
+            "l", //Less
+            "leu", //Less or Equal Unsigned
+            "c", //Carry set
+            "n", //Negative
+            "o", //Overflow set
+            "a", //Always
+            "ne", //Not Equal
+            "g", //Greater
+            "ge", //Greater or Equal
+            "gu", //Greater Unsigned
+            "cc", //Carry clear
+            "p", //Positive
+            "oc" //Overflow Clear
+        };
+}};
+
 def template ROrImmDecode {{
     {
         return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
index b4084518cfd6c871381145baeb75409cffaab569..823bf2626c9b500e1564b601d24108859e516f84 100644 (file)
@@ -423,41 +423,70 @@ decode OP default Unknown::unknown()
                 }
             }});
             0x39: Branch::return({{
+                //If both MemAddressNotAligned and
+                //a fill trap happen, it's not clear
+                //which one should be returned.
                 Addr target = Rs1 + Rs2_or_imm13;
                 if(target & 0x3)
                     fault = new MemAddressNotAligned;
                 else
                     NNPC = target;
-                //This needs to change the register window
-                //like restore does
+                if(fault == NoFault)
+                {
+                    //CWP should be set directly so that it always happens
+                    //Also, this will allow writing to the new window and
+                    //reading from the old one
+                    Cwp = (Cwp - 1 + NWindows) % NWindows;
+                    if(Canrestore == 0)
+                    {
+                        if(Otherwin)
+                            fault = new FillNOther(WstateOther);
+                        else
+                            fault = new FillNNormal(WstateNormal);
+                    }
+                    else
+                    {
+                        Rd = Rs1 + Rs2_or_imm13;
+                        Cansave = Cansave + 1;
+                        Canrestore = Canrestore - 1;
+                    }
+                    //This is here to make sure the CWP is written
+                    //no matter what. This ensures that the results
+                    //are written in the new window as well.
+                    xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
+                }
             }});
             0x3A: decode CC
             {
                 0x0: Trap::tcci({{
+                    if(passesCondition(CcrIcc, COND2))
+                    {
+                        int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2);
+                        DPRINTF(Sparc, "The trap number is %d\n", lTrapNum);
 #if FULL_SYSTEM
-                    fault = new TrapInstruction;
+                        fault = new TrapInstruction(lTrapNum);
 #else
-                    if(passesCondition(CcrIcc, machInst<25:28>))
+                        DPRINTF(Sparc, "The syscall number is %d\n", R1);
+                        xc->syscall(R1);
+#endif
+                    }
+                    else
                     {
-                        // At least glibc only uses trap 0,
-                        // solaris/sunos may use others
-                        assert((I ? Rs1 + Rs2 : Rs1 + SW_TRAP) == 0);
-                        xc->syscall();
+                        DPRINTF(Sparc, "Didn't fire on %s\n", CondTestAbbrev[machInst<25:28>]);
                     }
-#endif
                 }});
                 0x2: Trap::tccx({{
+                    if(passesCondition(CcrXcc, COND2))
+                    {
+                        int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2);
+                        DPRINTF(Sparc, "The trap number is %d\n", lTrapNum);
 #if FULL_SYSTEM
-                    fault = new TrapInstruction;
+                        fault = new TrapInstruction(lTrapNum);
 #else
-                    if(passesCondition(CcrXcc, machInst<25:28>))
-                    {
-                        // At least glibc only uses trap 0,
-                        // solaris/sunos may use others
-                        assert((I ? Rs1 + Rs2 : Rs1 + SW_TRAP) == 0);
-                        xc->syscall();
-                    }
+                        DPRINTF(Sparc, "The syscall number is %d\n", R1);
+                        xc->syscall(R1);
 #endif
+                    }
                 }});
             }
             0x3B: Nop::flush({{/*Instruction memory flush*/}});
@@ -482,8 +511,8 @@ decode OP default Unknown::unknown()
                 {
                     Cwp = (Cwp + 1) % NWindows;
                     Rd = Rs1 + Rs2_or_imm13;
-                    Cansave--;
-                    Canrestore++;
+                    Cansave = Cansave - 1;
+                    Canrestore = Canrestore + 1;
                 }
                 //This is here to make sure the CWP is written
                 //no matter what. This ensures that the results
@@ -505,8 +534,8 @@ decode OP default Unknown::unknown()
                 else
                 {
                     Rd = Rs1 + Rs2_or_imm13;
-                    Cansave++;
-                    Canrestore--;
+                    Cansave = Cansave + 1;
+                    Canrestore = Canrestore - 1;
                 }
                 //This is here to make sure the CWP is written
                 //no matter what. This ensures that the results
@@ -607,15 +636,15 @@ decode OP default Unknown::unknown()
         format Trap {
             0x20: ldf({{fault = new FpDisabled;}});
             0x21: decode X {
-                0x0: ldfsr({{fault = new FpDisabled;}});
-                0x1: ldxfsr({{fault = new FpDisabled;}});
+                0x0: Load::ldfsr({{Fsr = Mem<31:0> | Fsr<63:32>;}}, {{32}});
+                0x1: Load::ldxfsr({{Fsr = Mem;}}, {{64}});
             }
             0x22: ldqf({{fault = new FpDisabled;}});
             0x23: lddf({{fault = new FpDisabled;}});
             0x24: stf({{fault = new FpDisabled;}});
             0x25: decode X {
-                0x0: stfsr({{fault = new FpDisabled;}});
-                0x1: stxfsr({{fault = new FpDisabled;}});
+                0x0: Store::stfsr({{Mem = Fsr<31:0>;}}, {{32}});
+                0x1: Store::stxfsr({{Mem = Fsr;}}, {{64}});
             }
             0x26: stqf({{fault = new FpDisabled;}});
             0x27: stdf({{fault = new FpDisabled;}});
index e4ce4592c74f2f7ac425dc6a30a4c8b328deb7a4..b76f7a9f6a1dafebffa3305d8c74dd71b9e5c1ca 100644 (file)
@@ -230,14 +230,13 @@ def template BranchExecute {{
 def format Branch(code, *opt_flags) {{
         (usesImm, code, immCode,
          rString, iString) = splitOutImm(code)
-        codeBlk = CodeBlock(code)
-        iop = InstObjParams(name, Name, 'Branch', codeBlk, opt_flags)
+        iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         exec_output = BranchExecute.subst(iop)
         if usesImm:
             imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString,
-                    codeBlk, opt_flags)
+                    immCode, opt_flags)
             header_output += BasicDeclare.subst(imm_iop)
             decoder_output += BasicConstructor.subst(imm_iop)
             exec_output += BranchExecute.subst(imm_iop)
index f14f9e858549b1a7fce9109c66a1f169b8ce03cc..401af2e51c4c82e390a68485c34933a813528fba 100644 (file)
@@ -243,8 +243,8 @@ def template IntOpExecute {{
             //Write the resulting state to the execution context
             if(fault == NoFault)
             {
-                %(op_wb)s;
                 %(cc_code)s;
+                %(op_wb)s;
             }
             return fault;
         }
index db2a4aaaa6bd5ada46e9ecd5c2556ad52bc31033..e15349c7baa06b66864a3a83e4015e69c615f3b7 100644 (file)
@@ -47,17 +47,18 @@ output decoder {{
         {
             std::stringstream response;
             bool load = flags[IsLoad];
+            bool save = flags[IsStore];
 
             printMnemonic(response, mnemonic);
-            if(!load)
+            if(save)
             {
                 printReg(response, _srcRegIdx[0]);
                 ccprintf(response, ", ");
             }
             ccprintf(response, "[ ");
-            printReg(response, _srcRegIdx[load ? 0 : 1]);
+            printReg(response, _srcRegIdx[!save ? 0 : 1]);
             ccprintf(response, " + ");
-            printReg(response, _srcRegIdx[load ? 1 : 2]);
+            printReg(response, _srcRegIdx[!save ? 1 : 2]);
             ccprintf(response, " ]");
             if(load)
             {
@@ -73,15 +74,16 @@ output decoder {{
         {
             std::stringstream response;
             bool load = flags[IsLoad];
+            bool save = flags[IsStore];
 
             printMnemonic(response, mnemonic);
-            if(!load)
+            if(save)
             {
                 printReg(response, _srcRegIdx[0]);
                 ccprintf(response, ", ");
             }
             ccprintf(response, "[ ");
-            printReg(response, _srcRegIdx[load ? 0 : 1]);
+            printReg(response, _srcRegIdx[!save ? 0 : 1]);
             ccprintf(response, " + 0x%x ]", imm);
             if(load)
             {
index 5608548bddd47f72b771ed2ed95a0d3b04a1e3ff..f6a45ca4834a40a57f275b6653c50978cfe47f8d 100644 (file)
@@ -14,12 +14,14 @@ output header {{
 
             // Constructor
             Trap(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
-                SparcStaticInst(mnem, _machInst, __opClass)
+                SparcStaticInst(mnem, _machInst, __opClass), trapNum(SW_TRAP)
             {
             }
 
             std::string generateDisassembly(Addr pc,
                     const SymbolTable *symtab) const;
+
+            int trapNum;
         };
 }};
 
@@ -27,7 +29,15 @@ output decoder {{
         std::string Trap::generateDisassembly(Addr pc,
                 const SymbolTable *symtab) const
         {
-            return "Trap instruction";
+            std::stringstream response;
+
+            printMnemonic(response, mnemonic);
+            ccprintf(response, " ");
+            printReg(response, _srcRegIdx[0]);
+            ccprintf(response, ", 0x%x", trapNum);
+            ccprintf(response, ", or ");
+            printReg(response, _srcRegIdx[1]);
+            return response.str();
         }
 }};
 
index 17e58ad59da19168874d1ef3b6d3fff1db4944cb..64a032eea77e6ac2949134d8f777da2ed47e030e 100644 (file)
@@ -30,8 +30,9 @@ def operands {{
     #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
     #'FPCR':  ('ControlReg', 'uq', 'Fpcr', None, 1),
     'R0':              ('IntReg', 'udw', '0', None, 6),
-    'R15':             ('IntReg', 'udw', '15', 'IsInteger', 7),
-    'R16':             ('IntReg', 'udw', '16', None, 8),
+    'R1':              ('IntReg', 'udw', '1', None, 7),
+    'R15':             ('IntReg', 'udw', '15', 'IsInteger', 8),
+    'R16':             ('IntReg', 'udw', '16', None, 9),
     # Control registers
     'Pstate':          ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 1),
     'PstateAg':                ('ControlReg', 'udw', 'MISCREG_PSTATE_AG', None, 2),
index 57206c5e598a69cddb749d2ead3920559076889a..453d14664ba52cc59c6d64914c67e7f6b8218389 100644 (file)
@@ -118,13 +118,12 @@ namespace SparcISA
     const int ArgumentReg3 = 11;
     const int ArgumentReg4 = 12;
     const int ArgumentReg5 = 13;
-    const int SyscallNumReg = 1;
     // Some OS syscall use a second register (o1) to return a second value
     const int SyscallPseudoReturnReg = ArgumentReg1;
 
     //XXX These numbers are bogus
     const int MaxInstSrcRegs = 8;
-    const int MaxInstDestRegs = 3;
+    const int MaxInstDestRegs = 9;
 
     typedef uint64_t IntReg;
 
@@ -174,11 +173,11 @@ namespace SparcISA
         // and put the return value itself in the standard return value reg ().
         if (return_value.successful()) {
             // no error
-            regs->setMiscReg(MISCREG_CCR_ICC_C, 0);
+            regs->setMiscReg(MISCREG_CCR_XCC_C, 0);
             regs->setIntReg(ReturnValueReg, return_value.value());
         } else {
             // got an error, return details
-            regs->setMiscReg(MISCREG_CCR_ICC_C, 1);
+            regs->setMiscReg(MISCREG_CCR_XCC_C, 1);
             regs->setIntReg(ReturnValueReg, return_value.value());
         }
     }
index c7e5f79ca24b3b7f4ced6a245e63d90baa0d46f1..ca85a6d2dbc485f47f82ce84cf1afe05b47fa8b5 100644 (file)
@@ -26,8 +26,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "arch/sparc/linux/process.hh"
 #include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/linux/process.hh"
+#include "arch/sparc/regfile.hh"
 
 #include "base/trace.hh"
 #include "cpu/exec_context.hh"
@@ -54,6 +55,40 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
     strcpy(name->machine, "sparc");
 
     name.copyOut(xc->getMemPort());
+
+    return 0;
+}
+
+
+SyscallReturn SparcISA::getresuidFunc(SyscallDesc *desc, int num,
+                                         Process *p, ExecContext *xc)
+{
+    const IntReg id = htog(100);
+    Addr ruid = xc->getSyscallArg(0);
+    Addr euid = xc->getSyscallArg(1);
+    Addr suid = xc->getSyscallArg(2);
+    //Handle the EFAULT case
+    //Set the ruid
+    if(ruid)
+    {
+        BufferArg ruidBuff(ruid, sizeof(IntReg));
+        memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
+        ruidBuff.copyOut(xc->getMemPort());
+    }
+    //Set the euid
+    if(euid)
+    {
+        BufferArg euidBuff(euid, sizeof(IntReg));
+        memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
+        euidBuff.copyOut(xc->getMemPort());
+    }
+    //Set the suid
+    if(suid)
+    {
+        BufferArg suidBuff(suid, sizeof(IntReg));
+        memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
+        suidBuff.copyOut(xc->getMemPort());
+    }
     return 0;
 }
 
@@ -167,7 +202,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
     /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
     /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
     /* 108 */ SyscallDesc("setresuid", unimplementedFunc),
-    /* 109 */ SyscallDesc("getresuid", unimplementedFunc),
+    /* 109 */ SyscallDesc("getresuid", getresuidFunc),
     /* 110 */ SyscallDesc("setresgid", unimplementedFunc),
     /* 111 */ SyscallDesc("getresgid", unimplementedFunc),
     /* 112 */ SyscallDesc("setregid32", unimplementedFunc),
index 1565ab549ad08dafc7e82779c24b34db48acbf5f..38ddd68b908813a9c2691f7c6de06ae3e1ec6a35 100644 (file)
@@ -57,5 +57,8 @@ class SparcLinuxProcess : public SparcLiveProcess
     const int Num_Syscall_Descs;
 };
 
+SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
+                                 Process *p, ExecContext *xc);
+
 } // namespace SparcISA
 #endif // __ALPHA_LINUX_PROCESS_HH__
index c7e08358dc503a18fa17f7e8d9346df514abd2e5..44f2c59841ddbdd13b450f6d94b09bc7c9978376 100644 (file)
@@ -32,6 +32,8 @@
 #include "base/loader/object_file.hh"
 #include "base/misc.hh"
 #include "cpu/exec_context.hh"
+#include "mem/page_table.hh"
+#include "mem/translating_port.hh"
 #include "sim/builder.hh"
 #include "sim/system.hh"
 
@@ -81,9 +83,9 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
     brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
     brk_point = roundUp(brk_point, VMPageSize);
 
-    // Set up stack.  On Alpha, stack goes below text section.  This
-    // code should get moved to some architecture-specific spot.
-    stack_base = objFile->textBase() - (409600+4096);
+    // Set up stack. On SPARC Linux, stack goes from the top of memory
+    // downward, less the hole for the kernel address space.
+    stack_base = ((Addr)0x80000000000);
 
     // Set up region for mmaps.  Tru64 seems to start just above 0 and
     // grow up from there.
@@ -91,16 +93,151 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
 
     // Set pointer for next thread stack.  Reserve 8M for main stack.
     next_thread_stack_base = stack_base - (8 * 1024 * 1024);
-
 }
 
 void
 SparcLiveProcess::startup()
 {
     argsInit(MachineBytes, VMPageSize);
+
+    //From the SPARC ABI
+
+    //The process runs in user mode
+    execContexts[0]->setMiscRegWithEffect(MISCREG_PSTATE_PRIV, 0);
+    //Interrupts are enabled
+    execContexts[0]->setMiscRegWithEffect(MISCREG_PSTATE_IE, 1);
+    //Round to nearest
+    execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_RD, 0);
+    //Floating point traps are not enabled
+    execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_TEM, 0);
+    //Turn non standard mode off
+    execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_NS, 0);
+    //The floating point queue is empty
+    execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_QNE, 0);
+    //There are no accrued eexecContext[0]eptions
+    execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_AEXC, 0);
+    //There are no current eexecContext[0]eptions
+    execContexts[0]->setMiscRegWithEffect(MISCREG_FSR_CEXC, 0);
+
+    /*
+     * Register window management registers
+     */
+
+    //No windows contain info from other programs
+    execContexts[0]->setMiscRegWithEffect(MISCREG_OTHERWIN, 0);
+    //There are no windows to pop
+    execContexts[0]->setMiscRegWithEffect(MISCREG_CANRESTORE, 0);
+    //All windows are available to save into
+    execContexts[0]->setMiscRegWithEffect(MISCREG_CANSAVE, NWindows - 2);
+    //All windows are "clean"
+    execContexts[0]->setMiscRegWithEffect(MISCREG_CLEANWIN, NWindows);
+    //Start with register window 0
+    execContexts[0]->setMiscRegWithEffect(MISCREG_CWP, 0);
 }
 
+void
+SparcLiveProcess::argsInit(int intSize, int pageSize)
+{
+    Process::startup();
+
+    Addr alignmentMask = ~(intSize - 1);
+
+    // load object file into target memory
+    objFile->loadSections(initVirtMem);
 
+    //Figure out how big the initial stack needs to be
+
+    int aux_data_size = 0;
+    //Figure out the aux_data_size?
+    int env_data_size = 0;
+    for (int i = 0; i < envp.size(); ++i) {
+        env_data_size += envp[i].size() + 1;
+    }
+    int arg_data_size = 0;
+    for (int i = 0; i < argv.size(); ++i) {
+        arg_data_size += argv[i].size() + 1;
+    }
+
+    int aux_array_size = intSize * 2 * (auxv.size() + 1);
+
+    int argv_array_size = intSize * (argv.size() + 1);
+    int envp_array_size = intSize * (envp.size() + 1);
+
+    int argc_size = intSize;
+    int window_save_size = intSize * 16;
+
+    int info_block_size =
+        (aux_data_size +
+        env_data_size +
+        arg_data_size +
+        ~alignmentMask) & alignmentMask;
+
+    int info_block_padding =
+        info_block_size -
+        aux_data_size -
+        env_data_size -
+        arg_data_size;
+
+    int space_needed =
+        info_block_size +
+        aux_array_size +
+        envp_array_size +
+        argv_array_size +
+        argc_size +
+        window_save_size;
+
+    stack_min = stack_base - space_needed;
+    stack_min &= alignmentMask;
+    stack_size = stack_base - stack_min;
+
+    // map memory
+    pTable->allocate(roundDown(stack_min, pageSize),
+                     roundUp(stack_size, pageSize));
+
+    // map out initial stack contents
+    Addr aux_data_base = stack_base - aux_data_size - info_block_padding;
+    Addr env_data_base = aux_data_base - env_data_size;
+    Addr arg_data_base = env_data_base - arg_data_size;
+    Addr aux_array_base = arg_data_base - aux_array_size;
+    Addr envp_array_base = aux_array_base - envp_array_size;
+    Addr argv_array_base = envp_array_base - argv_array_size;
+    Addr argc_base = argv_array_base - argc_size;
+    Addr window_save_base = argc_base - window_save_size;
+
+    DPRINTF(Sparc, "The addresses of items on the initial stack:\n");
+    DPRINTF(Sparc, "0x%x - aux data\n", aux_data_base);
+    DPRINTF(Sparc, "0x%x - env data\n", env_data_base);
+    DPRINTF(Sparc, "0x%x - arg data\n", arg_data_base);
+    DPRINTF(Sparc, "0x%x - aux array\n", aux_array_base);
+    DPRINTF(Sparc, "0x%x - env array\n", envp_array_base);
+    DPRINTF(Sparc, "0x%x - arg array\n", argv_array_base);
+    DPRINTF(Sparc, "0x%x - argc \n", argc_base);
+    DPRINTF(Sparc, "0x%x - window save\n", window_save_base);
+    DPRINTF(Sparc, "0x%x - stack min\n", stack_min);
+
+    // write contents to stack
+    uint64_t argc = argv.size();
+
+    //Copy the aux stuff? For now just put in the null vect
+    const uint64_t zero = 0;
+    initVirtMem->writeBlob(aux_array_base, (uint8_t*)&zero, 2 * intSize);
+
+    copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+    copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+
+    initVirtMem->writeBlob(argc_base, (uint8_t*)&argc, intSize);
+
+    execContexts[0]->setIntReg(ArgumentReg0, argc);
+    execContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
+    execContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias);
+
+    Addr prog_entry = objFile->entryPoint();
+    execContexts[0]->setPC(prog_entry);
+    execContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
+    execContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+
+//    num_processes++;
+}
 
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcLiveProcess)
index cc4d0ae0a4cb462aec07ab0ccf3dccff41cb4049..7b2aec7b95d57077862119b75d606358ad4573a0 100644 (file)
@@ -39,6 +39,20 @@ class System;
 class SparcLiveProcess : public LiveProcess
 {
   protected:
+    typedef struct
+    {
+        int64_t a_type;
+        union {
+            int64_t a_val;
+            Addr    a_ptr;
+            Addr    a_fcn;
+        };
+    } m5_auxv_t;
+
+    static const Addr StackBias = 2047;
+
+    std::vector<m5_auxv_t> auxv;
+
     SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
                 System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
                 std::vector<std::string> &argv,
@@ -57,6 +71,8 @@ class SparcLiveProcess : public LiveProcess
                                std::vector<std::string> &argv,
                                std::vector<std::string> &envp);
 
+    void argsInit(int intSize, int pageSize);
+
 };
 
 #endif // __SPARC_PROCESS_HH__
index 566cd1d1f4906a81483c57b19dac149e9dce7b10..744d51771907f683a9348c4af17fd7075ae06b53 100644 (file)
@@ -45,7 +45,7 @@ namespace SparcISA
     const int MaxTL = 4;
 
     // NWINDOWS - number of register windows, can be 3 to 32
-    const int NWindows = 6;
+    const int NWindows = 32;
 
     class IntRegFile
     {
@@ -581,7 +581,7 @@ namespace SparcISA
             tickFields.npt = 1; //The TICK register is unreadable by
                                 //non-priveleged software
 #else
-            //This sets up the initial state of the processor for usermode processes
+/*         //This sets up the initial state of the processor for usermode processes
             pstateFields.priv = 0; //Process runs in user mode
             pstateFields.ie = 1; //Interrupts are enabled
             fsrFields.rd = 0; //Round to nearest
@@ -595,7 +595,7 @@ namespace SparcISA
             otherwin = 0; //No windows contain info from other programs
             canrestore = 0; //There are no windows to pop
             cansave = MaxTL - 2; //All windows are available to save into
-            cleanwin = MaxTL;
+            cleanwin = MaxTL;*/
 #endif
         }
 
index c74feec68aea58853010b38cc51f6c2265788ebd..736af85ba5d16a1d94843dac4f80a7a11a0edba8 100644 (file)
@@ -518,9 +518,9 @@ class CPUExecContext
         TheISA::setSyscallReturn(return_value, &regs);
     }
 
-    void syscall()
+    void syscall(int64_t callnum)
     {
-        process->syscall(proxy);
+        process->syscall(callnum, proxy);
     }
 
     Counter readFuncExeInst() { return func_exe_inst; }
index dd3d2cba1a2c11e32d28db09018f39cf6f3f481a..4e40bc48d9073380161eaacae42711e18ad193cd 100644 (file)
@@ -234,7 +234,7 @@ class ExecContext
 
     virtual void setSyscallReturn(SyscallReturn return_value) = 0;
 
-    virtual void syscall() = 0;
+    virtual void syscall(int64_t callnum) = 0;
 
     // Same with st cond failures.
     virtual Counter readFuncExeInst() = 0;
@@ -432,7 +432,7 @@ class ProxyExecContext : public ExecContext
     void setSyscallReturn(SyscallReturn return_value)
     { actualXC->setSyscallReturn(return_value); }
 
-    void syscall() { actualXC->syscall(); }
+    void syscall(int64_t callnum) { actualXC->syscall(callnum); }
 
     Counter readFuncExeInst() { return actualXC->readFuncExeInst(); }
 
index 43287a33b3eb40a4d564b1acef5222dde2a077bc..9da7072bffb2eefe756b88ef4756d38cb952636b 100644 (file)
@@ -414,7 +414,7 @@ class SimpleCPU : public BaseCPU
     void ev5_trap(Fault fault) { fault->invoke(xcProxy); }
     bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); }
 #else
-    void syscall() { cpuXC->syscall(); }
+    void syscall(int64_t callnum) { cpuXC->syscall(callnum); }
 #endif
 
     bool misspeculating() { return cpuXC->misspeculating(); }
index 4e4a545723987a634b240367f3348983be1d0689..1f2e8d0fdcd6124e99e064eebc1c4528a38b332d 100644 (file)
@@ -240,7 +240,7 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process)
 ////////////////////////////////////////////////////////////////////////
 
 
-static void
+void
 copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr,
                 TranslatingPort* memPort)
 {
@@ -348,12 +348,10 @@ LiveProcess::argsInit(int intSize, int pageSize)
 }
 
 void
-LiveProcess::syscall(ExecContext *xc)
+LiveProcess::syscall(int64_t callnum, ExecContext *xc)
 {
     num_syscalls++;
 
-    int64_t callnum = xc->readIntReg(SyscallNumReg);
-
     SyscallDesc *desc = getDesc(callnum);
     if (desc == NULL)
         fatal("Syscall %d out of range", callnum);
index b5b9d18b34e99e913873f2be3241124386bb1d15..807bf330f9c36d0a2aad0745c24fc9cb5f54805a 100644 (file)
@@ -50,6 +50,10 @@ class PageTable;
 class TranslatingPort;
 class System;
 
+void
+copyStringArray(std::vector<std::string> &strings, Addr array_ptr,
+        Addr data_ptr, TranslatingPort* memPort);
+
 class Process : public SimObject
 {
   public:
@@ -155,7 +159,7 @@ class Process : public SimObject
     // look up simulator fd for given target fd
     int sim_fd(int tgt_fd);
 
-    virtual void syscall(ExecContext *xc) = 0;
+    virtual void syscall(int64_t callnum, ExecContext *xc) = 0;
 };
 
 //
@@ -174,10 +178,10 @@ class LiveProcess : public Process
                 std::vector<std::string> &argv,
                 std::vector<std::string> &envp);
 
-    void argsInit(int intSize, int pageSize);
+    virtual void argsInit(int intSize, int pageSize);
 
   public:
-    virtual void syscall(ExecContext *xc);
+    virtual void syscall(int64_t callnum, ExecContext *xc);
 
     virtual SyscallDesc* getDesc(int callnum) = 0;
 };