Merge zizzer:/bk/newmem

into  zizzer.eecs.umich.edu:/.automount/zooks/y/ksewell/research/m5-sim/newmem

--HG--
extra : convert_revision : c48a8857f5a520ff8061eb3d8f08dcd43661e68c
This commit is contained in:
Korey Sewell
2006-05-04 21:10:51 -04:00
43 changed files with 1378 additions and 168 deletions

View File

@@ -45,7 +45,6 @@ class AlphaSystem : public System
{
std::string console_path;
std::string palcode;
std::string boot_osflags;
uint64_t system_type;
uint64_t system_rev;
};

View File

@@ -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
''')

View File

@@ -16,44 +16,62 @@ 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
{
format BranchSplit
{
0x1: bpreq({{
if(Rs1 == 0)
if(Rs1.sdw == 0)
NNPC = xc->readPC() + disp;
else
handle_annul
}});
0x2: bprle({{
if(Rs1 <= 0)
if(Rs1.sdw <= 0)
NNPC = xc->readPC() + disp;
else
handle_annul
}});
0x3: bprl({{
if(Rs1 < 0)
if(Rs1.sdw < 0)
NNPC = xc->readPC() + disp;
else
handle_annul
}});
0x5: bprne({{
if(Rs1 != 0)
if(Rs1.sdw != 0)
NNPC = xc->readPC() + disp;
else
handle_annul
}});
0x6: bprg({{
if(Rs1 > 0)
if(Rs1.sdw > 0)
NNPC = xc->readPC() + disp;
else
handle_annul
}});
0x7: bprge({{
if(Rs1 >= 0)
if(Rs1.sdw >= 0)
NNPC = xc->readPC() + disp;
else
handle_annul
}});
}
}
@@ -109,7 +127,7 @@ decode OP default Unknown::unknown()
if(Rd.udw<63:31> != 0)
Rd.udw = 0x7FFFFFFF;
else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF)
Rd.udw = 0xFFFFFFFF80000000;
Rd.udw = 0xFFFFFFFF80000000ULL;
}
}});
}
@@ -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({{
@@ -197,7 +214,7 @@ decode OP default Unknown::unknown()
overflow = (resTemp<63:31> != 0);
underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
if(overflow) Rd = resTemp = 0x7FFFFFFF;
else if(underflow) Rd = resTemp = 0xFFFFFFFF80000000;
else if(underflow) Rd = resTemp = 0xFFFFFFFF80000000ULL;
else Rd = resTemp;
} }},
{{0}},
@@ -333,11 +350,15 @@ decode OP default Unknown::unknown()
{
0x0: movcci({{
if(passesCondition(CcrIcc, COND4))
Rd = (I ? SIMM11 : RS2);
Rd = Rs2_or_imm11;
else
Rd = Rd;
}});
0x2: movccx({{
if(passesCondition(CcrXcc, COND4))
Rd = (I ? SIMM11 : RS2);
Rd = Rs2_or_imm11;
else
Rd = Rd;
}});
}
}
@@ -356,16 +377,17 @@ decode OP default Unknown::unknown()
count += oneBits[temp & 0xF];
temp = temp >> 4;
}
Rd = count;
}});
}
0x2F: decode RCOND3
{
0x1: movreq({{if(Rs1 == 0) Rd = Rs2_or_imm10;}});
0x2: movrle({{if(Rs1 <= 0) Rd = Rs2_or_imm10;}});
0x3: movrl({{if(Rs1 < 0) Rd = Rs2_or_imm10;}});
0x5: movrne({{if(Rs1 != 0) Rd = Rs2_or_imm10;}});
0x6: movrg({{if(Rs1 > 0) Rd = Rs2_or_imm10;}});
0x7: movrge({{if(Rs1 >= 0) Rd = Rs2_or_imm10;}});
0x1: movreq({{Rd = (Rs1 == 0) ? Rs2_or_imm10 : Rd;}});
0x2: movrle({{Rd = (Rs1 <= 0) ? Rs2_or_imm10 : Rd;}});
0x3: movrl({{Rd = (Rs1 < 0) ? Rs2_or_imm10 : Rd;}});
0x5: movrne({{Rd = (Rs1 != 0) ? Rs2_or_imm10 : Rd;}});
0x6: movrg({{Rd = (Rs1 > 0) ? Rs2_or_imm10 : Rd;}});
0x7: movrge({{Rd = (Rs1 >= 0) ? Rs2_or_imm10 : Rd;}});
}
0x30: decode RD {
0x0: wry({{Y = Rs1 ^ Rs2_or_imm13;}});

View File

@@ -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)

View File

@@ -61,6 +61,21 @@ output header {{
}
};
/**
* Base class for 11 bit immediate integer operations.
*/
class IntOpImm11 : public IntOpImm
{
protected:
// Constructor
IntOpImm11(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
imm = sign_ext(SIMM11, 11);
}
};
/**
* Base class for 13 bit immediate integer operations.
*/
@@ -271,14 +286,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);
'''
}};

