diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2006-04-28 14:03:42 -0400 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2006-04-28 14:03:42 -0400 |
commit | 20c85537871c131ec6c23d944db1f6b21da298fe (patch) | |
tree | 60ae6ce1165300453ec1b876539c4b368ab548b4 | |
parent | a183f66a8ad2a1ac822b07d9b399a3a3e6d3cb5c (diff) | |
parent | 7a9c65b7b6f4471c856bf009179c3231074a3930 (diff) | |
download | gem5-20c85537871c131ec6c23d944db1f6b21da298fe.tar.xz |
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
-rw-r--r-- | arch/sparc/SConscript | 1 | ||||
-rw-r--r-- | arch/sparc/isa/decoder.isa | 47 | ||||
-rw-r--r-- | arch/sparc/isa/formats/branch.isa | 23 | ||||
-rw-r--r-- | arch/sparc/isa/formats/integerop.isa | 16 | ||||
-rw-r--r-- | arch/sparc/isa/formats/mem.isa | 1 | ||||
-rw-r--r-- | arch/sparc/linux/linux.cc | 68 | ||||
-rw-r--r-- | arch/sparc/linux/linux.hh | 61 | ||||
-rw-r--r-- | arch/sparc/linux/process.cc | 6 | ||||
-rw-r--r-- | arch/sparc/linux/process.hh | 1 | ||||
-rw-r--r-- | arch/sparc/process.cc | 109 | ||||
-rw-r--r-- | arch/sparc/process.hh | 19 | ||||
-rwxr-xr-x | configs/test/hello_sparc | bin | 587552 -> 644149 bytes | |||
-rw-r--r-- | cpu/simple/cpu.cc | 8 |
13 files changed, 312 insertions, 48 deletions
diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript index 172e4390f..fd0df9349 100644 --- a/arch/sparc/SConscript +++ b/arch/sparc/SConscript @@ -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 ''') diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa index 823bf2626..792918267 100644 --- a/arch/sparc/isa/decoder.isa +++ b/arch/sparc/isa/decoder.isa @@ -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({{ diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa index b76f7a9f6..37bdb9402 100644 --- a/arch/sparc/isa/formats/branch.isa +++ b/arch/sparc/isa/formats/branch.isa @@ -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) diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa index 401af2e51..407a3e3cd 100644 --- a/arch/sparc/isa/formats/integerop.isa +++ b/arch/sparc/isa/formats/integerop.isa @@ -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); ''' }}; diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa index e15349c7b..ab8b85a94 100644 --- a/arch/sparc/isa/formats/mem.isa +++ b/arch/sparc/isa/formats/mem.isa @@ -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; diff --git a/arch/sparc/linux/linux.cc b/arch/sparc/linux/linux.cc new file mode 100644 index 000000000..c7ed29358 --- /dev/null +++ b/arch/sparc/linux/linux.cc @@ -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])); + diff --git a/arch/sparc/linux/linux.hh b/arch/sparc/linux/linux.hh new file mode 100644 index 000000000..1b31f67b0 --- /dev/null +++ b/arch/sparc/linux/linux.hh @@ -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 diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc index ca85a6d2d..4818f1fcc 100644 --- a/arch/sparc/linux/process.cc +++ b/arch/sparc/linux/process.cc @@ -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), diff --git a/arch/sparc/linux/process.hh b/arch/sparc/linux/process.hh index 38ddd68b9..23ce66d02 100644 --- a/arch/sparc/linux/process.hh +++ b/arch/sparc/linux/process.hh @@ -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" diff --git a/arch/sparc/process.cc b/arch/sparc/process.cc index 44f2c5984..f771b0d19 100644 --- a/arch/sparc/process.cc +++ b/arch/sparc/process.cc @@ -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(); - - //Copy the aux stuff? For now just put in the null vect + uint64_t guestArgc = TheISA::htog(argc); + + //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); diff --git a/arch/sparc/process.hh b/arch/sparc/process.hh index 7b2aec7b9..c177f20a5 100644 --- a/arch/sparc/process.hh +++ b/arch/sparc/process.hh @@ -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; diff --git a/configs/test/hello_sparc b/configs/test/hello_sparc Binary files differindex 7b7302771..e254ae33f 100755 --- a/configs/test/hello_sparc +++ b/configs/test/hello_sparc diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 40b506a78..be34d1791 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -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(); |