summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2006-04-18 09:27:22 -0400
committerGabe Black <gblack@eecs.umich.edu>2006-04-18 09:27:22 -0400
commit3d99b4a5447abb1ccca552cee281137e2b11a674 (patch)
treeb2c5fe75b956939247339e44cc546eb71393f9d5
parent832311a17094501a6883100ac9dba8c781211782 (diff)
downloadgem5-3d99b4a5447abb1ccca552cee281137e2b11a674.tar.xz
Fixes to SPARC syscall emulation mode.
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
-rw-r--r--arch/sparc/isa/base.isa25
-rw-r--r--arch/sparc/isa/decoder.isa79
-rw-r--r--arch/sparc/isa/formats/branch.isa5
-rw-r--r--arch/sparc/isa/formats/integerop.isa2
-rw-r--r--arch/sparc/isa/formats/mem.isa12
-rw-r--r--arch/sparc/isa/formats/trap.isa14
-rw-r--r--arch/sparc/isa/operands.isa5
-rw-r--r--arch/sparc/isa_traits.hh7
-rw-r--r--arch/sparc/linux/process.cc39
-rw-r--r--arch/sparc/linux/process.hh3
-rw-r--r--arch/sparc/process.cc145
-rw-r--r--arch/sparc/process.hh16
-rw-r--r--arch/sparc/regfile.hh6
-rw-r--r--cpu/cpu_exec_context.hh4
-rw-r--r--cpu/exec_context.hh4
-rw-r--r--cpu/simple/cpu.hh2
-rw-r--r--sim/process.cc6
-rw-r--r--sim/process.hh10
18 files changed, 321 insertions, 63 deletions
diff --git a/arch/sparc/isa/base.isa b/arch/sparc/isa/base.isa
index 434426ffa..cb370a3e7 100644
--- a/arch/sparc/isa/base.isa
+++ b/arch/sparc/isa/base.isa
@@ -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))
diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa
index b4084518c..823bf2626 100644
--- a/arch/sparc/isa/decoder.isa
+++ b/arch/sparc/isa/decoder.isa
@@ -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;}});
diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa
index e4ce4592c..b76f7a9f6 100644
--- a/arch/sparc/isa/formats/branch.isa
+++ b/arch/sparc/isa/formats/branch.isa
@@ -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)
diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa
index f14f9e858..401af2e51 100644
--- a/arch/sparc/isa/formats/integerop.isa
+++ b/arch/sparc/isa/formats/integerop.isa
@@ -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;
}
diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa
index db2a4aaaa..e15349c7b 100644
--- a/arch/sparc/isa/formats/mem.isa
+++ b/arch/sparc/isa/formats/mem.isa
@@ -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)
{
diff --git a/arch/sparc/isa/formats/trap.isa b/arch/sparc/isa/formats/trap.isa
index 5608548bd..f6a45ca48 100644
--- a/arch/sparc/isa/formats/trap.isa
+++ b/arch/sparc/isa/formats/trap.isa
@@ -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();
}
}};
diff --git a/arch/sparc/isa/operands.isa b/arch/sparc/isa/operands.isa
index 17e58ad59..64a032eea 100644
--- a/arch/sparc/isa/operands.isa
+++ b/arch/sparc/isa/operands.isa
@@ -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),
diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh
index 57206c5e5..453d14664 100644
--- a/arch/sparc/isa_traits.hh
+++ b/arch/sparc/isa_traits.hh
@@ -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());
}
}
diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc
index c7e5f79ca..ca85a6d2d 100644
--- a/arch/sparc/linux/process.cc
+++ b/arch/sparc/linux/process.cc
@@ -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),
diff --git a/arch/sparc/linux/process.hh b/arch/sparc/linux/process.hh
index 1565ab549..38ddd68b9 100644
--- a/arch/sparc/linux/process.hh
+++ b/arch/sparc/linux/process.hh
@@ -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__
diff --git a/arch/sparc/process.cc b/arch/sparc/process.cc
index c7e08358d..44f2c5984 100644
--- a/arch/sparc/process.cc
+++ b/arch/sparc/process.cc
@@ -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)
diff --git a/arch/sparc/process.hh b/arch/sparc/process.hh
index cc4d0ae0a..7b2aec7b9 100644
--- a/arch/sparc/process.hh
+++ b/arch/sparc/process.hh
@@ -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__
diff --git a/arch/sparc/regfile.hh b/arch/sparc/regfile.hh
index 566cd1d1f..744d51771 100644
--- a/arch/sparc/regfile.hh
+++ b/arch/sparc/regfile.hh
@@ -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
}
diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh
index c74feec68..736af85ba 100644
--- a/cpu/cpu_exec_context.hh
+++ b/cpu/cpu_exec_context.hh
@@ -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; }
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index dd3d2cba1..4e40bc48d 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -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(); }
diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh
index 43287a33b..9da7072bf 100644
--- a/cpu/simple/cpu.hh
+++ b/cpu/simple/cpu.hh
@@ -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(); }
diff --git a/sim/process.cc b/sim/process.cc
index 4e4a54572..1f2e8d0fd 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -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);
diff --git a/sim/process.hh b/sim/process.hh
index b5b9d18b3..807bf330f 100644
--- a/sim/process.hh
+++ b/sim/process.hh
@@ -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;
};