View File

@@ -30,8 +30,9 @@ output header {{
// Constructor
MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
Mem(mnem, _machInst, __opClass), imm(SIMM13)
Mem(mnem, _machInst, __opClass)
{
imm = sign_ext(SIMM13, 13);
}
std::string generateDisassembly(Addr pc,
@@ -84,7 +85,10 @@ output decoder {{
}
ccprintf(response, "[ ");
printReg(response, _srcRegIdx[!save ? 0 : 1]);
ccprintf(response, " + 0x%x ]", imm);
if(imm >= 0)
ccprintf(response, " + 0x%x ]", imm);
else
ccprintf(response, " + -0x%x ]", -imm);
if(load)
{
ccprintf(response, ", ");
@@ -104,6 +108,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;
@@ -126,7 +131,7 @@ let {{
def doMemFormat(code, load, store, name, Name, opt_flags):
addrCalcReg = 'EA = Rs1 + Rs2;'
addrCalcImm = 'EA = Rs1 + SIMM13;'
addrCalcImm = 'EA = Rs1 + imm;'
iop = InstObjParams(name, Name, 'Mem', code,
opt_flags, ("ea_code", addrCalcReg),
("load", load), ("store", store))

68
arch/sparc/linux/linux.cc Normal file
View 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
View 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

View File

@@ -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),
@@ -155,7 +155,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 59 */ SyscallDesc("execve", unimplementedFunc),
/* 60 */ SyscallDesc("umask", unimplementedFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("fstat", unimplementedFunc),
/* 62 */ SyscallDesc("fstat", fstatFunc<SparcLinux>),
/* 63 */ SyscallDesc("fstat64", unimplementedFunc),
/* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
/* 65 */ SyscallDesc("msync", 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),
@@ -281,7 +281,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 185 */ SyscallDesc("setpgid", unimplementedFunc),
/* 186 */ SyscallDesc("fremovexattr", unimplementedFunc),
/* 187 */ SyscallDesc("tkill", unimplementedFunc),
/* 188 */ SyscallDesc("exit_group", unimplementedFunc),
/* 188 */ SyscallDesc("exit_group", exitFunc),
/* 189 */ SyscallDesc("uname", unameFunc),
/* 190 */ SyscallDesc("init_module", unimplementedFunc),
/* 191 */ SyscallDesc("personality", unimplementedFunc),

View File

@@ -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"

View File

@@ -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,
@@ -85,11 +85,11 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
// 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);
stack_base = ((Addr)0x80000000000ULL);
// 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);

View File

@@ -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;

View File

@@ -140,7 +140,16 @@ namespace SparcISA
DPRINTF(Sparc, "Now using %s globals",
useAlt ? "alternate" : "regular");
regView[Globals] = useAlt ? altGlobals : regGlobals;
offset[Globals] = useAlt ? AltGlobalOffset : RegGlobalOffset;
// You have not included an out-of-class definition of your static
// members. See [9.4.2]/4 and about a billion gcc bug reports. If
// statements get around the problem through some magic, and than
// seems nicer that putting a definition of them in a c file
// somewhere.
if (useAlt)
offset[Globals] = AltGlobalOffset;
else
offset[Globals] = RegGlobalOffset;
}
void serialize(std::ostream &os);

200
arch/sparc/system.cc Normal file
View File

@@ -0,0 +1,200 @@
/*
* Copyright (c) 2002-2006 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/system.hh"
#include "arch/vtophys.hh"
#include "base/remote_gdb.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "mem/physical.hh"
#include "sim/byteswap.hh"
#include "sim/builder.hh"
using namespace BigEndianGuest;
SparcSystem::SparcSystem(Params *p)
: System(p)
{
resetSymtab = new SymbolTable;
hypervisorSymtab = new SymbolTable;
openbootSymtab = new SymbolTable;
/**
* Load the boot code, and hypervisor into memory.
*/
// Read the reset binary
reset = createObjectFile(params()->reset_bin);
if (reset == NULL)
fatal("Could not load reset binary %s", params()->reset_bin);
// Read the openboot binary
openboot = createObjectFile(params()->openboot_bin);
if (openboot == NULL)
fatal("Could not load openboot bianry %s", params()->openboot_bin);
// Read the hypervisor binary
hypervisor = createObjectFile(params()->hypervisor_bin);
if (hypervisor == NULL)
fatal("Could not load hypervisor binary %s", params()->hypervisor_bin);
// Load reset binary into memory
reset->loadSections(&functionalPort, SparcISA::LoadAddrMask);
// Load the openboot binary
openboot->loadSections(&functionalPort, SparcISA::LoadAddrMask);
// Load the hypervisor binary
hypervisor->loadSections(&functionalPort, SparcISA::LoadAddrMask);
// load symbols
if (!reset->loadGlobalSymbols(reset))
panic("could not load reset symbols\n");
if (!openboot->loadGlobalSymbols(openbootSymtab))
panic("could not load openboot symbols\n");
if (!hypervisor->loadLocalSymbols(hypervisorSymtab))
panic("could not load hypervisor symbols\n");
// load symbols into debug table
if (!reset->loadGlobalSymbols(debugSymbolTable))
panic("could not load reset symbols\n");
if (!openboot->loadGlobalSymbols(debugSymbolTable))
panic("could not load openboot symbols\n");
if (!hypervisor->loadLocalSymbols(debugSymbolTable))
panic("could not load hypervisor symbols\n");
// @todo any fixup code over writing data in binaries on setting break
// events on functions should happen here.
}
SparcSystem::~SparcSystem()
{
delete resetSymtab;
delete hypervisorSymtab;
delete openbootSymtab;
delete reset;
delete openboot;
delete hypervisor;
}
bool
SparcSystem::breakpoint()
{
panic("Need to implement");
}
void
SparcSystem::serialize(std::ostream &os)
{
System::serialize(os);
resetSymtab->serialize("reset_symtab", os);
hypervisorSymtab->serialize("hypervisor_symtab", os);
openbootSymtab->serialize("openboot_symtab", os);
}
void
SparcSystem::unserialize(Checkpoint *cp, const std::string &section)
{
System::unserialize(cp,section);
resetSymtab->unserialize("reset_symtab", cp, section);
hypervisorSymtab->unserialize("hypervisor_symtab", cp, section);
openbootSymtab->unserialize("openboot_symtab", cp, section);
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
SimObjectParam<PhysicalMemory *> physmem;
Param<std::string> kernel;
Param<std::string> reset_bin;
Param<std::string> hypervisor_bin;
Param<std::string> openboot_bin;
Param<std::string> boot_osflags;
Param<std::string> readfile;
Param<unsigned int> init_param;
Param<bool> bin;
VectorParam<std::string> binned_fns;
Param<bool> bin_int;
END_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem)
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(physmem, "phsyical memory"),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(reset_bin, "file that contains the reset code"),
INIT_PARAM(hypervisor_bin, "file that contains the hypervisor code"),
INIT_PARAM(openboot_bin, "file that contains the openboot code"),
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
"a"),
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
INIT_PARAM(binned_fns, "functions to be broken down and binned"),
INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
END_INIT_SIM_OBJECT_PARAMS(SparcSystem)
CREATE_SIM_OBJECT(SparcSystem)
{
SparcSystem::Params *p = new SparcSystem::Params;
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->physmem = physmem;
p->kernel_path = kernel;
p->reset_bin = reset_bin;
p->hypervisor_bin = hypervisor_bin;
p->openboot_bin = openboot_bin;
p->boot_osflags = boot_osflags;
p->init_param = init_param;
p->readfile = readfile;
p->system_type = system_type;
p->system_rev = system_rev;
p->bin = bin;
p->binned_fns = binned_fns;
p->bin_int = bin_int;
return new SparcSystem(p);
}
REGISTER_SIM_OBJECT("SparcSystem", SparcSystem)

114
arch/sparc/system.hh Normal file
View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2002-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 __ARCH_SPARC_SYSTEM_HH__
#define __ARCH_SPARC_SYSTEM_HH__
#include <string>
#include <vector>
#include "base/loader/symtab.hh"
#include "cpu/pc_event.hh"
#include "kern/system_events.hh"
#include "sim/sim_object.hh"
#include "sim/system.hh"
class SparcSystem : public System
{
public:
struct Params : public System::Params
{
std::string reset_bin;
std::string hypervison_bin;
std::string openboot_bin;
std::string boot_osflags;
uint64_t system_type;
uint64_t system_rev;
};
SparcSystem(Params *p);
~SparcaSystem();
virtual bool breakpoint();
/**
* Serialization stuff
*/
public:
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
/** reset binary symbol table */
SymbolTable *resetSymtab;
/** hypervison binary symbol table */
SymbolTable *hypervisorSymtab;
/** openboot symbol table */
SymbolTable *openbootSymtab;
/** Object pointer for the reset binary */
ObjectFile *reset;
/** Object pointer for the hypervisor code */
ObjectFile *hypervisor;
/** Object pointer for the openboot code */
ObjectFile *openboot;
protected:
const Params *params() const { return (const Params *)_params; }
/** Add a function-based event to reset binary. */
template <class T>
T *SparcSystem::addResetFuncEvent(const char *lbl)
{
return addFuncEvent<T>(resetSymtab, lbl);
}
/** Add a function-based event to the hypervisor. */
template <class T>
T *SparcSystem::addHypervisorFuncEvent(const char *lbl)
{
return addFuncEvent<T>(hypervisorSymtab, lbl);
}
/** Add a function-based event to the openboot. */
template <class T>
T *SparcSystem::addOpenbootFuncEvent(const char *lbl)
{
return addFuncEvent<T>(openbootSymtab, lbl);
}
virtual Addr fixFuncEventAddr(Addr addr);
};
#endif