summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/common/cpu2000.py1
-rw-r--r--src/arch/alpha/predecoder.hh1
-rwxr-xr-xsrc/arch/isa_parser.py23
-rw-r--r--src/arch/sparc/linux/syscalls.cc8
-rw-r--r--src/arch/sparc/predecoder.hh1
-rw-r--r--src/arch/x86/intregfile.hh5
-rw-r--r--src/arch/x86/intregs.hh3
-rw-r--r--src/arch/x86/isa/base.isa181
-rw-r--r--src/arch/x86/isa/bitfields.isa27
-rw-r--r--src/arch/x86/isa/decoder/decoder.isa89
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa398
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa393
-rw-r--r--src/arch/x86/isa/formats/basic.isa9
-rw-r--r--src/arch/x86/isa/formats/error.isa (renamed from src/arch/x86/isa/decoder.isa)23
-rw-r--r--src/arch/x86/isa/formats/formats.isa11
-rw-r--r--src/arch/x86/isa/formats/multi.isa106
-rw-r--r--src/arch/x86/isa/formats/unimp.isa174
-rw-r--r--src/arch/x86/isa/main.isa4
-rw-r--r--src/arch/x86/isa/operands.isa3
-rw-r--r--src/arch/x86/predecoder.cc79
-rw-r--r--src/arch/x86/predecoder.hh14
-rw-r--r--src/arch/x86/predecoder_tables.cc2
-rw-r--r--src/arch/x86/types.hh87
-rw-r--r--src/base/bitfield.hh267
-rw-r--r--src/cpu/exetrace.cc103
-rw-r--r--src/dev/i8254xGBe.cc684
-rw-r--r--src/dev/i8254xGBe.hh416
-rw-r--r--src/dev/i8254xGBe_defs.hh373
-rw-r--r--src/dev/io_device.hh9
-rw-r--r--tests/long/00.gzip/ref/sparc/linux/simple-atomic/config.ini64
-rw-r--r--tests/long/00.gzip/ref/sparc/linux/simple-atomic/config.out57
-rw-r--r--tests/long/00.gzip/ref/sparc/linux/simple-atomic/m5stats.txt18
-rw-r--r--tests/long/00.gzip/ref/sparc/linux/simple-atomic/stderr7
-rw-r--r--tests/long/00.gzip/ref/sparc/linux/simple-atomic/stdout44
-rw-r--r--tests/long/50.vortex/ref/sparc/linux/simple-atomic/config.ini64
-rw-r--r--tests/long/50.vortex/ref/sparc/linux/simple-atomic/config.out57
-rw-r--r--tests/long/50.vortex/ref/sparc/linux/simple-atomic/m5stats.txt18
-rw-r--r--tests/long/50.vortex/ref/sparc/linux/simple-atomic/smred.msg158
-rw-r--r--tests/long/50.vortex/ref/sparc/linux/simple-atomic/smred.out258
-rw-r--r--tests/long/50.vortex/ref/sparc/linux/simple-atomic/stderr569
-rw-r--r--tests/long/50.vortex/ref/sparc/linux/simple-atomic/stdout13
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, &regVal, 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, &regVal, 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, &regVal, 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, &regVal, 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, &regVal, 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()