From 5b561338ebb8bc750a4f45cfcd134873e5124abc Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2006 13:08:45 -0400 Subject: Added a linux.cc file to mesh with Korey's changes --HG-- extra : convert_revision : 2073c1cda4799a60fce917f227018dd2e52456a3 --- arch/sparc/SConscript | 1 + arch/sparc/linux/linux.cc | 68 +++++++++++++++++++++++++++++++++++++++++++++++ arch/sparc/linux/linux.hh | 61 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 arch/sparc/linux/linux.cc create mode 100644 arch/sparc/linux/linux.hh 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/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 -- cgit v1.2.3 From 9920976892fdfee878fd43d083f4e066ed1ebf1a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2006 13:10:03 -0400 Subject: Added in handling of the annul bit for branches, and fixed up computation of ccr bits. --HG-- extra : convert_revision : ed38d26e13d25e21819dd32d159f1ee4ffcc780b --- arch/sparc/isa/decoder.isa | 47 ++++++++++++++++++++++++++------------- arch/sparc/isa/formats/branch.isa | 23 ++++++++++++++++++- 2 files changed, 54 insertions(+), 16 deletions(-) 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) -- cgit v1.2.3 From 7abeb6b18de9a80f3fca6b8aaab9e12a6bc8b73e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2006 13:10:52 -0400 Subject: Some debugging of the ccr bits --HG-- extra : convert_revision : b3d100b2e34dcecc3ba33c9ad4b0b7e40c210ecc --- arch/sparc/isa/formats/integerop.isa | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) 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); ''' }}; -- cgit v1.2.3 From 25bf3125dac0370d8244deccaf6f208f5f8c101e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2006 13:11:32 -0400 Subject: Changed the hello_sparc executable back to the cross compiled one --HG-- extra : convert_revision : 565f75f76dd26ca0e25de4c89d1597a9f39483fd --- configs/test/hello_sparc | Bin 587552 -> 644149 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configs/test/hello_sparc b/configs/test/hello_sparc index 7b7302771..e254ae33f 100755 Binary files a/configs/test/hello_sparc and b/configs/test/hello_sparc differ -- cgit v1.2.3 From d514caa202379b6ff800ba1a05660e3b1187132c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2006 13:12:17 -0400 Subject: Fixed up some syscalls --HG-- extra : convert_revision : f9a32e14fa4d4d4710df83dbf54cb77482ba5d03 --- arch/sparc/linux/process.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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), + /* 5 */ SyscallDesc("open", openFunc), /* 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), /* 72 */ SyscallDesc("setreuid32", unimplementedFunc), - /* 73 */ SyscallDesc("munmap", unimplementedFunc), + /* 73 */ SyscallDesc("munmap", munmapFunc), /* 74 */ SyscallDesc("mprotect", unimplementedFunc), /* 75 */ SyscallDesc("madvise", unimplementedFunc), /* 76 */ SyscallDesc("vhangup", unimplementedFunc), -- cgit v1.2.3 From cba0c3736b52e56018b1784fd66ed40224b8c91b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2006 13:12:46 -0400 Subject: Added an include which was forgotten --HG-- extra : convert_revision : ad76ab45358787edddb89910049bac7cca288824 --- arch/sparc/linux/process.hh | 1 + 1 file changed, 1 insertion(+) 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" -- cgit v1.2.3 From 9eaedf314b5166ef52e7dd4be81b8a3c40276025 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2006 13:13:35 -0400 Subject: Improved the initial stack frame arch/sparc/isa/formats/mem.isa: Added some debugging output --HG-- extra : convert_revision : cea88e2b3eddfa4e60bbbcb02f459d274d80db2e --- arch/sparc/isa/formats/mem.isa | 1 + arch/sparc/process.cc | 109 ++++++++++++++++++++++++++++++++++++----- arch/sparc/process.hh | 19 +++---- 3 files changed, 107 insertions(+), 22 deletions(-) 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/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; -- cgit v1.2.3 From 7a9c65b7b6f4471c856bf009179c3231074a3930 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2006 13:13:58 -0400 Subject: Added byteswapping code --HG-- extra : convert_revision : 67bf0689399328a728a0f3130d58d483e5f2f06e --- cpu/simple/cpu.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 0f1f9574a..1a737fa6a 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -475,6 +475,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) // Not sure what to check for no fault... if (data_read_pkt->result == Success) { memcpy(&data, data_read_pkt->data, sizeof(T)); + data = gtoh(data); } if (traceData) { @@ -518,6 +519,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) if (data_read_pkt->result == Success) { memcpy(&data, data_read_pkt->data, sizeof(T)); + data = gtoh(data); } if (traceData) { @@ -622,9 +624,11 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) data_write_pkt->cmd = Write; data_write_pkt->req = data_write_req; data_write_pkt->data = new uint8_t[64]; - memcpy(data_write_pkt->data, &data, sizeof(T)); + T hostData = htog(data); + memcpy(data_write_pkt->data, &hostData, sizeof(T)); #else data_write_pkt->reset(); + data = htog(data); data_write_pkt->data = (uint8_t *)&data; #endif data_write_pkt->addr = data_write_req->getPaddr(); -- cgit v1.2.3 From 7bb70e3e30f30c669e475c47b950f0abd24367d0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2006 15:07:44 -0400 Subject: Fixed constants to work on 32 bit hosts --HG-- extra : convert_revision : acc8e6f60cfdca518fa45afef4165395cba23d4f --- arch/sparc/isa/decoder.isa | 4 ++-- arch/sparc/process.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa index 792918267..ca409fa66 100644 --- a/arch/sparc/isa/decoder.isa +++ b/arch/sparc/isa/decoder.isa @@ -127,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; } }}); } @@ -214,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}}, diff --git a/arch/sparc/process.cc b/arch/sparc/process.cc index f771b0d19..7f2b0d40a 100644 --- a/arch/sparc/process.cc +++ b/arch/sparc/process.cc @@ -85,7 +85,7 @@ 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. -- cgit v1.2.3 From c819a1c0e188a388cd1891fa5a36e81adcd6c279 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 28 Apr 2006 15:34:03 -0400 Subject: Add SparcSystem object arch/alpha/system.hh: sim/system.hh: make boot_osflags apply to all systems --HG-- extra : convert_revision : 48cf903fd92be250b86817210951b85fa5e74632 --- arch/alpha/system.hh | 1 - arch/sparc/system.cc | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++ arch/sparc/system.hh | 114 +++++++++++++++++++++++++++++ sim/system.hh | 1 + 4 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 arch/sparc/system.cc create mode 100644 arch/sparc/system.hh diff --git a/arch/alpha/system.hh b/arch/alpha/system.hh index fe1307ac3..924e16826 100644 --- a/arch/alpha/system.hh +++ b/arch/alpha/system.hh @@ -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; }; diff --git a/arch/sparc/system.cc b/arch/sparc/system.cc new file mode 100644 index 000000000..1e2882607 --- /dev/null +++ b/arch/sparc/system.cc @@ -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 §ion) +{ + 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 physmem; + + Param kernel; + Param reset_bin; + Param hypervisor_bin; + Param openboot_bin; + + Param boot_osflags; + Param readfile; + Param init_param; + + Param bin; + VectorParam binned_fns; + Param 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) + + diff --git a/arch/sparc/system.hh b/arch/sparc/system.hh new file mode 100644 index 000000000..27aa8768a --- /dev/null +++ b/arch/sparc/system.hh @@ -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 +#include + +#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 §ion); + + /** 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 + T *SparcSystem::addResetFuncEvent(const char *lbl) + { + return addFuncEvent(resetSymtab, lbl); + } + + /** Add a function-based event to the hypervisor. */ + template + T *SparcSystem::addHypervisorFuncEvent(const char *lbl) + { + return addFuncEvent(hypervisorSymtab, lbl); + } + + /** Add a function-based event to the openboot. */ + template + T *SparcSystem::addOpenbootFuncEvent(const char *lbl) + { + return addFuncEvent(openbootSymtab, lbl); + } + + virtual Addr fixFuncEventAddr(Addr addr); + +}; + +#endif + diff --git a/sim/system.hh b/sim/system.hh index 3c2c27bee..7e21bd587 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -155,6 +155,7 @@ class System : public SimObject #if FULL_SYSTEM Tick boot_cpu_frequency; + std::string boot_osflags; uint64_t init_param; bool bin; std::vector binned_fns; -- cgit v1.2.3 From 53d93ef9182aade99faa5996dece522d9aba88d1 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 28 Apr 2006 15:37:48 -0400 Subject: add a bridge object, modify bus object to be able to connect to other buses or bridges without panicing SConscript: add new cc files to scons mem/bus.cc: mem/bus.hh: implement addressRanges() on the bus. propigate address ranges to anyone who is interested stripping out ranges of who your propigating to (to avoid livelock) mem/packet.hh: add intersect function that returns true if two packets touch at least one byte of the same data (for functional access) add fixPacket() that will eventually take the correct action giving a timing and functional packet, right now it panics mem/physical.cc: Don't panic if the physical memory recieves a status change, just ignore. --HG-- extra : convert_revision : d470d51f2fb1db2700ad271e09792315ef33ba01 --- SConscript | 8 +- mem/bridge.cc | 263 ++++++++++++++++++++++++++++++++++++++++++++ mem/bridge.hh | 214 +++++++++++++++++++++++++++++++++++ mem/bus.cc | 45 ++++++-- mem/bus.hh | 21 +++- mem/packet.cc | 37 +++++++ mem/packet.hh | 18 ++- mem/physical.cc | 1 - python/m5/objects/Bridge.py | 9 ++ 9 files changed, 601 insertions(+), 15 deletions(-) create mode 100644 mem/bridge.cc create mode 100644 mem/bridge.hh create mode 100644 mem/packet.cc create mode 100644 python/m5/objects/Bridge.py diff --git a/SConscript b/SConscript index cac083b6b..d49bee5e4 100644 --- a/SConscript +++ b/SConscript @@ -87,13 +87,15 @@ base_sources = Split(''' cpu/pc_event.cc cpu/static_inst.cc cpu/sampler/sampler.cc - - mem/request.cc + + mem/bridge.cc + mem/bus.cc mem/connector.cc mem/mem_object.cc + mem/packet.cc mem/physical.cc mem/port.cc - mem/bus.cc + mem/request.cc python/pyconfig.cc python/embedded_py.cc diff --git a/mem/bridge.cc b/mem/bridge.cc new file mode 100644 index 000000000..d358ef77b --- /dev/null +++ b/mem/bridge.cc @@ -0,0 +1,263 @@ + +/* + * Copyright (c) 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. + */ + +/** + * @file Definition of a simple bus bridge without buffering. + */ + + +#include "base/trace.hh" +#include "mem/bridge.hh" +#include "sim/builder.hh" + +void +Bridge::init() +{ + // Make sure that both sides are connected to. + if (sideA == NULL || sideB == NULL) + panic("Both ports of bus bridge are not connected to a bus.\n"); +} + + +/** Function called by the port when the bus is recieving a Timing + * transaction.*/ +bool +Bridge::recvTiming(Packet &pkt, Side id) +{ + if (blockedA && id == SideA) + return false; + if (blockedB && id == SideB) + return false; + + if (delay) { + if (!sendEvent.scheduled()) + sendEvent.schedule(curTick + delay); + if (id == SideA) { + inboundA.push_back(std::make_pair(&pkt, curTick)); + blockCheck(SideA); + } else { + inboundB.push_back(std::make_pair(&pkt, curTick)); + blockCheck(SideB); + } + } else { + if (id == SideB) { + sideA->sendPkt(pkt); + blockCheck(SideB); + } else { + sideB->sendPkt(pkt); + blockCheck(SideA); + } + } + return true; + +} + +void +Bridge::blockCheck(Side id) +{ + /* Check that we still have buffer space available. */ + if (id == SideB) { + if (sideA->numQueued() + inboundB.size() >= queueSizeA && !blockedB) { + sideB->sendStatusChange(Port::Blocked); + blockedB = true; + } else if (sideA->numQueued() + inboundB.size() < queueSizeA && blockedB) { + sideB->sendStatusChange(Port::Unblocked); + blockedB = false; + } + } else { + if (sideB->numQueued() + inboundA.size() >= queueSizeB && !blockedA) { + sideA->sendStatusChange(Port::Blocked); + blockedA = true; + } else if (sideB->numQueued() + inboundA.size() < queueSizeB && blockedA) { + sideA->sendStatusChange(Port::Unblocked); + blockedA = false; + } + } +} + +void Bridge::timerEvent() +{ + Tick t = 0; + + assert(inboundA.size() || inboundB.size()); + if (inboundA.size()) { + while (inboundA.front().second <= curTick + delay){ + sideB->sendPkt(inboundA.front()); + inboundA.pop_front(); + } + if (inboundA.size()) + t = inboundA.front().second + delay; + } + if (inboundB.size()) { + while (inboundB.front().second <= curTick + delay){ + sideB->sendPkt(inboundA.front()); + inboundB.pop_front(); + } + if (inboundB.size()) + if (t == 0) + t = inboundB.front().second + delay; + else + t = std::min(t,inboundB.front().second + delay); + } else { + panic("timerEvent() called but nothing to do?"); + } + + if (t != 0) + sendEvent.schedule(t); +} + + +void +Bridge::BridgePort::sendPkt(Packet &pkt) +{ + if (!sendTiming(pkt)) + outbound.push_back(std::make_pair(&pkt, curTick)); +} + +void +Bridge::BridgePort::sendPkt(std::pair p) +{ + if (!sendTiming(*p.first)) + outbound.push_back(p); +} + + +Packet * +Bridge::BridgePort::recvRetry() +{ + Packet *pkt; + assert(outbound.size() > 0); + assert(outbound.front().second >= curTick + bridge->delay); + pkt = outbound.front().first; + outbound.pop_front(); + bridge->blockCheck(side); + return pkt; +} + +/** Function called by the port when the bus is recieving a Atomic + * transaction.*/ +Tick +Bridge::recvAtomic(Packet &pkt, Side id) +{ + pkt.time += delay; + + if (id == SideA) + return sideB->sendAtomic(pkt); + else + return sideA->sendAtomic(pkt); +} + +/** Function called by the port when the bus is recieving a Functional + * transaction.*/ +void +Bridge::recvFunctional(Packet &pkt, Side id) +{ + pkt.time += delay; + std::list >::iterator i; + bool pktContinue = true; + + for(i = inboundA.begin(); i != inboundA.end(); ++i) { + if (pkt.intersect(i->first)) { + pktContinue &= fixPacket(pkt, *i->first); + } + } + + for(i = inboundB.begin(); i != inboundB.end(); ++i) { + if (pkt.intersect(i->first)) { + pktContinue &= fixPacket(pkt, *i->first); + } + } + + for(i = sideA->outbound.begin(); i != sideA->outbound.end(); ++i) { + if (pkt.intersect(i->first)) { + pktContinue &= fixPacket(pkt, *i->first); + } + } + + for(i = sideB->outbound.begin(); i != sideB->outbound.end(); ++i) { + if (pkt.intersect(i->first)) { + pktContinue &= fixPacket(pkt, *i->first); + } + } + + if (pktContinue) { + if (id == SideA) + sideB->sendFunctional(pkt); + else + sideA->sendFunctional(pkt); + } +} + +/** Function called by the port when the bus is recieving a status change.*/ +void +Bridge::recvStatusChange(Port::Status status, Side id) +{ + if (status == Port::Blocked || status == Port::Unblocked) + return ; + + if (id == SideA) + sideB->sendStatusChange(status); + else + sideA->sendStatusChange(status); +} + +void +Bridge::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id) +{ + if (id == SideA) + sideB->getPeerAddressRanges(resp, snoop); + else + sideA->getPeerAddressRanges(resp, snoop); +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge) + + Param queue_size_a; + Param queue_size_b; + Param delay; + Param write_ack; + +END_DECLARE_SIM_OBJECT_PARAMS(Bridge) + +BEGIN_INIT_SIM_OBJECT_PARAMS(Bridge) + + INIT_PARAM(queue_size_a, "The size of the queue for data coming into side a"), + INIT_PARAM(queue_size_b, "The size of the queue for data coming into side b"), + INIT_PARAM(delay, "The miminum delay to cross this bridge"), + INIT_PARAM(write_ack, "Acknowledge any writes that are received.") + +END_INIT_SIM_OBJECT_PARAMS(Bridge) + +CREATE_SIM_OBJECT(Bridge) +{ + return new Bridge(getInstanceName(), queue_size_a, queue_size_b, delay, + write_ack); +} + +REGISTER_SIM_OBJECT("Bridge", Bridge) diff --git a/mem/bridge.hh b/mem/bridge.hh new file mode 100644 index 000000000..6bd4d81ab --- /dev/null +++ b/mem/bridge.hh @@ -0,0 +1,214 @@ +/* + * Copyright (c) 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. + */ + +/** + * @file Decleration of a simple bus bridge object with no buffering + */ + +#ifndef __MEM_BRIDGE_HH__ +#define __MEM_BRIDGE_HH__ + +#include +#include +#include +#include + + +#include "mem/mem_object.hh" +#include "mem/packet.hh" +#include "mem/port.hh" +#include "sim/eventq.hh" + +class Bridge : public MemObject +{ + public: + enum Side + { + SideA, + SideB + }; + + protected: + /** Function called by the port when the bus is recieving a Timing + transaction.*/ + bool recvTiming(Packet &pkt, Side id); + + /** Function called by the port when the bus is recieving a Atomic + transaction.*/ + Tick recvAtomic(Packet &pkt, Side id); + + /** Function called by the port when the bus is recieving a Functional + transaction.*/ + void recvFunctional(Packet &pkt, Side id); + + /** Function called by the port when the bus is recieving a status change.*/ + void recvStatusChange(Port::Status status, Side id); + + /** Process address range request. + * @param resp addresses that we can respond to + * @param snoop addresses that we would like to snoop + * @param id ide of the busport that made the request. + */ + void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id); + + + /** Event that the SendEvent calls when it fires. This code must reschedule + * the send event as required. */ + void timerEvent(); + + /** Decleration of the buses port type, one will be instantiated for each + of the interfaces connecting to the bus. */ + class BridgePort : public Port + { + /** A pointer to the bus to which this port belongs. */ + Bridge *bridge; + + /** A id to keep track of the intercafe ID this port is connected to. */ + Bridge::Side side; + + public: + + /** Constructor for the BusPort.*/ + BridgePort(Bridge *_bridge, Side _side) + : bridge(_bridge), side(_side) + { } + + int numQueued() { return outbound.size(); } + + protected: + /** Data this is waiting to be transmitted. */ + std::list > outbound; + + void sendPkt(Packet &pkt); + void sendPkt(std::pair p); + + /** When reciving a timing request from the peer port, + pass it to the bridge. */ + virtual bool recvTiming(Packet &pkt) + { return bridge->recvTiming(pkt, side); } + + /** When reciving a retry request from the peer port, + pass it to the bridge. */ + virtual Packet* recvRetry(); + + /** When reciving a Atomic requestfrom the peer port, + pass it to the bridge. */ + virtual Tick recvAtomic(Packet &pkt) + { return bridge->recvAtomic(pkt, side); } + + /** When reciving a Functional request from the peer port, + pass it to the bridge. */ + virtual void recvFunctional(Packet &pkt) + { bridge->recvFunctional(pkt, side); } + + /** When reciving a status changefrom the peer port, + pass it to the bridge. */ + virtual void recvStatusChange(Status status) + { bridge->recvStatusChange(status, side); } + + /** When reciving a address range request the peer port, + pass it to the bridge. */ + virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + { bridge->addressRanges(resp, snoop, side); } + + friend class Bridge; + }; + + class SendEvent : public Event + { + Bridge *bridge; + + SendEvent(Bridge *b) + : Event(&mainEventQueue), bridge(b) {} + + virtual void process() { bridge->timerEvent(); } + + virtual const char *description() { return "bridge delay event"; } + friend class Bridge; + }; + + SendEvent sendEvent; + + /** Sides of the bus bridges. */ + BridgePort* sideA; + BridgePort* sideB; + + /** inbound queues on both sides. */ + std::list > inboundA; + std::list > inboundB; + + /** The size of the queue for data coming into side a */ + int queueSizeA; + int queueSizeB; + + /* if the side is blocked or not. */ + bool blockedA; + bool blockedB; + + /** Miminum delay though this bridge. */ + Tick delay; + + /** If this bridge should acknowledge writes. */ + bool ackWrites; + + public: + + /** A function used to return the port associated with this bus object. */ + virtual Port *getPort(const std::string &if_name) + { + if (if_name == "side_a") { + if (sideA != NULL) + panic("bridge side a already connected to."); + sideA = new BridgePort(this, SideA); + return sideA; + } else if (if_name == "side_b") { + if (sideB != NULL) + panic("bridge side b already connected to."); + sideB = new BridgePort(this, SideB); + return sideB; + } else + return NULL; + } + + virtual void init(); + + Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack) + : MemObject(n), sendEvent(this), sideA(NULL), sideB(NULL), + queueSizeA(qsa), queueSizeB(qsb), blockedA(false), blockedB(false), + delay(_delay), ackWrites(write_ack) + {} + + /** Check if the port should block/unblock after recieving/sending a packet. + * */ + void blockCheck(Side id); + + friend class Bridge::SendEvent; + +}; + +#endif //__MEM_BUS_HH__ diff --git a/mem/bus.cc b/mem/bus.cc index 86e834894..acc941434 100644 --- a/mem/bus.cc +++ b/mem/bus.cc @@ -35,13 +35,22 @@ #include "mem/bus.hh" #include "sim/builder.hh" +/** Get the ranges of anyone that we are connected to. */ +void +Bus::init() +{ + std::vector::iterator intIter; + for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++) + (*intIter)->sendStatusChange(Port::RangeChange); +} + + /** Function called by the port when the bus is recieving a Timing * transaction.*/ bool Bus::recvTiming(Packet &pkt, int id) { - - panic("I need to be implemented, but not right now."); + return findPort(pkt.addr, id)->sendTiming(pkt); } Port * @@ -90,10 +99,13 @@ Bus::recvFunctional(Packet &pkt, int id) void Bus::recvStatusChange(Port::Status status, int id) { + DPRINTF(Bus, "Bus %d recieved status change from device id %d\n", + busId, id); assert(status == Port::RangeChange && "The other statuses need to be implemented."); assert(id < interfaces.size() && id >= 0); + int x; Port *port = interfaces[id]; AddrRangeList ranges; AddrRangeList snoops; @@ -122,12 +134,31 @@ Bus::recvStatusChange(Port::Status status, int id) portList.push_back(dm); } DPRINTF(MMU, "port list has %d entries\n", portList.size()); + + // tell all our peers that our address range has changed. + // Don't tell the device that caused this change, it already knows + for (x = 0; x < interfaces.size(); x++) + if (x != id) + interfaces[x]->sendStatusChange(Port::RangeChange); } void -Bus::BusPort::addressRanges(AddrRangeList &resp, AddrRangeList &snoop) +Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) { - panic("I'm not implemented.\n"); + std::vector::iterator portIter; + + resp.clear(); + snoop.clear(); + + DPRINTF(Bus, "Bus id %d recieved address range request returning\n", + busId); + for (portIter = portList.begin(); portIter != portList.end(); portIter++) { + if (portIter->portId != id) { + resp.push_back(portIter->range); + DPRINTF(Bus, "-- %#llX : %#llX\n", portIter->range.start, + portIter->range.end); + } + } } BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus) @@ -137,12 +168,12 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus) END_DECLARE_SIM_OBJECT_PARAMS(Bus) BEGIN_INIT_SIM_OBJECT_PARAMS(Bus) - INIT_PARAM(bus_id, "junk bus id") -END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) + INIT_PARAM(bus_id, "a globally unique bus id") +END_INIT_SIM_OBJECT_PARAMS(Bus) CREATE_SIM_OBJECT(Bus) { - return new Bus(getInstanceName()); + return new Bus(getInstanceName(), bus_id); } REGISTER_SIM_OBJECT("Bus", Bus) diff --git a/mem/bus.hh b/mem/bus.hh index fad44aba5..de9259a90 100644 --- a/mem/bus.hh +++ b/mem/bus.hh @@ -45,6 +45,9 @@ class Bus : public MemObject { + /** a globally unique id for this bus. */ + int busId; + struct DevMap { int portId; Range range; @@ -77,6 +80,14 @@ class Bus : public MemObject Port * Bus::findPort(Addr addr, int id); + /** Process address range request. + * @param resp addresses that we can respond to + * @param snoop addresses that we would like to snoop + * @param id ide of the busport that made the request. + */ + void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id); + + /** Decleration of the buses port type, one will be instantiated for each of the interfaces connecting to the bus. */ class BusPort : public Port @@ -120,7 +131,8 @@ class Bus : public MemObject // downstream from this bus, yes? That is, the union of all // the 'owned' address ranges of all the other interfaces on // this bus... - virtual void addressRanges(AddrRangeList &resp, AddrRangeList &snoop); + virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + { bus->addressRanges(resp, snoop, id); } // Hack to make translating port work without changes virtual int deviceBlockSize() { return 32; } @@ -141,8 +153,11 @@ class Bus : public MemObject interfaces.push_back(new BusPort(this, id)); return interfaces.back(); } - Bus(const std::string &n) - : MemObject(n) {} + + virtual void init(); + + Bus(const std::string &n, int bus_id) + : MemObject(n), busId(bus_id) {} }; diff --git a/mem/packet.cc b/mem/packet.cc new file mode 100644 index 000000000..590617f99 --- /dev/null +++ b/mem/packet.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 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. + */ + +/** + * @file + * Definition of the Packet Class, a packet is a transaction occuring + * between a single level of the memory heirarchy (ie L1->L2). + */ +#include "mem/packet.hh" + +bool fixPacket(Packet &func, Packet &timing) +{ panic("Need to implement!"); } diff --git a/mem/packet.hh b/mem/packet.hh index 4329094d5..a5bd6bc59 100644 --- a/mem/packet.hh +++ b/mem/packet.hh @@ -142,7 +142,7 @@ struct Packet Packet() : data(NULL), staticData(false), dynamicData(false), arrayData(false), - result(Unknown) + time(curTick), result(Unknown) {} ~Packet() @@ -156,6 +156,7 @@ struct Packet deleteData(); dynamicData = false; arrayData = false; + time = curTick; } } @@ -231,6 +232,21 @@ struct Packet arrayData = true; data = new uint8_t[size]; } + + /** Do the packet modify the same addresses. */ + bool intersect(Packet *p) { + Addr s1 = addr; + Addr e1 = addr + size; + Addr s2 = p->addr; + Addr e2 = p->addr + p->size; + + if (s1 >= s2 && s1 < e2) + return true; + if (e1 >= s2 && e1 < e2) + return true; + return false; + } }; +bool fixPacket(Packet &func, Packet &timing); #endif //__MEM_PACKET_HH diff --git a/mem/physical.cc b/mem/physical.cc index 02a48b22b..fd304e63b 100644 --- a/mem/physical.cc +++ b/mem/physical.cc @@ -181,7 +181,6 @@ PhysicalMemory::getPort(const std::string &if_name) void PhysicalMemory::recvStatusChange(Port::Status status) { - panic("??"); } PhysicalMemory::MemoryPort::MemoryPort(PhysicalMemory *_memory) diff --git a/python/m5/objects/Bridge.py b/python/m5/objects/Bridge.py new file mode 100644 index 000000000..ada715ce9 --- /dev/null +++ b/python/m5/objects/Bridge.py @@ -0,0 +1,9 @@ +from m5 import * +from MemObject import MemObject + +class Bridge(MemObject): + type = 'Bridge' + queue_size_a = Param.Int(16, "The number of requests to buffer") + queue_size_b = Param.Int(16, "The number of requests to buffer") + delay = Param.Latency('0ns', "The latency of this bridge") + write_ack = Param.Bool(False, "Should this bridge ack writes") -- cgit v1.2.3 From c4b3a2fa0f0cbddbb3590964abf1f20a2f2bc6f3 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 28 Apr 2006 15:38:43 -0400 Subject: devices should increment pkt.time instead of assiging to it --HG-- extra : convert_revision : b4ca3c7fc13bf0856eb2a800a11d5611b473ec3e --- dev/alpha_console.cc | 4 ++-- dev/ide_ctrl.cc | 4 ++-- dev/io_device.cc | 8 +++++++- dev/io_device.hh | 2 +- dev/isa_fake.cc | 4 ++-- dev/ns_gige.cc | 4 ++-- dev/pciconfigall.cc | 4 ++-- dev/sinic.cc | 4 ++-- dev/tsunami_cchip.cc | 4 ++-- dev/tsunami_io.cc | 4 ++-- dev/tsunami_pchip.cc | 4 ++-- dev/uart8250.cc | 4 ++-- 12 files changed, 28 insertions(+), 22 deletions(-) diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index e05337bfa..2e46f7be1 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -99,7 +99,7 @@ AlphaConsole::read(Packet &pkt) assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; Addr daddr = pkt.addr - pioAddr; pkt.allocate(); @@ -191,7 +191,7 @@ AlphaConsole::read(Packet &pkt) Tick AlphaConsole::write(Packet &pkt) { - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index 638be9c3d..abdbe5d0a 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -430,7 +430,7 @@ IdeController::read(Packet &pkt) IdeRegType reg_type; int disk; - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; pkt.allocate(); if (pkt.size != 1 && pkt.size != 2 && pkt.size !=4) panic("Bad IDE read size: %d\n", pkt.size); @@ -518,7 +518,7 @@ IdeController::write(Packet &pkt) int disk; uint8_t oldVal, newVal; - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; parseAddr(pkt.addr, offset, channel, reg_type); diff --git a/dev/io_device.cc b/dev/io_device.cc index 42b3c382f..24f33d84d 100644 --- a/dev/io_device.cc +++ b/dev/io_device.cc @@ -116,7 +116,13 @@ DmaPort::recvTiming(Packet &pkt) DmaReqState *state; state = (DmaReqState*)pkt.senderState; state->completionEvent->schedule(pkt.time - pkt.req->getTime()); + delete pkt.req; + delete &pkt; + } else { + delete pkt.req; + delete &pkt; } + return Success; } @@ -203,7 +209,7 @@ DmaPort::sendDma(Packet *pkt) if (state == Timing) { if (sendTiming(pkt) == Failure) transmitList.push_back(&packet); - } else if (state == Atomic) {*/ + } else if (state == Atomic) {*/ sendAtomic(*pkt); if (pkt->senderState) { DmaReqState *state = (DmaReqState*)pkt->senderState; diff --git a/dev/io_device.hh b/dev/io_device.hh index bc0160c46..1f4ef4b6e 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -167,7 +167,7 @@ class DmaPort : public Port friend class DmaPort; }; - void sendDma(Packet &pkt); + void sendDma(Packet *pkt); public: DmaPort(DmaDevice *dev, Platform *p); diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc index 8060d1a7c..2f392a41a 100644 --- a/dev/isa_fake.cc +++ b/dev/isa_fake.cc @@ -54,7 +54,7 @@ IsaFake::read(Packet &pkt) assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); @@ -80,7 +80,7 @@ IsaFake::read(Packet &pkt) Tick IsaFake::write(Packet &pkt) { - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size); pkt.result = Success; return pioDelay; diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 02c9bbca4..a2e224ed0 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -493,7 +493,7 @@ NSGigE::read(Packet &pkt) { assert(ioEnable); - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; pkt.allocate(); //The mask is to give you only the offset into the device register file @@ -729,7 +729,7 @@ NSGigE::write(Packet &pkt) DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n", daddr, pkt.addr, pkt.size); - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; if (daddr > LAST && daddr <= RESERVED) { panic("Accessing reserved register"); diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index c3597c486..dfb1d48f6 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -99,7 +99,7 @@ PciConfigAll::read(Packet &pkt) int func = (daddr >> 8) & 0x7; int reg = daddr & 0xFF; - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; pkt.allocate(); DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt.addr, daddr, @@ -134,7 +134,7 @@ PciConfigAll::read(Packet &pkt) Tick PciConfigAll::write(Packet &pkt) { - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); diff --git a/dev/sinic.cc b/dev/sinic.cc index b91ef83b0..b5b6c6cf5 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -321,7 +321,7 @@ Device::read(Packet &pkt) Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; pkt.allocate(); if (!regValid(raddr)) @@ -408,7 +408,7 @@ Device::write(Packet &pkt) Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; if (!regValid(raddr)) panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d", diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index f35c34138..7b9032f6e 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -76,7 +76,7 @@ TsunamiCChip::read(Packet &pkt) assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; Addr regnum = (pkt.addr - pioAddr) >> 6; Addr daddr = (pkt.addr - pioAddr); @@ -182,7 +182,7 @@ TsunamiCChip::read(Packet &pkt) Tick TsunamiCChip::write(Packet &pkt) { - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index ed526bdde..0efcc1028 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -441,7 +441,7 @@ TsunamiIO::read(Packet &pkt) assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; Addr daddr = pkt.addr - pioAddr; DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt.addr, @@ -505,7 +505,7 @@ TsunamiIO::read(Packet &pkt) Tick TsunamiIO::write(Packet &pkt) { - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index 05b480cb8..1323a0548 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -71,7 +71,7 @@ TsunamiPChip::read(Packet &pkt) assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; pkt.allocate(); Addr daddr = (pkt.addr - pioAddr) >> 6;; assert(pkt.size == sizeof(uint64_t)); @@ -151,7 +151,7 @@ TsunamiPChip::read(Packet &pkt) Tick TsunamiPChip::write(Packet &pkt) { - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); diff --git a/dev/uart8250.cc b/dev/uart8250.cc index 84885456f..15752c735 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -114,7 +114,7 @@ Uart8250::read(Packet &pkt) assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); assert(pkt.size == 1); - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; Addr daddr = pkt.addr - pioAddr; pkt.allocate(); @@ -198,7 +198,7 @@ Uart8250::write(Packet &pkt) assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); assert(pkt.size == 1); - pkt.time = curTick + pioDelay; + pkt.time += pioDelay; Addr daddr = pkt.addr - pioAddr; DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt.get()); -- cgit v1.2.3 From 79170b1be593cd366520166c8126ebec10144086 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 28 Apr 2006 15:40:45 -0400 Subject: random mix of tidbits configs/test/fs.py: update fs.py to use a bus bridge cpu/simple/cpu.hh: cpu should just return that it doesn't snoop any address ranges python/m5/objects/System.py: move boot_osflags to system --HG-- extra : convert_revision : b4256df7eada7e65b69513361de8bffc3fdd680b --- configs/test/fs.py | 10 +++++++--- cpu/simple/cpu.hh | 4 ++++ python/m5/objects/System.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/configs/test/fs.py b/configs/test/fs.py index 6cd4185ed..ce121bd76 100644 --- a/configs/test/fs.py +++ b/configs/test/fs.py @@ -139,9 +139,13 @@ class LinuxTsunami(BaseTsunami): pci_func=0, pci_dev=0, pci_bus=0) class LinuxAlphaSystem(LinuxAlphaSystem): - magicbus = Bus() + magicbus = Bus(bus_id=0) + magicbus2 = Bus(bus_id=1) + bridge = Bridge() physmem = PhysicalMemory(range = AddrRange('128MB')) - c1 = Connector(side_a=Parent.physmem, side_b=Parent.magicbus) + c0a = Connector(side_a=Parent.magicbus, side_b=Parent.bridge, side_b_name="side_a") + c0b = Connector(side_a=Parent.magicbus2, side_b=Parent.bridge, side_b_name="side_b") + c1 = Connector(side_a=Parent.physmem, side_b=Parent.magicbus2) tsunami = LinuxTsunami() c2 = Connector(side_a=Parent.tsunami.cchip, side_a_name='pio', side_b=Parent.magicbus) c3 = Connector(side_a=Parent.tsunami.pchip, side_a_name='pio', side_b=Parent.magicbus) @@ -177,7 +181,7 @@ class LinuxAlphaSystem(LinuxAlphaSystem): read_only=True) simple_disk = SimpleDisk(disk=Parent.raw_image) intrctrl = IntrControl() - cpu = SimpleCPU(mem=Parent.magicbus) + cpu = SimpleCPU(mem=Parent.magicbus2) sim_console = SimConsole(listener=ConsoleListener(port=3456)) kernel = '/z/saidi/work/m5.newmem/build/vmlinux' pal = binary('ts_osfpal') diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index 3640348a3..252d57206 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -103,6 +103,10 @@ class SimpleCPU : public BaseCPU virtual void recvStatusChange(Status status); virtual Packet *recvRetry(); + + virtual void getDeviceAddressRanges(AddrRangeList &resp, + AddrRangeList &snoop) + { resp.clear(); snoop.clear(); } }; MemObject *mem; diff --git a/python/m5/objects/System.py b/python/m5/objects/System.py index 65b621dff..622b5a870 100644 --- a/python/m5/objects/System.py +++ b/python/m5/objects/System.py @@ -9,6 +9,7 @@ class System(SimObject): init_param = Param.UInt64(0, "numerical value to pass into simulator") bin = Param.Bool(False, "is this system binned") binned_fns = VectorParam.String([], "functions broken down and binned") + boot_osflags = Param.String("a", "boot flags to pass to the kernel") kernel = Param.String("file that contains the kernel code") readfile = Param.String("", "file to read startup script from") @@ -16,6 +17,5 @@ class AlphaSystem(System): type = 'AlphaSystem' console = Param.String("file that contains the console code") pal = Param.String("file that contains palcode") - boot_osflags = Param.String("a", "boot flags to pass to the kernel") system_type = Param.UInt64("Type of system we are emulating") system_rev = Param.UInt64("Revision of system we are emulating") -- cgit v1.2.3 -- cgit v1.2.3 From 6a2e0388cf04fbdac68ed9543e4573a13c7f9b17 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 29 Apr 2006 17:37:25 -0400 Subject: fixes for se mem/packet.cc: mem/port.hh: fix for se compilation --HG-- extra : convert_revision : ac960e295f6b51875898245fb55383a59b06cac6 --- mem/packet.cc | 1 + mem/port.hh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mem/packet.cc b/mem/packet.cc index 590617f99..85b76919b 100644 --- a/mem/packet.cc +++ b/mem/packet.cc @@ -31,6 +31,7 @@ * Definition of the Packet Class, a packet is a transaction occuring * between a single level of the memory heirarchy (ie L1->L2). */ +#include "base/misc.hh" #include "mem/packet.hh" bool fixPacket(Packet &func, Packet &timing) diff --git a/mem/port.hh b/mem/port.hh index 9557f654c..2ab2806c9 100644 --- a/mem/port.hh +++ b/mem/port.hh @@ -227,7 +227,7 @@ class FunctionalPort : public Port virtual bool recvTiming(Packet &pkt) { panic("FuncPort is UniDir"); } virtual Tick recvAtomic(Packet &pkt) { panic("FuncPort is UniDir"); } virtual void recvFunctional(Packet &pkt) { panic("FuncPort is UniDir"); } - virtual void recvStatusChange(Status status) {panic("FuncPort is UniDir");} + virtual void recvStatusChange(Status status) {} template inline void write(Addr addr, T d) -- cgit v1.2.3 From a8fbc4ec76169a6d735817df2aa8bc2085df5ac8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 30 Apr 2006 01:46:00 -0400 Subject: Got hello world to work! arch/sparc/isa/decoder.isa: Made sure if a register was assigned to along some control path, then all paths on which no exception would block commit set a value as well. Also, Rs1 is treated as signed for bpr instructions. arch/sparc/isa/formats/integerop.isa: Added an IntOpImm11 class which sign extends the SIMM11 immediate field. arch/sparc/isa/formats/mem.isa: Fixed how offsets are used, and how disassembly is generated. arch/sparc/linux/process.cc: Added fstat and exit_group syscalls. --HG-- extra : convert_revision : 3b4427d239d254a92179a4137441125b8a364264 --- arch/sparc/isa/decoder.isa | 33 +++++++++++++++++++-------------- arch/sparc/isa/formats/integerop.isa | 15 +++++++++++++++ arch/sparc/isa/formats/mem.isa | 10 +++++++--- arch/sparc/linux/process.cc | 4 ++-- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa index ca409fa66..b9e83afd6 100644 --- a/arch/sparc/isa/decoder.isa +++ b/arch/sparc/isa/decoder.isa @@ -38,37 +38,37 @@ decode OP default Unknown::unknown() 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 @@ -350,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; }}); } } @@ -373,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;}}); diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa index 407a3e3cd..881154b67 100644 --- a/arch/sparc/isa/formats/integerop.isa +++ b/arch/sparc/isa/formats/integerop.isa @@ -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. */ diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa index ab8b85a94..12dae57e5 100644 --- a/arch/sparc/isa/formats/mem.isa +++ b/arch/sparc/isa/formats/mem.isa @@ -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, ", "); @@ -127,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)) diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc index 4818f1fcc..71be6a83a 100644 --- a/arch/sparc/linux/process.cc +++ b/arch/sparc/linux/process.cc @@ -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), /* 63 */ SyscallDesc("fstat64", unimplementedFunc), /* 64 */ SyscallDesc("getpagesize", unimplementedFunc), /* 65 */ SyscallDesc("msync", 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), -- cgit v1.2.3 From 8a9d270f6c17efa79f38e629c7cbcafa51aa8494 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 1 May 2006 18:53:28 -0400 Subject: move code from packet.hh to packet.cc and packet_impl.hh fix very annoying not-compiler bug arch/sparc/regfile.hh: 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. cpu/simple/cpu.cc: get() and set() do the conversion now dev/io_device.hh: need get() and set() defentions in all the devices mem/packet.cc: mem/packet.hh: move code from packet.hh to packet.cc mem/physical.cc: packet_impl needed for templated packet functions --HG-- extra : convert_revision : 6c11842aa928d9af7b4cabe826306fe1fe09e693 --- arch/sparc/regfile.hh | 11 ++++++- cpu/simple/cpu.cc | 8 ++--- dev/io_device.hh | 1 + mem/packet.cc | 56 +++++++++++++++++++++++++++++++++++ mem/packet.hh | 82 +++++++-------------------------------------------- mem/physical.cc | 1 + 6 files changed, 83 insertions(+), 76 deletions(-) diff --git a/arch/sparc/regfile.hh b/arch/sparc/regfile.hh index 744d51771..5169a332f 100644 --- a/arch/sparc/regfile.hh +++ b/arch/sparc/regfile.hh @@ -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); diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index be34d1791..33fe63c26 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -54,6 +54,7 @@ #include "cpu/smt.hh" #include "cpu/static_inst.hh" #include "kern/kernel_stats.hh" +#include "mem/packet_impl.hh" #include "sim/byteswap.hh" #include "sim/builder.hh" #include "sim/debug.hh" @@ -480,7 +481,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 = gtoh(data_read_pkt->get()); + data = data_read_pkt->get(); } if (traceData) { @@ -523,7 +524,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 = gtoh(data_read_pkt->get()); + data = data_read_pkt->get(); } if (traceData) { @@ -627,9 +628,8 @@ 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(hostData); + data_write_pkt->set(data); #else data_write_pkt->reset(); data = htog(data); diff --git a/dev/io_device.hh b/dev/io_device.hh index 1f4ef4b6e..e492ccf0b 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -31,6 +31,7 @@ #include "base/chunk_generator.hh" #include "mem/mem_object.hh" +#include "mem/packet_impl.hh" #include "sim/eventq.hh" #include "sim/sim_object.hh" diff --git a/mem/packet.cc b/mem/packet.cc index 85b76919b..ecd2a7be1 100644 --- a/mem/packet.cc +++ b/mem/packet.cc @@ -34,5 +34,61 @@ #include "base/misc.hh" #include "mem/packet.hh" + +/** delete the data pointed to in the data pointer. Ok to call to matter how + * data was allocted. */ +void +Packet::deleteData() { + assert(staticData || dynamicData); + if (staticData) + return; + + if (arrayData) + delete [] data; + else + delete data; +} + +/** If there isn't data in the packet, allocate some. */ +void +Packet::allocate() { + if (data) + return; + assert(!staticData); + dynamicData = true; + arrayData = true; + data = new uint8_t[size]; +} + +/** Do the packet modify the same addresses. */ +bool +Packet::intersect(Packet *p) { + Addr s1 = addr; + Addr e1 = addr + size; + Addr s2 = p->addr; + Addr e2 = p->addr + p->size; + + if (s1 >= s2 && s1 < e2) + return true; + if (e1 >= s2 && e1 < e2) + return true; + return false; +} + +/** Minimally reset a packet so something like simple cpu can reuse it. */ +void +Packet::reset() { + result = Unknown; + if (dynamicData) { + deleteData(); + dynamicData = false; + arrayData = false; + time = curTick; + } +} + + + + bool fixPacket(Packet &func, Packet &timing) { panic("Need to implement!"); } diff --git a/mem/packet.hh b/mem/packet.hh index a5bd6bc59..69d00675d 100644 --- a/mem/packet.hh +++ b/mem/packet.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -150,102 +150,42 @@ struct Packet /** Minimally reset a packet so something like simple cpu can reuse it. */ - void reset() { - result = Unknown; - if (dynamicData) { - deleteData(); - dynamicData = false; - arrayData = false; - time = curTick; - } - } + void reset(); /** Set the data pointer to the following value that should not be freed. */ template - void dataStatic(T *p) { - assert(!dynamicData); - data = (PacketDataPtr)p; - staticData = true; - } + void dataStatic(T *p); /** Set the data pointer to a value that should have delete [] called on it. */ template - void dataDynamicArray(T *p) { - assert(!staticData && !dynamicData); - data = (PacketDataPtr)p; - dynamicData = true; - arrayData = true; - } + void dataDynamicArray(T *p); /** set the data pointer to a value that should have delete called on it. */ template - void dataDynamic(T *p) { - assert(!staticData && !dynamicData); - data = (PacketDataPtr)p; - dynamicData = true; - arrayData = false; - } + void dataDynamic(T *p); /** return the value of what is pointed to in the packet. */ template - T get() { - assert(staticData || dynamicData); - assert(sizeof(T) <= size); - return *(T*)data; - } + T get(); /** get a pointer to the data ptr. */ template - T* getPtr() { - assert(staticData || dynamicData); - return (T*)data; - } - + T* getPtr(); /** set the value in the data pointer to v. */ template - void set(T v) { - assert(sizeof(T) <= size); - *(T*)data = v; - } + void set(T v); /** delete the data pointed to in the data pointer. Ok to call to matter how * data was allocted. */ - void deleteData() { - assert(staticData || dynamicData); - if (staticData) - return; - - if (arrayData) - delete [] data; - else - delete data; - } + void deleteData(); /** If there isn't data in the packet, allocate some. */ - void allocate() { - if (data) - return; - assert(!staticData); - dynamicData = true; - arrayData = true; - data = new uint8_t[size]; - } + void allocate(); /** Do the packet modify the same addresses. */ - bool intersect(Packet *p) { - Addr s1 = addr; - Addr e1 = addr + size; - Addr s2 = p->addr; - Addr e2 = p->addr + p->size; - - if (s1 >= s2 && s1 < e2) - return true; - if (e1 >= s2 && e1 < e2) - return true; - return false; - } + bool intersect(Packet *p); }; bool fixPacket(Packet &func, Packet &timing); diff --git a/mem/physical.cc b/mem/physical.cc index fd304e63b..a9cefc70b 100644 --- a/mem/physical.cc +++ b/mem/physical.cc @@ -40,6 +40,7 @@ #include "base/misc.hh" #include "config/full_system.hh" +#include "mem/packet_impl.hh" #include "mem/physical.hh" #include "sim/host.hh" #include "sim/builder.hh" -- cgit v1.2.3