Merge m5.eecs.umich.edu:/bk/newmem
into ewok.(none):/home/gblack/m5/newmem cpu/simple/cpu.cc: Hand merged --HG-- extra : convert_revision : 68414730c23d41c30cfb7bcfa604029a5fc8622c
This commit is contained in:
commit
20c8553787
13 changed files with 311 additions and 47 deletions
|
@ -57,6 +57,7 @@ full_system_sources = Split('''
|
|||
|
||||
# Syscall emulation (non-full-system) sources
|
||||
syscall_emulation_sources = Split('''
|
||||
linux/linux.cc
|
||||
linux/process.cc
|
||||
process.cc
|
||||
''')
|
||||
|
|
|
@ -16,16 +16,22 @@ decode OP default Unknown::unknown()
|
|||
0x0: bpcci({{
|
||||
if(passesCondition(CcrIcc, COND2))
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
0x2: bpccx({{
|
||||
if(passesCondition(CcrXcc, COND2))
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
}
|
||||
}
|
||||
0x2: Branch22::bicc({{
|
||||
if(passesCondition(CcrIcc, COND2))
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
0x3: decode RCOND2
|
||||
{
|
||||
|
@ -34,26 +40,38 @@ decode OP default Unknown::unknown()
|
|||
0x1: bpreq({{
|
||||
if(Rs1 == 0)
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
0x2: bprle({{
|
||||
if(Rs1 <= 0)
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
0x3: bprl({{
|
||||
if(Rs1 < 0)
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
0x5: bprne({{
|
||||
if(Rs1 != 0)
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
0x6: bprg({{
|
||||
if(Rs1 > 0)
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
0x7: bprge({{
|
||||
if(Rs1 >= 0)
|
||||
NNPC = xc->readPC() + disp;
|
||||
else
|
||||
handle_annul
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
@ -117,22 +135,22 @@ decode OP default Unknown::unknown()
|
|||
0x10: addcc({{
|
||||
int64_t resTemp, val2 = Rs2_or_imm13;
|
||||
Rd = resTemp = Rs1 + val2;}},
|
||||
{{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
|
||||
{{(Rs1<31:0> + val2<31:0>)<32:>}},
|
||||
{{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
|
||||
{{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
|
||||
{{(Rs1<63:1> + val2<63:1> + (Rs1 & val2)<0:>)<63:>}},
|
||||
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
|
||||
);
|
||||
0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}});
|
||||
0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}});
|
||||
0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}});
|
||||
0x14: subcc({{
|
||||
int64_t resTemp, val2 = Rs2_or_imm13;
|
||||
Rd = resTemp = Rs1 - val2;}},
|
||||
{{((Rs1 & 0xFFFFFFFF - val2 & 0xFFFFFFFF) >> 31)}},
|
||||
{{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
|
||||
{{(((Rs1 >> 1) + (~val2) >> 1) +
|
||||
((Rs1 | ~val2) & 0x1))<63:>}},
|
||||
{{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
|
||||
int64_t val2 = Rs2_or_imm13;
|
||||
Rd = Rs1 - val2;}},
|
||||
{{(~(Rs1<31:0> + (~val2)<31:0> + 1))<32:>}},
|
||||
{{(Rs1<31:> != val2<31:>) && (Rs1<31:> != Rd<31:>)}},
|
||||
{{(~(Rs1<63:1> + (~val2)<63:1> +
|
||||
(Rs1 | ~val2)<0:>))<63:>}},
|
||||
{{Rs1<63:> != val2<63:> && Rs1<63:> != Rd<63:>}}
|
||||
);
|
||||
0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}});
|
||||
0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}});
|
||||
|
@ -141,11 +159,10 @@ decode OP default Unknown::unknown()
|
|||
int64_t resTemp, val2 = Rs2_or_imm13;
|
||||
int64_t carryin = CcrIccC;
|
||||
Rd = resTemp = Rs1 + val2 + carryin;}},
|
||||
{{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31
|
||||
+ carryin)}},
|
||||
{{(Rs1<31:0> + val2<31:0> + carryin)<32:>}},
|
||||
{{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
|
||||
{{((Rs1 >> 1) + (val2 >> 1) +
|
||||
((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}},
|
||||
{{(Rs1<63:1> + val2<63:1> +
|
||||
((Rs1 & val2) | (carryin & (Rs1 | val2)))<0:>)<63:>}},
|
||||
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
|
||||
);
|
||||
0x1A: umulcc({{
|
||||
|
@ -162,9 +179,9 @@ decode OP default Unknown::unknown()
|
|||
int64_t resTemp, val2 = Rs2_or_imm13;
|
||||
int64_t carryin = CcrIccC;
|
||||
Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
|
||||
{{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}},
|
||||
{{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}},
|
||||
{{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
|
||||
{{(((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}},
|
||||
{{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}},
|
||||
{{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
|
||||
);
|
||||
0x1D: udivxcc({{
|
||||
|
|
|
@ -194,7 +194,7 @@ output decoder {{
|
|||
{
|
||||
ccprintf(response, " <%s", symbol);
|
||||
if(symbolAddr != target)
|
||||
ccprintf(response, "+0x%x>", target - symbolAddr);
|
||||
ccprintf(response, "+%d>", target - symbolAddr);
|
||||
else
|
||||
ccprintf(response, ">");
|
||||
}
|
||||
|
@ -226,8 +226,25 @@ def template BranchExecute {{
|
|||
}
|
||||
}};
|
||||
|
||||
let {{
|
||||
handle_annul = '''
|
||||
{
|
||||
if(A)
|
||||
{
|
||||
NPC = xc->readNextNPC();
|
||||
NNPC = NPC + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
NPC = xc->readNextPC();
|
||||
NNPC = xc->readNextNPC();
|
||||
}
|
||||
}'''
|
||||
}};
|
||||
|
||||
// Primary format for branch instructions:
|
||||
def format Branch(code, *opt_flags) {{
|
||||
code = re.sub(r'handle_annul', handle_annul, code)
|
||||
(usesImm, code, immCode,
|
||||
rString, iString) = splitOutImm(code)
|
||||
iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
|
||||
|
@ -247,6 +264,7 @@ def format Branch(code, *opt_flags) {{
|
|||
|
||||
// Primary format for branch instructions:
|
||||
def format Branch19(code, *opt_flags) {{
|
||||
code = re.sub(r'handle_annul', handle_annul, code)
|
||||
codeBlk = CodeBlock(code)
|
||||
iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
|
@ -257,6 +275,7 @@ def format Branch19(code, *opt_flags) {{
|
|||
|
||||
// Primary format for branch instructions:
|
||||
def format Branch22(code, *opt_flags) {{
|
||||
code = re.sub(r'handle_annul', handle_annul, code)
|
||||
codeBlk = CodeBlock(code)
|
||||
iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
|
@ -267,6 +286,7 @@ def format Branch22(code, *opt_flags) {{
|
|||
|
||||
// Primary format for branch instructions:
|
||||
def format Branch30(code, *opt_flags) {{
|
||||
code = re.sub(r'handle_annul', handle_annul, code)
|
||||
codeBlk = CodeBlock(code)
|
||||
iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
|
@ -277,6 +297,7 @@ def format Branch30(code, *opt_flags) {{
|
|||
|
||||
// Primary format for branch instructions:
|
||||
def format BranchSplit(code, *opt_flags) {{
|
||||
code = re.sub(r'handle_annul', handle_annul, code)
|
||||
codeBlk = CodeBlock(code)
|
||||
iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
|
|
|
@ -271,14 +271,22 @@ let {{
|
|||
return (header_output, decoder_output, exec_output, decode_block)
|
||||
|
||||
calcCcCode = '''
|
||||
CcrIccN = (Rd >> 63) & 1;
|
||||
CcrIccZ = (Rd == 0);
|
||||
CcrXccN = (Rd >> 31) & 1;
|
||||
CcrXccZ = ((Rd & 0xFFFFFFFF) == 0);
|
||||
CcrIccN = (Rd >> 31) & 1;
|
||||
CcrIccZ = ((Rd & 0xFFFFFFFF) == 0);
|
||||
CcrXccN = (Rd >> 63) & 1;
|
||||
CcrXccZ = (Rd == 0);
|
||||
CcrIccV = %(ivValue)s;
|
||||
CcrIccC = %(icValue)s;
|
||||
CcrXccV = %(xvValue)s;
|
||||
CcrXccC = %(xcValue)s;
|
||||
DPRINTF(Sparc, "in = %%d\\n", CcrIccN);
|
||||
DPRINTF(Sparc, "iz = %%d\\n", CcrIccZ);
|
||||
DPRINTF(Sparc, "xn = %%d\\n", CcrXccN);
|
||||
DPRINTF(Sparc, "xz = %%d\\n", CcrXccZ);
|
||||
DPRINTF(Sparc, "iv = %%d\\n", CcrIccV);
|
||||
DPRINTF(Sparc, "ic = %%d\\n", CcrIccC);
|
||||
DPRINTF(Sparc, "xv = %%d\\n", CcrXccV);
|
||||
DPRINTF(Sparc, "xc = %%d\\n", CcrXccC);
|
||||
'''
|
||||
}};
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ def template MemExecute {{
|
|||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(ea_code)s;
|
||||
DPRINTF(Sparc, "The address is 0x%x\n", EA);
|
||||
%(load)s;
|
||||
%(code)s;
|
||||
%(store)s;
|
||||
|
|
68
arch/sparc/linux/linux.cc
Normal file
68
arch/sparc/linux/linux.cc
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/sparc/linux/linux.hh"
|
||||
|
||||
// open(2) flags translation table
|
||||
OpenFlagTransTable SparcLinux::openFlagTable[] = {
|
||||
#ifdef _MSC_VER
|
||||
{ SparcLinux::TGT_O_RDONLY, _O_RDONLY },
|
||||
{ SparcLinux::TGT_O_WRONLY, _O_WRONLY },
|
||||
{ SparcLinux::TGT_O_RDWR, _O_RDWR },
|
||||
{ SparcLinux::TGT_O_APPEND, _O_APPEND },
|
||||
{ SparcLinux::TGT_O_CREAT, _O_CREAT },
|
||||
{ SparcLinux::TGT_O_TRUNC, _O_TRUNC },
|
||||
{ SparcLinux::TGT_O_EXCL, _O_EXCL },
|
||||
#ifdef _O_NONBLOCK
|
||||
{ SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
|
||||
#endif
|
||||
#ifdef _O_NOCTTY
|
||||
{ SparcLinux::TGT_O_NOCTTY, _O_NOCTTY },
|
||||
#endif
|
||||
#ifdef _O_SYNC
|
||||
{ SparcLinux::TGT_O_SYNC, _O_SYNC },
|
||||
#endif
|
||||
#else /* !_MSC_VER */
|
||||
{ SparcLinux::TGT_O_RDONLY, O_RDONLY },
|
||||
{ SparcLinux::TGT_O_WRONLY, O_WRONLY },
|
||||
{ SparcLinux::TGT_O_RDWR, O_RDWR },
|
||||
{ SparcLinux::TGT_O_APPEND, O_APPEND },
|
||||
{ SparcLinux::TGT_O_CREAT, O_CREAT },
|
||||
{ SparcLinux::TGT_O_TRUNC, O_TRUNC },
|
||||
{ SparcLinux::TGT_O_EXCL, O_EXCL },
|
||||
{ SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK },
|
||||
{ SparcLinux::TGT_O_NOCTTY, O_NOCTTY },
|
||||
#ifdef O_SYNC
|
||||
{ SparcLinux::TGT_O_SYNC, O_SYNC },
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
};
|
||||
|
||||
const int SparcLinux::NUM_OPEN_FLAGS =
|
||||
(sizeof(SparcLinux::openFlagTable)/sizeof(SparcLinux::openFlagTable[0]));
|
||||
|
61
arch/sparc/linux/linux.hh
Normal file
61
arch/sparc/linux/linux.hh
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __MIPS_MIPS_LINUX_HH
|
||||
#define __MIPS_MIPS_LINUX_HH
|
||||
|
||||
#include "kern/linux/linux.hh"
|
||||
|
||||
class SparcLinux : public Linux
|
||||
{
|
||||
public:
|
||||
|
||||
static OpenFlagTransTable openFlagTable[];
|
||||
|
||||
static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
|
||||
static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
|
||||
static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
|
||||
static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK
|
||||
static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
|
||||
static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT
|
||||
static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC
|
||||
static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL
|
||||
static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY
|
||||
static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC
|
||||
// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
|
||||
// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
|
||||
// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
|
||||
// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
|
||||
// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
|
||||
|
||||
static const int NUM_OPEN_FLAGS;
|
||||
|
||||
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -98,7 +98,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
|
|||
/* 2 */ SyscallDesc("fork", unimplementedFunc),
|
||||
/* 3 */ SyscallDesc("read", readFunc),
|
||||
/* 4 */ SyscallDesc("write", writeFunc),
|
||||
/* 5 */ SyscallDesc("open", openFunc<Linux>),
|
||||
/* 5 */ SyscallDesc("open", openFunc<SparcLinux>),
|
||||
/* 6 */ SyscallDesc("close", closeFunc),
|
||||
/* 7 */ SyscallDesc("wait4", unimplementedFunc),
|
||||
/* 8 */ SyscallDesc("creat", unimplementedFunc),
|
||||
|
@ -164,9 +164,9 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
|
|||
/* 68 */ SyscallDesc("pwrite64", unimplementedFunc),
|
||||
/* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
|
||||
/* 70 */ SyscallDesc("getdgid32", unimplementedFunc),
|
||||
/* 71 */ SyscallDesc("mmap", unimplementedFunc),
|
||||
/* 71 */ SyscallDesc("mmap", mmapFunc<SparcLinux>),
|
||||
/* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
|
||||
/* 73 */ SyscallDesc("munmap", unimplementedFunc),
|
||||
/* 73 */ SyscallDesc("munmap", munmapFunc),
|
||||
/* 74 */ SyscallDesc("mprotect", unimplementedFunc),
|
||||
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
|
||||
/* 76 */ SyscallDesc("vhangup", unimplementedFunc),
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#ifndef __SPARC_LINUX_PROCESS_HH__
|
||||
#define __SPARC_LINUX_PROCESS_HH__
|
||||
|
||||
#include "arch/sparc/linux/linux.hh"
|
||||
#include "arch/sparc/process.hh"
|
||||
#include "sim/process.hh"
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ SparcLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
|
|||
|
||||
|
||||
if (objFile->getArch() != ObjectFile::SPARC)
|
||||
fatal("Object file does not match architecture.");
|
||||
fatal("Object file with arch %x does not match architecture %x.", objFile->getArch(), ObjectFile::SPARC);
|
||||
switch (objFile->getOpSys()) {
|
||||
case ObjectFile::Linux:
|
||||
process = new SparcLinuxProcess(nm, objFile, system,
|
||||
|
@ -89,7 +89,7 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
|
|||
|
||||
// Set up region for mmaps. Tru64 seems to start just above 0 and
|
||||
// grow up from there.
|
||||
mmap_start = mmap_end = 0x10000;
|
||||
mmap_start = mmap_end = 0x800000;
|
||||
|
||||
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||
|
@ -135,6 +135,14 @@ SparcLiveProcess::startup()
|
|||
execContexts[0]->setMiscRegWithEffect(MISCREG_CWP, 0);
|
||||
}
|
||||
|
||||
m5_auxv_t buildAuxVect(int64_t type, int64_t val)
|
||||
{
|
||||
m5_auxv_t result;
|
||||
result.a_type = TheISA::htog(type);
|
||||
result.a_val = TheISA::htog(val);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
SparcLiveProcess::argsInit(int intSize, int pageSize)
|
||||
{
|
||||
|
@ -145,10 +153,75 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
|
|||
// load object file into target memory
|
||||
objFile->loadSections(initVirtMem);
|
||||
|
||||
//These are the auxilliary vector types
|
||||
enum auxTypes
|
||||
{
|
||||
SPARC_AT_HWCAP = 16,
|
||||
SPARC_AT_PAGESZ = 6,
|
||||
SPARC_AT_CLKTCK = 17,
|
||||
SPARC_AT_PHDR = 3,
|
||||
SPARC_AT_PHENT = 4,
|
||||
SPARC_AT_PHNUM = 5,
|
||||
SPARC_AT_BASE = 7,
|
||||
SPARC_AT_FLAGS = 8,
|
||||
SPARC_AT_ENTRY = 9,
|
||||
SPARC_AT_UID = 11,
|
||||
SPARC_AT_EUID = 12,
|
||||
SPARC_AT_GID = 13,
|
||||
SPARC_AT_EGID = 14
|
||||
};
|
||||
|
||||
enum hardwareCaps
|
||||
{
|
||||
M5_HWCAP_SPARC_FLUSH = 1,
|
||||
M5_HWCAP_SPARC_STBAR = 2,
|
||||
M5_HWCAP_SPARC_SWAP = 4,
|
||||
M5_HWCAP_SPARC_MULDIV = 8,
|
||||
M5_HWCAP_SPARC_V9 = 16,
|
||||
//This one should technically only be set
|
||||
//if there is a cheetah or cheetah_plus tlb,
|
||||
//but we'll use it all the time
|
||||
M5_HWCAP_SPARC_ULTRA3 = 32
|
||||
};
|
||||
|
||||
const int64_t hwcap =
|
||||
M5_HWCAP_SPARC_FLUSH |
|
||||
M5_HWCAP_SPARC_STBAR |
|
||||
M5_HWCAP_SPARC_SWAP |
|
||||
M5_HWCAP_SPARC_MULDIV |
|
||||
M5_HWCAP_SPARC_V9 |
|
||||
M5_HWCAP_SPARC_ULTRA3;
|
||||
|
||||
//Setup the auxilliary vectors. These will already have
|
||||
//endian conversion.
|
||||
auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100));
|
||||
auxv.push_back(buildAuxVect(SPARC_AT_GID, 100));
|
||||
auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100));
|
||||
auxv.push_back(buildAuxVect(SPARC_AT_UID, 100));
|
||||
//This would work, but the entry point is a protected member
|
||||
//auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entry));
|
||||
auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0));
|
||||
//This is the address of the elf "interpreter", which I don't
|
||||
//think we currently set up. It should be set to 0 (I think)
|
||||
//auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
|
||||
//This is the number of headers which were in the original elf
|
||||
//file. This information isn't avaibale by this point.
|
||||
//auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, 3));
|
||||
//This is the size of a program header entry. This isn't easy
|
||||
//to compute here.
|
||||
//auxv.push_back(buildAuxVect(SPARC_AT_PHENT, blah));
|
||||
//This is should be set to load_addr (whatever that is) +
|
||||
//e_phoff. I think it's a pointer to the program headers.
|
||||
//auxv.push_back(buildAuxVect(SPARC_AT_PHDR, blah));
|
||||
//This should be easy to get right, but I won't set it for now
|
||||
//auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, blah));
|
||||
auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
|
||||
auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
|
||||
|
||||
//Figure out how big the initial stack needs to be
|
||||
|
||||
int aux_data_size = 0;
|
||||
//Figure out the aux_data_size?
|
||||
//Each auxilliary vector is two 8 byte words
|
||||
int aux_data_size = 2 * intSize * auxv.size();
|
||||
int env_data_size = 0;
|
||||
for (int i = 0; i < envp.size(); ++i) {
|
||||
env_data_size += envp[i].size() + 1;
|
||||
|
@ -198,8 +271,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
|
|||
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 auxv_array_base = arg_data_base - aux_array_size;
|
||||
Addr envp_array_base = auxv_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;
|
||||
|
@ -208,24 +281,34 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
|
|||
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 - auxv array\n", auxv_array_base);
|
||||
DPRINTF(Sparc, "0x%x - envp array\n", envp_array_base);
|
||||
DPRINTF(Sparc, "0x%x - argv 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();
|
||||
uint64_t guestArgc = TheISA::htog(argc);
|
||||
|
||||
//Copy the aux stuff? For now just put in the null vect
|
||||
//Copy the aux stuff
|
||||
for(int x = 0; x < auxv.size(); x++)
|
||||
{
|
||||
initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
|
||||
(uint8_t*)&(auxv[x].a_type), intSize);
|
||||
initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
|
||||
(uint8_t*)&(auxv[x].a_val), intSize);
|
||||
}
|
||||
//Write out the terminating zeroed auxilliary vector
|
||||
const uint64_t zero = 0;
|
||||
initVirtMem->writeBlob(aux_array_base, (uint8_t*)&zero, 2 * intSize);
|
||||
initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
|
||||
(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);
|
||||
initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
|
||||
|
||||
execContexts[0]->setIntReg(ArgumentReg0, argc);
|
||||
execContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
|
||||
|
|
|
@ -36,18 +36,19 @@
|
|||
class ObjectFile;
|
||||
class System;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int64_t a_type;
|
||||
union {
|
||||
int64_t a_val;
|
||||
Addr a_ptr;
|
||||
Addr a_fcn;
|
||||
};
|
||||
} m5_auxv_t;
|
||||
|
||||
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;
|
||||
|
||||
|
|
Binary file not shown.
|
@ -480,7 +480,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
|
|||
// Fault fault = xc->read(memReq,data);
|
||||
// Not sure what to check for no fault...
|
||||
if (data_read_pkt->result == Success) {
|
||||
data = data_read_pkt->get<T>();
|
||||
data = gtoh(data_read_pkt->get<T>());
|
||||
}
|
||||
|
||||
if (traceData) {
|
||||
|
@ -523,7 +523,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
|
|||
// Need to find a way to not duplicate code above.
|
||||
|
||||
if (data_read_pkt->result == Success) {
|
||||
data = data_read_pkt->get<T>();
|
||||
data = gtoh(data_read_pkt->get<T>());
|
||||
}
|
||||
|
||||
if (traceData) {
|
||||
|
@ -627,10 +627,12 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
|||
data_write_pkt = new Packet;
|
||||
data_write_pkt->cmd = Write;
|
||||
data_write_pkt->req = data_write_req;
|
||||
T hostData = htog(data);
|
||||
data_write_pkt->allocate();
|
||||
data_write_pkt->set(data);
|
||||
data_write_pkt->set(hostData);
|
||||
#else
|
||||
data_write_pkt->reset();
|
||||
data = htog(data);
|
||||
data_write_pkt->dataStatic(&data);
|
||||
#endif
|
||||
data_write_pkt->addr = data_write_req->getPaddr();
|
||||
|
|
Loading…
Reference in a new issue