diff options
41 files changed, 4491 insertions, 330 deletions
diff --git a/configs/common/cpu2000.py b/configs/common/cpu2000.py index 59799eb49..18f6aedea 100644 --- a/configs/common/cpu2000.py +++ b/configs/common/cpu2000.py @@ -518,6 +518,7 @@ class mcf(MinneDefaultBenchmark): name = 'mcf' number = 181 lang = 'C' + args = [ 'mcf.in' ] class parser(MinneDefaultBenchmark): name = 'parser' diff --git a/src/arch/alpha/predecoder.hh b/src/arch/alpha/predecoder.hh index 4e89f53a6..650f2bfa2 100644 --- a/src/arch/alpha/predecoder.hh +++ b/src/arch/alpha/predecoder.hh @@ -33,6 +33,7 @@ #include "arch/alpha/types.hh" #include "base/misc.hh" +#include "config/full_system.hh" #include "sim/host.hh" class ThreadContext; diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 21860a2e1..f3981a6eb 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -81,12 +81,12 @@ tokens = reserved + ( # code literal 'CODELIT', - # ( ) [ ] { } < > , ; : :: * + # ( ) [ ] { } < > , ; . : :: * 'LPAREN', 'RPAREN', 'LBRACKET', 'RBRACKET', 'LBRACE', 'RBRACE', 'LESS', 'GREATER', 'EQUALS', - 'COMMA', 'SEMI', 'COLON', 'DBLCOLON', + 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON', 'ASTERISK', # C preprocessor directives @@ -113,6 +113,7 @@ t_GREATER = r'\>' t_EQUALS = r'=' t_COMMA = r',' t_SEMI = r';' +t_DOT = r'\.' t_COLON = r':' t_DBLCOLON = r'::' t_ASTERISK = r'\*' @@ -261,6 +262,7 @@ def p_defs_and_outputs_1(t): def p_def_or_output(t): '''def_or_output : def_format | def_bitfield + | def_bitfield_struct | def_template | def_operand_types | def_operands @@ -363,6 +365,23 @@ def p_def_bitfield_1(t): hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) t[0] = GenCode(header_output = hash_define) +# alternate form for structure member: 'def bitfield <ID> <ID>' +def p_def_bitfield_struct(t): + 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI' + if (t[2] != ''): + error(t.lineno(1), 'error: structure bitfields are always unsigned.') + expr = 'machInst.%s' % t[5] + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + +def p_id_with_dot_0(t): + 'id_with_dot : ID' + t[0] = t[1] + +def p_id_with_dot_1(t): + 'id_with_dot : ID DOT id_with_dot' + t[0] = t[1] + t[2] + t[3] + def p_opt_signed_0(t): 'opt_signed : SIGNED' t[0] = t[1] diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 24d568162..03c8bafe2 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -132,7 +132,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 40 */ SyscallDesc("lstat", unimplementedFunc), /* 41 */ SyscallDesc("dup", unimplementedFunc), /* 42 */ SyscallDesc("pipe", pipePseudoFunc), - /* 43 */ SyscallDesc("times", unimplementedFunc), + /* 43 */ SyscallDesc("times", ignoreFunc), /* 44 */ SyscallDesc("getuid32", unimplementedFunc), /* 45 */ SyscallDesc("umount2", unimplementedFunc), //32 bit /* 46 */ SyscallDesc("setgid", unimplementedFunc), //32 bit @@ -320,7 +320,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 228 */ SyscallDesc("setfsuid", unimplementedFunc), //32 bit /* 229 */ SyscallDesc("setfsgid", unimplementedFunc), //32 bit /* 230 */ SyscallDesc("_newselect", unimplementedFunc), //32 bit - /* 231 */ SyscallDesc("time", unimplementedFunc), + /* 231 */ SyscallDesc("time", ignoreFunc), /* 232 */ SyscallDesc("oldstat", unimplementedFunc), /* 233 */ SyscallDesc("stime", unimplementedFunc), /* 234 */ SyscallDesc("statfs64", unimplementedFunc), @@ -435,7 +435,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 40 */ SyscallDesc("lstat", unimplementedFunc), /* 41 */ SyscallDesc("dup", unimplementedFunc), /* 42 */ SyscallDesc("pipe", pipePseudoFunc), - /* 43 */ SyscallDesc("times", unimplementedFunc), + /* 43 */ SyscallDesc("times", ignoreFunc), /* 44 */ SyscallDesc("getuid32", unimplementedFunc), /* 45 */ SyscallDesc("umount2", unimplementedFunc), /* 46 */ SyscallDesc("setgid", unimplementedFunc), @@ -623,7 +623,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 228 */ SyscallDesc("setfsuid", unimplementedFunc), /* 229 */ SyscallDesc("setfsgid", unimplementedFunc), /* 230 */ SyscallDesc("_newselect", unimplementedFunc), - /* 231 */ SyscallDesc("time", unimplementedFunc), + /* 231 */ SyscallDesc("time", ignoreFunc), /* 232 */ SyscallDesc("oldstat", unimplementedFunc), /* 233 */ SyscallDesc("stime", unimplementedFunc), /* 234 */ SyscallDesc("statfs64", unimplementedFunc), diff --git a/src/arch/sparc/predecoder.hh b/src/arch/sparc/predecoder.hh index 71b14b020..4a8c9dc4a 100644 --- a/src/arch/sparc/predecoder.hh +++ b/src/arch/sparc/predecoder.hh @@ -33,6 +33,7 @@ #include "arch/sparc/types.hh" #include "base/misc.hh" +#include "cpu/thread_context.hh" #include "sim/host.hh" class ThreadContext; diff --git a/src/arch/x86/intregfile.hh b/src/arch/x86/intregfile.hh index da631d444..f7b03f0f0 100644 --- a/src/arch/x86/intregfile.hh +++ b/src/arch/x86/intregfile.hh @@ -88,8 +88,9 @@ #ifndef __ARCH_X86_INTREGFILE_HH__ #define __ARCH_X86_INTREGFILE_HH__ -#include "arch/x86/x86_traits.hh" +#include "arch/x86/intregs.hh" #include "arch/x86/types.hh" +#include "arch/x86/x86_traits.hh" #include <string> @@ -102,7 +103,7 @@ namespace X86ISA //This function translates integer register file indices into names std::string getIntRegName(RegIndex); - const int NumIntArchRegs = 16; + const int NumIntArchRegs = NUM_INTREGS; const int NumIntRegs = NumIntArchRegs + NumMicroIntRegs; class IntRegFile diff --git a/src/arch/x86/intregs.hh b/src/arch/x86/intregs.hh index 3fe25bd5f..ed801cc48 100644 --- a/src/arch/x86/intregs.hh +++ b/src/arch/x86/intregs.hh @@ -77,7 +77,8 @@ namespace X86ISA INTREG_R12W, INTREG_R13W, INTREG_R14W, - INTREG_R15W + INTREG_R15W, + NUM_INTREGS }; }; diff --git a/src/arch/x86/isa/base.isa b/src/arch/x86/isa/base.isa new file mode 100644 index 000000000..4776f7a7e --- /dev/null +++ b/src/arch/x86/isa/base.isa @@ -0,0 +1,181 @@ +// Copyright (c) 2007 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// 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. +// +// Authors: Gabe Black + +//////////////////////////////////////////////////////////////////// +// +// Base class for sparc instructions, and some support functions +// + +output header {{ + + /** + * Base class for all X86 static instructions. + */ + class X86StaticInst : public StaticInst + { + protected: + // Constructor. + X86StaticInst(const char *mnem, + ExtMachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + void printReg(std::ostream &os, int reg) const; + void printSrcReg(std::ostream &os, int reg) const; + void printDestReg(std::ostream &os, int reg) const; + }; +}}; + +output decoder {{ + + inline void printMnemonic(std::ostream &os, const char * mnemonic) + { + ccprintf(os, "\t%s ", mnemonic); + } + + void + X86StaticInst::printSrcReg(std::ostream &os, int reg) const + { + if(_numSrcRegs > reg) + printReg(os, _srcRegIdx[reg]); + } + + void + X86StaticInst::printDestReg(std::ostream &os, int reg) const + { + if(_numDestRegs > reg) + printReg(os, _destRegIdx[reg]); + } + + void + X86StaticInst::printReg(std::ostream &os, int reg) const + { + if (reg < FP_Base_DepTag) { + //FIXME These should print differently depending on the + //mode etc, but for now this will get the point across + switch (reg) { + case INTREG_RAX: + ccprintf(os, "rax"); + break; + case INTREG_RBX: + ccprintf(os, "rbx"); + break; + case INTREG_RCX: + ccprintf(os, "rcx"); + break; + case INTREG_RDX: + ccprintf(os, "rdx"); + break; + case INTREG_RSP: + ccprintf(os, "rsp"); + break; + case INTREG_RBP: + ccprintf(os, "rbp"); + break; + case INTREG_RSI: + ccprintf(os, "rsi"); + break; + case INTREG_RDI: + ccprintf(os, "rdi"); + break; + case INTREG_R8W: + ccprintf(os, "r8"); + break; + case INTREG_R9W: + ccprintf(os, "r9"); + break; + case INTREG_R10W: + ccprintf(os, "r10"); + break; + case INTREG_R11W: + ccprintf(os, "r11"); + break; + case INTREG_R12W: + ccprintf(os, "r12"); + break; + case INTREG_R13W: + ccprintf(os, "r13"); + break; + case INTREG_R14W: + ccprintf(os, "r14"); + break; + case INTREG_R15W: + ccprintf(os, "r15"); + break; + } + } else if (reg < Ctrl_Base_DepTag) { + ccprintf(os, "%%f%d", reg - FP_Base_DepTag); + } else { + switch (reg - Ctrl_Base_DepTag) { + default: + ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag); + } + } + } + + std::string X86StaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream ss; + + printMnemonic(ss, mnemonic); + + return ss.str(); + } +}}; diff --git a/src/arch/x86/isa/bitfields.isa b/src/arch/x86/isa/bitfields.isa index 47aec4fa1..fff324caa 100644 --- a/src/arch/x86/isa/bitfields.isa +++ b/src/arch/x86/isa/bitfields.isa @@ -58,5 +58,30 @@ // Bitfield definitions. // -def bitfield EXAMPLE <24>; +//Prefixes +def bitfield REX rex; +def bitfield LEGACY legacy; +// Pieces of the opcode +def bitfield OPCODE_NUM opcode.num; +def bitfield OPCODE_PREFIXA opcode.prefixA; +def bitfield OPCODE_PREFIXB opcode.prefixB; +def bitfield OPCODE_OP opcode.op; +//The top 5 bits of the opcode tend to split the instructions into groups +def bitfield OPCODE_OP_TOP5 opcode.op.top5; +def bitfield OPCODE_OP_BOTTOM3 opcode.op.bottom3; + +// Immediate fields +def bitfield IMMEDIATE immediate; +def bitfield DISPLACEMENT displacement; + +//Modifier bytes +def bitfield MODRM modRM; +def bitfield MODRM_MOD modRM.mod; +def bitfield MODRM_REG modRM.reg; +def bitfield MODRM_RM modRM.rm; + +def bitfield SIB sib; +def bitfield SIB_SCALE sib.scale; +def bitfield SIB_INDEX sib.index; +def bitfield SIB_BASE sib.base; diff --git a/src/arch/x86/isa/decoder/decoder.isa b/src/arch/x86/isa/decoder/decoder.isa new file mode 100644 index 000000000..20f31f882 --- /dev/null +++ b/src/arch/x86/isa/decoder/decoder.isa @@ -0,0 +1,89 @@ +// Copyright (c) 2007 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// 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. +// +// Authors: Gabe Black + +//////////////////////////////////////////////////////////////////// +// +// The actual decoder specification +// + +decode OPCODE_NUM default Unknown::unknown() +{ + 0x0: M5InternalError::error( + {{"Saw an ExtMachInst with zero opcode bytes!"}}); + //1 byte opcodes + ##include "one_byte_opcodes.isa" + //2 byte opcodes + ##include "two_byte_opcodes.isa" + //3 byte opcodes + 0x3: decode OPCODE_PREFIXA { + 0xF0: decode OPCODE_PREFIXB { + //We don't handle these properly in the predecoder yet, so there's + //no reason to implement them for now. + 0x38: decode OPCODE_OP { + default: FailUnimpl::sseThreeEight(); + } + 0x3A: decode OPCODE_OP { + default: FailUnimpl::sseThreeA(); + } + 0xF0: decode OPCODE_OP { + default: FailUnimpl::threednow(); + } + default: M5InternalError::error( + {{"Unexpected second opcode byte in three byte opcode!"}}); + } + default: M5InternalError::error( + {{"Unexpected first opcode byte in three byte opcode!"}}); + } +} diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa new file mode 100644 index 000000000..c56a8bf92 --- /dev/null +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -0,0 +1,398 @@ +// Copyright (c) 2007 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// 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. +// +// Authors: Gabe Black + +//////////////////////////////////////////////////////////////////// +// +// Decode the one byte opcodes +// + +0x1: decode OPCODE_OP_TOP5 { + format WarnUnimpl { + 0x00: decode OPCODE_OP_BOTTOM3 { + 0x6: push_ES(); + 0x7: pop_ES(); + default: MultiOp::add( + {{out1 = in1 + in2}}, + OPCODE_OP_BOTTOM3, + [[Eb,Gb],[Ev,Gv], + [Gb,Eb],[Gv,Ev], + [Al,Ib],[rAx,Iz]]); + } + 0x01: decode OPCODE_OP_BOTTOM3 { + 0x0: or_Eb_Gb(); + 0x1: or_Ev_Gv(); + 0x2: or_Gb_Eb(); + 0x3: or_Gv_Ev(); + 0x4: or_Al_Ib(); + 0x5: or_rAX_Iz(); + 0x6: push_CS(); + //Any time this is seen, it should generate a two byte opcode + 0x7: M5InternalError::error( + {{"Saw a one byte opcode whose value was 0x0F!"}}); + } + 0x02: decode OPCODE_OP_BOTTOM3 { + 0x0: adc_Eb_Gb(); + 0x1: adc_Ev_Gv(); + 0x2: adc_Gb_Eb(); + 0x3: adc_Gv_Ev(); + 0x4: adc_Al_Ib(); + 0x5: adc_rAX_Iz(); + 0x6: push_SS(); + 0x7: pop_SS(); + } + 0x03: decode OPCODE_OP_BOTTOM3 { + 0x0: sbb_Eb_Gb(); + 0x1: sbb_Ev_Gv(); + 0x2: sbb_Gb_Eb(); + 0x3: sbb_Gv_Ev(); + 0x4: sbb_Al_Ib(); + 0x5: sbb_rAX_Iz(); + 0x6: push_DS(); + 0x7: pop_DS(); + } + 0x04: decode OPCODE_OP_BOTTOM3 { + 0x0: and_Eb_Gb(); + 0x1: and_Ev_Gv(); + 0x2: and_Gb_Eb(); + 0x3: and_Gv_Ev(); + 0x4: and_Al_Ib(); + 0x5: and_rAX_Iz(); + 0x6: M5InternalError::error( + {{"Tried to execute the ES segment override prefix!"}}); + 0x7: daa(); + } + 0x05: decode OPCODE_OP_BOTTOM3 { + 0x0: sub_Eb_Gb(); + 0x1: sub_Ev_Gv(); + 0x2: sub_Gb_Eb(); + 0x3: sub_Gv_Ev(); + 0x4: sub_Al_Ib(); + 0x5: sub_rAX_Iz(); + 0x6: M5InternalError::error( + {{"Tried to execute the CS segment override prefix!"}}); + 0x7: das(); + } + 0x06: decode OPCODE_OP_BOTTOM3 { + 0x0: xor_Eb_Gb(); + 0x1: xor_Ev_Gv(); + 0x2: xor_Gb_Eb(); + 0x3: xor_Gv_Ev(); + 0x4: xor_Al_Ib(); + 0x5: xor_rAX_Iz(); + 0x6: M5InternalError::error( + {{"Tried to execute the SS segment override prefix!"}}); + 0x7: aaa(); + } + 0x07: decode OPCODE_OP_BOTTOM3 { + 0x0: cmp_Eb_Gb(); + 0x1: cmp_Ev_Gv(); + 0x2: cmp_Gb_Eb(); + 0x3: cmp_Gv_Ev(); + 0x4: cmp_Al_Ib(); + 0x5: cmp_rAX_Iz(); + 0x6: M5InternalError::error( + {{"Tried to execute the DS segment override prefix!"}}); + 0x7: aas(); + } + 0x08: decode OPCODE_OP_BOTTOM3 { + 0x0: inc_eAX(); + 0x1: inc_eCX(); + 0x2: inc_eDX(); + 0x3: inc_eBX(); + 0x4: inc_eSP(); + 0x5: inc_eBP(); + 0x6: inc_eSI(); + 0x7: inc_eDI(); + } + 0x09: decode OPCODE_OP_BOTTOM3 { + 0x0: dec_eAX(); + 0x1: dec_eCX(); + 0x2: dec_eDX(); + 0x3: dec_eBX(); + 0x4: dec_eSP(); + 0x5: dec_eBP(); + 0x6: dec_eSI(); + 0x7: dec_eDI(); + } + 0x0A: decode OPCODE_OP_BOTTOM3 { + 0x0: push_rAX(); + 0x1: push_rCX(); + 0x2: push_rDX(); + 0x3: push_rBX(); + 0x4: push_rSP(); + 0x5: push_rBP(); + 0x6: push_rSI(); + 0x7: push_rDI(); + } + 0x0B: decode OPCODE_OP_BOTTOM3 { + 0x0: pop_rAX(); + 0x1: pop_rCX(); + 0x2: pop_rDX(); + 0x3: pop_rBX(); + 0x4: pop_rSP(); + 0x5: pop_rBP(); + 0x6: pop_rSI(); + 0x7: pop_rDI(); + } + 0x0C: decode OPCODE_OP_BOTTOM3 { + 0x0: pusha(); + 0x1: popa(); + 0x2: bound_Gv_Ma(); + 0x3: arpl_Ew_Gw(); + 0x4: M5InternalError::error( + {{"Tried to execute the FS segment override prefix!"}}); + 0x5: M5InternalError::error( + {{"Tried to execute the GS segment override prefix!"}}); + 0x6: M5InternalError::error( + {{"Tried to execute the operand size override prefix!"}}); + 0x7: M5InternalError::error( + {{"Tried to execute the DS address size override prefix!"}}); + } + 0x0D: decode OPCODE_OP_BOTTOM3 { + 0x0: push_Iz(); + 0x1: imul_Gv_Ev_Iz(); + 0x2: push_Ib(); + 0x3: imul_Gv_Ev_Ib(); + 0x4: ins_Yb_Dx(); + 0x5: ins_Yz_Dx(); + 0x6: outs_Dx_Xb(); + 0x7: outs_Dx_Xz(); + } + 0x0E: decode OPCODE_OP_BOTTOM3 { + 0x0: jo_Jb(); + 0x1: jno_Jb(); + 0x2: jb_Jb(); + 0x3: jnb_Jb(); + 0x4: jz_Jb(); + 0x5: jnz_Jb(); + 0x6: jbe_Jb(); + 0x7: jnbe_Jb(); + } + 0x0F: decode OPCODE_OP_BOTTOM3 { + 0x0: js_Jb(); + 0x1: jns_Jb(); + 0x2: jp_Jb(); + 0x3: jnp_Jb(); + 0x4: jl_Jb(); + 0x5: jnl_Jb(); + 0x6: jle_Jb(); + 0x7: jnke_Jb(); + } + 0x10: decode OPCODE_OP_BOTTOM3 { + 0x0: group1_Eb_Ib(); + 0x1: group1_Ev_Iz(); + 0x2: group1_Eb_Ib(); + 0x3: group1_Ev_Ib(); + 0x4: test_Eb_Gb(); + 0x5: test_Ev_Gv(); + 0x6: xchg_Eb_Gb(); + 0x7: xchg_Ev_Gv(); + } + 0x11: decode OPCODE_OP_BOTTOM3 { + 0x0: mov_Eb_Gb(); + 0x1: mov_Ev_Gv(); + 0x2: mov_Gb_Eb(); + 0x3: mov_Gv_Ev(); + 0x4: mov_MwRv_Sw(); + 0x5: lea_Gv_M(); + 0x6: mov_Sw_MwRv(); + 0x7: group10_Ev(); //Make sure this is Ev + } + 0x12: decode OPCODE_OP_BOTTOM3 { + 0x0: nop_or_pause(); //Check for repe prefix + 0x1: xchg_rCX_rAX(); + 0x2: xchg_rDX_rAX(); + 0x3: xchg_rVX_rAX(); + 0x4: xchg_rSP_rAX(); + 0x5: xchg_rBP_rAX(); + 0x6: xchg_rSI_rAX(); + 0x7: xchg_rDI_rAX(); + } + 0x13: decode OPCODE_OP_BOTTOM3 { + 0x0: cbw_or_cwde_or_cdqe_rAX(); + 0x1: cwd_or_cdq_or_cqo_rAX_rDX(); + 0x2: call_Ap(); + 0x3: fwait(); //aka wait + 0x4: pushf_Fv(); + 0x5: popf_Fv(); + 0x6: sahf(); + 0x7: lahf(); + } + 0x14: decode OPCODE_OP_BOTTOM3 { + 0x0: mov_Al_Ob(); + 0x1: mov_rAX_Ov(); + 0x2: mov_Ob_Al(); + 0x3: mov_Ov_rAX(); + 0x4: movs_Yb_Xb(); + 0x5: movs_Yv_Xv(); + 0x6: cmps_Yb_Xb(); + 0x7: cmps_Yv_Xv(); + } + 0x15: decode OPCODE_OP_BOTTOM3 { + 0x0: test_Al_Ib(); + 0x1: test_rAX_Iz(); + 0x2: stos_Yb_Al(); + 0x3: stos_Yv_rAX(); + 0x4: lods_Al_Xb(); + 0x5: lods_rAX_Xv(); + 0x6: scas_Yb_Al(); + 0x7: scas_Yv_rAX(); + } + 0x16: decode OPCODE_OP_BOTTOM3 { + 0x0: mov_Al_Ib(); + 0x1: mov_Cl_Ib(); + 0x2: mov_Dl_Ib(); + 0x3: mov_Bl_Ib(); + 0x4: mov_Ah_Ib(); + 0x5: mov_Ch_Ib(); + 0x6: mov_Dh_Ib(); + 0x7: mov_Bh_Ib(); + } + 0x17: decode OPCODE_OP_BOTTOM3 { + 0x0: mov_rAX_Iv(); + 0x1: mov_rCX_Iv(); + 0x2: mov_rDX_Iv(); + 0x3: mov_rBX_Iv(); + 0x4: mov_rSP_Iv(); + 0x5: mov_rBP_Iv(); + 0x6: mov_rSI_Iv(); + 0x7: mov_rDI_Iv(); + } + 0x18: decode OPCODE_OP_BOTTOM3 { + 0x0: group2_Eb_Ib(); + 0x1: group2_Ev_Ib(); + 0x2: ret_near_Iw(); + 0x3: ret_near(); + 0x4: les_Gz_Mp(); + 0x5: lds_Gz_Mp(); + 0x6: group12_Eb_Ib(); + 0x7: group12_Ev_Iz(); + } + 0x19: decode OPCODE_OP_BOTTOM3 { + 0x0: enter_Iw_Ib(); + 0x1: leave(); + 0x2: ret_far_Iw(); + 0x3: ret_far(); + 0x4: int3(); + 0x5: int_Ib(); + 0x6: into(); + 0x7: iret(); + } + 0x1A: decode OPCODE_OP_BOTTOM3 { + 0x0: group2_Eb_1(); + 0x1: group2_Ev_1(); + 0x2: group2_Eb_Cl(); + 0x3: group2_Ev_Cl(); + 0x4: aam_Ib(); + 0x5: aad_Ib(); + 0x6: salc(); + 0x7: xlat(); + } + 0x1B: decode OPCODE_OP_BOTTOM3 { + 0x0: esc0(); + 0x1: esc1(); + 0x2: esc2(); + 0x3: esc3(); + 0x4: esc4(); + 0x5: esc5(); + 0x6: esc6(); + 0x7: esc7(); + } + 0x1C: decode OPCODE_OP_BOTTOM3 { + 0x0: loopne_Jb(); + 0x1: loope_Jb(); + 0x2: loop_Jb(); + 0x3: jcxz_or_jecx_or_jrcx(); + 0x4: in_Al_Ib(); + 0x5: in_eAX_Ib(); + 0x6: out_Ib_Al(); + 0x7: out_Ib_eAX(); + } + 0x1D: decode OPCODE_OP_BOTTOM3 { + 0x0: call_Jz(); + 0x1: jmp_Jz(); + 0x2: jmp_Ap(); + 0x3: jmp_Jb(); + 0x4: in_Al_Dx(); + 0x5: in_eAX_Dx(); + 0x6: out_Dx_Al(); + 0x7: out_Dx_eAX(); + } + 0x1E: decode OPCODE_OP_BOTTOM3 { + 0x0: M5InternalError::error( + {{"Tried to execute the lock prefix!"}}); + 0x1: int1(); + 0x2: M5InternalError::error( + {{"Tried to execute the repne prefix!"}}); + 0x3: M5InternalError::error( + {{"Tried to execute the rep/repe prefix!"}}); + 0x4: hlt(); + 0x5: cmc(); + 0x6: group3_Eb(); + 0x7: group3_Ev(); + } + 0x1F: decode OPCODE_OP_BOTTOM3 { + 0x0: clc(); + 0x1: stc(); + 0x2: cli(); + 0x3: sti(); + 0x4: cld(); + 0x5: std(); + 0x6: group4(); + 0x7: group5(); + } + } + default: FailUnimpl::oneByteOps(); +} diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa new file mode 100644 index 000000000..f05c33bdb --- /dev/null +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -0,0 +1,393 @@ +// Copyright (c) 2007 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// 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. +// +// Authors: Gabe Black + +//////////////////////////////////////////////////////////////////// +// +// Decode the two byte opcodes +// +0x2: decode OPCODE_PREFIXA { + 0xF0: decode OPCODE_OP_TOP5 { + format WarnUnimpl { + 0x00: decode OPCODE_OP_BOTTOM3 { + 0x00: group6(); + 0x01: group7(); + 0x02: lar_Gv_Ew(); + 0x03: lsl_Gv_Ew(); + //sandpile.org doesn't seem to know what this is... ? + 0x04: loadall_or_reset_or_hang(); + //sandpile.org says (AMD) after syscall, so I might want to check + //if that means amd64 or AMD machines + 0x05: loadall_or_syscall(); + 0x06: clts(); + //sandpile.org says (AMD) after sysret, so I might want to check + //if that means amd64 or AMD machines + 0x07: loadall_or_sysret(); + } + 0x01: decode OPCODE_OP_BOTTOM3 { + 0x0: holderholder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x02: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x03: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x04: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x05: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x06: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x07: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x08: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x09: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x0A: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x0B: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x0C: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x0D: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x0E: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x0F: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x10: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x11: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x12: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x13: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x14: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x15: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x16: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x17: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x18: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x19: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x1A: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x1B: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x1C: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x1D: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x1E: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + 0x1F: decode OPCODE_OP_BOTTOM3 { + 0x0: holder(); + 0x1: holder(); + 0x2: holder(); + 0x3: holder(); + 0x4: holder(); + 0x5: holder(); + 0x6: holder(); + 0x7: holder(); + } + default: FailUnimpl::twoByteOps(); + } + } + default: M5InternalError::error( + {{"Unexpected first opcode byte in two byte opcode!"}}); +} diff --git a/src/arch/x86/isa/formats/basic.isa b/src/arch/x86/isa/formats/basic.isa index 7aea7085f..ea224d638 100644 --- a/src/arch/x86/isa/formats/basic.isa +++ b/src/arch/x86/isa/formats/basic.isa @@ -147,3 +147,12 @@ def template BasicDecode {{ def template BasicDecodeWithMnemonic {{ return new %(class_name)s("%(mnemonic)s", machInst); }}; + +// The most basic instruction format... used only for a few misc. insts +def format BasicOperate(code, *flags) {{ + iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/x86/isa/decoder.isa b/src/arch/x86/isa/formats/error.isa index 85f376b49..8ac2ea44d 100644 --- a/src/arch/x86/isa/decoder.isa +++ b/src/arch/x86/isa/formats/error.isa @@ -1,3 +1,5 @@ +// -*- mode:c++ -*- + // Copyright (c) 2007 The Hewlett-Packard Development Company // All rights reserved. // @@ -55,10 +57,21 @@ //////////////////////////////////////////////////////////////////// // -// The actual decoder specification +// "Format" which really indicates an internal error. This is a more +// significant problem for x86 than for other ISAs because of it's complex +// ExtMachInst type. // -decode EXAMPLE default Unknown::unknown() -{ - 0x0: Unknown::unknown2(); -} +def template ErrorDecode {{ + { + panic("X86 decoder internal error: '%%s' %%s", + %(message)s, machInst); + } +}}; + +def format M5InternalError(error_message) {{ + iop = InstObjParams(name, 'M5InternalError') + iop.message = error_message + decode_block = ErrorDecode.subst(iop) +}}; + diff --git a/src/arch/x86/isa/formats/formats.isa b/src/arch/x86/isa/formats/formats.isa index 0d3d1c6dc..d763c05bc 100644 --- a/src/arch/x86/isa/formats/formats.isa +++ b/src/arch/x86/isa/formats/formats.isa @@ -87,3 +87,14 @@ //Include the "unknown" format ##include "unknown.isa" + +//Include the "unimp" format +##include "unimp.isa" + +//Include a format to signal m5 internal errors. This is used to indicate a +//malfunction of the decode mechanism. +##include "error.isa" + +//Include a format which implements a batch of instructions which do the same +//thing on a variety of inputs +##include "multi.isa" diff --git a/src/arch/x86/isa/formats/multi.isa b/src/arch/x86/isa/formats/multi.isa new file mode 100644 index 000000000..3e80f9cfb --- /dev/null +++ b/src/arch/x86/isa/formats/multi.isa @@ -0,0 +1,106 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2007 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// 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. +// +// Authors: Gabe Black + +//////////////////////////////////////////////////////////////////// +// +// Instructions that do the same thing to multiple sets of arguments. +// + +output header {{ +}}; + +output decoder {{ +}}; + +output exec {{ +}}; + +let {{ + multiops = {} +}}; + +def format MultiOp(code, switchVal, opTags, *opt_flags) {{ + # Loads and stores that bring in and write out values from the + # instructions. These are determined by the input and output tags, + # and the resulting instruction will have the right number of micro ops, + # or could be implemented as an atomic macro op. + instNames = [] + for tagSet in opTags: + loads = [] + stores = [] + postfix = '' + for tag in tagSet: + postfix += '_' + tag + gather_inputs = '' + if len(loads) + len(stores) == 0: + # If there are no loads or stores, make this a single instruction. + iop = InstObjParams(name, Name + postfix, 'X86StaticInst', + {"code": code, "gather_inputs": gather_inputs}, + opt_flags) + else: + # Build up a macro op. We'll punt on this for now + pass + + decodeBlob = 'switch(%s) {\n' % switchVal + counter = 0 + for inst in instNames: + decodeBlob += '%d: return (X86StaticInst *)(new %s(machInst));\n' % \ + (counter, inst) + counter += 1 + decodeBlob += '}\n' + # decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; diff --git a/src/arch/x86/isa/formats/unimp.isa b/src/arch/x86/isa/formats/unimp.isa new file mode 100644 index 000000000..12fa8387b --- /dev/null +++ b/src/arch/x86/isa/formats/unimp.isa @@ -0,0 +1,174 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2007 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// 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. +// +// Authors: Gabe Black + +//////////////////////////////////////////////////////////////////// +// +// Unimplemented instructions +// + +output header {{ + /** + * Static instruction class for unimplemented instructions that + * cause simulator termination. Note that these are recognized + * (legal) instructions that the simulator does not support; the + * 'Unknown' class is used for unrecognized/illegal instructions. + * This is a leaf class. + */ + class FailUnimplemented : public X86StaticInst + { + public: + /// Constructor + FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst) + : X86StaticInst(_mnemonic, _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for unimplemented instructions that cause a warning + * to be printed (but do not terminate simulation). This + * implementation is a little screwy in that it will print a + * warning for each instance of a particular unimplemented machine + * instruction, not just for each unimplemented opcode. Should + * probably make the 'warned' flag a static member of the derived + * class. + */ + class WarnUnimplemented : public X86StaticInst + { + private: + /// Have we warned on this instruction yet? + mutable bool warned; + + public: + /// Constructor + WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst) + : X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + FailUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } + + std::string + WarnUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return csprintf("%-10s", mnemonic); +#else + return csprintf("%-10s (unimplemented)", mnemonic); +#endif + } +}}; + +output exec {{ + Fault + FailUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unimplemented instruction '%s' %s", + mnemonic, machInst); + return NoFault; + } + + Fault + WarnUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (!warned) { + warn("instruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return NoFault; + } +}}; + + +def format FailUnimpl() {{ + iop = InstObjParams(name, 'FailUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +def format WarnUnimpl() {{ + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + diff --git a/src/arch/x86/isa/main.isa b/src/arch/x86/isa/main.isa index fd1b461f0..146f714a7 100644 --- a/src/arch/x86/isa/main.isa +++ b/src/arch/x86/isa/main.isa @@ -79,10 +79,10 @@ namespace X86ISA; ##include "operands.isa" //Include the base class for x86 instructions, and some support code -//##include "base.isa" +##include "base.isa" //Include the definitions for the instruction formats ##include "formats/formats.isa" //Include the decoder definition -##include "decoder.isa" +##include "decoder/decoder.isa" diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 4b144dce0..20376f38f 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -96,4 +96,7 @@ def operand_types {{ }}; def operands {{ + # This is just copied from SPARC, because having no operands confuses + # the parser. + 'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1) }}; diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index 5ea960b36..fbed4fe41 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -78,22 +78,22 @@ namespace X86ISA uint8_t nextByte = getNextByte(); switch(state) { - case Prefix: + case PrefixState: state = doPrefixState(nextByte); break; - case Opcode: + case OpcodeState: state = doOpcodeState(nextByte); break; - case ModRM: + case ModRMState: state = doModRMState(nextByte); break; - case SIB: + case SIBState: state = doSIBState(nextByte); break; - case Displacement: + case DisplacementState: state = doDisplacementState(); break; - case Immediate: + case ImmediateState: state = doImmediateState(); break; case ErrorState: @@ -109,7 +109,7 @@ namespace X86ISA Predecoder::State Predecoder::doPrefixState(uint8_t nextByte) { uint8_t prefix = Prefixes[nextByte]; - State nextState = Prefix; + State nextState = PrefixState; if(prefix) consumeByte(); switch(prefix) @@ -149,13 +149,13 @@ namespace X86ISA case Repne: DPRINTF(Predecoder, "Found repne prefix.\n"); break; - case Rex: + case RexPrefix: DPRINTF(Predecoder, "Found Rex prefix %#x.\n", nextByte); - emi.rexPrefix = nextByte; + emi.rex = nextByte; break; case 0: - emi.numOpcodes = 0; - nextState = Opcode; + emi.opcode.num = 0; + nextState = OpcodeState; break; default: panic("Unrecognized prefix %#x\n", nextByte); @@ -168,18 +168,29 @@ namespace X86ISA Predecoder::State Predecoder::doOpcodeState(uint8_t nextByte) { State nextState = ErrorState; - emi.numOpcodes++; + emi.opcode.num++; //We can't handle 3+ byte opcodes right now - assert(emi.numOpcodes < 2); + assert(emi.opcode.num < 3); consumeByte(); - if(nextByte == 0xf0) + if(emi.opcode.num == 1 && nextByte == 0x0f) { - nextState = Opcode; + nextState = OpcodeState; DPRINTF(Predecoder, "Found two byte opcode.\n"); + emi.opcode.prefixA = nextByte; + } + else if(emi.opcode.num == 2 && + (nextByte == 0x0f || + (nextByte & 0xf8) == 0x38)) + { + panic("Three byte opcodes aren't yet supported!\n"); + nextState = OpcodeState; + DPRINTF(Predecoder, "Found three byte opcode.\n"); + emi.opcode.prefixB = nextByte; } else { DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte); + emi.opcode.op = nextByte; //Prepare for any immediate/displacement we might need immediateCollected = 0; @@ -190,22 +201,22 @@ namespace X86ISA //Figure out how big of an immediate we'll retreive based //on the opcode. int immType = ImmediateType[ - emi.numOpcodes - 1][nextByte]; + emi.opcode.num - 1][nextByte]; if(0) //16 bit mode immediateSize = ImmediateTypeToSize[0][immType]; - else if(!(emi.rexPrefix & 0x4)) //32 bit mode + else if(!(emi.rex & 0x4)) //32 bit mode immediateSize = ImmediateTypeToSize[1][immType]; else //64 bit mode immediateSize = ImmediateTypeToSize[2][immType]; //Determine what to expect next - if (UsesModRM[emi.numOpcodes - 1][nextByte]) { - nextState = ModRM; + if (UsesModRM[emi.opcode.num - 1][nextByte]) { + nextState = ModRMState; } else if(immediateSize) { - nextState = Immediate; + nextState = ImmediateState; } else { emiIsReady = true; - nextState = Prefix; + nextState = PrefixState; } } return nextState; @@ -217,6 +228,7 @@ namespace X86ISA Predecoder::State Predecoder::doModRMState(uint8_t nextByte) { State nextState = ErrorState; + emi.modRM = nextByte; DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte); if (0) {//FIXME in 16 bit mode //figure out 16 bit displacement size @@ -242,14 +254,14 @@ namespace X86ISA if(nextByte & 0x7 == 4 && nextByte & 0xC0 != 0xC0) { // && in 32/64 bit mode) - nextState = SIB; + nextState = SIBState; } else if(displacementSize) { - nextState = Displacement; + nextState = DisplacementState; } else if(immediateSize) { - nextState = Immediate; + nextState = ImmediateState; } else { emiIsReady = true; - nextState = Prefix; + nextState = PrefixState; } //The ModRM byte is consumed no matter what consumeByte(); @@ -262,15 +274,16 @@ namespace X86ISA Predecoder::State Predecoder::doSIBState(uint8_t nextByte) { State nextState = ErrorState; + emi.sib = nextByte; DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte); consumeByte(); if(displacementSize) { - nextState = Displacement; + nextState = DisplacementState; } else if(immediateSize) { - nextState = Immediate; + nextState = ImmediateState; } else { emiIsReady = true; - nextState = Prefix; + nextState = PrefixState; } return nextState; } @@ -307,14 +320,14 @@ namespace X86ISA DPRINTF(Predecoder, "Collected displacement %#x.\n", emi.displacement); if(immediateSize) { - nextState = Immediate; + nextState = ImmediateState; } else { emiIsReady = true; - nextState = Prefix; + nextState = PrefixState; } } else - nextState = Displacement; + nextState = DisplacementState; return nextState; } @@ -336,10 +349,10 @@ namespace X86ISA DPRINTF(Predecoder, "Collected immediate %#x.\n", emi.immediate); emiIsReady = true; - nextState = Prefix; + nextState = PrefixState; } else - nextState = Immediate; + nextState = ImmediateState; return nextState; } } diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh index d7734be88..1df17d6d2 100644 --- a/src/arch/x86/predecoder.hh +++ b/src/arch/x86/predecoder.hh @@ -144,12 +144,12 @@ namespace X86ISA int immediateCollected; enum State { - Prefix, - Opcode, - ModRM, - SIB, - Displacement, - Immediate, + PrefixState, + OpcodeState, + ModRMState, + SIBState, + DisplacementState, + ImmediateState, //We should never get to this state. Getting here is an error. ErrorState }; @@ -168,7 +168,7 @@ namespace X86ISA Predecoder(ThreadContext * _tc) : tc(_tc), basePC(0), offset(0), outOfBytes(true), emiIsReady(false), - state(Prefix) + state(PrefixState) {} ThreadContext * getTC() diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc index 0cebef61a..f233ad234 100644 --- a/src/arch/x86/predecoder_tables.cc +++ b/src/arch/x86/predecoder_tables.cc @@ -72,7 +72,7 @@ namespace X86ISA const uint8_t LO = Lock; const uint8_t RE = Rep; const uint8_t RN = Repne; - const uint8_t RX = Rex; + const uint8_t RX = RexPrefix; //This table identifies whether a byte is a prefix, and if it is, //which prefix it is. diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index 583f03d55..ca4a15d24 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -61,6 +61,9 @@ #include <inttypes.h> #include <iostream> +#include "base/bitfield.hh" +#include "base/cprintf.hh" + namespace X86ISA { //This really determines how many bytes are passed to the predecoder. @@ -76,7 +79,7 @@ namespace X86ISA SSOverride = 6, //The Rex prefix obviously doesn't fit in with the above, but putting //it here lets us save double the space the enums take up. - Rex = 7, + RexPrefix = 7, //There can be only one segment override, so they share the //first 3 bits in the legacyPrefixes bitfield. SegmentOverride = 0x7, @@ -87,43 +90,71 @@ namespace X86ISA Repne = 128 }; + BitUnion8(ModRM) + Bitfield<7,6> mod; + Bitfield<5,3> reg; + Bitfield<2,0> rm; + EndBitUnion(ModRM) + + BitUnion8(Sib) + Bitfield<7,6> scale; + Bitfield<5,3> index; + Bitfield<2,0> base; + EndBitUnion(Sib) + + BitUnion8(Rex) + Bitfield<3> w; + Bitfield<2> r; + Bitfield<1> x; + Bitfield<0> b; + EndBitUnion(Rex) + + BitUnion8(Opcode) + Bitfield<7,3> top5; + Bitfield<2,0> bottom3; + EndBitUnion(Opcode) + //The intermediate structure the x86 predecoder returns. struct ExtMachInst { - public: //XXX These should be hidden in the future - - uint8_t legacyPrefixes; - uint8_t rexPrefix; - //Right now, we ignore that this can be 3 in - //some cases - uint8_t numOpcodes; - //This will need to be decoded specially later - bool is3dnow; - uint8_t opcode; + //Prefixes + uint8_t legacy; + Rex rex; + //This holds all of the bytes of the opcode + struct + { + //The number of bytes in this opcode. Right now, we ignore that + //this can be 3 in some cases + uint8_t num; + //The first byte detected in a 2+ byte opcode. Should be 0xF0. + uint8_t prefixA; + //The second byte detected in a 3+ byte opcode. Could be 0xF0 for + //3dnow instructions, or 0x38-0x3F for some SSE instructions. + uint8_t prefixB; + //The main opcode byte. The highest addressed byte in the opcode. + Opcode op; + } opcode; + //Modifier bytes + ModRM modRM; + uint8_t sib; + //Immediate fields uint64_t immediate; uint64_t displacement; - - public: - - //These are to pacify the decoder for now. This will go away once - //it can handle non integer inputs, and in the mean time allow me to - //excercise the predecoder a little. - operator unsigned int() - { - return 0; - } - - ExtMachInst(unsigned int) - {;} - - ExtMachInst() - {;} }; inline static std::ostream & operator << (std::ostream & os, const ExtMachInst & emi) { - os << "{X86 ExtMachInst}"; + ccprintf(os, "\n{\n\tleg = %#x,\n\trex = %#x,\n\t" + "op = {\n\t\tnum = %d,\n\t\top = %#x,\n\t\t" + "prefixA = %#x,\n\t\tprefixB = %#x\n\t},\n\t" + "modRM = %#x,\n\tsib = %#x,\n\t" + "immediate = %#x,\n\tdisplacement = %#x\n}\n", + emi.legacy, (uint8_t)emi.rex, + emi.opcode.num, emi.opcode.op, + emi.opcode.prefixA, emi.opcode.prefixB, + (uint8_t)emi.modRM, (uint8_t)emi.sib, + emi.immediate, emi.displacement); return os; } diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh index 79dbcc86c..69cce2245 100644 --- a/src/base/bitfield.hh +++ b/src/base/bitfield.hh @@ -130,6 +130,273 @@ findMsbSet(uint64_t val) { return msb; } +// The following implements the BitUnion system of defining bitfields +//on top of an underlying class. This is done through the pervasive use of +//both named and unnamed unions which all contain the same actual storage. +//Since they're unioned with each other, all of these storage locations +//overlap. This allows all of the bitfields to manipulate the same data +//without having to have access to each other. More details are provided with the +//individual components. +//This namespace is for classes which implement the backend of the BitUnion +//stuff. Don't use any of these directly, except for the Bitfield classes in +//the *BitfieldTypes class(es). +namespace BitfieldBackend +{ + //A base class for all bitfields. It instantiates the actual storage, + //and provides getBits and setBits functions for manipulating it. The + //Data template parameter is type of the underlying storage. + template<class Data> + class BitfieldBase + { + protected: + Data __data; + + //This function returns a range of bits from the underlying storage. + //It relies on the "bits" function above. It's the user's + //responsibility to make sure that there is a properly overloaded + //version of this function for whatever type they want to overlay. + inline uint64_t + getBits(int first, int last) const + { + return bits(__data, first, last); + } + + //Similar to the above, but for settings bits with replaceBits. + inline void + setBits(int first, int last, uint64_t val) + { + replaceBits(__data, first, last, val); + } + }; + + //This class contains all the "regular" bitfield classes. It is inherited + //by all BitUnions which give them access to those types. + template<class Type> + class RegularBitfieldTypes + { + protected: + //This class implements ordinary bitfields, that is a span of bits + //who's msb is "first", and who's lsb is "last". + template<int first, int last=first> + class Bitfield : public BitfieldBase<Type> + { + public: + operator uint64_t () const + { + return this->getBits(first, last); + } + + uint64_t + operator=(const uint64_t _data) + { + this->setBits(first, last, _data); + return _data; + } + }; + + //A class which specializes the above so that it can only be read + //from. This is accomplished explicitly making sure the assignment + //operator is blocked. The conversion operator is carried through + //inheritance. This will unfortunately need to be copied into each + //bitfield type due to limitations with how templates work + template<int first, int last=first> + class BitfieldRO : public Bitfield<first, last> + { + private: + uint64_t + operator=(const uint64_t _data); + }; + + //Similar to the above, but only allows writing. + template<int first, int last=first> + class BitfieldWO : public Bitfield<first, last> + { + private: + operator uint64_t () const; + + public: + using Bitfield<first, last>::operator=; + }; + }; + + //This class contains all the "regular" bitfield classes. It is inherited + //by all BitUnions which give them access to those types. + template<class Type> + class SignedBitfieldTypes + { + protected: + //This class implements ordinary bitfields, that is a span of bits + //who's msb is "first", and who's lsb is "last". + template<int first, int last=first> + class SignedBitfield : public BitfieldBase<Type> + { + public: + operator int64_t () const + { + return sext<first - last + 1>(this->getBits(first, last)); + } + + int64_t + operator=(const int64_t _data) + { + this->setBits(first, last, _data); + return _data; + } + }; + + //A class which specializes the above so that it can only be read + //from. This is accomplished explicitly making sure the assignment + //operator is blocked. The conversion operator is carried through + //inheritance. This will unfortunately need to be copied into each + //bitfield type due to limitations with how templates work + template<int first, int last=first> + class SignedBitfieldRO : public SignedBitfield<first, last> + { + private: + int64_t + operator=(const int64_t _data); + }; + + //Similar to the above, but only allows writing. + template<int first, int last=first> + class SignedBitfieldWO : public SignedBitfield<first, last> + { + private: + operator int64_t () const; + + public: + int64_t operator=(const int64_t _data) + { + *((SignedBitfield<first, last> *)this) = _data; + return _data; + } + }; + }; + + template<class Type> + class BitfieldTypes : public RegularBitfieldTypes<Type>, + public SignedBitfieldTypes<Type> + {}; + + //When a BitUnion is set up, an underlying class is created which holds + //the actual union. This class then inherits from it, and provids the + //implementations for various operators. Setting things up this way + //prevents having to redefine these functions in every different BitUnion + //type. More operators could be implemented in the future, as the need + //arises. + template <class Type, class Base> + class BitUnionOperators : public Base + { + public: + operator Type () const + { + return Base::__data; + } + + Type + operator=(const Type & _data) + { + Base::__data = _data; + return _data; + } + + bool + operator<(const Base & base) const + { + return Base::__data < base.__data; + } + + bool + operator==(const Base & base) const + { + return Base::__data == base.__data; + } + }; +} + +//This macro is a backend for other macros that specialize it slightly. +//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and +//sticks the class which has the actual union in it, which +//BitfieldOperators above inherits from. Putting these classes in a special +//namespace ensures that there will be no collisions with other names as long +//as the BitUnion names themselves are all distinct and nothing else uses +//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself +//creates a typedef of the "type" parameter called __DataType. This allows +//the type to propagate outside of the macro itself in a controlled way. +//Finally, the base storage is defined which BitfieldOperators will refer to +//in the operators it defines. This macro is intended to be followed by +//bitfield definitions which will end up inside it's union. As explained +//above, these is overlayed the __data member in its entirety by each of the +//bitfields which are defined in the union, creating shared storage with no +//overhead. +#define __BitUnion(type, name) \ + namespace BitfieldUnderlyingClasses \ + { \ + class name; \ + } \ + class BitfieldUnderlyingClasses::name : \ + public BitfieldBackend::BitfieldTypes<type> \ + { \ + public: \ + typedef type __DataType; \ + union { \ + type __data;\ + +//This closes off the class and union started by the above macro. It is +//followed by a typedef which makes "name" refer to a BitfieldOperator +//class inheriting from the class and union just defined, which completes +//building up the type for the user. +#define EndBitUnion(name) \ + }; \ + }; \ + typedef BitfieldBackend::BitUnionOperators< \ + BitfieldUnderlyingClasses::name::__DataType, \ + BitfieldUnderlyingClasses::name> name; + +//This sets up a bitfield which has other bitfields nested inside of it. The +//__data member functions like the "underlying storage" of the top level +//BitUnion. Like everything else, it overlays with the top level storage, so +//making it a regular bitfield type makes the entire thing function as a +//regular bitfield when referred to by itself. +#define __SubBitUnion(fieldType, first, last, name) \ + class : public BitfieldBackend::BitfieldTypes<__DataType> \ + { \ + public: \ + union { \ + fieldType<first, last> __data; + +//This closes off the union created above and gives it a name. Unlike the top +//level BitUnion, we're interested in creating an object instead of a type. +//The operators are defined in the macro itself instead of a class for +//technical reasons. If someone determines a way to move them to one, please +//do so. +#define EndSubBitUnion(name) \ + }; \ + inline operator const __DataType () \ + { return __data; } \ + \ + inline const __DataType operator = (const __DataType & _data) \ + { __data = _data; } \ + } name; + +//Regular bitfields +//These define macros for read/write regular bitfield based subbitfields. +#define SubBitUnion(name, first, last) \ + __SubBitUnion(Bitfield, first, last, name) + +//Regular bitfields +//These define macros for read/write regular bitfield based subbitfields. +#define SignedSubBitUnion(name, first, last) \ + __SubBitUnion(SignedBitfield, first, last, name) + +//Use this to define an arbitrary type overlayed with bitfields. +#define BitUnion(type, name) __BitUnion(type, name) + +//Use this to define conveniently sized values overlayed with bitfields. +#define BitUnion64(name) __BitUnion(uint64_t, name) +#define BitUnion32(name) __BitUnion(uint32_t, name) +#define BitUnion16(name) __BitUnion(uint16_t, name) +#define BitUnion8(name) __BitUnion(uint8_t, name) #endif // __BASE_BITFIELD_HH__ diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 54d8c68fa..c568b1439 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -31,14 +31,17 @@ * Steve Raasch */ +#include <errno.h> #include <fstream> #include <iomanip> #include <sys/ipc.h> #include <sys/shm.h> +#include "arch/predecoder.hh" #include "arch/regfile.hh" #include "arch/utility.hh" #include "base/loader/symtab.hh" +#include "base/socket.hh" #include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" @@ -64,6 +67,7 @@ static bool wasMicro = false; namespace Trace { SharedData *shared_data = NULL; +ListenSocket *cosim_listener = NULL; void setupSharedData() @@ -149,9 +153,96 @@ Trace::InstRecord::dump() ostream &outs = Trace::output(); DPRINTF(Sparc, "Instruction: %#X\n", staticInst->machInst); + bool diff = true; if (IsOn(ExecRegDelta)) { + diff = false; +#ifndef NDEBUG #if THE_ISA == SPARC_ISA + static int fd = 0; + //Don't print what happens for each micro-op, just print out + //once at the last op, and for regular instructions. + if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) + { + if(!cosim_listener) + { + int port = 8000; + cosim_listener = new ListenSocket(); + while(!cosim_listener->listen(port, true)) + { + DPRINTF(GDBMisc, "Can't bind port %d\n", port); + port++; + } + ccprintf(cerr, "Listening for cosimulator on port %d\n", port); + fd = cosim_listener->accept(); + } + char prefix[] = "goli"; + for(int p = 0; p < 4; p++) + { + for(int i = 0; i < 8; i++) + { + uint64_t regVal; + int res = read(fd, ®Val, sizeof(regVal)); + if(res < 0) + panic("First read call failed! %s\n", strerror(errno)); + regVal = TheISA::gtoh(regVal); + uint64_t realRegVal = thread->readIntReg(p * 8 + i); + if((regVal & 0xffffffffULL) != (realRegVal & 0xffffffffULL)) + { + DPRINTF(ExecRegDelta, "Register %s%d should be %#x but is %#x.\n", prefix[p], i, regVal, realRegVal); + diff = true; + } + //ccprintf(outs, "%s%d m5 = %#x statetrace = %#x\n", prefix[p], i, realRegVal, regVal); + } + } + /*for(int f = 0; f <= 62; f+=2) + { + uint64_t regVal; + int res = read(fd, ®Val, sizeof(regVal)); + if(res < 0) + panic("First read call failed! %s\n", strerror(errno)); + regVal = TheISA::gtoh(regVal); + uint64_t realRegVal = thread->readFloatRegBits(f, 64); + if(regVal != realRegVal) + { + DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal); + } + }*/ + uint64_t regVal; + int res = read(fd, ®Val, sizeof(regVal)); + if(res < 0) + panic("First read call failed! %s\n", strerror(errno)); + regVal = TheISA::gtoh(regVal); + uint64_t realRegVal = thread->readNextPC(); + if(regVal != realRegVal) + { + DPRINTF(ExecRegDelta, "Register pc should be %#x but is %#x.\n", regVal, realRegVal); + diff = true; + } + res = read(fd, ®Val, sizeof(regVal)); + if(res < 0) + panic("First read call failed! %s\n", strerror(errno)); + regVal = TheISA::gtoh(regVal); + realRegVal = thread->readNextNPC(); + if(regVal != realRegVal) + { + DPRINTF(ExecRegDelta, "Register npc should be %#x but is %#x.\n", regVal, realRegVal); + diff = true; + } + res = read(fd, ®Val, sizeof(regVal)); + if(res < 0) + panic("First read call failed! %s\n", strerror(errno)); + regVal = TheISA::gtoh(regVal); + realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2); + if((regVal & 0xF) != (realRegVal & 0xF)) + { + DPRINTF(ExecRegDelta, "Register ccr should be %#x but is %#x.\n", regVal, realRegVal); + diff = true; + } + } +#endif +#endif +#if 0 //THE_ISA == SPARC_ISA //Don't print what happens for each micro-op, just print out //once at the last op, and for regular instructions. if(!staticInst->isMicroOp() || staticInst->isLastMicroOp()) @@ -210,7 +301,8 @@ Trace::InstRecord::dump() } #endif } - else if (IsOn(ExecIntel)) { + if(!diff) { + } else if (IsOn(ExecIntel)) { ccprintf(outs, "%7d ) ", when); outs << "0x" << hex << PC << ":\t"; if (staticInst->isLoad()) { @@ -302,6 +394,7 @@ Trace::InstRecord::dump() outs << endl; } #if THE_ISA == SPARC_ISA && FULL_SYSTEM + static TheISA::Predecoder predecoder(NULL); // Compare if (IsOn(ExecLegion)) { @@ -556,9 +649,13 @@ Trace::InstRecord::dump() << staticInst->disassemble(m5Pc, debugSymbolTable) << endl; + predecoder.setTC(thread); + predecoder.moreBytes(m5Pc, 0, shared_data->instruction); + + assert(predecoder.extMachInstRead()); + StaticInstPtr legionInst = - StaticInst::decode(makeExtMI(shared_data->instruction, - thread)); + StaticInst::decode(predecoder.getExtMachInst()); outs << setfill(' ') << setw(15) << " Legion Inst: " << "0x" << setw(8) << setfill('0') << hex diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc index 5476ef9eb..d6449f6c5 100644 --- a/src/dev/i8254xGBe.cc +++ b/src/dev/i8254xGBe.cc @@ -35,7 +35,13 @@ * other MACs with slight modifications. */ + +/* + * @todo really there are multiple dma engines.. we should implement them. + */ + #include "base/inet.hh" +#include "base/trace.hh" #include "dev/i8254xGBe.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" @@ -43,32 +49,34 @@ #include "sim/stats.hh" #include "sim/system.hh" +#include <algorithm> + using namespace iGbReg; +using namespace Net; IGbE::IGbE(Params *p) - : PciDev(p), etherInt(NULL), useFlowControl(p->use_flow_control) + : PciDev(p), etherInt(NULL), useFlowControl(p->use_flow_control), + rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxTick(false), + txTick(false), rdtrEvent(this), radvEvent(this), tadvEvent(this), + tidvEvent(this), tickEvent(this), interEvent(this), + rxDescCache(this, name()+".TxDesc", p->rx_desc_cache_size), + txDescCache(this, name()+".RxDesc", p->tx_desc_cache_size), clock(p->clock) { // Initialized internal registers per Intel documentation - regs.tctl(0); - regs.rctl(0); - regs.ctrl(0); + // All registers intialized to 0 by per register constructor regs.ctrl.fd(1); regs.ctrl.lrst(1); regs.ctrl.speed(2); regs.ctrl.frcspd(1); - regs.sts(0); regs.sts.speed(3); // Say we're 1000Mbps regs.sts.fd(1); // full duplex - regs.eecd(0); regs.eecd.fwe(1); regs.eecd.ee_type(1); - regs.eerd(0); - regs.icr(0); - regs.rctl(0); - regs.tctl(0); - regs.fcrtl(0); + regs.imr = 0; + regs.iam = 0; + regs.rxdctl.gran(1); + regs.rxdctl.wthresh(1); regs.fcrth(1); - regs.manc(0); regs.pba.rxa(0x30); regs.pba.txa(0x10); @@ -92,6 +100,9 @@ IGbE::IGbE(Params *p) // Magic happy checksum value flash[EEPROM_SIZE-1] = htobe((uint16_t)(EEPROM_CSUM - csum)); + + rxFifo.clear(); + txFifo.clear(); } @@ -156,7 +167,12 @@ IGbE::read(PacketPtr pkt) break; case REG_ICR: pkt->set<uint32_t>(regs.icr()); - // handle auto setting mask from IAM + if (regs.icr.int_assert()) + regs.imr &= regs.iam; + if (regs.imr == 0 || (regs.icr.int_assert() && regs.ctrl_ext.iame())) { + regs.icr(0); + cpuClearInt(); + } break; case REG_ITR: pkt->set<uint32_t>(regs.itr()); @@ -200,6 +216,18 @@ IGbE::read(PacketPtr pkt) break; case REG_RDTR: pkt->set<uint32_t>(regs.rdtr()); + if (regs.rdtr.fpd()) { + rxDescCache.writeback(0); + postInterrupt(IT_RXT); + regs.rdtr.fpd(0); + } + if (regs.rdtr.delay()) { + Tick t = regs.rdtr.delay() * Clock::Int::ns * 1024; + if (rdtrEvent.scheduled()) + rdtrEvent.reschedule(curTick + t); + else + rdtrEvent.schedule(curTick + t); + } break; case REG_RADV: pkt->set<uint32_t>(regs.radv()); @@ -271,6 +299,9 @@ IGbE::write(PacketPtr pkt) /// uint32_t val = pkt->get<uint32_t>(); + Regs::RCTL oldrctl; + Regs::TCTL oldtctl; + switch (daddr) { case REG_CTRL: regs.ctrl = val; @@ -372,36 +403,60 @@ IGbE::write(PacketPtr pkt) regs.mdic.r(1); break; case REG_ICR: - regs.icr = val; - // handle auto setting mask from IAM + if (regs.icr.int_assert()) + regs.imr &= regs.iam; + + regs.icr = ~bits(val,30,0) & regs.icr(); + // if no more bits are set clear the int_asserted bit + if (!bits(regs.icr(),31,31)) + cpuClearInt(); + break; case REG_ITR: regs.itr = val; break; case REG_ICS: - regs.icr = val | regs.icr(); - // generate an interrupt if needed here + postInterrupt((IntTypes)val); break; case REG_IMS: regs.imr |= val; - // handle interrupts if needed here + chkInterrupt(); break; case REG_IMC: - regs.imr |= ~val; - // handle interrupts if needed here + regs.imr &= ~val; + chkInterrupt(); break; case REG_IAM: regs.iam = val; break; case REG_RCTL: + oldrctl = regs.rctl; regs.rctl = val; + if (regs.rctl.rst()) { + rxDescCache.reset(); + rxFifo.clear(); + regs.rctl.rst(0); + } + if (regs.rctl.en()) + rxTick = true; + if ((rxTick || txTick) && !tickEvent.scheduled()) + tickEvent.schedule(curTick + cycles(1)); break; case REG_FCTTV: regs.fcttv = val; break; case REG_TCTL: regs.tctl = val; - break; + oldtctl = regs.tctl; + regs.tctl = val; + if (regs.tctl.en()) + txTick = true; + if ((rxTick || txTick) && !tickEvent.scheduled()) + tickEvent.schedule(curTick + cycles(1)); + if (regs.tctl.en() && !oldtctl.en()) { + txDescCache.reset(); + } + break; case REG_PBA: regs.pba.rxa(val); regs.pba.txa(64 - regs.pba.rxa()); @@ -424,18 +479,25 @@ IGbE::write(PacketPtr pkt) break; case REG_RDBAL: regs.rdba.rdbal( val & ~mask(4)); + rxDescCache.areaChanged(); break; case REG_RDBAH: regs.rdba.rdbah(val); + rxDescCache.areaChanged(); break; case REG_RDLEN: regs.rdlen = val & ~mask(7); + rxDescCache.areaChanged(); break; case REG_RDH: regs.rdh = val; + rxDescCache.areaChanged(); break; case REG_RDT: regs.rdt = val; + rxTick = true; + if ((rxTick || txTick) && !tickEvent.scheduled()) + tickEvent.schedule(curTick + cycles(1)); break; case REG_RDTR: regs.rdtr = val; @@ -445,18 +507,25 @@ IGbE::write(PacketPtr pkt) break; case REG_TDBAL: regs.tdba.tdbal( val & ~mask(4)); + txDescCache.areaChanged(); break; case REG_TDBAH: regs.tdba.tdbah(val); + txDescCache.areaChanged(); break; case REG_TDLEN: regs.tdlen = val & ~mask(7); + txDescCache.areaChanged(); break; case REG_TDH: regs.tdh = val; + txDescCache.areaChanged(); break; case REG_TDT: regs.tdt = val; + txTick = true; + if ((rxTick || txTick) && !tickEvent.scheduled()) + tickEvent.schedule(curTick + cycles(1)); break; case REG_TIDV: regs.tidv = val; @@ -484,18 +553,585 @@ IGbE::write(PacketPtr pkt) return pioDelay; } +void +IGbE::postInterrupt(IntTypes t, bool now) +{ + // Interrupt is already pending + if (t & regs.icr()) + return; + + if (regs.icr() & regs.imr) + { + // already in an interrupt state, set new int and done + regs.icr = regs.icr() | t; + } else { + regs.icr = regs.icr() | t; + if (regs.itr.interval() == 0 || now) { + if (now) { + if (interEvent.scheduled()) + interEvent.deschedule(); + } + cpuPostInt(); + } else { + DPRINTF(EthernetIntr, "EINT: Scheduling timer interrupt for %d ticks\n", + Clock::Int::ns * 256 * regs.itr.interval()); + assert(!interEvent.scheduled()); + interEvent.schedule(curTick + Clock::Int::ns * 256 * regs.itr.interval()); + } + } +} + +void +IGbE::cpuPostInt() +{ + if (rdtrEvent.scheduled()) { + regs.icr.rxt0(1); + rdtrEvent.deschedule(); + } + if (radvEvent.scheduled()) { + regs.icr.rxt0(1); + radvEvent.deschedule(); + } + if (tadvEvent.scheduled()) { + regs.icr.txdw(1); + tadvEvent.deschedule(); + } + if (tidvEvent.scheduled()) { + regs.icr.txdw(1); + tidvEvent.deschedule(); + } + + regs.icr.int_assert(1); + DPRINTF(EthernetIntr, "EINT: Posting interrupt to CPU now. Vector %#x\n", + regs.icr()); + intrPost(); +} + +void +IGbE::cpuClearInt() +{ + regs.icr.int_assert(0); + DPRINTF(EthernetIntr, "EINT: Clearing interrupt to CPU now. Vector %#x\n", + regs.icr()); + intrClear(); +} + +void +IGbE::chkInterrupt() +{ + // Check if we need to clear the cpu interrupt + if (!(regs.icr() & regs.imr)) + cpuClearInt(); + + // Check if we need to set the cpu interupt + postInterrupt(IT_NONE); +} + + +IGbE::RxDescCache::RxDescCache(IGbE *i, const std::string n, int s) + : DescCache<RxDesc>(i, n, s), pktDone(false), pktEvent(this) + +{ +} bool -IGbE::ethRxPkt(EthPacketPtr packet) +IGbE::RxDescCache::writePacket(EthPacketPtr packet) +{ + // We shouldn't have to deal with any of these yet + assert(packet->length < igbe->regs.rctl.descSize()); + + if (!unusedCache.size()) + return false; + + pktPtr = packet; + + igbe->dmaWrite(unusedCache.front()->buf, packet->length, &pktEvent, packet->data); + return true; +} + +void +IGbE::RxDescCache::pktComplete() +{ + assert(unusedCache.size()); + RxDesc *desc; + desc = unusedCache.front(); + + desc->len = pktPtr->length; + // no support for anything but starting at 0 + assert(igbe->regs.rxcsum.pcss() == 0); + + DPRINTF(EthernetDesc, "RxDesc: Packet written to memory updating Descriptor\n"); + + uint8_t status = RXDS_DD | RXDS_EOP; + uint8_t err = 0; + IpPtr ip(pktPtr); + if (ip) { + if (igbe->regs.rxcsum.ipofld()) { + DPRINTF(EthernetDesc, "RxDesc: Checking IP checksum\n"); + status |= RXDS_IPCS; + desc->csum = cksum(ip); + if (cksum(ip) != 0) { + err |= RXDE_IPE; + DPRINTF(EthernetDesc, "RxDesc: Checksum is bad!!\n"); + } + } + TcpPtr tcp(ip); + if (tcp && igbe->regs.rxcsum.tuofld()) { + DPRINTF(EthernetDesc, "RxDesc: Checking TCP checksum\n"); + status |= RXDS_TCPCS; + desc->csum = cksum(tcp); + if (cksum(tcp) != 0) { + DPRINTF(EthernetDesc, "RxDesc: Checksum is bad!!\n"); + err |= RXDE_TCPE; + } + } + + UdpPtr udp(ip); + if (udp && igbe->regs.rxcsum.tuofld()) { + DPRINTF(EthernetDesc, "RxDesc: Checking UDP checksum\n"); + status |= RXDS_UDPCS; + desc->csum = cksum(udp); + if (cksum(tcp) != 0) { + DPRINTF(EthernetDesc, "RxDesc: Checksum is bad!!\n"); + err |= RXDE_TCPE; + } + } + } // if ip + + desc->status = status; + desc->errors = err; + + // No vlan support at this point... just set it to 0 + desc->vlan = 0; + + // Deal with the rx timer interrupts + if (igbe->regs.rdtr.delay()) { + DPRINTF(EthernetSM, "RXS: Scheduling DTR for %d\n", + igbe->regs.rdtr.delay() * igbe->intClock()); + if (igbe->rdtrEvent.scheduled()) + igbe->rdtrEvent.reschedule(curTick + igbe->regs.rdtr.delay() * + igbe->intClock()); + else + igbe->rdtrEvent.schedule(curTick + igbe->regs.rdtr.delay() * + igbe->intClock()); + } + + if (igbe->regs.radv.idv() && igbe->regs.rdtr.delay()) { + DPRINTF(EthernetSM, "RXS: Scheduling ADV for %d\n", + igbe->regs.radv.idv() * igbe->intClock()); + if (!igbe->radvEvent.scheduled()) + igbe->radvEvent.schedule(curTick + igbe->regs.radv.idv() * + igbe->intClock()); + } + + // If the packet is small enough, interrupt appropriately + if (pktPtr->length <= igbe->regs.rsrpd.idv()) + igbe->postInterrupt(IT_SRPD); + + DPRINTF(EthernetDesc, "RxDesc: Processing of this descriptor complete\n"); + unusedCache.pop_front(); + usedCache.push_back(desc); + pktPtr = NULL; + enableSm(); + pktDone = true; +} + +void +IGbE::RxDescCache::enableSm() +{ + igbe->rxTick = true; + if ((igbe->rxTick || igbe->txTick) && !igbe->tickEvent.scheduled()) + igbe->tickEvent.schedule((curTick/igbe->cycles(1)) * igbe->cycles(1) + + igbe->cycles(1)); +} + +bool +IGbE::RxDescCache::packetDone() +{ + if (pktDone) { + pktDone = false; + return true; + } + return false; +} + +///////////////////////////////////// IGbE::TxDesc ///////////////////////////////// + +IGbE::TxDescCache::TxDescCache(IGbE *i, const std::string n, int s) + : DescCache<TxDesc>(i,n, s), pktDone(false), isTcp(false), pktWaiting(false), + pktEvent(this) + { - panic("Need to implemenet\n"); } +int +IGbE::TxDescCache::getPacketSize() +{ + assert(unusedCache.size()); + + TxDesc *desc; + + DPRINTF(EthernetDesc, "TxDesc: Starting processing of descriptor\n"); + + while (unusedCache.size() && TxdOp::isContext(unusedCache.front())) { + DPRINTF(EthernetDesc, "TxDesc: Got context descriptor type... skipping\n"); + + // I think we can just ignore these for now? + desc = unusedCache.front(); + // is this going to be a tcp or udp packet? + isTcp = TxdOp::tcp(desc) ? true : false; + + // make sure it's ipv4 + assert(TxdOp::ip(desc)); + + TxdOp::setDd(desc); + unusedCache.pop_front(); + usedCache.push_back(desc); + } + + if (!unusedCache.size()) + return -1; + + DPRINTF(EthernetDesc, "TxDesc: Next TX packet is %d bytes\n", + TxdOp::getLen(unusedCache.front())); + + return TxdOp::getLen(unusedCache.front()); +} + +void +IGbE::TxDescCache::getPacketData(EthPacketPtr p) +{ + assert(unusedCache.size()); + + TxDesc *desc; + desc = unusedCache.front(); + + assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) && TxdOp::getLen(desc)); + + pktPtr = p; + + pktWaiting = true; + + DPRINTF(EthernetDesc, "TxDesc: Starting DMA of packet\n"); + igbe->dmaRead(TxdOp::getBuf(desc), TxdOp::getLen(desc), &pktEvent, p->data); + + +} + +void +IGbE::TxDescCache::pktComplete() +{ + + TxDesc *desc; + assert(unusedCache.size()); + assert(pktPtr); + + DPRINTF(EthernetDesc, "TxDesc: DMA of packet complete\n"); + + desc = unusedCache.front(); + assert((TxdOp::isLegacy(desc) || TxdOp::isData(desc)) && TxdOp::getLen(desc)); + + // no support for vlans + assert(!TxdOp::vle(desc)); + + // we alway report status + assert(TxdOp::rs(desc)); + + // we only support single packet descriptors at this point + assert(TxdOp::eop(desc)); + + // set that this packet is done + TxdOp::setDd(desc); + + // Checksums are only ofloaded for new descriptor types + if (TxdOp::isData(desc) && ( TxdOp::ixsm(desc) || TxdOp::txsm(desc)) ) { + DPRINTF(EthernetDesc, "TxDesc: Calculating checksums for packet\n"); + IpPtr ip(pktPtr); + if (TxdOp::ixsm(desc)) { + ip->sum(0); + ip->sum(cksum(ip)); + DPRINTF(EthernetDesc, "TxDesc: Calculated IP checksum\n"); + } + if (TxdOp::txsm(desc)) { + if (isTcp) { + TcpPtr tcp(ip); + tcp->sum(0); + tcp->sum(cksum(tcp)); + DPRINTF(EthernetDesc, "TxDesc: Calculated TCP checksum\n"); + } else { + UdpPtr udp(ip); + udp->sum(0); + udp->sum(cksum(udp)); + DPRINTF(EthernetDesc, "TxDesc: Calculated UDP checksum\n"); + } + } + } + + if (TxdOp::ide(desc)) { + // Deal with the rx timer interrupts + DPRINTF(EthernetDesc, "TxDesc: Descriptor had IDE set\n"); + if (igbe->regs.tidv.idv()) { + DPRINTF(EthernetDesc, "TxDesc: setting tidv\n"); + if (igbe->tidvEvent.scheduled()) + igbe->tidvEvent.reschedule(curTick + igbe->regs.tidv.idv() * + igbe->intClock()); + else + igbe->tidvEvent.schedule(curTick + igbe->regs.tidv.idv() * + igbe->intClock()); + } + + if (igbe->regs.tadv.idv() && igbe->regs.tidv.idv()) { + DPRINTF(EthernetDesc, "TxDesc: setting tadv\n"); + if (!igbe->tadvEvent.scheduled()) + igbe->tadvEvent.schedule(curTick + igbe->regs.tadv.idv() * + igbe->intClock()); + } + } + + unusedCache.pop_front(); + usedCache.push_back(desc); + pktDone = true; + pktWaiting = false; + pktPtr = NULL; + + DPRINTF(EthernetDesc, "TxDesc: Descriptor Done\n"); +} + +bool +IGbE::TxDescCache::packetAvailable() +{ + if (pktDone) { + pktDone = false; + return true; + } + return false; +} + +void +IGbE::TxDescCache::enableSm() +{ + igbe->txTick = true; + if ((igbe->rxTick || igbe->txTick) && !igbe->tickEvent.scheduled()) + igbe->tickEvent.schedule((curTick/igbe->cycles(1)) * igbe->cycles(1) + + igbe->cycles(1)); +} + + + + +///////////////////////////////////// IGbE ///////////////////////////////// + +void +IGbE::txStateMachine() +{ + if (!regs.tctl.en()) { + txTick = false; + DPRINTF(EthernetSM, "TXS: RX disabled, stopping ticking\n"); + return; + } + + if (txPacket && txDescCache.packetAvailable()) { + bool success; + DPRINTF(EthernetSM, "TXS: packet placed in TX FIFO\n"); + success = txFifo.push(txPacket); + assert(success); + txPacket = NULL; + return; + } + + // Only support descriptor granularity + assert(regs.txdctl.gran()); + if (regs.txdctl.lwthresh() && txDescCache.descLeft() < (regs.txdctl.lwthresh() * 8)) { + DPRINTF(EthernetSM, "TXS: LWTHRESH caused posting of TXDLOW\n"); + postInterrupt(IT_TXDLOW); + } + + if (!txPacket) { + txPacket = new EthPacketData(16384); + } + + if (!txDescCache.packetWaiting()) { + if (txDescCache.descLeft() == 0) { + DPRINTF(EthernetSM, "TXS: No descriptors left in ring, forcing writeback\n"); + txDescCache.writeback(0); + DPRINTF(EthernetSM, "TXS: No descriptors left, stopping ticking\n"); + txTick = false; + } + + if (!(txDescCache.descUnused())) { + DPRINTF(EthernetSM, "TXS: No descriptors available in cache, stopping ticking\n"); + txTick = false; + DPRINTF(EthernetSM, "TXS: No descriptors left, fetching\n"); + txDescCache.fetchDescriptors(); + return; + } + + int size; + size = txDescCache.getPacketSize(); + if (size > 0 && rxFifo.avail() > size) { + DPRINTF(EthernetSM, "TXS: Reserving %d bytes in FIFO and begining DMA of next packet\n"); + rxFifo.reserve(size); + txDescCache.getPacketData(txPacket); + } else { + DPRINTF(EthernetSM, "TXS: No packets to get, writing back used descriptors\n"); + txDescCache.writeback(0); + } + + return; + } +} + +bool +IGbE::ethRxPkt(EthPacketPtr pkt) +{ + DPRINTF(Ethernet, "RxFIFO: Receiving pcakte from wire\n"); + if (!regs.rctl.en()) { + DPRINTF(Ethernet, "RxFIFO: RX not enabled, dropping\n"); + return true; + } + + // restart the state machines if they are stopped + rxTick = true; + if ((rxTick || txTick) && !tickEvent.scheduled()) { + DPRINTF(EthernetSM, "RXS: received packet into fifo, starting ticking\n"); + tickEvent.schedule(curTick/cycles(1) + cycles(1)); + } + + if (!rxFifo.push(pkt)) { + DPRINTF(Ethernet, "RxFIFO: Packet won't fit in fifo... dropped\n"); + postInterrupt(IT_RXO, true); + return false; + } + return true; +} + + +void +IGbE::rxStateMachine() +{ + if (!regs.rctl.en()) { + rxTick = false; + DPRINTF(EthernetSM, "RXS: RX disabled, stopping ticking\n"); + return; + } + + // If the packet is done check for interrupts/descriptors/etc + if (rxDescCache.packetDone()) { + DPRINTF(EthernetSM, "RXS: Packet completed DMA to memory\n"); + int descLeft = rxDescCache.descLeft(); + switch (regs.rctl.rdmts()) { + case 2: if (descLeft > .125 * regs.rdlen()) break; + case 1: if (descLeft > .250 * regs.rdlen()) break; + case 0: if (descLeft > .500 * regs.rdlen()) break; + DPRINTF(Ethernet, "RXS: Interrupting (RXDMT) because of descriptors left\n"); + postInterrupt(IT_RXDMT); + break; + } + + if (descLeft == 0) { + DPRINTF(EthernetSM, "RXS: No descriptors left in ring, forcing writeback\n"); + rxDescCache.writeback(0); + DPRINTF(EthernetSM, "RXS: No descriptors left, stopping ticking\n"); + rxTick = false; + } + + // only support descriptor granulaties + assert(regs.rxdctl.gran()); + + if (regs.rxdctl.wthresh() >= rxDescCache.descUsed()) { + DPRINTF(EthernetSM, "RXS: Writing back because WTHRESH >= descUsed\n"); + rxDescCache.writeback(cacheBlockSize()-1); + } + + if ((rxDescCache.descUnused() < regs.rxdctl.pthresh()) && + ((rxDescCache.descLeft() - rxDescCache.descUnused()) > regs.rxdctl.hthresh())) { + DPRINTF(EthernetSM, "RXS: Fetching descriptors because descUnused < PTHRESH\n"); + rxDescCache.fetchDescriptors(); + } + + if (rxDescCache.descUnused() == 0) { + DPRINTF(EthernetSM, "RXS: No descriptors available in cache, stopping ticking\n"); + rxTick = false; + DPRINTF(EthernetSM, "RXS: Fetching descriptors because none available\n"); + rxDescCache.fetchDescriptors(); + } + return; + } + + if (!rxDescCache.descUnused()) { + DPRINTF(EthernetSM, "RXS: No descriptors available in cache, stopping ticking\n"); + rxTick = false; + DPRINTF(EthernetSM, "RXS: No descriptors available, fetching\n"); + rxDescCache.fetchDescriptors(); + return; + } + + if (rxFifo.empty()) { + DPRINTF(EthernetSM, "RXS: RxFIFO empty, stopping ticking\n"); + rxTick = false; + return; + } + + EthPacketPtr pkt; + pkt = rxFifo.front(); + + DPRINTF(EthernetSM, "RXS: Writing packet into memory\n"); + if (!rxDescCache.writePacket(pkt)) { + return; + } + + DPRINTF(EthernetSM, "RXS: Removing packet from FIFO\n"); + rxFifo.pop(); + DPRINTF(EthernetSM, "RXS: stopping ticking until packet DMA completes\n"); + rxTick = false; +} + +void +IGbE::txWire() +{ + if (txFifo.empty()) { + return; + } + + txTick = true; + + if (etherInt->sendPacket(txFifo.front())) { + DPRINTF(Ethernet, "TxFIFO: Successful transmit, bytes in fifo: %d\n", + txFifo.avail()); + txFifo.pop(); + } + + if (txFifo.empty()) { + postInterrupt(IT_TXQE); + DPRINTF(Ethernet, "TxFIFO: Empty, posting interruppt\n"); + } +} + +void +IGbE::tick() +{ + DPRINTF(EthernetSM, "IGbE: -------------- Cycle -------------- "); + + if (rxTick) + rxStateMachine(); + + if (txTick) { + txStateMachine(); + txWire(); + } + + if (rxTick || txTick) + tickEvent.schedule(curTick + cycles(1)); +} void IGbE::ethTxDone() { - panic("Need to implemenet\n"); + // restart the state machines if they are stopped + txTick = true; + if ((rxTick || txTick) && !tickEvent.scheduled()) + tickEvent.schedule(curTick/cycles(1) + cycles(1)); + DPRINTF(Ethernet, "TxFIFO: Transmission complete\n"); } void diff --git a/src/dev/i8254xGBe.hh b/src/dev/i8254xGBe.hh index fa9e65b22..d7d20ae50 100644 --- a/src/dev/i8254xGBe.hh +++ b/src/dev/i8254xGBe.hh @@ -35,6 +35,9 @@ #ifndef __DEV_I8254XGBE_HH__ #define __DEV_I8254XGBE_HH__ +#include <deque> +#include <string> + #include "base/inet.hh" #include "base/statistics.hh" #include "dev/etherint.hh" @@ -50,24 +53,434 @@ class IGbE : public PciDev { private: IGbEInt *etherInt; + + // device registers iGbReg::Regs regs; + + // eeprom data, status and control bits int eeOpBits, eeAddrBits, eeDataBits; uint8_t eeOpcode, eeAddr; + uint16_t flash[iGbReg::EEPROM_SIZE]; + // cached parameters from params struct + Tick tickRate; bool useFlowControl; - uint16_t flash[iGbReg::EEPROM_SIZE]; + // packet fifos + PacketFifo rxFifo; + PacketFifo txFifo; + + // Packet that we are currently putting into the txFifo + EthPacketPtr txPacket; + + // Should to Rx/Tx State machine tick? + bool rxTick; + bool txTick; + + // Event and function to deal with RDTR timer expiring + void rdtrProcess() { postInterrupt(iGbReg::IT_RXDMT, true); } + //friend class EventWrapper<IGbE, &IGbE::rdtrProcess>; + EventWrapper<IGbE, &IGbE::rdtrProcess> rdtrEvent; + + // Event and function to deal with RADV timer expiring + void radvProcess() { postInterrupt(iGbReg::IT_RXDMT, true); } + //friend class EventWrapper<IGbE, &IGbE::radvProcess>; + EventWrapper<IGbE, &IGbE::radvProcess> radvEvent; + + // Event and function to deal with TADV timer expiring + void tadvProcess() { postInterrupt(iGbReg::IT_TXDW, true); } + //friend class EventWrapper<IGbE, &IGbE::tadvProcess>; + EventWrapper<IGbE, &IGbE::tadvProcess> tadvEvent; + + // Event and function to deal with TIDV timer expiring + void tidvProcess() { postInterrupt(iGbReg::IT_TXDW, true); }; + //friend class EventWrapper<IGbE, &IGbE::tidvProcess>; + EventWrapper<IGbE, &IGbE::tidvProcess> tidvEvent; + + // Main event to tick the device + void tick(); + //friend class EventWrapper<IGbE, &IGbE::tick>; + EventWrapper<IGbE, &IGbE::tick> tickEvent; + + + void rxStateMachine(); + void txStateMachine(); + void txWire(); + + /** Write an interrupt into the interrupt pending register and check mask + * and interrupt limit timer before sending interrupt to CPU + * @param t the type of interrupt we are posting + * @param now should we ignore the interrupt limiting timer + */ + void postInterrupt(iGbReg::IntTypes t, bool now = false); + + /** Check and see if changes to the mask register have caused an interrupt + * to need to be sent or perhaps removed an interrupt cause. + */ + void chkInterrupt(); + + /** Send an interrupt to the cpu + */ + void cpuPostInt(); + // Event to moderate interrupts + EventWrapper<IGbE, &IGbE::cpuPostInt> interEvent; + + /** Clear the interupt line to the cpu + */ + void cpuClearInt(); + + Tick intClock() { return Clock::Int::ns * 1024; } + + template<class T> + class DescCache + { + protected: + virtual Addr descBase() const = 0; + virtual long descHead() const = 0; + virtual long descTail() const = 0; + virtual long descLen() const = 0; + virtual void updateHead(long h) = 0; + virtual void enableSm() = 0; + + std::deque<T*> usedCache; + std::deque<T*> unusedCache; + + T *fetchBuf; + T *wbBuf; + + // Pointer to the device we cache for + IGbE *igbe; + + // Name of this descriptor cache + std::string _name; + + // How far we've cached + int cachePnt; + + // The size of the descriptor cache + int size; + + // How many descriptors we are currently fetching + int curFetching; + + // How many descriptors we are currently writing back + int wbOut; + + // if the we wrote back to the end of the descriptor ring and are going + // to have to wrap and write more + bool moreToWb; + + // What the alignment is of the next descriptor writeback + Addr wbAlignment; + + /** The packet that is currently being dmad to memory if any + */ + EthPacketPtr pktPtr; + + public: + DescCache(IGbE *i, const std::string n, int s) + : igbe(i), _name(n), cachePnt(0), size(s), curFetching(0), wbOut(0), + pktPtr(NULL), fetchEvent(this), wbEvent(this) + { + fetchBuf = new T[size]; + wbBuf = new T[size]; + } + + virtual ~DescCache() + { + reset(); + } + + std::string name() { return _name; } + + /** If the address/len/head change when we've got descriptors that are + * dirty that is very bad. This function checks that we don't and if we + * do panics. + */ + void areaChanged() + { + if (usedCache.size() > 0 || unusedCache.size() > 0) + panic("Descriptor Address, Length or Head changed. Bad\n"); + } + + void writeback(Addr aMask) + { + int curHead = descHead(); + int max_to_wb = usedCache.size() + curHead; + + DPRINTF(EthernetDesc, "Writing back descriptors head: %d tail: " + "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n", + curHead, descTail(), descLen(), cachePnt, max_to_wb, + descLeft()); + + // Check if this writeback is less restrictive that the previous + // and if so setup another one immediately following it + if (wbOut && (aMask < wbAlignment)) { + moreToWb = true; + wbAlignment = aMask; + DPRINTF(EthernetDesc, "Writing back already in process, returning\n"); + return; + } + + + moreToWb = false; + wbAlignment = aMask; + + if (max_to_wb > descLen()) { + max_to_wb = descLen() - curHead; + moreToWb = true; + // this is by definition aligned correctly + } else if (aMask != 0) { + // align the wb point to the mask + max_to_wb = max_to_wb & ~(aMask>>4); + } + + DPRINTF(EthernetDesc, "Writing back %d descriptors\n", max_to_wb); + + if (max_to_wb <= 0 || wbOut) + return; + + wbOut = max_to_wb - curHead; + + for (int x = 0; x < wbOut; x++) + memcpy(&wbBuf[x], usedCache[x], sizeof(T)); + + for (int x = 0; x < wbOut; x++) { + assert(usedCache.size()); + delete usedCache[0]; + usedCache.pop_front(); + }; + + igbe->dmaWrite(descBase() + curHead * sizeof(T), wbOut * sizeof(T), + &wbEvent, (uint8_t*)wbBuf); + } + + /** Fetch a chunk of descriptors into the descriptor cache. + * Calls fetchComplete when the memory system returns the data + */ + void fetchDescriptors() + { + size_t max_to_fetch = cachePnt - descTail(); + if (max_to_fetch < 0) + max_to_fetch = descLen() - cachePnt; + + max_to_fetch = std::min(max_to_fetch, (size - usedCache.size() - + unusedCache.size())); + + DPRINTF(EthernetDesc, "Fetching descriptors head: %d tail: " + "%d len: %d cachePnt: %d max_to_wb: %d descleft: %d\n", + descHead(), descTail(), descLen(), cachePnt, + max_to_fetch, descLeft()); + // Nothing to do + if (max_to_fetch == 0 || curFetching) + return; + + // So we don't have two descriptor fetches going on at once + curFetching = max_to_fetch; + + igbe->dmaRead(descBase() + cachePnt * sizeof(T), + curFetching * sizeof(T), &fetchEvent, (uint8_t*)fetchBuf); + } + + + /** Called by event when dma to read descriptors is completed + */ + void fetchComplete() + { + T *newDesc; + for (int x = 0; x < curFetching; x++) { + newDesc = new T; + memcpy(newDesc, &fetchBuf[x], sizeof(T)); + unusedCache.push_back(newDesc); + } + +#ifndef NDEBUG + int oldCp = cachePnt; +#endif + + cachePnt += curFetching; + if (cachePnt > descLen()) + cachePnt -= descLen(); + + DPRINTF(EthernetDesc, "Fetching complete cachePnt %d -> %d\n", + oldCp, cachePnt); + + enableSm(); + + } + + EventWrapper<DescCache, &DescCache::fetchComplete> fetchEvent; + + /** Called by event when dma to writeback descriptors is completed + */ + void wbComplete() + { + long curHead = descHead(); +#ifndef NDEBUG + long oldHead = curHead; +#endif + + curHead += wbOut; + wbOut = 0; + + if (curHead > descLen()) + curHead = 0; + + // Update the head + updateHead(curHead); + + DPRINTF(EthernetDesc, "Writeback complete cachePnt %d -> %d\n", + oldHead, curHead); + + // If we still have more to wb, call wb now + if (moreToWb) { + DPRINTF(EthernetDesc, "Writeback has more todo\n"); + writeback(wbAlignment); + } + } + + + EventWrapper<DescCache, &DescCache::wbComplete> wbEvent; + + /* Return the number of descriptors left in the ring, so the device has + * a way to figure out if it needs to interrupt. + */ + int descLeft() const + { + int left = unusedCache.size(); + if (cachePnt - descTail() >= 0) + left += (cachePnt - descTail()); + else + left += (descLen() - cachePnt); + + return left; + } + + /* Return the number of descriptors used and not written back. + */ + int descUsed() const { return usedCache.size(); } + + /* Return the number of cache unused descriptors we have. */ + int descUnused() const {return unusedCache.size(); } + + /* Get into a state where the descriptor address/head/etc colud be + * changed */ + void reset() + { + DPRINTF(EthernetDesc, "Reseting descriptor cache\n"); + for (int x = 0; x < usedCache.size(); x++) + delete usedCache[x]; + for (int x = 0; x < unusedCache.size(); x++) + delete unusedCache[x]; + + usedCache.clear(); + unusedCache.clear(); + } + + }; + + + class RxDescCache : public DescCache<iGbReg::RxDesc> + { + protected: + virtual Addr descBase() const { return igbe->regs.rdba(); } + virtual long descHead() const { return igbe->regs.rdh(); } + virtual long descLen() const { return igbe->regs.rdlen() >> 4; } + virtual long descTail() const { return igbe->regs.rdt(); } + virtual void updateHead(long h) { igbe->regs.rdh(h); } + virtual void enableSm(); + + bool pktDone; + + public: + RxDescCache(IGbE *i, std::string n, int s); + + /** Write the given packet into the buffer(s) pointed to by the + * descriptor and update the book keeping. Should only be called when + * there are no dma's pending. + * @param packet ethernet packet to write + * @return if the packet could be written (there was a free descriptor) + */ + bool writePacket(EthPacketPtr packet); + /** Called by event when dma to write packet is completed + */ + void pktComplete(); + + /** Check if the dma on the packet has completed. + */ + + bool packetDone(); + + EventWrapper<RxDescCache, &RxDescCache::pktComplete> pktEvent; + + }; + friend class RxDescCache; + + RxDescCache rxDescCache; + + class TxDescCache : public DescCache<iGbReg::TxDesc> + { + protected: + virtual Addr descBase() const { return igbe->regs.tdba(); } + virtual long descHead() const { return igbe->regs.tdh(); } + virtual long descTail() const { return igbe->regs.tdt(); } + virtual long descLen() const { return igbe->regs.tdlen() >> 4; } + virtual void updateHead(long h) { igbe->regs.tdh(h); } + virtual void enableSm(); + + bool pktDone; + bool isTcp; + bool pktWaiting; + + public: + TxDescCache(IGbE *i, std::string n, int s); + + /** Tell the cache to DMA a packet from main memory into its buffer and + * return the size the of the packet to reserve space in tx fifo. + * @return size of the packet + */ + int getPacketSize(); + void getPacketData(EthPacketPtr p); + + /** Ask if the packet has been transfered so the state machine can give + * it to the fifo. + * @return packet available in descriptor cache + */ + bool packetAvailable(); + + /** Ask if we are still waiting for the packet to be transfered. + * @return packet still in transit. + */ + bool packetWaiting() { return pktWaiting; } + + /** Called by event when dma to write packet is completed + */ + void pktComplete(); + EventWrapper<TxDescCache, &TxDescCache::pktComplete> pktEvent; + + }; + friend class TxDescCache; + + TxDescCache txDescCache; public: struct Params : public PciDev::Params { bool use_flow_control; + int rx_fifo_size; + int tx_fifo_size; + int rx_desc_cache_size; + int tx_desc_cache_size; + Tick clock; }; IGbE(Params *params); ~IGbE() {;} + Tick clock; + inline Tick cycles(int numCycles) const { return numCycles * clock; } + virtual Tick read(PacketPtr pkt); virtual Tick write(PacketPtr pkt); @@ -78,6 +491,7 @@ class IGbE : public PciDev void setEthInt(IGbEInt *i) { assert(!etherInt); etherInt = i; } + const Params *params() const {return (const Params *)_params; } virtual void serialize(std::ostream &os); diff --git a/src/dev/i8254xGBe_defs.hh b/src/dev/i8254xGBe_defs.hh index b59b34a67..d9648a7c2 100644 --- a/src/dev/i8254xGBe_defs.hh +++ b/src/dev/i8254xGBe_defs.hh @@ -35,59 +35,58 @@ namespace iGbReg { -const uint32_t REG_CTRL = 0x00000; //* -const uint32_t REG_STATUS = 0x00008; //* -const uint32_t REG_EECD = 0x00010; //* -const uint32_t REG_EERD = 0x00014; //* -const uint32_t REG_CTRL_EXT = 0x00018; //*- -const uint32_t REG_MDIC = 0x00020; //* -const uint32_t REG_FCAL = 0x00028; //* -const uint32_t REG_FCAH = 0x0002C; //* -const uint32_t REG_FCT = 0x00030; //* -const uint32_t REG_VET = 0x00038; //* -const uint32_t REG_PBA = 0x01000; //* -const uint32_t REG_ICR = 0x000C0; //* -const uint32_t REG_ITR = 0x000C4; //* -const uint32_t REG_ICS = 0x000C8; //* -const uint32_t REG_IMS = 0x000D0; //* -const uint32_t REG_IMC = 0x000D8; //* -const uint32_t REG_IAM = 0x000E0; //* -const uint32_t REG_RCTL = 0x00100; //* -const uint32_t REG_FCTTV = 0x00170; //* -const uint32_t REG_TIPG = 0x00410; //* -const uint32_t REG_AIFS = 0x00458; //* -const uint32_t REG_LEDCTL = 0x00e00; //* -const uint32_t REG_FCRTL = 0x02160; //* -const uint32_t REG_FCRTH = 0x02168; //* -const uint32_t REG_RDBAL = 0x02800; //*- -const uint32_t REG_RDBAH = 0x02804; //*- -const uint32_t REG_RDLEN = 0x02808; //*- -const uint32_t REG_RDH = 0x02810; //*- -const uint32_t REG_RDT = 0x02818; //*- -const uint32_t REG_RDTR = 0x02820; //*- -const uint32_t REG_RXDCTL = 0x02828; //* -const uint32_t REG_RADV = 0x0282C; //*- -const uint32_t REG_RSRPD = 0x02C00; -const uint32_t REG_TCTL = 0x00400; //* -const uint32_t REG_TDBAL = 0x03800; //* -const uint32_t REG_TDBAH = 0x03804; //* -const uint32_t REG_TDLEN = 0x03808; //* -const uint32_t REG_TDH = 0x03810; //* -const uint32_t REG_TDT = 0x03818; //* -const uint32_t REG_TIDV = 0x03820; //* -const uint32_t REG_TXDMAC = 0x03000; -const uint32_t REG_TXDCTL = 0x03828; //* -const uint32_t REG_TADV = 0x0382C; //* -const uint32_t REG_TSPMT = 0x03830; + +// Registers used by the Intel GbE NIC +const uint32_t REG_CTRL = 0x00000; +const uint32_t REG_STATUS = 0x00008; +const uint32_t REG_EECD = 0x00010; +const uint32_t REG_EERD = 0x00014; +const uint32_t REG_CTRL_EXT = 0x00018; +const uint32_t REG_MDIC = 0x00020; +const uint32_t REG_FCAL = 0x00028; +const uint32_t REG_FCAH = 0x0002C; +const uint32_t REG_FCT = 0x00030; +const uint32_t REG_VET = 0x00038; +const uint32_t REG_PBA = 0x01000; +const uint32_t REG_ICR = 0x000C0; +const uint32_t REG_ITR = 0x000C4; +const uint32_t REG_ICS = 0x000C8; +const uint32_t REG_IMS = 0x000D0; +const uint32_t REG_IMC = 0x000D8; +const uint32_t REG_IAM = 0x000E0; +const uint32_t REG_RCTL = 0x00100; +const uint32_t REG_FCTTV = 0x00170; +const uint32_t REG_TIPG = 0x00410; +const uint32_t REG_AIFS = 0x00458; +const uint32_t REG_LEDCTL = 0x00e00; +const uint32_t REG_FCRTL = 0x02160; +const uint32_t REG_FCRTH = 0x02168; +const uint32_t REG_RDBAL = 0x02800; +const uint32_t REG_RDBAH = 0x02804; +const uint32_t REG_RDLEN = 0x02808; +const uint32_t REG_RDH = 0x02810; +const uint32_t REG_RDT = 0x02818; +const uint32_t REG_RDTR = 0x02820; +const uint32_t REG_RXDCTL = 0x02828; +const uint32_t REG_RADV = 0x0282C; +const uint32_t REG_TCTL = 0x00400; +const uint32_t REG_TDBAL = 0x03800; +const uint32_t REG_TDBAH = 0x03804; +const uint32_t REG_TDLEN = 0x03808; +const uint32_t REG_TDH = 0x03810; +const uint32_t REG_TDT = 0x03818; +const uint32_t REG_TIDV = 0x03820; +const uint32_t REG_TXDCTL = 0x03828; +const uint32_t REG_TADV = 0x0382C; const uint32_t REG_CRCERRS = 0x04000; -const uint32_t REG_RXCSUM = 0x05000; //*- +const uint32_t REG_RXCSUM = 0x05000; const uint32_t REG_MTA = 0x05200; const uint32_t REG_RAL = 0x05400; const uint32_t REG_RAH = 0x05404; const uint32_t REG_VFTA = 0x05600; -const uint32_t REG_WUC = 0x05800;//* -const uint32_t REG_MANC = 0x05820;//* +const uint32_t REG_WUC = 0x05800; +const uint32_t REG_MANC = 0x05820; const uint8_t EEPROM_READ_OPCODE_SPI = 0x03; const uint8_t EEPROM_RDSR_OPCODE_SPI = 0x05; @@ -99,6 +98,8 @@ const uint8_t RCV_ADDRESS_TABLE_SIZE = 16; const uint8_t MULTICAST_TABLE_SIZE = 128; const uint32_t STATS_REGS_SIZE = 0x124; + +// Registers in that are accessed in the PHY const uint8_t PHY_PSTATUS = 0x1; const uint8_t PHY_PID = 0x2; const uint8_t PHY_EPID = 0x3; @@ -106,179 +107,102 @@ const uint8_t PHY_GSTATUS = 10; const uint8_t PHY_EPSTATUS = 15; const uint8_t PHY_AGC = 18; +// Receive Descriptor Status Flags +const uint8_t RXDS_PIF = 0x80; +const uint8_t RXDS_IPCS = 0x40; +const uint8_t RXDS_TCPCS = 0x20; +const uint8_t RXDS_UDPCS = 0x10; +const uint8_t RXDS_VP = 0x08; +const uint8_t RXDS_IXSM = 0x04; +const uint8_t RXDS_EOP = 0x02; +const uint8_t RXDS_DD = 0x01; + +// Receive Descriptor Error Flags +const uint8_t RXDE_RXE = 0x80; +const uint8_t RXDE_IPE = 0x40; +const uint8_t RXDE_TCPE = 0x20; +const uint8_t RXDE_SEQ = 0x04; +const uint8_t RXDE_SE = 0x02; +const uint8_t RXDE_CE = 0x01; + +// Interrupt types +enum IntTypes +{ + IT_NONE = 0x00000, //dummy value + IT_TXDW = 0x00001, + IT_TXQE = 0x00002, + IT_LSC = 0x00004, + IT_RXSEQ = 0x00008, + IT_RXDMT = 0x00010, + IT_RXO = 0x00040, + IT_RXT = 0x00080, + IT_MADC = 0x00200, + IT_RXCFG = 0x00400, + IT_GPI0 = 0x02000, + IT_GPI1 = 0x04000, + IT_TXDLOW = 0x08000, + IT_SRPD = 0x10000, + IT_ACK = 0x20000 +}; +// Receive Descriptor struct struct RxDesc { Addr buf; uint16_t len; uint16_t csum; - union { - uint8_t status; - struct { // these may be in the worng order - uint8_t dd:1; // descriptor done (hw is done when 1) - uint8_t eop:1; // end of packet - uint8_t xism:1; // ignore checksum - uint8_t vp:1; // packet is vlan packet - uint8_t rsv:1; // reserved - uint8_t tcpcs:1; // TCP checksum done - uint8_t ipcs:1; // IP checksum done - uint8_t pif:1; // passed in-exact filter - } st; - }; - union { - uint8_t errors; - struct { - uint8_t ce:1; // crc error or alignment error - uint8_t se:1; // symbol error - uint8_t seq:1; // sequence error - uint8_t rsv:1; // reserved - uint8_t cxe:1; // carrier extension error - uint8_t tcpe:1; // tcp checksum error - uint8_t ipe:1; // ip checksum error - uint8_t rxe:1; // PX data error - } er; - }; - union { - uint16_t special; - struct { - uint16_t vlan:12; //vlan id - uint16_t cfi:1; // canocial form id - uint16_t pri:3; // user priority - } sp; - }; + uint8_t status; + uint8_t errors; + uint16_t vlan; }; -union TxDesc { - uint8_t data[16]; - struct { - Addr buf; - uint16_t len; - uint8_t cso; - union { - uint8_t command; - struct { - uint8_t eop:1; // end of packet - uint8_t ifcs:1; // insert crc - uint8_t ic:1; // insert checksum - uint8_t rs:1; // report status - uint8_t rps:1; // report packet sent - uint8_t dext:1; // extension - uint8_t vle:1; // vlan enable - uint8_t ide:1; // interrupt delay enable - } cmd; - }; - union { - uint8_t status:4; - struct { - uint8_t dd:1; // descriptor done - uint8_t ec:1; // excess collisions - uint8_t lc:1; // late collision - uint8_t tu:1; // transmit underrun - } st; - }; - uint8_t reserved:4; - uint8_t css; - union { - uint16_t special; - struct { - uint16_t vlan:12; //vlan id - uint16_t cfi:1; // canocial form id - uint16_t pri:3; // user priority - } sp; - }; - } legacy; - - // Type 0000 descriptor - struct { - uint8_t ipcss; - uint8_t ipcso; - uint16_t ipcse; - uint8_t tucss; - uint8_t tucso; - uint16_t tucse; - uint32_t paylen:20; - uint8_t dtype:4; - union { - uint8_t tucommand; - struct { - uint8_t tcp:1; // tcp/udp - uint8_t ip:1; // ip ipv4/ipv6 - uint8_t tse:1; // tcp segment enbale - uint8_t rs:1; // report status - uint8_t rsv0:1; // reserved - uint8_t dext:1; // descriptor extension - uint8_t rsv1:1; // reserved - uint8_t ide:1; // interrupt delay enable - } tucmd; - }; - union { - uint8_t status:4; - struct { - uint8_t dd:1; - uint8_t rsvd:3; - } sta; - }; - uint8_t reserved:4; - uint8_t hdrlen; - uint16_t mss; - } t0; - - // Type 0001 descriptor - struct { - Addr buf; - uint32_t dtalen:20; - uint8_t dtype:4; - union { - uint8_t dcommand; - struct { - uint8_t eop:1; // end of packet - uint8_t ifcs:1; // insert crc - uint8_t tse:1; // segmentation enable - uint8_t rs:1; // report status - uint8_t rps:1; // report packet sent - uint8_t dext:1; // extension - uint8_t vle:1; // vlan enable - uint8_t ide:1; // interrupt delay enable - } dcmd; - }; - union { - uint8_t status:4; - struct { - uint8_t dd:1; // descriptor done - uint8_t ec:1; // excess collisions - uint8_t lc:1; // late collision - uint8_t tu:1; // transmit underrun - } sta; - }; - union { - uint8_t pktopts; - struct { - uint8_t ixsm:1; // insert ip checksum - uint8_t txsm:1; // insert tcp checksum - }; - }; - union { - uint16_t special; - struct { - uint16_t vlan:12; //vlan id - uint16_t cfi:1; // canocial form id - uint16_t pri:3; // user priority - } sp; - }; - } t1; - - // Junk to test descriptor type! - struct { - uint64_t junk; - uint32_t junk1:20; - uint8_t dtype; - uint8_t junk2:5; - uint8_t dext:1; - uint8_t junk3:2; - uint8_t junk4:4; - uint32_t junk5; - } type; +struct TxDesc { + uint64_t d1; + uint64_t d2; }; +namespace TxdOp { +const uint8_t TXD_CNXT = 0x0; +const uint8_t TXD_DATA = 0x0; + +bool isLegacy(TxDesc *d) { return !bits(d->d2,29,29); } +uint8_t getType(TxDesc *d) { return bits(d->d2, 23,20); } +bool isContext(TxDesc *d) { return !isLegacy(d) && getType(d) == TXD_CNXT; } +bool isData(TxDesc *d) { return !isLegacy(d) && getType(d) == TXD_DATA; } + +Addr getBuf(TxDesc *d) { assert(isLegacy(d) || isData(d)); return d->d1; } +Addr getLen(TxDesc *d) { if (isLegacy(d)) return bits(d->d2,15,0); else return bits(d->d2, 19,0); } +void setDd(TxDesc *d) +{ + replaceBits(d->d1, 35, 32, 1); +} + +bool ide(TxDesc *d) { return bits(d->d2, 31,31); } +bool vle(TxDesc *d) { assert(isLegacy(d) || isData(d)); return bits(d->d2, 30,30); } +bool rs(TxDesc *d) { return bits(d->d2, 28,28); } +bool ic(TxDesc *d) { assert(isLegacy(d) || isData(d)); return isLegacy(d) && bits(d->d2, 27,27); } +bool tse(TxDesc *d) { return (isData(d) || isContext(d)) && bits(d->d2, 27,27); } +bool ifcs(TxDesc *d) { assert(isLegacy(d) || isData(d)); return bits(d->d2, 26,26); } +bool eop(TxDesc *d) { assert(isLegacy(d) || isData(d)); return bits(d->d2, 25,25); } +bool ip(TxDesc *d) { assert(isContext(d)); return bits(d->d2, 26,26); } +bool tcp(TxDesc *d) { assert(isContext(d)); return bits(d->d2, 25,25); } + +uint8_t getCso(TxDesc *d) { assert(isLegacy(d)); return bits(d->d2, 23,16); } +uint8_t getCss(TxDesc *d) { assert(isLegacy(d)); return bits(d->d2, 47,40); } + +bool ixsm(TxDesc *d) { return isData(d) && bits(d->d2, 40,40); } +bool txsm(TxDesc *d) { return isData(d) && bits(d->d2, 41,41); } + +int tucse(TxDesc *d) { assert(isContext(d)); return bits(d->d1,63,48); } +int tucso(TxDesc *d) { assert(isContext(d)); return bits(d->d1,47,40); } +int tucss(TxDesc *d) { assert(isContext(d)); return bits(d->d1,39,32); } +int ipcse(TxDesc *d) { assert(isContext(d)); return bits(d->d1,31,16); } +int ipcso(TxDesc *d) { assert(isContext(d)); return bits(d->d1,15,8); } +int ipcss(TxDesc *d) { assert(isContext(d)); return bits(d->d1,7,0); } +int mss(TxDesc *d) { assert(isContext(d)); return bits(d->d2,63,48); } +int hdrlen(TxDesc *d) { assert(isContext(d)); return bits(d->d2,47,40); } +} // namespace TxdOp + + #define ADD_FIELD32(NAME, OFFSET, BITS) \ inline uint32_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \ inline void NAME(uint32_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); } @@ -295,6 +219,7 @@ struct Regs { const Reg<T> &operator=(T d) { _data = d; return *this;} bool operator==(T d) { return d == _data; } void operator()(T d) { _data = d; } + Reg() { _data = 0; } }; struct CTRL : public Reg<uint32_t> { // 0x0000 CTRL Register @@ -454,7 +379,6 @@ struct Regs { ADD_FIELD32(lpe,5,1); // long packet reception enabled ADD_FIELD32(lbm,6,2); // ADD_FIELD32(rdmts,8,2); // - ADD_FIELD32(rsvd,10,2); // ADD_FIELD32(mo,12,2); // ADD_FIELD32(mdr,14,1); // ADD_FIELD32(bam,15,1); // @@ -462,11 +386,21 @@ struct Regs { ADD_FIELD32(vfe,18,1); // ADD_FIELD32(cfien,19,1); // ADD_FIELD32(cfi,20,1); // - ADD_FIELD32(rsvd2,21,1); // ADD_FIELD32(dpf,22,1); // discard pause frames ADD_FIELD32(pmcf,23,1); // pass mac control frames ADD_FIELD32(bsex,25,1); // buffer size extension ADD_FIELD32(secrc,26,1); // strip ethernet crc from incoming packet + int descSize() + { + switch(bsize()) { + case 0: return bsex() ? 2048 : -1; + case 1: return bsex() ? 1024 : 16384; + case 2: return bsex() ? 512 : 8192; + case 3: return bsex() ? 256 : 4096; + default: + return -1; + } + } }; RCTL rctl; @@ -543,10 +477,21 @@ struct Regs { struct RDTR : public Reg<uint32_t> { // 0x2820 RDTR Register using Reg<uint32_t>::operator=; ADD_FIELD32(delay,0,16); // receive delay timer - ADD_FIELD32(fpd, 31,); // flush partial descriptor block ?? + ADD_FIELD32(fpd, 31,1); // flush partial descriptor block ?? }; RDTR rdtr; + struct RXDCTL : public Reg<uint32_t> { // 0x2828 RXDCTL Register + using Reg<uint32_t>::operator=; + ADD_FIELD32(pthresh,0,6); // prefetch threshold, less that this + // consider prefetch + ADD_FIELD32(hthresh,8,6); // number of descriptors in host mem to + // consider prefetch + ADD_FIELD32(wthresh,16,6); // writeback threshold + ADD_FIELD32(gran,24,1); // granularity 0 = desc, 1 = cacheline + }; + RXDCTL rxdctl; + struct RADV : public Reg<uint32_t> { // 0x282C RADV Register using Reg<uint32_t>::operator=; ADD_FIELD32(idv,0,16); // absolute interrupt delay diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index 902cde909..cd7a5296a 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -132,6 +132,7 @@ class DmaPort : public Port bool dmaPending() { return pendingCount > 0; } + int cacheBlockSize() { return peerBlockSize(); } unsigned int drain(Event *de); }; @@ -261,13 +262,17 @@ class DmaDevice : public PioDevice addr, size, event, data); } - void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL) - { dmaPort->dmaAction(MemCmd::ReadReq, addr, size, event, data); } + void dmaRead(Addr addr, int size, Event *event, uint8_t *data) + { + dmaPort->dmaAction(MemCmd::ReadReq, addr, size, event, data); + } bool dmaPending() { return dmaPort->dmaPending(); } virtual unsigned int drain(Event *de); + int cacheBlockSize() { return dmaPort->cacheBlockSize(); } + virtual Port *getPort(const std::string &if_name, int idx = -1) { if (if_name == "pio") { diff --git a/tests/long/00.gzip/ref/sparc/linux/simple-atomic/config.ini b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/config.ini new file mode 100644 index 000000000..1cf7e8a9b --- /dev/null +++ b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/config.ini @@ -0,0 +1,64 @@ +[root] +type=Root +children=system +dummy=0 + +[system] +type=System +children=cpu membus physmem +mem_mode=atomic +physmem=system.physmem + +[system.cpu] +type=AtomicSimpleCPU +children=workload +clock=1 +cpu_id=0 +defer_registration=false +function_trace=false +function_trace_start=0 +max_insts_all_threads=0 +max_insts_any_thread=0 +max_loads_all_threads=0 +max_loads_any_thread=0 +phase=0 +progress_interval=0 +simulate_stalls=false +system=system +width=1 +workload=system.cpu.workload +dcache_port=system.membus.port[2] +icache_port=system.membus.port[1] + +[system.cpu.workload] +type=LiveProcess +cmd=gzip input.log 1 +cwd=build/SPARC_SE/tests/fast/long/00.gzip/sparc/linux/simple-atomic +egid=100 +env= +euid=100 +executable=/dist/m5/cpu2000/binaries/sparc/linux/gzip +gid=100 +input=cin +output=cout +pid=100 +ppid=99 +system=system +uid=100 + +[system.membus] +type=Bus +bus_id=0 +clock=1000 +responder_set=false +width=64 +port=system.physmem.port system.cpu.icache_port system.cpu.dcache_port + +[system.physmem] +type=PhysicalMemory +file= +latency=1 +range=0:134217727 +zero=false +port=system.membus.port[0] + diff --git a/tests/long/00.gzip/ref/sparc/linux/simple-atomic/config.out b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/config.out new file mode 100644 index 000000000..f6ace951d --- /dev/null +++ b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/config.out @@ -0,0 +1,57 @@ +[root] +type=Root +dummy=0 + +[system.physmem] +type=PhysicalMemory +file= +range=[0,134217727] +latency=1 +zero=false + +[system] +type=System +physmem=system.physmem +mem_mode=atomic + +[system.membus] +type=Bus +bus_id=0 +clock=1000 +width=64 +responder_set=false + +[system.cpu.workload] +type=LiveProcess +cmd=gzip input.log 1 +executable=/dist/m5/cpu2000/binaries/sparc/linux/gzip +input=cin +output=cout +env= +cwd=build/SPARC_SE/tests/fast/long/00.gzip/sparc/linux/simple-atomic +system=system +uid=100 +euid=100 +gid=100 +egid=100 +pid=100 +ppid=99 + +[system.cpu] +type=AtomicSimpleCPU +max_insts_any_thread=0 +max_insts_all_threads=0 +max_loads_any_thread=0 +max_loads_all_threads=0 +progress_interval=0 +system=system +cpu_id=0 +workload=system.cpu.workload +clock=1 +phase=0 +defer_registration=false +width=1 +function_trace=false +function_trace_start=0 +simulate_stalls=false + diff --git a/tests/long/00.gzip/ref/sparc/linux/simple-atomic/m5stats.txt b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/m5stats.txt new file mode 100644 index 000000000..6cf88af9d --- /dev/null +++ b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/m5stats.txt @@ -0,0 +1,18 @@ + +---------- Begin Simulation Statistics ---------- +host_inst_rate 713136 # Simulator instruction rate (inst/s) +host_mem_usage 148308 # Number of bytes of host memory used +host_seconds 2088.68 # Real time elapsed on the host +host_tick_rate 713136 # Simulator tick rate (ticks/s) +sim_freq 1000000000000 # Frequency of simulated ticks +sim_insts 1489514860 # Number of instructions simulated +sim_seconds 0.001490 # Number of seconds simulated +sim_ticks 1489514859 # Number of ticks simulated +system.cpu.idle_fraction 0 # Percentage of idle cycles +system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles +system.cpu.numCycles 1489514860 # number of cpu cycles simulated +system.cpu.num_insts 1489514860 # Number of instructions executed +system.cpu.num_refs 569359656 # Number of memory references +system.cpu.workload.PROG:num_syscalls 19 # Number of system calls + +---------- End Simulation Statistics ---------- diff --git a/tests/long/00.gzip/ref/sparc/linux/simple-atomic/stderr b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/stderr new file mode 100644 index 000000000..e74a68c71 --- /dev/null +++ b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/stderr @@ -0,0 +1,7 @@ +warn: More than two loadable segments in ELF object. +warn: Ignoring segment @ 0xb4000 length 0x10. +warn: More than two loadable segments in ELF object. +warn: Ignoring segment @ 0x0 length 0x0. +0: system.remote_gdb.listener: listening for remote gdb on port 7000 +warn: Entering event queue @ 0. Starting simulation... +warn: Ignoring request to flush register windows. diff --git a/tests/long/00.gzip/ref/sparc/linux/simple-atomic/stdout b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/stdout new file mode 100644 index 000000000..3f5dab90b --- /dev/null +++ b/tests/long/00.gzip/ref/sparc/linux/simple-atomic/stdout @@ -0,0 +1,44 @@ +spec_init +Loading Input Data +Duplicating 262144 bytes +Duplicating 524288 bytes +Input data 1048576 bytes in length +Compressing Input Data, level 1 +Compressed data 108074 bytes in length +Uncompressing Data +Uncompressed data 1048576 bytes in length +Uncompressed data compared correctly +Compressing Input Data, level 3 +Compressed data 97831 bytes in length +Uncompressing Data +Uncompressed data 1048576 bytes in length +Uncompressed data compared correctly +Compressing Input Data, level 5 +Compressed data 83382 bytes in length +Uncompressing Data +Uncompressed data 1048576 bytes in length +Uncompressed data compared correctly +Compressing Input Data, level 7 +Compressed data 76606 bytes in length +Uncompressing Data +Uncompressed data 1048576 bytes in length +Uncompressed data compared correctly +Compressing Input Data, level 9 +Compressed data 73189 bytes in length +Uncompressing Data +Uncompressed data 1048576 bytes in length +Uncompressed data compared correctly +Tested 1MB buffer: OK! +M5 Simulator System + +Copyright (c) 2001-2006 +The Regents of The University of Michigan +All Rights Reserved + + +M5 compiled Mar 21 2007 00:46:54 +M5 started Wed Mar 21 00:47:20 2007 +M5 executing on zizzer.eecs.umich.edu +command line: build/SPARC_SE/m5.fast -d build/SPARC_SE/tests/fast/long/00.gzip/sparc/linux/simple-atomic tests/run.py long/00.gzip/sparc/linux/simple-atomic +Global frequency set at 1000000000000 ticks per second +Exiting @ tick 1489514859 because target called exit() diff --git a/tests/long/50.vortex/ref/sparc/linux/simple-atomic/config.ini b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/config.ini new file mode 100644 index 000000000..7dbc37b58 --- /dev/null +++ b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/config.ini @@ -0,0 +1,64 @@ +[root] +type=Root +children=system +dummy=0 + +[system] +type=System +children=cpu membus physmem +mem_mode=atomic +physmem=system.physmem + +[system.cpu] +type=AtomicSimpleCPU +children=workload +clock=1 +cpu_id=0 +defer_registration=false +function_trace=false +function_trace_start=0 +max_insts_all_threads=0 +max_insts_any_thread=0 +max_loads_all_threads=0 +max_loads_any_thread=0 +phase=0 +progress_interval=0 +simulate_stalls=false +system=system +width=1 +workload=system.cpu.workload +dcache_port=system.membus.port[2] +icache_port=system.membus.port[1] + +[system.cpu.workload] +type=LiveProcess +cmd=vortex bendian.raw +cwd=build/SPARC_SE/tests/fast/long/50.vortex/sparc/linux/simple-atomic +egid=100 +env= +euid=100 +executable=/dist/m5/cpu2000/binaries/sparc/linux/vortex +gid=100 +input=cin +output=cout +pid=100 +ppid=99 +system=system +uid=100 + +[system.membus] +type=Bus +bus_id=0 +clock=1000 +responder_set=false +width=64 +port=system.physmem.port system.cpu.icache_port system.cpu.dcache_port + +[system.physmem] +type=PhysicalMemory +file= +latency=1 +range=0:134217727 +zero=false +port=system.membus.port[0] + diff --git a/tests/long/50.vortex/ref/sparc/linux/simple-atomic/config.out b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/config.out new file mode 100644 index 000000000..ee1fc877f --- /dev/null +++ b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/config.out @@ -0,0 +1,57 @@ +[root] +type=Root +dummy=0 + +[system.physmem] +type=PhysicalMemory +file= +range=[0,134217727] +latency=1 +zero=false + +[system] +type=System +physmem=system.physmem +mem_mode=atomic + +[system.membus] +type=Bus +bus_id=0 +clock=1000 +width=64 +responder_set=false + +[system.cpu.workload] +type=LiveProcess +cmd=vortex bendian.raw +executable=/dist/m5/cpu2000/binaries/sparc/linux/vortex +input=cin +output=cout +env= +cwd=build/SPARC_SE/tests/fast/long/50.vortex/sparc/linux/simple-atomic +system=system +uid=100 +euid=100 +gid=100 +egid=100 +pid=100 +ppid=99 + +[system.cpu] +type=AtomicSimpleCPU +max_insts_any_thread=0 +max_insts_all_threads=0 +max_loads_any_thread=0 +max_loads_all_threads=0 +progress_interval=0 +system=system +cpu_id=0 +workload=system.cpu.workload +clock=1 +phase=0 +defer_registration=false +width=1 +function_trace=false +function_trace_start=0 +simulate_stalls=false + diff --git a/tests/long/50.vortex/ref/sparc/linux/simple-atomic/m5stats.txt b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/m5stats.txt new file mode 100644 index 000000000..323b8a93c --- /dev/null +++ b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/m5stats.txt @@ -0,0 +1,18 @@ + +---------- Begin Simulation Statistics ---------- +host_inst_rate 638506 # Simulator instruction rate (inst/s) +host_mem_usage 150340 # Number of bytes of host memory used +host_seconds 213.38 # Real time elapsed on the host +host_tick_rate 638505 # Simulator tick rate (ticks/s) +sim_freq 1000000000000 # Frequency of simulated ticks +sim_insts 136246936 # Number of instructions simulated +sim_seconds 0.000136 # Number of seconds simulated +sim_ticks 136246935 # Number of ticks simulated +system.cpu.idle_fraction 0 # Percentage of idle cycles +system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles +system.cpu.numCycles 136246936 # number of cpu cycles simulated +system.cpu.num_insts 136246936 # Number of instructions executed +system.cpu.num_refs 58111522 # Number of memory references +system.cpu.workload.PROG:num_syscalls 1946 # Number of system calls + +---------- End Simulation Statistics ---------- diff --git a/tests/long/50.vortex/ref/sparc/linux/simple-atomic/smred.msg b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/smred.msg new file mode 100644 index 000000000..0ac2d9980 --- /dev/null +++ b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/smred.msg @@ -0,0 +1,158 @@ + + SYSTEM TYPE... + __ZTC__ := False + __UNIX__ := True + __RISC__ := True + SPEC_CPU2000_LP64 := False + __MAC__ := False + __BCC__ := False + __BORLANDC__ := False + __GUI__ := False + __WTC__ := False + __HP__ := False + + CODE OPTIONS... + __MACROIZE_HM__ := True + __MACROIZE_MEM__ := True + ENV01 := True + USE_HPP_STYPE_HDRS := False + USE_H_STYPE_HDRS := False + + CODE INCLUSION PARAMETERS... + INCLUDE_ALL_CODE := False + INCLUDE_DELETE_CODE := True + __SWAP_GRP_POS__ := True + __INCLUDE_MTRX__ := False + __BAD_CODE__ := False + API_INCLUDE := False + BE_CAREFUL := False + OLDWAY := False + NOTUSED := False + + SYSTEM PARAMETERS... + EXT_ENUM := 999999999L + CHUNK_CONSTANT := 55555555 + CORE_CONSTANT := 55555555 + CORE_LIMIT := 20971520 + CorePage_Size := 384000 + ALIGN_BYTES := True + CORE_BLOCK_ALIGN := 8 + FAR_MEM := False + + MEMORY MANAGEMENT PARAMETERS... + SYSTEM_ALLOC := True + SYSTEM_FREESTORE := True + __NO_DISKCACHE__ := False + __FREEZE_VCHUNKS__ := True + __FREEZE_GRP_PACKETS__ := True + __MINIMIZE_TREE_CACHE__:= True + + SYSTEM STD PARAMETERS... + __STDOUT__ := False + NULL := 0 + LPTR := False + False_Status := 1 + True_Status := 0 + LARGE := True + TWOBYTE_BOOL := False + __NOSTR__ := False + + MEMORY VALIDATION PARAMETERS... + CORE_CRC_CHECK := False + VALIDATE_MEM_CHUNKS := False + + SYSTEM DEBUG OPTIONS... + DEBUG := False + MCSTAT := False + TRACKBACK := False + FLUSH_FILES := False + DEBUG_CORE0 := False + DEBUG_RISC := False + __TREE_BUG__ := False + __TRACK_FILE_READS__ := False + PAGE_SPACE := False + LEAVE_NO_TRACE := True + NULL_TRACE_STRS := False + + TIME PARAMETERS... + CLOCK_IS_LONG := False + __DISPLAY_TIME__ := False + __TREE_TIME__ := False + __DISPLAY_ERRORS__ := False + + API MACROS... + __BMT01__ := True + OPTIMIZE := True + + END OF DEFINES. + + + + ... IMPLODE MEMORY ... + + SWAP to DiskCache := False + + FREEZE_GRP_PACKETS:= True + + QueBug := 1000 + + sizeof(boolean) = 4 + sizeof(sizetype) = 4 + sizeof(chunkstruc) = 32 + + sizeof(shorttype ) = 2 + sizeof(idtype ) = 2 + sizeof(sizetype ) = 4 + sizeof(indextype ) = 4 + sizeof(numtype ) = 4 + sizeof(handletype) = 4 + sizeof(tokentype ) = 8 + + sizeof(short ) = 2 + sizeof(int ) = 4 + + sizeof(lt64 ) = 4 + sizeof(farlongtype) = 4 + sizeof(long ) = 4 + sizeof(longaddr ) = 4 + + sizeof(float ) = 4 + sizeof(double ) = 8 + + sizeof(addrtype ) = 4 + sizeof(char * ) = 4 + ALLOC CORE_1 :: 8 + BHOOLE NATH + + OPEN File ./input/bendian.rnv + *Status = 0 + DB HDR restored from FileVbn[ 0] + DB BlkDirOffset : @ 2030c0 + DB BlkDirChunk : Chunk[ 10] AT Vbn[3146] + DB BlkTknChunk : Chunk[ 11] AT Vbn[3147] + DB BlkSizeChunk : Chunk[ 12] AT Vbn[3148] + DB Handle Chunk's StackPtr = 20797 + + DB[ 1] LOADED; Handles= 20797 + KERNEL in CORE[ 1] Restored @ 1b4750 + + OPEN File ./input/bendian.wnv + *Status = 0 + DB HDR restored from FileVbn[ 0] + DB BlkDirOffset : @ 21c40 + DB BlkDirChunk : Chunk[ 31] AT Vbn[ 81] + DB BlkTknChunk : Chunk[ 32] AT Vbn[ 82] + DB BlkSizeChunk : Chunk[ 33] AT Vbn[ 83] + DB Handle Chunk's StackPtr = 17 + + DB[ 2] LOADED; Handles= 17 + VORTEx_Status == -8 || fffffff8 + + BE HERE NOW !!! + + + + ... VORTEx ON LINE ... + + + ... END OF SESSION ... diff --git a/tests/long/50.vortex/ref/sparc/linux/simple-atomic/smred.out b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/smred.out new file mode 100644 index 000000000..726b45c60 --- /dev/null +++ b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/smred.out @@ -0,0 +1,258 @@ + CREATE Db Header and Db Primal ... + NEW DB [ 3] Created. + +VORTEX INPUT PARAMETERS:: + MESSAGE FileName: smred.msg + OUTPUT FileName: smred.out + DISK CACHE FileName: NULL + PART DB FileName: parts.db + DRAW DB FileName: draw.db + PERSON DB FileName: emp.db + PERSONS Data FileName: ./input/persons.250 + PARTS Count : 100 + OUTER Loops : 1 + INNER Loops : 1 + LOOKUP Parts : 25 + DELETE Parts : 10 + STUFF Parts : 10 + DEPTH Traverse: 5 + % DECREASE Parts : 0 + % INCREASE LookUps : 0 + % INCREASE Deletes : 0 + % INCREASE Stuffs : 0 + FREEZE_PACKETS : 1 + ALLOC_CHUNKS : 10000 + EXTEND_CHUNKS : 5000 + DELETE Draw objects : True + DELETE Part objects : False + QUE_BUG : 1000 + VOID_BOUNDARY : 67108864 + VOID_RESERVE : 1048576 + + COMMIT_DBS : False + + + + BMT TEST :: files... + EdbName := PartLib + EdbFileName := parts.db + DrwName := DrawLib + DrwFileName := draw.db + EmpName := PersonLib + EmpFileName := emp.db + + Swap to DiskCache := False + Freeze the cache := True + + + BMT TEST :: parms... + DeBug modulo := 1000 + Create Parts count:= 100 + Outer Loops := 1 + Inner Loops := 1 + Look Ups := 25 + Delete Parts := 10 + Stuff Parts := 10 + Traverse Limit := 5 + Delete Draws := True + Delete Parts := False + Delete ALL Parts := after every <mod 0>Outer Loop + + INITIALIZE LIBRARY :: + + INITIALIZE SCHEMA :: + Primal_CreateDb Accessed !!! + CREATE Db Header and Db Primal ... + NEW DB [ 4] Created. + PartLibCreate:: Db[ 4]; VpartsDir= 1 + + Part Count= 1 + + Initialize the Class maps + LIST HEADS loaded ... DbListHead_Class = 207 + DbListNode_Class = 206 + +...NOTE... ShellLoadCode:: Class[ 228] will NOT be Activated. + + +...NOTE... ShellLoadCode:: Class[ 229] will NOT be Activated. + + Primal_CreateDb Accessed !!! + CREATE Db Header and Db Primal ... + NEW DB [ 5] Created. + DrawLibCreate:: Db[ 5]; VpartsDir= 1 + + Initialize the Class maps of this schema. + Primal_CreateDb Accessed !!! + CREATE Db Header and Db Primal ... + NEW DB [ 6] Created. + + ***NOTE*** Persons Library Extended! + + Create <131072> Persons. + ItNum 0. Person[ 6: 5]. Name= Riddell , Robert V. ; + + LAST Person Read:: + ItNum 250. Person[ 6: 503]. Name= Gonzales , Warren X. ; + + BUILD <Query0> for <Part2> class:: + + if (link[1].length >= 5) :: + + Build Query2 for <Address> class:: + + if (State == CA || State == T*) + + Build Query1 for <Person> class:: + + if (LastName >= H* && LastName <= P* && Query0(Residence)) :: + + BUILD <Query3> for <DrawObj> class:: + + if (Id >= 3000 + && (Id >= 3000 && Id <= 3001) + && Id >= 3002) + + BUILD <Query4> for <NamedDrawObj> class:: + + if (Nam == Pre* + || (Nam == ??Mid??? || == Pre??Mid?? || == ??Post + || == Pre??Post || == ??Mid???Post || == Pre??Mid???Post) + && Id <= 7) + SEED := 1008; Swap = False; RgnEntries = 135 + + OUTER LOOP [ 1] : NewParts = 100 LookUps = 25 StuffParts = 10. + + Create 100 New Parts + Create Part 1. Token[ 4: 2]. + + < 100> Parts Created. CurrentId= 100 + + Connect each instantiated Part TO 3 unique Parts + Connect Part 1. Token[ 4: 2] + Connect Part 25. Token[ 4: 26] FromList= 26. + Connect Part 12. Token[ 4: 13] FromList= 13. + Connect Part 59. Token[ 4: 60] FromList= 60. + + SET <DrawObjs> entries:: + 1. [ 5: 5] := <1 >; @[: 6] + Iteration count = 100 + + SET <NamedDrawObjs> entries:: + 1. [ 5: 39] := <14 >; + Iteration count = 12 + + SET <LibRectangles> entries:: + 1. [ 5: 23] := <8 >; @[: 24] + Iteration count = 12 + + LIST <DbRectangles> entries:: + 1. [ 5: 23] + Iteration count = 12 + + SET <PersonNames > entries:: + Iteration count = 250 + + COMMIT All Image copies:: Release=<True>; Max Parts= 100 + < 100> Part images' Committed. + < 0> are Named. + < 50> Point images' Committed. + < 81> Person images' Committed. + + COMMIT Parts(* 100) + + Commit TestObj_Class in <Primal> DB. + ItNum 0. Token[ 0: 0]. TestObj Committed. + < 0> TestObj images' Committed. + + Commit CartesianPoint_Class in <Primal> DB. + ItNum 0. Token[ 0: 0]. CartesianPoint Committed. + < 0> CartesianPoint images' Committed. + + BEGIN Inner Loop Sequence::. + + INNER LOOP [ 1: 1] : + + LOOK UP 25 Random Parts and Export each Part. + + LookUp for 26 parts; Asserts = 8 + <Part2 > Asserts = 2; NULL Asserts = 3. + <DrawObj > Asserts = 0; NULL Asserts = 5. + <NamedObj > Asserts = 0; NULL Asserts = 0. + <Person > Asserts = 0; NULL Asserts = 5. + <TestObj > Asserts = 60; NULL Asserts = 0. + + DELETE 10 Random Parts. + + PartDelete :: Token[ 4: 91]. + PartDisconnect:: Token[ 4: 91] id:= 90 for each link. + DisConnect link [ 0]:= 50; PartToken[ 51: 51]. + DisConnect link [ 1]:= 17; PartToken[ 18: 18]. + DisConnect link [ 2]:= 72; PartToken[ 73: 73]. + DeleteFromList:: Vchunk[ 4: 91]. (* 1) + DisConnect FromList[ 0]:= 56; Token[ 57: 57]. + Vlists[ 89] := 100; + + Delete for 11 parts; + + Traverse Count= 0 + + TRAVERSE PartId[ 6] and all Connections to 5 Levels + SEED In Traverse Part [ 4: 65] @ Level = 4. + + Traverse Count= 357 + Traverse Asserts = 5. True Tests = 1 + < 5> DrawObj objects DELETED. + < 2> are Named. + < 2> Point objects DELETED. + + CREATE 10 Additional Parts + + Create 10 New Parts + Create Part 101. Token[ 4: 102]. + + < 10> Parts Created. CurrentId= 110 + + Connect each instantiated Part TO 3 unique Parts + + COMMIT All Image copies:: Release=<True>; Max Parts= 110 + < 81> Part images' Committed. + < 0> are Named. + < 38> Point images' Committed. + < 31> Person images' Committed. + + COMMIT Parts(* 100) + + Commit TestObj_Class in <Primal> DB. + ItNum 0. Token[ 3: 4]. TestObj Committed. + < 15> TestObj images' Committed. + + Commit CartesianPoint_Class in <Primal> DB. + ItNum 0. Token[ 3: 3]. CartesianPoint Committed. + < 16> CartesianPoint images' Committed. + + DELETE All TestObj objects; + + Delete TestObj_Class in <Primal> DB. + ItNum 0. Token[ 3: 4]. TestObj Deleted. + < 15> TestObj objects Deleted. + + Commit CartesianPoint_Class in <Primal> DB. + ItNum 0. Token[ 3: 3]. CartesianPoint Deleted. + < 16> CartesianPoint objects Deleted. + + DELETE TestObj and Point objects... + + END INNER LOOP [ 1: 1]. + + DELETE All TestObj objects; + + Delete TestObj_Class in <Primal> DB. + < 0> TestObj objects Deleted. + + Commit CartesianPoint_Class in <Primal> DB. + < 0> CartesianPoint objects Deleted. + + DELETE TestObj and Point objects... + STATUS= -201 +V O R T E x 0 1!V O R T E x 0 1!V O R T E x 0 1!V O R T E x 0 1!V O R T E x 0 1! diff --git a/tests/long/50.vortex/ref/sparc/linux/simple-atomic/stderr b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/stderr new file mode 100644 index 000000000..c0f1c1fbb --- /dev/null +++ b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/stderr @@ -0,0 +1,569 @@ +warn: More than two loadable segments in ELF object. +warn: Ignoring segment @ 0x1838c0 length 0x10. +warn: More than two loadable segments in ELF object. +warn: Ignoring segment @ 0x0 length 0x0. +0: system.remote_gdb.listener: listening for remote gdb on port 7001 +warn: Entering event queue @ 0. Starting simulation... +warn: Ignoring request to flush register windows. +warn: ignoring syscall time(4026527856, 4026528256, ...) +warn: ignoring syscall time(4026527408, 1375098, ...) +warn: ignoring syscall time(4026527320, 1, ...) +warn: ignoring syscall time(4026527056, 413, ...) +warn: ignoring syscall time(4026527056, 414, ...) +warn: ignoring syscall time(4026527296, 4026527696, ...) +warn: ignoring syscall time(4026526848, 1375098, ...) +warn: Increasing stack size by one page. +warn: ignoring syscall time(4026527056, 409, ...) +warn: ignoring syscall time(4026527056, 409, ...) +warn: ignoring syscall time(4026526968, 409, ...) +warn: ignoring syscall time(4026527048, 409, ...) +warn: ignoring syscall time(4026527008, 409, ...) +warn: ignoring syscall time(4026526992, 409, ...) +warn: ignoring syscall time(4026526992, 409, ...) +warn: ignoring syscall time(4026526880, 409, ...) +warn: ignoring syscall time(4026526320, 19045, ...) +warn: ignoring syscall time(4026526840, 409, ...) +warn: ignoring syscall time(4026526880, 409, ...) +warn: ignoring syscall time(4026526880, 409, ...) +warn: ignoring syscall time(4026526856, 409, ...) +warn: ignoring syscall time(4026526848, 409, ...) +warn: ignoring syscall time(4026526880, 409, ...) +warn: ignoring syscall time(4026526864, 409, ...) +warn: ignoring syscall time(4026526856, 409, ...) +warn: ignoring syscall time(4026526944, 409, ...) +warn: ignoring syscall time(4026527016, 4026527416, ...) +warn: ignoring syscall time(4026526568, 1375098, ...) +warn: ignoring syscall time(4026527192, 18732, ...) +warn: ignoring syscall time(4026526640, 409, ...) +warn: ignoring syscall time(4026526744, 0, ...) +warn: ignoring syscall time(4026527328, 0, ...) +warn: ignoring syscall time(4026527752, 225, ...) +warn: ignoring syscall time(4026527056, 409, ...) +warn: ignoring syscall time(4026526864, 409, ...) +warn: ignoring syscall time(4026526880, 409, ...) +warn: ignoring syscall time(4026527104, 4026527504, ...) +warn: ignoring syscall time(4026526656, 1375098, ...) +warn: ignoring syscall time(4026526832, 0, ...) +warn: ignoring syscall time(4026527328, 0, ...) +warn: ignoring syscall time(4026527192, 1879089152, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall times(4026527736, 246, ...) +warn: ignoring syscall time(4026527480, 1595768, ...) +warn: ignoring syscall time(4026526920, 17300, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026526920, 19045, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026527480, 0, ...) +warn: ignoring syscall time(4026526920, 19045, ...) +warn: ignoring syscall time(4026526920, 17300, ...) +warn: ignoring syscall time(4026525976, 20500, ...) +warn: ignoring syscall time(4026525976, 4026526444, ...) +warn: ignoring syscall time(4026526064, 7004192, ...) +warn: ignoring syscall time(4026527520, 4, ...) +warn: ignoring syscall time(4026525768, 0, ...) diff --git a/tests/long/50.vortex/ref/sparc/linux/simple-atomic/stdout b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/stdout new file mode 100644 index 000000000..8e5f7bf90 --- /dev/null +++ b/tests/long/50.vortex/ref/sparc/linux/simple-atomic/stdout @@ -0,0 +1,13 @@ +M5 Simulator System + +Copyright (c) 2001-2006 +The Regents of The University of Michigan +All Rights Reserved + + +M5 compiled Mar 21 2007 00:48:18 +M5 started Wed Mar 21 00:48:40 2007 +M5 executing on zizzer.eecs.umich.edu +command line: build/SPARC_SE/m5.fast -d build/SPARC_SE/tests/fast/long/50.vortex/sparc/linux/simple-atomic tests/run.py long/50.vortex/sparc/linux/simple-atomic +Global frequency set at 1000000000000 ticks per second +Exiting @ tick 136246935 because target called exit() |