diff options
Diffstat (limited to 'src')
60 files changed, 1726 insertions, 1230 deletions
diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index e0545761d..16bcee47a 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -47,22 +47,22 @@ class ArmLinux : public Linux //@{ /// open(2) flag values. - static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR - static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT - static const int TGT_O_EXCL = 0x00000200; //!< O_EXCL - static const int TGT_O_NOCTTY = 0x00000400; //!< O_NOCTTY - static const int TGT_O_TRUNC = 0x00001000; //!< O_TRUNC - static const int TGT_O_APPEND = 0x00002000; //!< O_APPEND - static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK - static const int TGT_O_SYNC = 0x00010000; //!< O_SYNC - static const int TGT_FASYNC = 0x00020000; //!< FASYNC - static const int TGT_O_DIRECT = 0x00040000; //!< O_DIRECT - static const int TGT_O_LARGEFILE = 0x00100000; //!< O_LARGEFILE - static const int TGT_O_DIRECTORY = 0x00200000; //!< O_DIRECTORY - static const int TGT_O_NOFOLLOW = 0x00400000; //!< O_NOFOLLOW - static const int TGT_O_NOATIME = 0x01000000; //!< O_NOATIME + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_CREAT = 00000100; //!< O_CREAT + static const int TGT_O_EXCL = 00000200; //!< O_EXCL + static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY + static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC + static const int TGT_O_APPEND = 00002000; //!< O_APPEND + static const int TGT_O_NONBLOCK = 00004000; //!< O_NONBLOCK + static const int TGT_O_SYNC = 00010000; //!< O_SYNC + static const int TGT_FASYNC = 00020000; //!< FASYNC + static const int TGT_O_DIRECTORY = 00040000; //!< O_DIRECTORY + static const int TGT_O_NOFOLLOW = 00100000; //!< O_NOFOLLOW + static const int TGT_O_DIRECT = 00200000; //!< O_DIRECT + static const int TGT_O_LARGEFILE = 00400000; //!< O_LARGEFILE + static const int TGT_O_NOATIME = 01000000; //!< O_NOATIME //@} /// For mmap(). @@ -70,13 +70,13 @@ class ArmLinux : public Linux //@{ /// For getsysinfo(). - static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string - static const unsigned GSI_CPU_INFO = 59; //!< CPU information - static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type - static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine - static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system - static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB - static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz //@} //@{ diff --git a/src/arch/x86/floatregs.hh b/src/arch/x86/floatregs.hh index dc9867c42..2108db8d5 100644 --- a/src/arch/x86/floatregs.hh +++ b/src/arch/x86/floatregs.hh @@ -166,7 +166,7 @@ namespace X86ISA static inline FloatRegIndex FLOATREG_STACK(int index, int top) { - return (FloatRegIndex)(NUM_FLOATREGS + ((top + index + 8) % 8)); + return FLOATREG_FPR((top + index + 8) % 8); } }; diff --git a/src/arch/x86/insts/microfpop.hh b/src/arch/x86/insts/microfpop.hh index 2e01cadbc..d3cecd67b 100644 --- a/src/arch/x86/insts/microfpop.hh +++ b/src/arch/x86/insts/microfpop.hh @@ -80,13 +80,13 @@ namespace X86ISA const char *mnem, const char *_instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, int8_t _spm, OpClass __opClass) : X86MicroopBase(_machInst, mnem, _instMnem, isMicro, isDelayed, isFirst, isLast, __opClass), - src1(_src1), src2(_src2), dest(_dest), + src1(_src1.idx), src2(_src2.idx), dest(_dest.idx), dataSize(_dataSize), spm(_spm) {} /* diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh index ec9cb52b3..309a2e6b7 100644 --- a/src/arch/x86/insts/microldstop.hh +++ b/src/arch/x86/insts/microldstop.hh @@ -93,20 +93,21 @@ namespace X86ISA LdStOp(ExtMachInst _machInst, const char * mnem, const char * _instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - uint8_t _scale, RegIndex _index, RegIndex _base, - uint64_t _disp, uint8_t _segment, - RegIndex _data, + uint8_t _scale, InstRegIndex _index, InstRegIndex _base, + uint64_t _disp, InstRegIndex _segment, + InstRegIndex _data, uint8_t _dataSize, uint8_t _addressSize, Request::FlagsType _memFlags, OpClass __opClass) : X86MicroopBase(machInst, mnem, _instMnem, isMicro, isDelayed, isFirst, isLast, __opClass), - scale(_scale), index(_index), base(_base), - disp(_disp), segment(_segment), - data(_data), + scale(_scale), index(_index.idx), base(_base.idx), + disp(_disp), segment(_segment.idx), + data(_data.idx), dataSize(_dataSize), addressSize(_addressSize), - memFlags(_memFlags | _segment) + memFlags(_memFlags | _segment.idx) { + assert(_segment.idx < NUM_SEGMENTREGS); foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; foldABit = (addressSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc index 2ea975746..2edd3ba87 100644 --- a/src/arch/x86/insts/microregop.cc +++ b/src/arch/x86/insts/microregop.cc @@ -67,7 +67,7 @@ namespace X86ISA bool subtract) const { DPRINTF(X86, "flagMask = %#x\n", flagMask); - if (_destRegIdx[0] & (1 << 6)) { + if (_destRegIdx[0] & IntFoldBit) { _dest >>= 8; } uint64_t flags = oldFlags & ~flagMask; diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh index d805adb33..16e1afc0a 100644 --- a/src/arch/x86/insts/microregop.hh +++ b/src/arch/x86/insts/microregop.hh @@ -79,13 +79,13 @@ namespace X86ISA const char *mnem, const char *_instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext, OpClass __opClass) : X86MicroopBase(_machInst, mnem, _instMnem, isMicro, isDelayed, isFirst, isLast, __opClass), - src1(_src1), dest(_dest), + src1(_src1.idx), dest(_dest.idx), dataSize(_dataSize), ext(_ext) { foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; @@ -107,14 +107,14 @@ namespace X86ISA const char *mnem, const char *_instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext, OpClass __opClass) : RegOpBase(_machInst, mnem, _instMnem, isMicro, isDelayed, isFirst, isLast, _src1, _dest, _dataSize, _ext, __opClass), - src2(_src2) + src2(_src2.idx) { } @@ -132,7 +132,7 @@ namespace X86ISA const char * mnem, const char *_instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, uint8_t _imm8, RegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext, OpClass __opClass) : RegOpBase(_machInst, mnem, _instMnem, diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc index f4ed44603..4f48c4c59 100644 --- a/src/arch/x86/insts/static_inst.cc +++ b/src/arch/x86/insts/static_inst.cc @@ -149,14 +149,11 @@ namespace X86ISA if (reg < FP_Base_DepTag) { const char * suffix = ""; - bool fold = reg & (1 << 6); - reg &= ~(1 << 6); + bool fold = reg & IntFoldBit; + reg &= ~IntFoldBit; if(fold) - { suffix = "h"; - reg -= 4; - } else if(reg < 8 && size == 1) suffix = "l"; diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh index 8480f2713..32065f7c0 100644 --- a/src/arch/x86/insts/static_inst.hh +++ b/src/arch/x86/insts/static_inst.hh @@ -64,6 +64,18 @@ namespace X86ISA { /** + * Class for register indices passed to instruction constructors. Using a + * wrapper struct for these lets take advantage of the compiler's type + * checking. + */ + struct InstRegIndex + { + RegIndex idx; + explicit InstRegIndex(RegIndex _idx) : idx(_idx) + {} + }; + + /** * Base class for all X86 static instructions. */ @@ -96,7 +108,7 @@ namespace X86ISA inline uint64_t merge(uint64_t into, uint64_t val, int size) const { X86IntReg reg = into; - if(_destRegIdx[0] & (1 << 6)) + if(_destRegIdx[0] & IntFoldBit) { reg.H = val; return reg; @@ -127,7 +139,7 @@ namespace X86ISA { X86IntReg reg = from; DPRINTF(X86, "Picking with size %d\n", size); - if(_srcRegIdx[idx] & (1 << 6)) + if(_srcRegIdx[idx] & IntFoldBit) return reg.H; switch(size) { @@ -148,7 +160,7 @@ namespace X86ISA { X86IntReg reg = from; DPRINTF(X86, "Picking with size %d\n", size); - if(_srcRegIdx[idx] & (1 << 6)) + if(_srcRegIdx[idx] & IntFoldBit) return reg.SH; switch(size) { diff --git a/src/arch/x86/intregs.hh b/src/arch/x86/intregs.hh index 6f252392e..2c6d871ed 100644 --- a/src/arch/x86/intregs.hh +++ b/src/arch/x86/intregs.hh @@ -60,6 +60,8 @@ #include "arch/x86/x86_traits.hh" #include "base/bitunion.hh" +#include "base/misc.hh" +#include "sim/core.hh" namespace X86ISA { @@ -165,6 +167,9 @@ namespace X86ISA NUM_INTREGS }; + // This needs to be large enough to miss all the other bits of an index. + static const IntRegIndex IntFoldBit = (IntRegIndex)(1 << 6); + inline static IntRegIndex INTREG_MICRO(int index) { @@ -187,7 +192,9 @@ namespace X86ISA inline static IntRegIndex INTREG_FOLDED(int index, int foldBit) { - return (IntRegIndex)(((index & 0x1C) == 4 ? foldBit : 0) | index); + if ((index & 0x1C) == 4 && foldBit) + index = (index - 4) | foldBit; + return (IntRegIndex)index; } }; diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc index d19a2a6cc..06a656efc 100644 --- a/src/arch/x86/isa.cc +++ b/src/arch/x86/isa.cc @@ -28,7 +28,6 @@ * Authors: Gabe Black */ -#include "arch/x86/floatregs.hh" #include "arch/x86/isa.hh" #include "arch/x86/tlb.hh" #include "cpu/base.hh" @@ -355,25 +354,4 @@ ISA::unserialize(EventManager *em, Checkpoint * cp, UNSERIALIZE_ARRAY(regVal, NumMiscRegs); } -int -ISA::flattenIntIndex(int reg) -{ - //If we need to fold over the index to match byte semantics, do that. - //Otherwise, just strip off any extra bits and pass it through. - if (reg & (1 << 6)) - return (reg & (~(1 << 6) - 0x4)); - else - return (reg & ~(1 << 6)); -} - -int -ISA::flattenFloatIndex(int reg) -{ - if (reg >= NUM_FLOATREGS) { - int top = readMiscRegNoEffect(MISCREG_X87_TOP); - reg = FLOATREG_STACK(reg - NUM_FLOATREGS, top); - } - return reg; -} - } diff --git a/src/arch/x86/isa.hh b/src/arch/x86/isa.hh index 285f0aa82..9a1880062 100644 --- a/src/arch/x86/isa.hh +++ b/src/arch/x86/isa.hh @@ -31,6 +31,7 @@ #ifndef __ARCH_X86_ISA_HH__ #define __ARCH_X86_ISA_HH__ +#include "arch/x86/floatregs.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/registers.hh" #include "base/types.hh" @@ -65,8 +66,21 @@ namespace X86ISA void setMiscRegNoEffect(int miscReg, MiscReg val); void setMiscReg(int miscReg, MiscReg val, ThreadContext *tc); - int flattenIntIndex(int reg); - int flattenFloatIndex(int reg); + int + flattenIntIndex(int reg) + { + return reg & ~IntFoldBit; + } + + int + flattenFloatIndex(int reg) + { + if (reg >= NUM_FLOATREGS) { + reg = FLOATREG_STACK(reg - NUM_FLOATREGS, + regVal[MISCREG_X87_TOP]); + } + return reg; + } void serialize(EventManager *em, std::ostream &os); void unserialize(EventManager *em, Checkpoint *cp, diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 3ac9cd4f9..78046c0c8 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -109,6 +109,8 @@ output header {{ #include "cpu/static_inst.hh" #include "mem/packet.hh" #include "sim/faults.hh" + +using X86ISA::InstRegIndex; }}; output decoder {{ diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py index 22364e038..da10d8478 100644 --- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py +++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py @@ -84,7 +84,7 @@ microcode = ''' def macroop BSR_R_R { # Determine if the input was zero, and also move it to a temp reg. - movi t1, t1, t0, dataSize=8 + mov t1, t1, t0, dataSize=8 and t1, regm, regm, flags=(ZF,) br label("end"), flags=(CZF,) @@ -132,7 +132,7 @@ end: def macroop BSR_R_M { - movi t1, t1, t0, dataSize=8 + mov t1, t1, t0, dataSize=8 ld t1, seg, sib, disp # Determine if the input was zero, and also move it to a temp reg. @@ -184,7 +184,7 @@ end: def macroop BSR_R_P { rdip t7 - movi t1, t1, t0, dataSize=8 + mov t1, t1, t0, dataSize=8 ld t1, seg, riprel, disp # Determine if the input was zero, and also move it to a temp reg. diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index 358fe43c8..a9ad611b7 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -143,7 +143,7 @@ processCSDescriptor: # appropriate/other RIP checks. # if temp_RIP > CS.limit throw #GP(0) rdlimit t6, cs, dataSize=8 - subi t0, t1, t6, flags=(ECF,) + sub t0, t1, t6, flags=(ECF,) fault "new GeneralProtection(0)", flags=(CECF,) #(temp_CPL!=CPL) diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/jump.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/jump.py index 4f0cdf770..461861b0d 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/jump.py @@ -118,7 +118,7 @@ def macroop JMP_FAR_I limm t2, imm, dataSize=8 # Figure out the width of the offset. limm t3, dsz, dataSize=8 - sll t3, t3, 3, dataSize=8 + slli t3, t3, 3, dataSize=8 # Get the selector into t1. sll t1, t2, t3, dataSize=8 mov t1, t0, t1, dataSize=2 @@ -178,7 +178,7 @@ def macroop JMP_FAR_REAL_I limm t2, imm, dataSize=8 # Figure out the width of the offset. limm t3, dsz, dataSize=8 - sll t3, t3, 3, dataSize=8 + slli t3, t3, 3, dataSize=8 # Get the selector into t1. sll t1, t2, t3, dataSize=8 mov t1, t0, t1, dataSize=2 diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py index 82fdffc63..f4c8a4663 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py @@ -163,7 +163,7 @@ def macroop ENTER_I_I { # Pull the different components out of the immediate limm t1, imm zexti t2, t1, 15, dataSize=8 - srl t1, t1, 16 + srli t1, t1, 16 zexti t1, t1, 5, dataSize=8 # t1 is now the masked nesting level, and t2 is the amount of storage. @@ -174,7 +174,7 @@ def macroop ENTER_I_I { mov t6, t6, rsp, dataSize=asz # If the nesting level is zero, skip all this stuff. - subi t0, t1, t0, flags=(EZF,), dataSize=2 + sub t0, t1, t0, flags=(EZF,), dataSize=2 br label("skipLoop"), flags=(CEZF,) # If the level was 1, only push the saved rbp diff --git a/src/arch/x86/isa/insts/general_purpose/system_calls.py b/src/arch/x86/isa/insts/general_purpose/system_calls.py index 9501116d9..31184eae7 100644 --- a/src/arch/x86/isa/insts/general_purpose/system_calls.py +++ b/src/arch/x86/isa/insts/general_purpose/system_calls.py @@ -65,7 +65,7 @@ def macroop SYSCALL_64 # Stick rflags with RF masked into r11. rflags t2 limm t3, "~RFBit", dataSize=8 - andi r11, t2, t3, dataSize=8 + and r11, t2, t3, dataSize=8 rdval t3, star srli t3, t3, 32, dataSize=8 @@ -118,7 +118,7 @@ def macroop SYSCALL_COMPAT # Stick rflags with RF masked into r11. rflags t2 limm t3, "~RFBit", dataSize=8 - andi r11, t2, t3, dataSize=8 + and r11, t2, t3, dataSize=8 rdval t3, star srli t3, t3, 32, dataSize=8 diff --git a/src/arch/x86/isa/insts/system/control_registers.py b/src/arch/x86/isa/insts/system/control_registers.py index 82811bb07..da105e411 100644 --- a/src/arch/x86/isa/insts/system/control_registers.py +++ b/src/arch/x86/isa/insts/system/control_registers.py @@ -28,58 +28,58 @@ microcode = ''' def macroop CLTS { - rdcr t1, 0, dataSize=8 + rdcr t1, regIdx(0), dataSize=8 andi t1, t1, 0xF7, dataSize=1 - wrcr 0, t1, dataSize=8 + wrcr regIdx(0), t1, dataSize=8 }; def macroop LMSW_R { - rdcr t1, 0, dataSize=8 + rdcr t1, regIdx(0), dataSize=8 # This logic sets MP, EM, and TS to whatever is in the operand. It will # set PE but not clear it. limm t2, "~ULL(0xe)", dataSize=8 and t1, t1, t2, dataSize=8 andi t2, reg, 0xf, dataSize=8 or t1, t1, t2, dataSize=8 - wrcr 0, t1, dataSize=8 + wrcr regIdx(0), t1, dataSize=8 }; def macroop LMSW_M { ld t3, seg, sib, disp, dataSize=2 - rdcr t1, 0, dataSize=8 + rdcr t1, regIdx(0), dataSize=8 # This logic sets MP, EM, and TS to whatever is in the operand. It will # set PE but not clear it. limm t2, "~ULL(0xe)", dataSize=8 and t1, t1, t2, dataSize=8 andi t2, t3, 0xf, dataSize=8 or t1, t1, t2, dataSize=8 - wrcr 0, t1, dataSize=8 + wrcr regIdx(0), t1, dataSize=8 }; def macroop LMSW_P { rdip t7, dataSize=asz ld t3, seg, riprel, disp, dataSize=2 - rdcr t1, 0, dataSize=8 + rdcr t1, regIdx(0), dataSize=8 # This logic sets MP, EM, and TS to whatever is in the operand. It will # set PE but not clear it. limm t2, "~ULL(0xe)", dataSize=8 and t1, t1, t2, dataSize=8 andi t2, t3, 0xf, dataSize=8 or t1, t1, t2, dataSize=8 - wrcr 0, t1, dataSize=8 + wrcr regIdx(0), t1, dataSize=8 }; def macroop SMSW_R { - rdcr reg, 0 + rdcr reg, regIdx(0) }; def macroop SMSW_M { - rdcr t1, 0 + rdcr t1, regIdx(0) st t1, seg, sib, disp, dataSize=2 }; def macroop SMSW_P { - rdcr t1, 0 + rdcr t1, regIdx(0) rdip t7, dataSize=asz st t1, seg, riprel, disp, dataSize=2 }; diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index c7c6dae2e..0cc72bf7b 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -75,14 +75,22 @@ let {{ from micro_asm import MicroAssembler, Rom_Macroop mainRom = X86MicrocodeRom('main ROM') assembler = MicroAssembler(X86Macroop, microopClasses, mainRom, Rom_Macroop) + + def regIdx(idx): + return "InstRegIndex(%s)" % idx + + assembler.symbols["regIdx"] = regIdx + # Add in symbols for the microcode registers for num in range(16): - assembler.symbols["t%d" % num] = "NUM_INTREGS+%d" % num + assembler.symbols["t%d" % num] = regIdx("NUM_INTREGS+%d" % num) for num in range(8): - assembler.symbols["ufp%d" % num] = "FLOATREG_MICROFP(%d)" % num + assembler.symbols["ufp%d" % num] = \ + regIdx("FLOATREG_MICROFP(%d)" % num) # Add in symbols for the segment descriptor registers for letter in ("C", "D", "E", "F", "G", "H", "S"): - assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter + assembler.symbols["%ss" % letter.lower()] = \ + regIdx("SEGMENT_REG_%sS" % letter) # Add in symbols for the various checks of segment selectors. for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck", @@ -91,25 +99,25 @@ let {{ assembler.symbols[check] = "Seg%s" % check for reg in ("TR", "IDTR"): - assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg + assembler.symbols[reg.lower()] = regIdx("SYS_SEGMENT_REG_%s" % reg) for reg in ("TSL", "TSG"): - assembler.symbols[reg.lower()] = "SEGMENT_REG_%s" % reg + assembler.symbols[reg.lower()] = regIdx("SEGMENT_REG_%s" % reg) # Miscellaneous symbols symbols = { - "reg" : "env.reg", - "xmml" : "FLOATREG_XMM_LOW(env.reg)", - "xmmh" : "FLOATREG_XMM_HIGH(env.reg)", - "regm" : "env.regm", - "xmmlm" : "FLOATREG_XMM_LOW(env.regm)", - "xmmhm" : "FLOATREG_XMM_HIGH(env.regm)", + "reg" : regIdx("env.reg"), + "xmml" : regIdx("FLOATREG_XMM_LOW(env.reg)"), + "xmmh" : regIdx("FLOATREG_XMM_HIGH(env.reg)"), + "regm" : regIdx("env.regm"), + "xmmlm" : regIdx("FLOATREG_XMM_LOW(env.regm)"), + "xmmhm" : regIdx("FLOATREG_XMM_HIGH(env.regm)"), "imm" : "adjustedImm", "disp" : "adjustedDisp", - "seg" : "env.seg", + "seg" : regIdx("env.seg"), "scale" : "env.scale", - "index" : "env.index", - "base" : "env.base", + "index" : regIdx("env.index"), + "base" : regIdx("env.base"), "dsz" : "env.dataSize", "asz" : "env.addressSize", "ssz" : "env.stackSize" @@ -133,17 +141,18 @@ let {{ # This segment selects an internal address space mapped to MSRs, # CPUID info, etc. - assembler.symbols["intseg"] = "SEGMENT_REG_MS" + assembler.symbols["intseg"] = regIdx("SEGMENT_REG_MS") # This segment always has base 0, and doesn't imply any special handling # like the internal segment above - assembler.symbols["flatseg"] = "SEGMENT_REG_LS" + assembler.symbols["flatseg"] = regIdx("SEGMENT_REG_LS") for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di', \ '8', '9', '10', '11', '12', '13', '14', '15'): - assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper() + assembler.symbols["r%s" % reg] = \ + regIdx("INTREG_R%s" % reg.upper()) for reg in range(16): - assembler.symbols["cr%d" % reg] = "MISCREG_CR%d" % reg + assembler.symbols["cr%d" % reg] = regIdx("MISCREG_CR%d" % reg) for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF', \ 'TF', 'IF', 'NT', 'RF', 'VM', 'AC', 'VIF', 'VIP', 'ID'): @@ -164,7 +173,7 @@ let {{ for reg in ('sysenter_cs', 'sysenter_esp', 'sysenter_eip', 'star', 'lstar', 'cstar', 'sf_mask', 'kernel_gs_base'): - assembler.symbols[reg] = "MISCREG_%s" % reg.upper() + assembler.symbols[reg] = regIdx("MISCREG_%s" % reg.upper()) # Code literal which forces a default 64 bit operand size in 64 bit mode. assembler.symbols["oszIn64Override"] = ''' @@ -201,7 +210,7 @@ let {{ assembler.symbols["rom_local_label"] = rom_local_labeler def stack_index(index): - return "(NUM_FLOATREGS + (((%s) + 8) %% 8))" % index + return regIdx("NUM_FLOATREGS + (((%s) + 8) %% 8)" % index) assembler.symbols["st"] = stack_index diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index f1007bf71..8541df831 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -86,7 +86,7 @@ let {{ const EmulEnv &env = macroop ? macroop->getEmulEnv() : dummyEmulEnv; // env may not be used in the microop's constructor. - RegIndex reg = env.reg; + InstRegIndex reg(env.reg); reg = reg; using namespace RomLabels; return %s; diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa index d4acfdbf4..e49bd8a20 100644 --- a/src/arch/x86/isa/microops/fpop.isa +++ b/src/arch/x86/isa/microops/fpop.isa @@ -99,12 +99,12 @@ def template MicroFpOpDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, int8_t _spm); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, int8_t _spm); %(BasicExecDeclare)s @@ -120,7 +120,7 @@ def template MicroFpOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, int8_t _spm) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, @@ -133,7 +133,7 @@ def template MicroFpOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, int8_t _spm) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, @@ -256,9 +256,9 @@ let {{ "spm" : self.spm} class Movfp(FpOp): - def __init__(self, dest, src1, flags=0, spm=0, \ + def __init__(self, dest, src1, spm=0, \ SetStatus=False, dataSize="env.dataSize"): - super(Movfp, self).__init__(dest, src1, flags, \ + super(Movfp, self).__init__(dest, src1, "InstRegIndex(0)", \ spm, SetStatus, dataSize) code = 'FpDestReg.uqw = FpSrcReg1.uqw;' else_code = 'FpDestReg.uqw = FpDestReg.uqw;' @@ -274,7 +274,8 @@ let {{ class ConvOp(FpOp): abstract = True def __init__(self, dest, src1): - super(ConvOp, self).__init__(dest, src1, "(int)FLOATREG_MICROFP0") + super(ConvOp, self).__init__(dest, src1, \ + "InstRegIndex(FLOATREG_MICROFP0)") # These probably shouldn't look at the ExtMachInst directly to figure # out what size to use and should instead delegate that to the macroop's @@ -318,7 +319,7 @@ let {{ class Compfp(FpOp): def __init__(self, src1, src2, spm=0, setStatus=False, \ dataSize="env.dataSize"): - super(Compfp, self).__init__("(int)FLOATREG_MICROFP0", \ + super(Compfp, self).__init__("InstRegIndex(FLOATREG_MICROFP0)", \ src1, src2, spm, setStatus, dataSize) # This class sets the condition codes in rflags according to the # rules for comparing floating point. diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index c4c57a954..94c707f73 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -121,17 +121,17 @@ def template MicroLeaDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - uint8_t _scale, RegIndex _index, RegIndex _base, - uint64_t _disp, uint8_t _segment, - RegIndex _data, + uint8_t _scale, InstRegIndex _index, InstRegIndex _base, + uint64_t _disp, InstRegIndex _segment, + InstRegIndex _data, uint8_t _dataSize, uint8_t _addressSize, Request::FlagsType _memFlags); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - uint8_t _scale, RegIndex _index, RegIndex _base, - uint64_t _disp, uint8_t _segment, - RegIndex _data, + uint8_t _scale, InstRegIndex _index, InstRegIndex _base, + uint64_t _disp, InstRegIndex _segment, + InstRegIndex _data, uint8_t _dataSize, uint8_t _addressSize, Request::FlagsType _memFlags); @@ -297,17 +297,17 @@ def template MicroLdStOpDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - uint8_t _scale, RegIndex _index, RegIndex _base, - uint64_t _disp, uint8_t _segment, - RegIndex _data, + uint8_t _scale, InstRegIndex _index, InstRegIndex _base, + uint64_t _disp, InstRegIndex _segment, + InstRegIndex _data, uint8_t _dataSize, uint8_t _addressSize, Request::FlagsType _memFlags); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - uint8_t _scale, RegIndex _index, RegIndex _base, - uint64_t _disp, uint8_t _segment, - RegIndex _data, + uint8_t _scale, InstRegIndex _index, InstRegIndex _base, + uint64_t _disp, InstRegIndex _segment, + InstRegIndex _data, uint8_t _dataSize, uint8_t _addressSize, Request::FlagsType _memFlags); @@ -328,9 +328,9 @@ def template MicroLdStOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, - uint8_t _scale, RegIndex _index, RegIndex _base, - uint64_t _disp, uint8_t _segment, - RegIndex _data, + uint8_t _scale, InstRegIndex _index, InstRegIndex _base, + uint64_t _disp, InstRegIndex _segment, + InstRegIndex _data, uint8_t _dataSize, uint8_t _addressSize, Request::FlagsType _memFlags) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, @@ -345,9 +345,9 @@ def template MicroLdStOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - uint8_t _scale, RegIndex _index, RegIndex _base, - uint64_t _disp, uint8_t _segment, - RegIndex _data, + uint8_t _scale, InstRegIndex _index, InstRegIndex _base, + uint64_t _disp, InstRegIndex _segment, + InstRegIndex _data, uint8_t _dataSize, uint8_t _addressSize, Request::FlagsType _memFlags) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, @@ -517,7 +517,7 @@ let {{ def __init__(self, segment, addr, disp = 0, dataSize="env.dataSize", addressSize="env.addressSize"): - super(TiaOp, self).__init__("NUM_INTREGS", segment, + super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, addr, disp, dataSize, addressSize, "0", False, False) self.className = "Tia" self.mnemonic = "tia" @@ -528,7 +528,7 @@ let {{ def __init__(self, segment, addr, disp = 0, dataSize="env.dataSize", addressSize="env.addressSize", atCPL0=False): - super(CdaOp, self).__init__("NUM_INTREGS", segment, + super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment, addr, disp, dataSize, addressSize, "0", atCPL0, False) self.className = "Cda" self.mnemonic = "cda" diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa index 4e75ab8b0..f7e7728ab 100644 --- a/src/arch/x86/isa/microops/limmop.isa +++ b/src/arch/x86/isa/microops/limmop.isa @@ -88,11 +88,11 @@ def template MicroLimmOpDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _dest, uint64_t _imm, uint8_t _dataSize); + InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - RegIndex _dest, uint64_t _imm, uint8_t _dataSize); + InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize); %(BasicExecDeclare)s }; @@ -122,10 +122,10 @@ def template MicroLimmOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, - RegIndex _dest, uint64_t _imm, uint8_t _dataSize) : + InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, %(op_class)s), - dest(_dest), imm(_imm), dataSize(_dataSize) + dest(_dest.idx), imm(_imm), dataSize(_dataSize) { buildMe(); } @@ -133,10 +133,10 @@ def template MicroLimmOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _dest, uint64_t _imm, uint8_t _dataSize) : + InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, %(op_class)s), - dest(_dest), imm(_imm), dataSize(_dataSize) + dest(_dest.idx), imm(_imm), dataSize(_dataSize) { buildMe(); } diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index dfa10587a..cabdc2172 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -126,12 +126,12 @@ def template MicroRegOpDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(BasicExecDeclare)s @@ -149,12 +149,12 @@ def template MicroRegOpImmDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, uint16_t _imm8, RegIndex _dest, + InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - RegIndex _src1, uint16_t _imm8, RegIndex _dest, + InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(BasicExecDeclare)s @@ -170,7 +170,7 @@ def template MicroRegOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, @@ -183,7 +183,7 @@ def template MicroRegOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, RegIndex _src2, RegIndex _dest, + InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, @@ -203,7 +203,7 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, - RegIndex _src1, uint16_t _imm8, RegIndex _dest, + InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, @@ -216,7 +216,7 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _src1, uint16_t _imm8, RegIndex _dest, + InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, @@ -481,12 +481,14 @@ let {{ def __init__(self, dest, src1=None, dataSize="env.dataSize"): if not src1: src1 = dest - super(RdRegOp, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize) + super(RdRegOp, self).__init__(dest, src1, \ + "InstRegIndex(NUM_INTREGS)", None, dataSize) class WrRegOp(RegOp): abstract = True def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"): - super(WrRegOp, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize) + super(WrRegOp, self).__init__("InstRegIndex(NUM_INTREGS)", \ + src1, src2, flags, dataSize) class Add(FlagRegOp): code = 'DestReg = merge(DestReg, psrc1 + op2, dataSize);' @@ -553,7 +555,8 @@ let {{ def __init__(self, dest, src1=None, flags=None, dataSize="env.dataSize"): if not src1: src1 = dest - super(RdRegOp, self).__init__(dest, src1, "NUM_INTREGS", flags, dataSize) + super(RdRegOp, self).__init__(dest, src1, \ + "InstRegIndex(NUM_INTREGS)", flags, dataSize) code = 'DestReg = merge(SrcReg1, ProdHi, dataSize);' flag_code = ''' if (ProdHi) @@ -885,7 +888,7 @@ let {{ def __init__(self, dest, imm, flags=None, \ dataSize="env.dataSize"): super(Ruflag, self).__init__(dest, \ - "NUM_INTREGS", imm, flags, dataSize) + "InstRegIndex(NUM_INTREGS)", imm, flags, dataSize) class Rflag(RegOp): code = ''' @@ -899,7 +902,7 @@ let {{ def __init__(self, dest, imm, flags=None, \ dataSize="env.dataSize"): super(Rflag, self).__init__(dest, \ - "NUM_INTREGS", imm, flags, dataSize) + "InstRegIndex(NUM_INTREGS)", imm, flags, dataSize) class Sext(RegOp): code = ''' @@ -926,7 +929,7 @@ let {{ class Rddr(RegOp): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): super(Rddr, self).__init__(dest, \ - src1, "NUM_INTREGS", flags, dataSize) + src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) code = ''' CR4 cr4 = CR4Op; DR7 dr7 = DR7Op; @@ -942,14 +945,13 @@ let {{ class Wrdr(RegOp): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): super(Wrdr, self).__init__(dest, \ - src1, "NUM_INTREGS", flags, dataSize) + src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) code = ''' CR4 cr4 = CR4Op; DR7 dr7 = DR7Op; if ((cr4.de == 1 && (dest == 4 || dest == 5)) || dest >= 8) { fault = new InvalidOpcode(); - } else if ((dest == 6 || dest == 7) && - bits(psrc1, 63, 32) && + } else if ((dest == 6 || dest == 7) && bits(psrc1, 63, 32) && machInst.mode.mode == LongMode) { fault = new GeneralProtection(0); } else if (dr7.gd) { @@ -962,7 +964,7 @@ let {{ class Rdcr(RegOp): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): super(Rdcr, self).__init__(dest, \ - src1, "NUM_INTREGS", flags, dataSize) + src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) code = ''' if (src1 == 1 || (src1 > 4 && src1 < 8) || (src1 > 8)) { fault = new InvalidOpcode(); @@ -974,7 +976,7 @@ let {{ class Wrcr(RegOp): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): super(Wrcr, self).__init__(dest, \ - src1, "NUM_INTREGS", flags, dataSize) + src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) code = ''' if (dest == 1 || (dest > 4 && dest < 8) || (dest > 8)) { fault = new InvalidOpcode(); @@ -1028,7 +1030,7 @@ let {{ abstract = True def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): super(SegOp, self).__init__(dest, \ - src1, "NUM_INTREGS", flags, dataSize) + src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize) class Wrbase(SegOp): code = ''' @@ -1072,16 +1074,16 @@ let {{ class Rdval(RegOp): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Rdval, self).__init__(dest, \ - src1, "NUM_INTREGS", flags, dataSize) + super(Rdval, self).__init__(dest, src1, \ + "InstRegIndex(NUM_INTREGS)", flags, dataSize) code = ''' DestReg = MiscRegSrc1; ''' class Wrval(RegOp): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Wrval, self).__init__(dest, \ - src1, "NUM_INTREGS", flags, dataSize) + super(Wrval, self).__init__(dest, src1, \ + "InstRegIndex(NUM_INTREGS)", flags, dataSize) code = ''' MiscRegDest = SrcReg1; ''' diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index ab1e9a851..5ea803bfc 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -94,75 +94,94 @@ def operand_types {{ 'df' : ('float', 64), }}; +let {{ + def foldInt(idx, foldBit, id): + return ('IntReg', 'uqw', 'INTREG_FOLDED(%s, %s)' % (idx, foldBit), + 'IsInteger', id) + def intReg(idx, id): + return ('IntReg', 'uqw', idx, 'IsInteger', id) + def impIntReg(idx, id): + return ('IntReg', 'uqw', 'INTREG_IMPLICIT(%s)' % idx, 'IsInteger', id) + def floatReg(idx, id): + return ('FloatReg', 'df', idx, 'IsFloating', id) + def controlReg(idx, id, ctype = 'uqw'): + return ('ControlReg', ctype, idx, + (None, None, ['IsSerializeAfter', + 'IsSerializing', + 'IsNonSpeculative']), + id) +}}; + def operands {{ - 'SrcReg1': ('IntReg', 'uqw', 'INTREG_FOLDED(src1, foldOBit)', 'IsInteger', 1), - 'SSrcReg1': ('IntReg', 'uqw', 'src1', 'IsInteger', 1), - 'SrcReg2': ('IntReg', 'uqw', 'INTREG_FOLDED(src2, foldOBit)', 'IsInteger', 2), - 'SSrcReg2': ('IntReg', 'uqw', 'src2', 'IsInteger', 1), - 'Index': ('IntReg', 'uqw', 'INTREG_FOLDED(index, foldABit)', 'IsInteger', 3), - 'Base': ('IntReg', 'uqw', 'INTREG_FOLDED(base, foldABit)', 'IsInteger', 4), - 'DestReg': ('IntReg', 'uqw', 'INTREG_FOLDED(dest, foldOBit)', 'IsInteger', 5), - 'SDestReg': ('IntReg', 'uqw', 'dest', 'IsInteger', 5), - 'Data': ('IntReg', 'uqw', 'INTREG_FOLDED(data, foldOBit)', 'IsInteger', 6), - 'ProdLow': ('IntReg', 'uqw', 'INTREG_IMPLICIT(0)', 'IsInteger', 7), - 'ProdHi': ('IntReg', 'uqw', 'INTREG_IMPLICIT(1)', 'IsInteger', 8), - 'Quotient': ('IntReg', 'uqw', 'INTREG_IMPLICIT(2)', 'IsInteger', 9), - 'Remainder': ('IntReg', 'uqw', 'INTREG_IMPLICIT(3)', 'IsInteger', 10), - 'Divisor': ('IntReg', 'uqw', 'INTREG_IMPLICIT(4)', 'IsInteger', 11), - 'Rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 12), - 'Rbx': ('IntReg', 'uqw', '(INTREG_RBX)', 'IsInteger', 13), - 'Rcx': ('IntReg', 'uqw', '(INTREG_RCX)', 'IsInteger', 14), - 'Rdx': ('IntReg', 'uqw', '(INTREG_RDX)', 'IsInteger', 15), - 'Rsp': ('IntReg', 'uqw', '(INTREG_RSP)', 'IsInteger', 16), - 'Rbp': ('IntReg', 'uqw', '(INTREG_RBP)', 'IsInteger', 17), - 'Rsi': ('IntReg', 'uqw', '(INTREG_RSI)', 'IsInteger', 18), - 'Rdi': ('IntReg', 'uqw', '(INTREG_RDI)', 'IsInteger', 19), - 'FpSrcReg1': ('FloatReg', 'df', 'src1', 'IsFloating', 20), - 'FpSrcReg2': ('FloatReg', 'df', 'src2', 'IsFloating', 21), - 'FpDestReg': ('FloatReg', 'df', 'dest', 'IsFloating', 22), - 'FpData': ('FloatReg', 'df', 'data', 'IsFloating', 23), + 'SrcReg1': foldInt('src1', 'foldOBit', 1), + 'SSrcReg1': intReg('src1', 1), + 'SrcReg2': foldInt('src2', 'foldOBit', 2), + 'SSrcReg2': intReg('src2', 1), + 'Index': foldInt('index', 'foldABit', 3), + 'Base': foldInt('base', 'foldABit', 4), + 'DestReg': foldInt('dest', 'foldOBit', 5), + 'SDestReg': intReg('dest', 5), + 'Data': foldInt('data', 'foldOBit', 6), + 'ProdLow': impIntReg(0, 7), + 'ProdHi': impIntReg(1, 8), + 'Quotient': impIntReg(2, 9), + 'Remainder': impIntReg(3, 10), + 'Divisor': impIntReg(4, 11), + 'Rax': intReg('(INTREG_RAX)', 12), + 'Rbx': intReg('(INTREG_RBX)', 13), + 'Rcx': intReg('(INTREG_RCX)', 14), + 'Rdx': intReg('(INTREG_RDX)', 15), + 'Rsp': intReg('(INTREG_RSP)', 16), + 'Rbp': intReg('(INTREG_RBP)', 17), + 'Rsi': intReg('(INTREG_RSI)', 18), + 'Rdi': intReg('(INTREG_RDI)', 19), + 'FpSrcReg1': floatReg('src1', 20), + 'FpSrcReg2': floatReg('src2', 21), + 'FpDestReg': floatReg('dest', 22), + 'FpData': floatReg('data', 23), 'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 50), 'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51), 'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52), # This holds the condition code portion of the flag register. The # nccFlagBits version holds the rest. - 'ccFlagBits': ('IntReg', 'uqw', 'INTREG_PSEUDO(0)', None, 60), + 'ccFlagBits': intReg('INTREG_PSEUDO(0)', 60), # These register should needs to be more protected so that later # instructions don't map their indexes with an old value. - 'nccFlagBits': ('ControlReg', 'uqw', 'MISCREG_RFLAGS', None, 61), - 'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 62), + 'nccFlagBits': controlReg('MISCREG_RFLAGS', 61), + 'TOP': controlReg('MISCREG_X87_TOP', 62, ctype='ub'), # The segment base as used by memory instructions. - 'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_EFF_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70), + 'SegBase': controlReg('MISCREG_SEG_EFF_BASE(segment)', 70), # Operands to get and set registers indexed by the operands of the # original instruction. - 'ControlDest': ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 100), - 'ControlSrc1': ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 101), - 'DebugDest': ('ControlReg', 'uqw', 'MISCREG_DR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 102), - 'DebugSrc1': ('ControlReg', 'uqw', 'MISCREG_DR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 103), - 'SegBaseDest': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 104), - 'SegBaseSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 105), - 'SegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 106), - 'SegLimitSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 107), - 'SegSelDest': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 108), - 'SegSelSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 109), - 'SegAttrDest': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 110), - 'SegAttrSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 111), + 'ControlDest': controlReg('MISCREG_CR(dest)', 100), + 'ControlSrc1': controlReg('MISCREG_CR(src1)', 101), + 'DebugDest': controlReg('MISCREG_DR(dest)', 102), + 'DebugSrc1': controlReg('MISCREG_DR(src1)', 103), + 'SegBaseDest': controlReg('MISCREG_SEG_BASE(dest)', 104), + 'SegBaseSrc1': controlReg('MISCREG_SEG_BASE(src1)', 105), + 'SegLimitDest': controlReg('MISCREG_SEG_LIMIT(dest)', 106), + 'SegLimitSrc1': controlReg('MISCREG_SEG_LIMIT(src1)', 107), + 'SegSelDest': controlReg('MISCREG_SEG_SEL(dest)', 108), + 'SegSelSrc1': controlReg('MISCREG_SEG_SEL(src1)', 109), + 'SegAttrDest': controlReg('MISCREG_SEG_ATTR(dest)', 110), + 'SegAttrSrc1': controlReg('MISCREG_SEG_ATTR(src1)', 111), # Operands to access specific control registers directly. - 'EferOp': ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 200), - 'CR4Op': ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 201), - 'DR7Op': ('ControlReg', 'uqw', 'MISCREG_DR7', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 202), - 'LDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSL_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 203), - 'LDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSL_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 204), - 'LDTRSel': ('ControlReg', 'uqw', 'MISCREG_TSL', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205), - 'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206), - 'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207), - 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208), - 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 209), - 'MiscRegDest': ('ControlReg', 'uqw', 'dest', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 210), - 'MiscRegSrc1': ('ControlReg', 'uqw', 'src1', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 211), - 'TscOp': ('ControlReg', 'uqw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 212), - 'M5Reg': ('ControlReg', 'uqw', 'MISCREG_M5_REG', (None, None, None), 213), - 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300) + 'EferOp': controlReg('MISCREG_EFER', 200), + 'CR4Op': controlReg('MISCREG_CR4', 201), + 'DR7Op': controlReg('MISCREG_DR7', 202), + 'LDTRBase': controlReg('MISCREG_TSL_BASE', 203), + 'LDTRLimit': controlReg('MISCREG_TSL_LIMIT', 204), + 'LDTRSel': controlReg('MISCREG_TSL', 205), + 'GDTRBase': controlReg('MISCREG_TSG_BASE', 206), + 'GDTRLimit': controlReg('MISCREG_TSG_LIMIT', 207), + 'CSBase': controlReg('MISCREG_CS_EFF_BASE', 208), + 'CSAttr': controlReg('MISCREG_CS_ATTR', 209), + 'MiscRegDest': controlReg('dest', 210), + 'MiscRegSrc1': controlReg('src1', 211), + 'TscOp': controlReg('MISCREG_TSC', 212), + 'M5Reg': controlReg('MISCREG_M5_REG', 213), + 'Mem': ('Mem', 'uqw', None, \ + ('IsMemRef', 'IsLoad', 'IsStore'), 300) }}; diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 106996848..2dc4587e3 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -165,8 +165,9 @@ namespace X86ISA MISCREG_MTRR_PHYS_BASE_5, MISCREG_MTRR_PHYS_BASE_6, MISCREG_MTRR_PHYS_BASE_7, + MISCREG_MTRR_PHYS_BASE_END, - MISCREG_MTRR_PHYS_MASK_BASE, + MISCREG_MTRR_PHYS_MASK_BASE = MISCREG_MTRR_PHYS_BASE_END, MISCREG_MTRR_PHYS_MASK_0 = MISCREG_MTRR_PHYS_MASK_BASE, MISCREG_MTRR_PHYS_MASK_1, MISCREG_MTRR_PHYS_MASK_2, @@ -175,8 +176,9 @@ namespace X86ISA MISCREG_MTRR_PHYS_MASK_5, MISCREG_MTRR_PHYS_MASK_6, MISCREG_MTRR_PHYS_MASK_7, + MISCREG_MTRR_PHYS_MASK_END, - MISCREG_MTRR_FIX_64K_00000, + MISCREG_MTRR_FIX_64K_00000 = MISCREG_MTRR_PHYS_MASK_END, MISCREG_MTRR_FIX_16K_80000, MISCREG_MTRR_FIX_16K_A0000, MISCREG_MTRR_FIX_4K_C0000, @@ -201,8 +203,9 @@ namespace X86ISA MISCREG_MC5_CTL, MISCREG_MC6_CTL, MISCREG_MC7_CTL, + MISCREG_MC_CTL_END, - MISCREG_MC_STATUS_BASE, + MISCREG_MC_STATUS_BASE = MISCREG_MC_CTL_END, MISCREG_MC0_STATUS = MISCREG_MC_STATUS_BASE, MISCREG_MC1_STATUS, MISCREG_MC2_STATUS, @@ -211,8 +214,9 @@ namespace X86ISA MISCREG_MC5_STATUS, MISCREG_MC6_STATUS, MISCREG_MC7_STATUS, + MISCREG_MC_STATUS_END, - MISCREG_MC_ADDR_BASE, + MISCREG_MC_ADDR_BASE = MISCREG_MC_STATUS_END, MISCREG_MC0_ADDR = MISCREG_MC_ADDR_BASE, MISCREG_MC1_ADDR, MISCREG_MC2_ADDR, @@ -221,8 +225,9 @@ namespace X86ISA MISCREG_MC5_ADDR, MISCREG_MC6_ADDR, MISCREG_MC7_ADDR, + MISCREG_MC_ADDR_END, - MISCREG_MC_MISC_BASE, + MISCREG_MC_MISC_BASE = MISCREG_MC_ADDR_END, MISCREG_MC0_MISC = MISCREG_MC_MISC_BASE, MISCREG_MC1_MISC, MISCREG_MC2_MISC, @@ -231,9 +236,10 @@ namespace X86ISA MISCREG_MC5_MISC, MISCREG_MC6_MISC, MISCREG_MC7_MISC, + MISCREG_MC_MISC_END, // Extended feature enable register - MISCREG_EFER, + MISCREG_EFER = MISCREG_MC_MISC_END, MISCREG_STAR, MISCREG_LSTAR, @@ -250,24 +256,28 @@ namespace X86ISA MISCREG_PERF_EVT_SEL1, MISCREG_PERF_EVT_SEL2, MISCREG_PERF_EVT_SEL3, + MISCREG_PERF_EVT_SEL_END, - MISCREG_PERF_EVT_CTR_BASE, + MISCREG_PERF_EVT_CTR_BASE = MISCREG_PERF_EVT_SEL_END, MISCREG_PERF_EVT_CTR0 = MISCREG_PERF_EVT_CTR_BASE, MISCREG_PERF_EVT_CTR1, MISCREG_PERF_EVT_CTR2, MISCREG_PERF_EVT_CTR3, + MISCREG_PERF_EVT_CTR_END, - MISCREG_SYSCFG, + MISCREG_SYSCFG = MISCREG_PERF_EVT_CTR_END, MISCREG_IORR_BASE_BASE, MISCREG_IORR_BASE0 = MISCREG_IORR_BASE_BASE, MISCREG_IORR_BASE1, + MISCREG_IORR_BASE_END, - MISCREG_IORR_MASK_BASE, + MISCREG_IORR_MASK_BASE = MISCREG_IORR_BASE_END, MISCREG_IORR_MASK0 = MISCREG_IORR_MASK_BASE, MISCREG_IORR_MASK1, + MISCREG_IORR_MASK_END, - MISCREG_TOP_MEM, + MISCREG_TOP_MEM = MISCREG_IORR_MASK_END, MISCREG_TOP_MEM2, MISCREG_VM_CR, @@ -377,102 +387,129 @@ namespace X86ISA static inline MiscRegIndex MISCREG_CR(int index) { + assert(index >= 0 && index < NumCRegs); return (MiscRegIndex)(MISCREG_CR_BASE + index); } static inline MiscRegIndex MISCREG_DR(int index) { + assert(index >= 0 && index < NumDRegs); return (MiscRegIndex)(MISCREG_DR_BASE + index); } static inline MiscRegIndex MISCREG_MTRR_PHYS_BASE(int index) { + assert(index >= 0 && index < (MISCREG_MTRR_PHYS_BASE_END - + MISCREG_MTRR_PHYS_BASE_BASE)); return (MiscRegIndex)(MISCREG_MTRR_PHYS_BASE_BASE + index); } static inline MiscRegIndex MISCREG_MTRR_PHYS_MASK(int index) { + assert(index >= 0 && index < (MISCREG_MTRR_PHYS_MASK_END - + MISCREG_MTRR_PHYS_MASK_BASE)); return (MiscRegIndex)(MISCREG_MTRR_PHYS_MASK_BASE + index); } static inline MiscRegIndex MISCREG_MC_CTL(int index) { + assert(index >= 0 && index < (MISCREG_MC_CTL_END - + MISCREG_MC_CTL_BASE)); return (MiscRegIndex)(MISCREG_MC_CTL_BASE + index); } static inline MiscRegIndex MISCREG_MC_STATUS(int index) { + assert(index >= 0 && index < (MISCREG_MC_STATUS_END - + MISCREG_MC_STATUS_BASE)); return (MiscRegIndex)(MISCREG_MC_STATUS_BASE + index); } static inline MiscRegIndex MISCREG_MC_ADDR(int index) { + assert(index >= 0 && index < (MISCREG_MC_ADDR_END - + MISCREG_MC_ADDR_BASE)); return (MiscRegIndex)(MISCREG_MC_ADDR_BASE + index); } static inline MiscRegIndex MISCREG_MC_MISC(int index) { + assert(index >= 0 && index < (MISCREG_MC_MISC_END - + MISCREG_MC_MISC_BASE)); return (MiscRegIndex)(MISCREG_MC_MISC_BASE + index); } static inline MiscRegIndex MISCREG_PERF_EVT_SEL(int index) { + assert(index >= 0 && index < (MISCREG_PERF_EVT_SEL_END - + MISCREG_PERF_EVT_SEL_BASE)); return (MiscRegIndex)(MISCREG_PERF_EVT_SEL_BASE + index); } static inline MiscRegIndex MISCREG_PERF_EVT_CTR(int index) { + assert(index >= 0 && index < (MISCREG_PERF_EVT_CTR_END - + MISCREG_PERF_EVT_CTR_BASE)); return (MiscRegIndex)(MISCREG_PERF_EVT_CTR_BASE + index); } static inline MiscRegIndex MISCREG_IORR_BASE(int index) { + assert(index >= 0 && index < (MISCREG_IORR_BASE_END - + MISCREG_IORR_BASE_BASE)); return (MiscRegIndex)(MISCREG_IORR_BASE_BASE + index); } static inline MiscRegIndex MISCREG_IORR_MASK(int index) { + assert(index >= 0 && index < (MISCREG_IORR_MASK_END - + MISCREG_IORR_MASK_BASE)); return (MiscRegIndex)(MISCREG_IORR_MASK_BASE + index); } static inline MiscRegIndex MISCREG_SEG_SEL(int index) { + assert(index >= 0 && index < NUM_SEGMENTREGS); return (MiscRegIndex)(MISCREG_SEG_SEL_BASE + index); } static inline MiscRegIndex MISCREG_SEG_BASE(int index) { + assert(index >= 0 && index < NUM_SEGMENTREGS); return (MiscRegIndex)(MISCREG_SEG_BASE_BASE + index); } static inline MiscRegIndex MISCREG_SEG_EFF_BASE(int index) { + assert(index >= 0 && index < NUM_SEGMENTREGS); return (MiscRegIndex)(MISCREG_SEG_EFF_BASE_BASE + index); } static inline MiscRegIndex MISCREG_SEG_LIMIT(int index) { + assert(index >= 0 && index < NUM_SEGMENTREGS); return (MiscRegIndex)(MISCREG_SEG_LIMIT_BASE + index); } static inline MiscRegIndex MISCREG_SEG_ATTR(int index) { + assert(index >= 0 && index < NUM_SEGMENTREGS); return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index); } diff --git a/src/mem/ruby/common/Driver.hh b/src/mem/ruby/common/Driver.hh index 9aa756386..9d17fcadb 100644 --- a/src/mem/ruby/common/Driver.hh +++ b/src/mem/ruby/common/Driver.hh @@ -40,13 +40,8 @@ #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/system/NodeID.hh" -#include "mem/protocol/CacheRequestType.hh" +#include "mem/ruby/common/Address.hh" -class RubySystem; -class SubBlock; -class Address; -class MachineID; -class SimicsHypervisor; class Driver { public: @@ -58,15 +53,12 @@ public: // Public Methods virtual void get_network_config() {} - virtual void dmaHitCallback() = 0; - virtual void hitCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread) = 0; // Called by sequencer - virtual void conflictCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread) { assert(0); }; // Called by sequencer + virtual void dmaHitCallback() {}; + virtual void hitCallback(int64_t id) = 0; // Called by sequencer + virtual void go() = 0; virtual integer_t getInstructionCount(int procID) const { return 1; } virtual integer_t getCycleCount(int procID) const { return 1; } virtual void addThreadDependency(int procID, int requestor_thread, int conflict_thread) const { assert(0);} - virtual int inTransaction(int procID, int thread ) const{ - cout << "Driver.hh inTransaction " << endl; -return false; } //called by Sequencer virtual void printDebug(){} //called by Sequencer virtual void printStats(ostream& out) const = 0; @@ -74,7 +66,6 @@ return false; } //called by Sequencer virtual void printConfig(ostream& out) const = 0; - //virtual void abortCallback(NodeID proc){} virtual integer_t readPhysicalMemory(int procID, physical_address_t address, int len ){ ASSERT(0); return 0; } diff --git a/src/mem/ruby/libruby.cc b/src/mem/ruby/libruby.cc index 987f4fd10..b867fec34 100644 --- a/src/mem/ruby/libruby.cc +++ b/src/mem/ruby/libruby.cc @@ -9,6 +9,7 @@ #include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/system/MemoryVector.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/recorder/Tracer.hh" string RubyRequestType_to_string(const RubyRequestType& obj) { @@ -19,8 +20,14 @@ string RubyRequestType_to_string(const RubyRequestType& obj) return "LD"; case RubyRequestType_ST: return "ST"; - case RubyRequestType_RMW: - return "RMW"; + case RubyRequestType_Locked_Read: + return "Locked_Read"; + case RubyRequestType_Locked_Write: + return "Locked_Write"; + case RubyRequestType_RMW_Read: + return "RMW_Read"; + case RubyRequestType_RMW_Write: + return "RMW_Write"; case RubyRequestType_NULL: default: assert(0); @@ -36,8 +43,14 @@ RubyRequestType string_to_RubyRequestType(std::string str) return RubyRequestType_LD; else if (str == "ST") return RubyRequestType_ST; - else if (str == "RMW") - return RubyRequestType_RMW; + else if (str == "Locked_Read") + return RubyRequestType_Locked_Read; + else if (str == "Locked_Write") + return RubyRequestType_Locked_Write; + else if (str == "RMW_Read") + return RubyRequestType_RMW_Read; + else if (str == "RMW_Write") + return RubyRequestType_RMW_Write; else assert(0); return RubyRequestType_NULL; @@ -200,6 +213,20 @@ void libruby_print_stats(std::ostream & out) { RubySystem::printStats(out); } +void libruby_playback_trace(char * trace_filename) +{ + RubySystem::getTracer()->playbackTrace(trace_filename); +} + +void libruby_start_tracing(char * record_filename) { + // start the trace + RubySystem::getTracer()->startTrace(record_filename); +} + +void libruby_stop_tracing() { + // start the trace + RubySystem::getTracer()->stopTrace(); +} uint64_t libruby_get_time() { return RubySystem::getCycleCount(0); diff --git a/src/mem/ruby/libruby.hh b/src/mem/ruby/libruby.hh index 5916c98e6..94018e9b9 100644 --- a/src/mem/ruby/libruby.hh +++ b/src/mem/ruby/libruby.hh @@ -11,7 +11,10 @@ enum RubyRequestType { RubyRequestType_IFETCH, RubyRequestType_LD, RubyRequestType_ST, - RubyRequestType_RMW + RubyRequestType_Locked_Read, + RubyRequestType_Locked_Write, + RubyRequestType_RMW_Read, + RubyRequestType_RMW_Write }; enum RubyAccessMode { @@ -101,6 +104,20 @@ void libruby_print_config(std::ostream & out); */ void libruby_print_stats(std::ostream & out); +/** + * does not return until done + */ +void libruby_playback_trace(char * trace_filename); + +/* + * enables the tracer and opens the trace file + */ +void libruby_start_tracing(char * record_filename); + +/* + * closes the trace file + */ +void libruby_stop_tracing(); /** * get time diff --git a/src/mem/ruby/recorder/TraceRecord.cc b/src/mem/ruby/recorder/TraceRecord.cc index 1521d2a3f..8f426d690 100644 --- a/src/mem/ruby/recorder/TraceRecord.cc +++ b/src/mem/ruby/recorder/TraceRecord.cc @@ -47,7 +47,10 @@ TraceRecord::TraceRecord(const string & sequencer_name, const Address& data_addr // Don't differentiate between store misses and atomic requests in // the trace - if (m_type == RubyRequestType_RMW) { + if (m_type == RubyRequestType_Locked_Read) { + m_type = RubyRequestType_ST; + } + else if (m_type == RubyRequestType_Locked_Write) { m_type = RubyRequestType_ST; } } diff --git a/src/mem/ruby/recorder/Tracer.cc b/src/mem/ruby/recorder/Tracer.cc index d2df544d8..5b1e4274b 100644 --- a/src/mem/ruby/recorder/Tracer.cc +++ b/src/mem/ruby/recorder/Tracer.cc @@ -92,10 +92,11 @@ void Tracer::startTrace(string filename) void Tracer::stopTrace() { - assert(m_enabled == true); - m_trace_file.close(); - cout << "Request trace file closed." << endl; - m_enabled = false; + if (m_enabled == true) { + m_trace_file.close(); + cout << "Request trace file closed." << endl; + m_enabled = false; + } } void Tracer::traceRequest(const string & sequencer_name, const Address& data_addr, const Address& pc_addr, RubyRequestType type, Time time) diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh index 941073ad2..625d5ce59 100644 --- a/src/mem/ruby/system/CacheMemory.hh +++ b/src/mem/ruby/system/CacheMemory.hh @@ -116,6 +116,9 @@ public: void setMemoryValue(const Address& addr, char* value, unsigned int size_in_bytes ); + void setLocked (const Address& addr, int context); + void clearLocked (const Address& addr); + bool isLocked (const Address& addr, int context); // Print cache contents void print(ostream& out) const; void printData(ostream& out) const; @@ -147,6 +150,7 @@ private: // The first index is the # of cache lines. // The second index is the the amount associativity. Vector<Vector<AbstractCacheEntry*> > m_cache; + Vector<Vector<int> > m_locked; AbstractReplacementPolicy *m_replacementPolicy_ptr; @@ -252,10 +256,13 @@ void CacheMemory::init(const vector<string> & argv) assert(false); m_cache.setSize(m_cache_num_sets); + m_locked.setSize(m_cache_num_sets); for (int i = 0; i < m_cache_num_sets; i++) { m_cache[i].setSize(m_cache_assoc); + m_locked[i].setSize(m_cache_assoc); for (int j = 0; j < m_cache_assoc; j++) { m_cache[i][j] = NULL; + m_locked[i][j] = -1; } } } @@ -474,6 +481,7 @@ void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) m_cache[cacheSet][i] = entry; // Init entry m_cache[cacheSet][i]->m_Address = address; m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; + m_locked[cacheSet][i] = -1; m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime()); @@ -494,6 +502,7 @@ void CacheMemory::deallocate(const Address& address) if (location != -1){ delete m_cache[cacheSet][location]; m_cache[cacheSet][location] = NULL; + m_locked[cacheSet][location] = -1; } } @@ -542,6 +551,9 @@ void CacheMemory::changePermission(const Address& address, AccessPermission new_ { assert(address == line_address(address)); lookup(address).m_Permission = new_perm; + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + m_locked[cacheSet][loc] = -1; assert(getPermission(address) == new_perm); } @@ -630,5 +642,38 @@ void CacheMemory::setMemoryValue(const Address& addr, char* value, // entry = lookup(line_address(addr)); } +inline +void +CacheMemory::setLocked(const Address& address, int context) +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + m_locked[cacheSet][loc] = context; +} + +inline +void +CacheMemory::clearLocked(const Address& address) +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + m_locked[cacheSet][loc] = -1; +} + +inline +bool +CacheMemory::isLocked(const Address& address, int context) +{ + assert(address == line_address(address)); + Index cacheSet = addressToCacheSet(address); + int loc = findTagInSet(cacheSet, address); + assert(loc != -1); + return m_locked[cacheSet][loc] == context; +} + #endif //CACHEMEMORY_H diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc index 5da7ea51e..58ec7bb45 100644 --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -47,7 +47,10 @@ int64_t DMASequencer::makeRequest(const RubyRequest & request) break; case RubyRequestType_NULL: case RubyRequestType_IFETCH: - case RubyRequestType_RMW: + case RubyRequestType_Locked_Read: + case RubyRequestType_Locked_Write: + case RubyRequestType_RMW_Read: + case RubyRequestType_RMW_Write: assert(0); } diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 97416d2d3..1587aa5fa 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -43,6 +43,8 @@ //Sequencer::Sequencer(int core_id, MessageBuffer* mandatory_q) +#define LLSC_FAIL -2 + Sequencer::Sequencer(const string & name) :RubyPort(name) { @@ -201,7 +203,10 @@ bool Sequencer::insertRequest(SequencerRequest* request) { Address line_addr(request->ruby_request.paddr); line_addr.makeLineAddress(); if ((request->ruby_request.type == RubyRequestType_ST) || - (request->ruby_request.type == RubyRequestType_RMW)) { + (request->ruby_request.type == RubyRequestType_RMW_Read) || + (request->ruby_request.type == RubyRequestType_RMW_Write) || + (request->ruby_request.type == RubyRequestType_Locked_Read) || + (request->ruby_request.type == RubyRequestType_Locked_Write)) { if (m_writeRequestTable.exist(line_addr)) { m_writeRequestTable.lookup(line_addr) = request; // return true; @@ -237,7 +242,10 @@ void Sequencer::removeRequest(SequencerRequest* srequest) { Address line_addr(ruby_request.paddr); line_addr.makeLineAddress(); if ((ruby_request.type == RubyRequestType_ST) || - (ruby_request.type == RubyRequestType_RMW)) { + (ruby_request.type == RubyRequestType_RMW_Read) || + (ruby_request.type == RubyRequestType_RMW_Write) || + (ruby_request.type == RubyRequestType_Locked_Read) || + (ruby_request.type == RubyRequestType_Locked_Write)) { m_writeRequestTable.deallocate(line_addr); } else { m_readRequestTable.deallocate(line_addr); @@ -256,7 +264,14 @@ void Sequencer::writeCallback(const Address& address, DataBlock& data) { removeRequest(request); assert((request->ruby_request.type == RubyRequestType_ST) || - (request->ruby_request.type == RubyRequestType_RMW)); + (request->ruby_request.type == RubyRequestType_RMW_Read) || + (request->ruby_request.type == RubyRequestType_RMW_Write) || + (request->ruby_request.type == RubyRequestType_Locked_Read) || + (request->ruby_request.type == RubyRequestType_Locked_Write)); + // POLINA: the assumption is that atomics are only on data cache and not instruction cache + if (request->ruby_request.type == RubyRequestType_Locked_Read) { + m_dataCache_ptr->setLocked(address, m_version); + } hitCallback(request, data); } @@ -347,6 +362,7 @@ bool Sequencer::empty() const { return (m_writeRequestTable.size() == 0) && (m_readRequestTable.size() == 0); } + int64_t Sequencer::makeRequest(const RubyRequest & request) { assert(Address(request.paddr).getOffset() + request.len <= RubySystem::getBlockSizeBytes()); @@ -355,6 +371,16 @@ int64_t Sequencer::makeRequest(const RubyRequest & request) SequencerRequest *srequest = new SequencerRequest(request, id, g_eventQueue_ptr->getTime()); bool found = insertRequest(srequest); if (!found) + if (request.type == RubyRequestType_Locked_Write) { + // NOTE: it is OK to check the locked flag here as the mandatory queue will be checked first + // ensuring that nothing comes between checking the flag and servicing the store + if (!m_dataCache_ptr->isLocked(line_address(Address(request.paddr)), m_version)) { + return LLSC_FAIL; + } + else { + m_dataCache_ptr->clearLocked(line_address(Address(request.paddr))); + } + } issueRequest(request); // TODO: issue hardware prefetches here @@ -379,7 +405,16 @@ void Sequencer::issueRequest(const RubyRequest& request) { case RubyRequestType_ST: ctype = CacheRequestType_ST; break; - case RubyRequestType_RMW: + case RubyRequestType_Locked_Read: + ctype = CacheRequestType_ST; + break; + case RubyRequestType_Locked_Write: + ctype = CacheRequestType_ST; + break; + case RubyRequestType_RMW_Read: + ctype = CacheRequestType_ATOMIC; + break; + case RubyRequestType_RMW_Write: ctype = CacheRequestType_ATOMIC; break; default: diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh index 40c425ad7..8cbeb2b0e 100644 --- a/src/mem/ruby/system/System.hh +++ b/src/mem/ruby/system/System.hh @@ -106,7 +106,7 @@ public: static int getNumberOfSequencers() { return m_sequencers.size(); } Profiler* getProfiler() {assert(m_profiler_ptr != NULL); return m_profiler_ptr; } - Tracer* getTracer() { assert(m_tracer_ptr != NULL); return m_tracer_ptr; } + static Tracer* getTracer() { assert(m_tracer_ptr != NULL); return m_tracer_ptr; } static MemoryVector* getMemoryVector() { assert(m_mem_vec_ptr != NULL); return m_mem_vec_ptr;} void recordCacheContents(CacheRecorder& tr) const; diff --git a/src/mem/ruby/tester/DetermGETXGenerator.cc b/src/mem/ruby/tester/DetermGETXGenerator.cc index 6692fb80c..1eb9cb3ee 100644 --- a/src/mem/ruby/tester/DetermGETXGenerator.cc +++ b/src/mem/ruby/tester/DetermGETXGenerator.cc @@ -1,31 +1,58 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ @@ -38,7 +65,8 @@ #include "mem/ruby/tester/DetermGETXGenerator.hh" #include "mem/protocol/DetermGETXGeneratorStatus.hh" #include "mem/ruby/tester/DeterministicDriver.hh" -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/tester/Tester_Globals.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh" //#include "DMAController.hh" #include "mem/ruby/libruby.hh" @@ -48,9 +76,11 @@ DetermGETXGenerator::DetermGETXGenerator(NodeID node, DeterministicDriver * driv { m_status = DetermGETXGeneratorStatus_Thinking; m_last_transition = 0; + counter = 0; m_node = node; - m_address = Address(9999); // initialize to null value + m_address = Address(1); // initialize to null value m_counter = 0; + issued_load = false; parent_driver = driver; // don't know exactly when this node needs to request so just guess randomly parent_driver->eventQueue->scheduleEvent(this, 1+(random() % 200)); @@ -68,7 +98,9 @@ void DetermGETXGenerator::wakeup() // determine if this node is next for the GETX round robin request if (m_status == DetermGETXGeneratorStatus_Thinking) { if (parent_driver->isStoreReady(m_node)) { - pickAddress(); + if (!issued_load) { + pickAddress(); + } m_status = DetermGETXGeneratorStatus_Store_Pending; // Store Pending m_last_transition = parent_driver->eventQueue->getTime(); initiateStore(); // GETX @@ -85,13 +117,13 @@ void DetermGETXGenerator::wakeup() void DetermGETXGenerator::performCallback(NodeID proc, Address address) { assert(proc == m_node); - assert(address == m_address); + assert(address == m_address); DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, address); - if (m_status == DetermGETXGeneratorStatus_Store_Pending) { + if (m_status == DetermGETXGeneratorStatus_Store_Pending) { parent_driver->recordStoreLatency(parent_driver->eventQueue->getTime() - m_last_transition); parent_driver->storeCompleted(m_node, address); // advance the store queue @@ -104,7 +136,7 @@ void DetermGETXGenerator::performCallback(NodeID proc, Address address) parent_driver->reportDone(); m_status = DetermGETXGeneratorStatus_Done; m_last_transition = parent_driver->eventQueue->getTime(); - } + } } else { WARN_EXPR(m_status); @@ -132,7 +164,6 @@ void DetermGETXGenerator::pickAddress() void DetermGETXGenerator::initiateStore() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store"); - uint8_t *write_data = new uint8_t[64]; for(int i=0; i < 64; i++) { write_data[i] = m_node; @@ -141,12 +172,29 @@ void DetermGETXGenerator::initiateStore() char name [] = "Sequencer_"; char port_name [13]; sprintf(port_name, "%s%d", name, m_node); - - int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_ST, RubyAccessMode_Supervisor)); + int64_t request_id; + if (counter%10 == 0) { + if (!issued_load) { + cerr << m_node << " RMW_Read to address: " << m_address.getAddress() << endl << flush; + request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_RMW_Read, RubyAccessMode_Supervisor)); + issued_load = true; + } + else { + cerr << m_node << " RMW_Write to address: " << m_address.getAddress() << endl << flush; + request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_RMW_Write, RubyAccessMode_Supervisor)); + issued_load = false; + counter++; + } + } + else { + cerr << m_node << " ST to address: " << m_address.getAddress() << endl << flush; + request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_ST, RubyAccessMode_Supervisor)); + counter++; + } // delete [] write_data; - ASSERT(parent_driver->requests.find(request_id) == parent_driver->requests.end()); + ASSERT(parent_driver->requests.find(request_id) == parent_driver->requests.end()); parent_driver->requests.insert(make_pair(request_id, make_pair(m_node, m_address))); } diff --git a/src/mem/ruby/tester/DetermGETXGenerator.hh b/src/mem/ruby/tester/DetermGETXGenerator.hh index 82e616e4b..7d7e9ea70 100644 --- a/src/mem/ruby/tester/DetermGETXGenerator.hh +++ b/src/mem/ruby/tester/DetermGETXGenerator.hh @@ -1,36 +1,63 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ * - * Description: + * Description: * */ @@ -40,11 +67,12 @@ #ifndef DETERMGETXGENERATOR_H #define DETERMGETXGENERATOR_H -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/tester/Tester_Globals.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/protocol/DetermGETXGeneratorStatus.hh" -#include "Address_Tester.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/Address.hh" class DeterministicDriver; class DMAController; @@ -56,7 +84,7 @@ public: // Destructor ~DetermGETXGenerator(); - + // Public Methods void wakeup(); void performCallback(NodeID proc, Address address); @@ -80,8 +108,10 @@ private: // Data Members (m_ prefix) DetermGETXGeneratorStatus m_status; int m_counter; + bool issued_load; Address m_address; NodeID m_node; + long int counter; Time m_last_transition; }; @@ -91,7 +121,7 @@ ostream& operator<<(ostream& out, const DetermGETXGenerator& obj); // ******************* Definitions ******************* // Output operator definition -extern inline +extern inline ostream& operator<<(ostream& out, const DetermGETXGenerator& obj) { obj.print(out); diff --git a/src/mem/ruby/tester/DetermInvGenerator.cc b/src/mem/ruby/tester/DetermInvGenerator.cc index eebe18057..73ef8b66a 100644 --- a/src/mem/ruby/tester/DetermInvGenerator.cc +++ b/src/mem/ruby/tester/DetermInvGenerator.cc @@ -1,31 +1,58 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ @@ -36,10 +63,11 @@ // then Invalidates them with a GETX. The GETS and GETX request are generated one // at a time in round-robin fashion 0...1...2...etc. +#include "mem/ruby/common/Global.hh" #include "mem/ruby/tester/DetermInvGenerator.hh" #include "mem/protocol/DetermInvGeneratorStatus.hh" #include "mem/ruby/tester/DeterministicDriver.hh" -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/tester/Tester_Globals.hh" //#include "DMAController.hh" #include "mem/ruby/libruby.hh" @@ -75,7 +103,7 @@ void DetermInvGenerator::wakeup() } else { // I'll check again later m_driver.eventQueue->scheduleEvent(this, thinkTime()); } - } else if (m_status == DetermInvGeneratorStatus_Load_Complete) { + } else if (m_status == DetermInvGeneratorStatus_Load_Complete) { if (m_driver.isStoreReady(m_node, m_address)) { // do a store in this transaction or start the next one if (m_driver.isLoadReady((0), m_address)) { // everyone is in S for this address i.e. back to node 0 m_status = DetermInvGeneratorStatus_Store_Pending; @@ -98,13 +126,13 @@ void DetermInvGenerator::wakeup() void DetermInvGenerator::performCallback(NodeID proc, Address address) { assert(proc == m_node); - assert(address == m_address); + assert(address == m_address); DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, address); - if (m_status == DetermInvGeneratorStatus_Load_Pending) { + if (m_status == DetermInvGeneratorStatus_Load_Pending) { m_driver.recordLoadLatency(m_driver.eventQueue->getTime() - m_last_transition); //NodeID firstByte = data.readByte(); // dummy read @@ -121,9 +149,9 @@ void DetermInvGenerator::performCallback(NodeID proc, Address address) m_driver.reportDone(); m_status = DetermInvGeneratorStatus_Done; m_last_transition = m_driver.eventQueue->getTime(); - } + } - } else if (m_status == DetermInvGeneratorStatus_Store_Pending) { + } else if (m_status == DetermInvGeneratorStatus_Store_Pending) { m_driver.recordStoreLatency(m_driver.eventQueue->getTime() - m_last_transition); //data.writeByte(m_node); m_driver.storeCompleted(m_node, address); // advance the store queue @@ -137,7 +165,7 @@ void DetermInvGenerator::performCallback(NodeID proc, Address address) m_driver.reportDone(); m_status = DetermInvGeneratorStatus_Done; m_last_transition = m_driver.eventQueue->getTime(); - } + } } else { WARN_EXPR(m_status); ERROR_MSG("Invalid status"); @@ -174,7 +202,7 @@ void DetermInvGenerator::pickLoadAddress() void DetermInvGenerator::initiateLoad() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Load"); - // sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_LD, Address(1), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */)); + // sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_LD, Address(1), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */)); uint8_t * read_data = new uint8_t[64]; char name [] = "Sequencer_"; @@ -185,7 +213,7 @@ void DetermInvGenerator::initiateLoad() //delete [] read_data; - ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address))); } @@ -193,7 +221,7 @@ void DetermInvGenerator::initiateLoad() void DetermInvGenerator::initiateStore() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store"); - // sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */)); + // sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */)); uint8_t *write_data = new uint8_t[64]; for(int i=0; i < 64; i++) { write_data[i] = m_node; @@ -207,7 +235,7 @@ void DetermInvGenerator::initiateStore() //delete [] write_data; - ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address))); } diff --git a/src/mem/ruby/tester/DetermInvGenerator.hh b/src/mem/ruby/tester/DetermInvGenerator.hh index 6127c3af4..fc334c0e3 100644 --- a/src/mem/ruby/tester/DetermInvGenerator.hh +++ b/src/mem/ruby/tester/DetermInvGenerator.hh @@ -1,36 +1,63 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ * - * Description: + * Description: * */ @@ -41,8 +68,10 @@ #ifndef DETERMINVGENERATOR_H #define DETERMINVGENERATOR_H -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/tester/Tester_Globals.hh" #include "mem/ruby/common/Consumer.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/protocol/DetermInvGeneratorStatus.hh" #include "Address_Tester.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh" @@ -56,7 +85,7 @@ public: // Destructor ~DetermInvGenerator(); - + // Public Methods void wakeup(); void performCallback(NodeID proc, Address address); @@ -71,7 +100,7 @@ private: void initiateStore(); void pickLoadAddress(); void pickStoreAddress(); - + // copy constructor and assignment operator DetermInvGenerator(const DetermInvGenerator& obj); DetermInvGenerator& operator=(const DetermInvGenerator& obj); @@ -92,7 +121,7 @@ ostream& operator<<(ostream& out, const DetermInvGenerator& obj); // ******************* Definitions ******************* // Output operator definition -extern inline +extern inline ostream& operator<<(ostream& out, const DetermInvGenerator& obj) { obj.print(out); diff --git a/src/mem/ruby/tester/DetermSeriesGETSGenerator.cc b/src/mem/ruby/tester/DetermSeriesGETSGenerator.cc index 38688f10d..47a4eda0d 100644 --- a/src/mem/ruby/tester/DetermSeriesGETSGenerator.cc +++ b/src/mem/ruby/tester/DetermSeriesGETSGenerator.cc @@ -1,31 +1,58 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ @@ -44,7 +71,7 @@ DetermSeriesGETSGenerator::DetermSeriesGETSGenerator(NodeID node, DeterministicD m_node = node; m_address = Address(9999); // initialize to null value m_counter = 0; - + // don't know exactly when this node needs to request so just guess randomly m_driver.eventQueue->scheduleEvent(this, 1+(random() % 200)); @@ -79,13 +106,13 @@ void DetermSeriesGETSGenerator::wakeup() void DetermSeriesGETSGenerator::performCallback(NodeID proc, Address address) { assert(proc == m_node); - assert(address == m_address); + assert(address == m_address); DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, address); - if (m_status == DetermSeriesGETSGeneratorStatus_Load_Pending) { + if (m_status == DetermSeriesGETSGeneratorStatus_Load_Pending) { m_driver.recordLoadLatency(m_driver.eventQueue->getTime() - m_last_transition); //data.writeByte(m_node); m_driver.loadCompleted(m_node, address); // advance the load queue @@ -100,7 +127,7 @@ void DetermSeriesGETSGenerator::performCallback(NodeID proc, Address address) m_driver.reportDone(); m_status = DetermSeriesGETSGeneratorStatus_Done; m_last_transition = m_driver.eventQueue->getTime(); - } + } } else { WARN_EXPR(m_status); @@ -128,7 +155,7 @@ void DetermSeriesGETSGenerator::pickAddress() void DetermSeriesGETSGenerator::initiateLoad() { DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Load"); - //sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_IFETCH, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */)); + //sequencer()->makeRequest(CacheMsg(m_address, m_address, CacheRequestType_IFETCH, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No, Address(0), 0 /* only 1 SMT thread */)); uint8_t *read_data = new uint8_t[64]; @@ -140,7 +167,7 @@ void DetermSeriesGETSGenerator::initiateLoad() //delete [] read_data; - ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address))); } diff --git a/src/mem/ruby/tester/DetermSeriesGETSGenerator.hh b/src/mem/ruby/tester/DetermSeriesGETSGenerator.hh index 225e45a11..e2034bde1 100644 --- a/src/mem/ruby/tester/DetermSeriesGETSGenerator.hh +++ b/src/mem/ruby/tester/DetermSeriesGETSGenerator.hh @@ -1,36 +1,63 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ * - * Description: + * Description: * */ @@ -42,10 +69,11 @@ #ifndef DETERMSERIESGETSGENERATOR_H #define DETERMSERIESGETSGENERATOR_H -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/tester/Tester_Globals.hh" #include "mem/ruby/common/Consumer.hh" +#include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/protocol/DetermSeriesGETSGeneratorStatus.hh" -#include "Address_Tester.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh" class DeterministicDriver; @@ -57,7 +85,7 @@ public: // Destructor ~DetermSeriesGETSGenerator(); - + // Public Methods void wakeup(); void performCallback(NodeID proc, Address address); @@ -89,7 +117,7 @@ ostream& operator<<(ostream& out, const DetermSeriesGETSGenerator& obj); // ******************* Definitions ******************* // Output operator definition -extern inline +extern inline ostream& operator<<(ostream& out, const DetermSeriesGETSGenerator& obj) { obj.print(out); diff --git a/src/mem/ruby/tester/DeterministicDriver.cc b/src/mem/ruby/tester/DeterministicDriver.cc index 54b5f5e0d..b6eb79497 100644 --- a/src/mem/ruby/tester/DeterministicDriver.cc +++ b/src/mem/ruby/tester/DeterministicDriver.cc @@ -1,40 +1,68 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ * */ -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Tester_Globals.hh" #include "mem/ruby/tester/DeterministicDriver.hh" -#include "mem/ruby/tester/EventQueue_Tester.hh" +#include "mem/ruby/eventqueue/RubyEventQueue.hh" //#include "DMAGenerator.hh" #include "mem/ruby/tester/DetermGETXGenerator.hh" @@ -42,20 +70,19 @@ DeterministicDriver::DeterministicDriver(string generator_type, int num_completions, int num_procs, Time g_think_time, Time g_wait_time, int g_tester_length) { - eventQueue = new RubyEventQueue; + eventQueue = new RubyEventQueue; m_finish_time = 0; m_last_issue = -11; m_done_counter = 0; m_loads_completed = 0; m_stores_completed = 0; - + m_numCompletionsPerNode = num_completions; m_num_procs = num_procs; m_think_time = g_think_time; m_wait_time = g_wait_time; m_tester_length = g_tester_length; - - + m_last_progress_vector.setSize(num_procs); for (int i=0; i<m_last_progress_vector.size(); i++) { m_last_progress_vector[i] = 0; @@ -129,7 +156,7 @@ void DeterministicDriver::hitCallback(int64_t request_id) Address address = requests[request_id].second; m_generator_vector[proc]->performCallback(proc, address); - + m_last_progress_vector[proc] = eventQueue->getTime(); requests.erase(request_id); @@ -153,7 +180,7 @@ bool DeterministicDriver::isLoadReady(NodeID node) } bool DeterministicDriver::isLoadReady(NodeID node, Address addr) -{ +{ return isAddrReady(node, m_load_vector, addr); } @@ -163,7 +190,7 @@ bool DeterministicDriver::isAddrReady(NodeID node, Vector<NodeID> addr_vector) for (int i=0; i<addr_vector.size(); i++) { if (((addr_vector[i]+1)%m_num_procs == node) && (m_loads_completed+m_stores_completed >= m_numCompletionsPerNode*node) && // is this node next - (eventQueue->getTime() >= m_last_issue + 10)) { // controll rate of requests + (eventQueue->getTime() >= m_last_issue + 10)) { // controll rate of requests return true; } } @@ -180,7 +207,7 @@ bool DeterministicDriver::isAddrReady(NodeID node, Vector<NodeID> addr_vector, A if (((addr_vector[addr_number]+1)%m_num_procs == node) && (m_loads_completed+m_stores_completed >= m_numCompletionsPerNode*node) && // is this node next - (eventQueue->getTime() >= m_last_issue + 10)) { // controll rate of requests + (eventQueue->getTime() >= m_last_issue + 10)) { // controll rate of requests return true; } else { return false; @@ -203,7 +230,7 @@ void DeterministicDriver::setNextAddr(NodeID node, Address addr, Vector<NodeID>& { // mark the addr vector that this proc was the last to use the particular address int addr_number = addr.getAddress()/DATA_BLOCK_BYTES; - addr_vector[addr_number] = node; + addr_vector[addr_number] = node; } Address DeterministicDriver::getNextLoadAddr(NodeID node) @@ -221,16 +248,18 @@ Address DeterministicDriver::getNextAddr(NodeID node, Vector<NodeID> addr_vector // This method deterministically picks the next addr the node should acquirer // The addrs cycle through according to NodeID 0->1->...->lastID->0... - + Address addr; - + // should only be called if we know a addr is ready for the node ASSERT(isAddrReady(node, addr_vector)); for (int addr_number=0; addr_number<addr_vector.size(); addr_number++) { // is this node next in line for the addr - if ((addr_vector[addr_number] != 1) && ((addr_vector[addr_number]+1)%m_num_procs) == node) { + // POLINA: LOOK HERE! + // if ((addr_vector[addr_number] != 1) && ((addr_vector[addr_number]+1)%m_num_procs) == node) { + if (((addr_vector[addr_number]+1)%m_num_procs) == node) { // One addr per cache line addr.setAddress(addr_number * DATA_BLOCK_BYTES); diff --git a/src/mem/ruby/tester/DeterministicDriver.hh b/src/mem/ruby/tester/DeterministicDriver.hh index 288ad5a15..61c028f0c 100644 --- a/src/mem/ruby/tester/DeterministicDriver.hh +++ b/src/mem/ruby/tester/DeterministicDriver.hh @@ -1,58 +1,86 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ * - * Description: + * Description: * */ #ifndef DETERMINISTICDRIVER_H #define DETERMINISTICDRIVER_H #include <map> -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Tester_Globals.hh" #include "mem/ruby/common/Histogram.hh" // includes global, but doesn't use anything, so it should be fine #include "mem/protocol/CacheRequestType.hh" // includes global, but doesn't use anything, so it should be fine -#include "Address_Tester.hh" // we redefined the address +#include "mem/ruby/common/Address.hh" // we redefined the address #include "mem/ruby/tester/DetermGETXGenerator.hh" // this is our file #include "mem/ruby/tester/DetermSeriesGETSGenerator.hh" // this is our file #include "mem/ruby/tester/DetermInvGenerator.hh" // this is our file #include "mem/ruby/libruby.hh" -#include "mem/ruby/tester/Driver_Tester.hh" +#include "mem/ruby/common/Driver.hh" #include "mem/ruby/common/Consumer.hh" -#include "mem/ruby/tester/EventQueue_Tester.hh" +#include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/protocol/SpecifiedGeneratorType.hh" //class DMAGenerator; -class DeterministicDriver : public Driver_Tester, public Consumer { +class DeterministicDriver : public Driver, public Consumer { public: friend class DetermGETXGenerator; friend class DetermSeriesGETSGenerator; @@ -62,7 +90,7 @@ public: // Destructor ~DeterministicDriver(); - + // Public Methods void go(); bool isStoreReady(NodeID node); @@ -100,7 +128,7 @@ private: bool isAddrReady(NodeID node, Vector<NodeID> addr_vector, Address addr); void setNextAddr(NodeID node, Address addr, Vector<NodeID>& addr_vector); - + // Data Members (m_ prefix) Vector<Time> m_last_progress_vector; Vector<SpecifiedGenerator*> m_generator_vector; @@ -114,14 +142,14 @@ private: int m_stores_completed; // enforces the previous node to have a certain # of completions // before next node starts - + map <int64_t, pair <int, Address> > requests; Time m_think_time; Time m_wait_time; int m_tester_length; int m_num_procs; RubyEventQueue * eventQueue; - int m_numCompletionsPerNode; + int m_numCompletionsPerNode; Histogram m_load_latency; Histogram m_store_latency; @@ -135,7 +163,7 @@ ostream& operator<<(ostream& out, const DeterministicDriver& obj); // ******************* Definitions ******************* // Output operator definition -extern inline +extern inline ostream& operator<<(ostream& out, const DeterministicDriver& obj) { obj.print(out); diff --git a/src/mem/ruby/tester/Driver_Tester.cc b/src/mem/ruby/tester/Driver_Tester.cc deleted file mode 100644 index d29e6f988..000000000 --- a/src/mem/ruby/tester/Driver_Tester.cc +++ /dev/null @@ -1,44 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * Description: See Driver_Tester.hh - * - */ - -#include "mem/ruby/tester/Driver_Tester.hh" - -Driver_Tester::Driver_Tester() { -} - -// still need to be defined for subclasses -Driver_Tester::~Driver_Tester() { -} diff --git a/src/mem/ruby/tester/Driver_Tester.hh b/src/mem/ruby/tester/Driver_Tester.hh deleted file mode 100644 index 77cd4ed3c..000000000 --- a/src/mem/ruby/tester/Driver_Tester.hh +++ /dev/null @@ -1,82 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * Description: - * - */ - -#ifndef Driver_Tester_H -#define Driver_Tester_H - -#include "mem/ruby/tester/Global_Tester.hh" -#include "mem/ruby/common/Consumer.hh" -#include "mem/ruby/system/NodeID.hh" -#include "Address_Tester.hh" - -class Driver_Tester { -public: - // Constructors - Driver_Tester(); - - // Destructor - virtual ~Driver_Tester() = 0; - - // Public Methods - virtual void get_network_config() {} - virtual void dmaHitCallback() {}; - virtual void hitCallback(int64_t id) = 0; - virtual void go() = 0; - virtual integer_t getInstructionCount(int procID) const { return 1; } - virtual integer_t getCycleCount(int procID) const { return 1; } - virtual void addThreadDependency(int procID, int requestor_thread, int conflict_thread) const { assert(0);} - virtual void printDebug(){} - - virtual void printStats(ostream& out) const = 0; - virtual void clearStats() = 0; - - virtual void printConfig(ostream& out) const = 0; - - virtual integer_t readPhysicalMemory(int procID, physical_address_t address, - int len ){ ASSERT(0); return 0; } - - virtual void writePhysicalMemory( int procID, physical_address_t address, - integer_t value, int len ){ ASSERT(0); } - -protected: - // accessible by subclasses - -private: - // inaccessible by subclasses - -}; - -#endif //Driver_Tester_H diff --git a/src/mem/ruby/tester/EventQueue_Tester.hh b/src/mem/ruby/tester/EventQueue_Tester.hh deleted file mode 100644 index fe600bb84..000000000 --- a/src/mem/ruby/tester/EventQueue_Tester.hh +++ /dev/null @@ -1,118 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * Description: The RubyEventQueue class implements an event queue which - * can be trigger events, allowing our simulation to be event driven. - * - * Currently, the only event we support is a Consumer being signaled - * by calling the consumer's wakeup() routine. Adding the event to - * the queue does not require a virtual function call, though calling - * wakeup() is a virtual function call. - * - * The method triggerEvents() is called with a global time. All - * events which are before or at this time are triggered in timestamp - * order. No ordering is enforced for events scheduled to occur at - * the same time. Events scheduled to wakeup the same consumer at the - * same time are combined into a single event. - * - * The method scheduleConsumerWakeup() is called with a global time - * and a consumer pointer. The event queue will call the wakeup() - * method of the consumer at the appropriate time. - * - * This implementation of RubyEventQueue uses a dynamically sized array - * managed as a heap. The algorithms used has O(lg n) for insert and - * O(lg n) for extract minimum element. (Based on chapter 7 of Cormen, - * Leiserson, and Rivest.) The array is dynamically sized and is - * automatically doubled in size when necessary. - * - */ - -#ifndef EVENTQUEUE_H -#define EVENTQUEUE_H - -#include "mem/ruby/tester/Global_Tester.hh" -#include "mem/gems_common/Vector.hh" - -class Consumer; -template <class TYPE> class PrioHeap; -class RubyEventQueueNode; - -class RubyEventQueue { -public: - // Constructors - RubyEventQueue(); - - // Destructor - ~RubyEventQueue(); - - // Public Methods - - Time getTime() const { return m_globalTime; } - void scheduleEvent(Consumer* consumer, Time timeDelta) { scheduleEventAbsolute(consumer, timeDelta + m_globalTime); } - void scheduleEventAbsolute(Consumer* consumer, Time timeAbs); - void triggerEvents(Time t); // called to handle all events <= time t - void triggerAllEvents(); - void print(ostream& out) const; - bool isEmpty() const; - - Time getTimeOfLastRecovery() {return m_timeOfLastRecovery;} - void setTimeOfLastRecovery(Time t) {m_timeOfLastRecovery = t;} - - // Private Methods -private: - // Private copy constructor and assignment operator - void init(); - RubyEventQueue(const RubyEventQueue& obj); - RubyEventQueue& operator=(const RubyEventQueue& obj); - - // Data Members (m_ prefix) - PrioHeap<RubyEventQueueNode>* m_prio_heap_ptr; - Time m_globalTime; - Time m_timeOfLastRecovery; -}; - -// Output operator declaration -inline extern -ostream& operator<<(ostream& out, const RubyEventQueue& obj); - -// ******************* Definitions ******************* - -// Output operator definition -inline extern -ostream& operator<<(ostream& out, const RubyEventQueue& obj) -{ - obj.print(out); - out << flush; - return out; -} - -#endif //EVENTQUEUE_H diff --git a/src/mem/ruby/tester/Global_Tester.hh b/src/mem/ruby/tester/Global_Tester.hh deleted file mode 100644 index 9d622bbf6..000000000 --- a/src/mem/ruby/tester/Global_Tester.hh +++ /dev/null @@ -1,74 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * */ - -#ifndef GLOBAL_H -#define GLOBAL_H - -typedef unsigned char uint8; -typedef unsigned int uint32; -typedef unsigned long long uint64; - -typedef signed char int8; -typedef int int32; -typedef long long int64; - -typedef long long integer_t; -typedef unsigned long long uinteger_t; - -typedef int64 Time; -typedef uint64 physical_address_t; -typedef uint64 la_t; -typedef uint64 pa_t; -typedef integer_t simtime_t; -typedef int NodeID; - -#include "mem/ruby/common/TypeDefines.hh" -#include "mem/gems_common/std-includes.hh" -#include "Debug_Tester.hh" - -// simple type declarations -typedef Time LogicalTime; -typedef int64 Index; // what the address bit ripper returns -typedef int word; // one word of a cache line -typedef unsigned int uint; -typedef int SwitchID; -typedef int LinkID; - - -class Debug; -extern Debug * debug_ptr; -class RubyEventQueue; -extern RubyEventQueue * eventQueue; -#endif //GLOBAL_H - diff --git a/src/mem/ruby/tester/RaceyDriver.cc b/src/mem/ruby/tester/RaceyDriver.cc index dfecfa796..2cde0d432 100644 --- a/src/mem/ruby/tester/RaceyDriver.cc +++ b/src/mem/ruby/tester/RaceyDriver.cc @@ -1,40 +1,67 @@ /* - * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty, + Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and + Luke Yen. + + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ * */ - -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Tester_Globals.hh" #include "mem/ruby/tester/RaceyDriver.hh" -#include "mem/ruby/tester/EventQueue_Tester.hh" +#include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/tester/RaceyPseudoThread.hh" RaceyDriver::RaceyDriver(int num_procs, int tester_length) @@ -83,7 +110,7 @@ void RaceyDriver::hitCallback(int64_t request_id) uint8_t * data = new uint8_t[4]; for (int i = 0; i < 4; i++) { data[i] = requests[request_id].second.data[i]; - } + } requests[request_id].second.data; m_racey_pseudo_threads[proc]->performCallback(proc, address, data); requests.erase(request_id); diff --git a/src/mem/ruby/tester/RaceyDriver.hh b/src/mem/ruby/tester/RaceyDriver.hh index cc2130ef9..d7a5c278d 100644 --- a/src/mem/ruby/tester/RaceyDriver.hh +++ b/src/mem/ruby/tester/RaceyDriver.hh @@ -1,31 +1,58 @@ /* - * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty, + Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and + Luke Yen. + + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ @@ -38,8 +65,9 @@ #ifndef RACEYDRIVER_H #define RACEYDRIVER_H -#include "mem/ruby/tester/Global_Tester.hh" -#include "mem/ruby/tester/Driver_Tester.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Tester_Globals.hh" +#include "mem/ruby/common/Driver.hh" #include "mem/ruby/tester/RaceyPseudoThread.hh" #include <map> #include "mem/ruby/libruby.hh" @@ -52,7 +80,7 @@ struct address_data { uint8_t * data; }; -class RaceyDriver : public Driver_Tester, public Consumer { +class RaceyDriver : public Driver, public Consumer { public: friend class RaceyPseudoThread; // Constructors @@ -92,13 +120,13 @@ public: } void print(ostream& out) const; - + private: // Private copy constructor and assignment operator RaceyDriver(const RaceyDriver& obj); RaceyDriver& operator=(const RaceyDriver& obj); - + // Data Members (m_ prefix) Vector<RaceyPseudoThread*> m_racey_pseudo_threads; int m_done_counter; @@ -116,7 +144,7 @@ ostream& operator<<(ostream& out, const RaceyDriver& obj); // ******************* Definitions ******************* // Output operator definition -extern inline +extern inline ostream& operator<<(ostream& out, const RaceyDriver& obj) { obj.print(out); diff --git a/src/mem/ruby/tester/RaceyPseudoThread.cc b/src/mem/ruby/tester/RaceyPseudoThread.cc index e5e1c1169..c681c0a7e 100644 --- a/src/mem/ruby/tester/RaceyPseudoThread.cc +++ b/src/mem/ruby/tester/RaceyPseudoThread.cc @@ -1,33 +1,23 @@ /* - * Copyright (c) 1999 Mark D. Hill and David A. Wood - * All rights reserved. + * Copyright (c) 1999 by Mark Hill and David Wood for the Wisconsin + * Multifacet Project. ALL RIGHTS RESERVED. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * ##HEADER## * - * 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. - */ + * This software is furnished under a license and may be used and + * copied only in accordance with the terms of such license and the + * inclusion of the above copyright notice. This software or any + * other copies thereof or any derivative works may not be provided or + * otherwise made available to any other persons. Title to and + * ownership of the software is retained by Mark Hill and David Wood. + * Any use of this software must include the above copyright notice. + * + * THIS SOFTWARE IS PROVIDED "AS IS". THE LICENSOR MAKES NO + * WARRANTIES ABOUT ITS CORRECTNESS OR PERFORMANCE. + * */ /* - * Description: see RaceyPseudoThread.hh + * Description: see RaceyPseudoThread.h */ #include "mem/ruby/tester/RaceyPseudoThread.hh" @@ -225,18 +215,18 @@ void RaceyPseudoThread::load_sig(unsigned index) { // pc is zero, problem? int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(sig(index), read_data, 4, 0, RubyRequestType_LD, RubyAccessMode_User)); - + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); struct address_data request_data; request_data.address = Address(sig(index)); request_data.data = read_data; m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data))); - + /*sequencer()->makeRequest(CacheMsg(Address(sig(index)), Address(sig(index)), CacheRequestType_LD, Address(physical_address_t(1)), AccessModeType_UserMode, 4, - PrefetchBit_No, 0, Address(0), + PrefetchBit_No, 0, Address(0), 0, 0 , false)); */ } @@ -252,18 +242,18 @@ void RaceyPseudoThread::load_m(unsigned index) { // pc is zero, problem? int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m(index), read_data, 4, 0, RubyRequestType_LD, RubyAccessMode_User)); - + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); struct address_data request_data; request_data.address = Address(m(index)); request_data.data = read_data; m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data))); - + /*sequencer()->makeRequest(CacheMsg(Address(m(index)), Address(m(index)), CacheRequestType_LD, Address(physical_address_t(1)), AccessModeType_UserMode, 4, - PrefetchBit_No, 0, Address(0), + PrefetchBit_No, 0, Address(0), 0, 0, false)); */ } @@ -273,6 +263,8 @@ void RaceyPseudoThread::store_sig(unsigned index, unsigned value) { m_read = false; m_value = value; uint8_t * write_data = new uint8_t[4]; + uint8_t * read_data = new uint8_t[4]; + memcpy(write_data, &value, 4); @@ -282,13 +274,15 @@ void RaceyPseudoThread::store_sig(unsigned index, unsigned value) { // pc is zero, problem? int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(sig(index), write_data, 4, 0, RubyRequestType_ST, RubyAccessMode_User)); - + //int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(sig(index), read_data, 4, 0, RubyRequestType_RMW_Read, RubyAccessMode_User)); + //int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(sig(index), write_data, 4, 0, RubyRequestType_RMW_Write, RubyAccessMode_User)); + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); struct address_data request_data; request_data.address = Address(sig(index)); request_data.data = write_data; - m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data))); + m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data))); /*sequencer()->makeRequest(CacheMsg(Address(sig(index)), Address(sig(index)), CacheRequestType_ST, Address(physical_address_t(1)), @@ -303,6 +297,7 @@ void RaceyPseudoThread::store_m(unsigned index, unsigned value) { m_read = false; m_value = value; uint8_t * write_data = new uint8_t[4]; + uint8_t * read_data = new uint8_t[4]; memcpy(write_data, &value, 4); char name [] = "Sequencer_"; @@ -311,13 +306,15 @@ void RaceyPseudoThread::store_m(unsigned index, unsigned value) { // pc is zero, problem? int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m(index), write_data, 4, 0, RubyRequestType_ST, RubyAccessMode_User)); - + //int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m(index), read_data, 4, 0, RubyRequestType_RMW_Read, RubyAccessMode_User)); + //int64_t request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m(index), write_data, 4, 0, RubyRequestType_RMW_Write, RubyAccessMode_User)); + ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end()); struct address_data request_data; request_data.address = Address(m(index)); request_data.data = write_data; - m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data))); + m_driver.requests.insert(make_pair(request_id, make_pair(m_proc_id, request_data))); /*sequencer()->makeRequest(CacheMsg(Address(m(index)), Address(m(index)), CacheRequestType_ST, Address(physical_address_t(1)), diff --git a/src/mem/ruby/tester/RaceyPseudoThread.hh b/src/mem/ruby/tester/RaceyPseudoThread.hh index 9db4ad04a..381cc1d87 100644 --- a/src/mem/ruby/tester/RaceyPseudoThread.hh +++ b/src/mem/ruby/tester/RaceyPseudoThread.hh @@ -1,30 +1,20 @@ /* - * Copyright (c) 1999 Mark D. Hill and David A. Wood - * All rights reserved. + * Copyright (c) 1999 by Mark Hill and David Wood for the Wisconsin + * Multifacet Project. ALL RIGHTS RESERVED. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * ##HEADER## * - * 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. - */ + * This software is furnished under a license and may be used and + * copied only in accordance with the terms of such license and the + * inclusion of the above copyright notice. This software or any + * other copies thereof or any derivative works may not be provided or + * otherwise made available to any other persons. Title to and + * ownership of the software is retained by Mark Hill and David Wood. + * Any use of this software must include the above copyright notice. + * + * THIS SOFTWARE IS PROVIDED "AS IS". THE LICENSOR MAKES NO + * WARRANTIES ABOUT ITS CORRECTNESS OR PERFORMANCE. + * */ /* * Description: This implements a pseudo racey thread which drives ruby timing @@ -35,10 +25,11 @@ #ifndef RACEYPSEUDOTHREAD_H #define RACEYPSEUDOTHREAD_H -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Tester_Globals.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/system/NodeID.hh" -#include "Address_Tester.hh" +#include "mem/ruby/common/Address.hh" #include "mem/ruby/libruby.hh" class RaceyDriver; @@ -69,7 +60,7 @@ public: // Destructor ~RaceyPseudoThread(); - + // Public Methods void performCallback(int proc, Address address, uint8_t * data); @@ -106,7 +97,7 @@ private: // Private copy constructor and assignment operator RaceyPseudoThread(const RaceyPseudoThread& obj); RaceyPseudoThread& operator=(const RaceyPseudoThread& obj); - + // Data Members (m_ prefix) RaceyDriver& m_driver; NodeID m_proc_id; @@ -139,7 +130,7 @@ ostream& operator<<(ostream& out, const RaceyPseudoThread& obj); // ******************* Definitions ******************* // Output operator definition -extern inline +extern inline ostream& operator<<(ostream& out, const RaceyPseudoThread& obj) { obj.print(out); diff --git a/src/mem/ruby/tester/SpecifiedGenerator.cc b/src/mem/ruby/tester/SpecifiedGenerator.cc index 63e4a7ae8..15a1e046f 100644 --- a/src/mem/ruby/tester/SpecifiedGenerator.cc +++ b/src/mem/ruby/tester/SpecifiedGenerator.cc @@ -1,31 +1,58 @@ /* - * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty, + Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and + Luke Yen. + + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ diff --git a/src/mem/ruby/tester/SpecifiedGenerator.hh b/src/mem/ruby/tester/SpecifiedGenerator.hh index 976947ce6..dffb699ea 100644 --- a/src/mem/ruby/tester/SpecifiedGenerator.hh +++ b/src/mem/ruby/tester/SpecifiedGenerator.hh @@ -1,46 +1,74 @@ /* - * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty, + Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and + Luke Yen. + + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ * - * Description: + * Description: * */ #ifndef SPECIFIEDGENERATOR_H #define SPECIFIEDGENERATOR_H -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Tester_Globals.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/system/NodeID.hh" -#include "Address_Tester.hh" +#include "mem/ruby/common/Address.hh" class SpecifiedGenerator : public Consumer { public: @@ -49,7 +77,7 @@ public: // Destructor virtual ~SpecifiedGenerator() = 0; - + // Public Methods virtual void wakeup() = 0; virtual void performCallback(NodeID proc, Address address) = 0; diff --git a/src/mem/ruby/tester/Tester_Globals.hh b/src/mem/ruby/tester/Tester_Globals.hh new file mode 100644 index 000000000..cecedeaad --- /dev/null +++ b/src/mem/ruby/tester/Tester_Globals.hh @@ -0,0 +1,66 @@ + +/* + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ + +/* + * $Id$ + * + * */ + +#include "mem/ruby/eventqueue/RubyEventQueue.hh" + +class RubyEventQueue; +extern RubyEventQueue * eventQueue; + diff --git a/src/mem/ruby/tester/main.cc b/src/mem/ruby/tester/main.cc index 849206de9..a37827521 100644 --- a/src/mem/ruby/tester/main.cc +++ b/src/mem/ruby/tester/main.cc @@ -1,31 +1,58 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ diff --git a/src/mem/ruby/tester/main.hh b/src/mem/ruby/tester/main.hh index ca036ddd7..a5fa2b995 100644 --- a/src/mem/ruby/tester/main.hh +++ b/src/mem/ruby/tester/main.hh @@ -1,42 +1,70 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ * - * Description: + * Description: * */ #ifndef MAIN_H #define MAIN_H -#include "Global_Tester.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Tester_Globals.hh" #endif //MAIN_H diff --git a/src/mem/ruby/tester/test_framework.cc b/src/mem/ruby/tester/test_framework.cc index 6b7c7ddec..cc11abe8a 100644 --- a/src/mem/ruby/tester/test_framework.cc +++ b/src/mem/ruby/tester/test_framework.cc @@ -1,31 +1,58 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ @@ -39,7 +66,9 @@ using namespace std; #include "getopt.hh" #include "mem/ruby/tester/DeterministicDriver.hh" #include "mem/ruby/tester/RaceyDriver.hh" -#include "mem/ruby/tester/Driver_Tester.hh" +#include "mem/ruby/common/Driver.hh" +#include "mem/ruby/recorder/Tracer.hh" + #include <string> #include <map> @@ -53,37 +82,37 @@ using namespace std; #include "mem/ruby/libruby.hh" // FIXME: should really make this a class if can't figure out how to make a function to get the ruby parameter - - static void set_defaults(); static void parseOptions(int argc, char **argv); static void usageInstructions(); static void checkArg(char ch); static void tester_initialize(int argc, char **argv); +static void tester_playback_trace(); static void tester_destroy(); static void hit_callback(int64_t request_id); // Tester variables string driver_type; string generator_type; -Driver_Tester * m_driver_ptr; +Driver * m_driver_ptr; int g_tester_length; int num_completions; Time g_think_time; Time g_wait_time; int num_procs; - -// Debugger variables -Debug * debug_ptr; -string g_debug_verbosity_string; -string g_debug_filter_string; -string g_debug_output_filename; -Time g_debug_start_time; - +static string trace_filename; +bool replaying; void tester_main(int argc, char **argv) { tester_initialize(argc, argv); + + if (trace_filename != "") { + // playback a trace (for multicast-mask prediction) + replaying = true; + tester_playback_trace(); + } + tester_destroy(); } @@ -117,7 +146,7 @@ vector<string> getPorts(const char* cfg_script, int cfg_script_argc, char* cfg_s perror("Error Creating Pipe"); exit(EXIT_FAILURE); } - + pid = fork(); if (pid == -1){ perror("Error forking"); @@ -139,7 +168,7 @@ vector<string> getPorts(const char* cfg_script, int cfg_script_argc, char* cfg_s exit(EXIT_FAILURE); } } else { - close(fd[1]); + close(fd[1]); int child_status; if (wait(&child_status) == -1) { @@ -149,12 +178,12 @@ vector<string> getPorts(const char* cfg_script, int cfg_script_argc, char* cfg_s if (child_status != EXIT_SUCCESS) { exit(EXIT_FAILURE); } - + char buf[100]; int bytes_read; while( (bytes_read = read(fd[0], buf, 100)) > 0 ) { for (int i=0;i<bytes_read;i++) { - cfg_output << buf[i]; + cfg_output << buf[i]; } } assert(bytes_read == 0); @@ -183,12 +212,7 @@ void tester_initialize(int argc, char **argv) for (vector<string>::const_iterator it = port_names.begin(); it != port_names.end(); it++) ports.push_back(libruby_get_port((*it).c_str(), hit_callback)); - - debug_ptr = new Debug( g_debug_filter_string.c_str(), - g_debug_verbosity_string.c_str(), - g_debug_start_time, - g_debug_output_filename.c_str() ); - + if (driver_type == "Deterministic") { m_driver_ptr = new DeterministicDriver(generator_type, num_completions, num_procs, g_think_time, g_wait_time, g_tester_length); } @@ -200,7 +224,22 @@ void tester_initialize(int argc, char **argv) } }*/ - m_driver_ptr->go(); + if (trace_filename == "") { + m_driver_ptr->go(); + } +} + +void tester_playback_trace() +{ + replaying = true; + assert(trace_filename != ""); + cout << "Reading trace from file '" << trace_filename << "'..." << endl; + Tracer * replayer = new Tracer("noname"); + int read = replayer->playbackTrace(trace_filename); + cout << "(" << read << " requests read)" << endl; + if (read == 0) { + ERROR_MSG("Zero items read from tracefile."); + } } void tester_destroy() @@ -213,7 +252,9 @@ void tester_destroy() void hit_callback(int64_t request_id) { - m_driver_ptr->hitCallback(request_id); + if (!replaying) { + m_driver_ptr->hitCallback(request_id); + } } // ************************************************************************ @@ -227,36 +268,31 @@ static struct option const long_options[] = {"help", no_argument, NULL, 'h'}, {"number of processors", required_argument, NULL, 'p'}, {"test run length", required_argument, NULL, 'l'}, - {"debugger verbosity", required_argument, NULL, 'v'}, - {"debugger filter component", required_argument, NULL, 'c'}, - {"debugger output file", required_argument, NULL, 'o'}, - {"debugger start time", required_argument, NULL, 's'}, {"generator think time", required_argument, NULL, 'k'}, {"generator wait time", required_argument, NULL, 'w'}, {"driver type", required_argument, NULL, 'd'}, {"generator type", required_argument, NULL, 'g'}, {"num completions before pass", required_argument, NULL, 'n'}, + {"test tracer", required_argument, NULL, 'z'}, {NULL, 0, NULL, 0} }; // This is awkward and temporary, need the defaults config, and also need functions to // just lookup a parameter in the configuration file -// Ideally the default values are set by libruby_init and then a function is provided to +// Ideally the default values are set by libruby_init and then a function is provided to // set values at run-time static void set_defaults() { + replaying = false; g_tester_length = 0; - g_think_time = 5; - g_wait_time = 20; - + g_think_time = 10; + g_wait_time = 10; + num_procs = 1; + trace_filename = ""; num_completions = 1; driver_type = "Deterministic"; - generator_type = "DetermInvGenerator"; - g_debug_verbosity_string = "none"; - g_debug_filter_string = "none"; - g_debug_output_filename = "none"; - g_debug_start_time = 0; + generator_type = "DetermSeriesGETSGenerator"; } static void parseOptions(int argc, char **argv) @@ -289,15 +325,6 @@ static void parseOptions(int argc, char **argv) cout << " number of processors = " << optarg << endl; num_procs = atoi( optarg ); break; - case 'v': - checkArg(c); - cout << " verbosity string = " << optarg << endl; - error = Debug::checkVerbosityString(optarg); - if (error) { - usageInstructions(); - } - g_debug_verbosity_string = strdup( optarg ); - break; case 'l': { checkArg(c); g_tester_length = atoi(optarg); @@ -307,25 +334,6 @@ static void parseOptions(int argc, char **argv) } break; } - case 'c': - checkArg(c); - cout << " component filter string = " << optarg << endl; - error = Debug::checkFilterString( optarg ); - if (error) { - usageInstructions(); - } - g_debug_filter_string = strdup( optarg ); - break; - case 's': { - checkArg(c); - long long start_time = atoll(optarg); - cout << " debug start cycle = " << start_time << endl; - if (start_time == 0) { - usageInstructions(); - } - g_debug_start_time = start_time; - break; - } case 'k': { checkArg(c); g_think_time = atoi(optarg); @@ -336,11 +344,6 @@ static void parseOptions(int argc, char **argv) g_wait_time = atoi(optarg); break; } - case 'o': - checkArg(c); - cout << " output file = " << optarg << endl; - g_debug_output_filename = strdup( optarg ); - break; case 'd': checkArg(c); cout << " driver type = " << optarg << endl; @@ -356,6 +359,12 @@ static void parseOptions(int argc, char **argv) cout << " num completions before pass = " << optarg << endl; num_completions = atoi( optarg ); break; + case 'z': + checkArg(c); + trace_filename = string(optarg); + cout << " tracefile = " << trace_filename << endl; + break; + default: cerr << "parameter '" << c << "' unknown" << endl; usageInstructions(); @@ -384,7 +393,7 @@ static void usageInstructions() } cerr << endl; - debug_ptr->usageInstructions(); + g_debug_ptr->usageInstructions(); cerr << endl; exit(1); diff --git a/src/mem/ruby/tester/test_framework.hh b/src/mem/ruby/tester/test_framework.hh index ade27a78f..afdd146a9 100644 --- a/src/mem/ruby/tester/test_framework.hh +++ b/src/mem/ruby/tester/test_framework.hh @@ -1,43 +1,71 @@ /* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the + Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu + http://www.cs.wisc.edu/gems/ + + -------------------------------------------------------------------- + + This file is part of the Ruby Multiprocessor Memory System Simulator, + a component of the Multifacet GEMS (General Execution-driven + Multiprocessor Simulator) software toolset originally developed at + the University of Wisconsin-Madison. + + Ruby was originally developed primarily by Milo Martin and Daniel + Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj + Plakal. + + Substantial further development of Multifacet GEMS at the + University of Wisconsin was performed by Alaa Alameldeen, Brad + Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper, + Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan, + Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos, + Min Xu, and Luke Yen. + -------------------------------------------------------------------- + + If your use of this software contributes to a published paper, we + request that you (1) cite our summary paper that appears on our + website (http://www.cs.wisc.edu/gems/) and (2) e-mail a citation + for your published paper to gems@cs.wisc.edu. + + If you redistribute derivatives of this software, we request that + you notify us and either (1) ask people to register with us at our + website (http://www.cs.wisc.edu/gems/) or (2) collect registration + information and periodically send it to us. + + -------------------------------------------------------------------- + + Multifacet GEMS is free software; you can redistribute it and/or + modify it under the terms of version 2 of the GNU General Public + License as published by the Free Software Foundation. + + Multifacet GEMS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the Multifacet GEMS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA + + The GNU General Public License is contained in the file LICENSE. + +### END HEADER ### +*/ /* * $Id$ * - * Description: + * Description: * */ #ifndef TESTFRAMEWORK_H #define TESTFRAMEWORK_H -#include "mem/ruby/tester/Global_Tester.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/tester/Tester_Globals.hh" void tester_main(int argc, char **argv); diff --git a/src/mem/rubymem.cc b/src/mem/rubymem.cc index 62685a71b..4d9f8051f 100644 --- a/src/mem/rubymem.cc +++ b/src/mem/rubymem.cc @@ -231,7 +231,7 @@ RubyMemory::Port::recvTiming(PacketPtr pkt) } else if (pkt->isWrite()) { type = RubyRequestType_ST; } else if (pkt->isReadWrite()) { - type = RubyRequestType_RMW; + // type = RubyRequestType_RMW; } RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(), diff --git a/src/mem/slicc/symbols/StateMachine.cc b/src/mem/slicc/symbols/StateMachine.cc index 96592c4e0..b2ec4d676 100644 --- a/src/mem/slicc/symbols/StateMachine.cc +++ b/src/mem/slicc/symbols/StateMachine.cc @@ -282,13 +282,16 @@ void StateMachine::printControllerH(ostream& out, string component) out << " void printStats(ostream& out) const { s_profiler.dumpStats(out); }" << endl; out << " void clearStats() { s_profiler.clearStats(); }" << endl; out << "private:" << endl; - //added by SS // found_to_mem = 0; std::vector<std::string*>::const_iterator it; for(it=m_latency_vector.begin();it!=m_latency_vector.end();it++){ out << " int m_" << (*it)->c_str() << ";" << endl; } + if (strncmp(component.c_str(), "L1Cache", 7) == 0) { + out << " bool servicing_atomic;" << endl; + out << " Address locked_read_request;" << endl; + } out << " int m_number_of_TBEs;" << endl; out << " TransitionResult doTransition(" << component << "_Event event, " << component @@ -395,7 +398,11 @@ void StateMachine::printControllerC(ostream& out, string component) << "_Controller(const string & name)" << endl; out << " : m_name(name)" << endl; out << "{ " << endl; - out << " m_num_controllers++; " << endl; + if (strncmp(component.c_str(), "L1Cache", 7) == 0) { + out << " servicing_atomic = false;" << endl; + out << " locked_read_request = Address(-1);" << endl; + } + out << " m_num_controllers++; " << endl; for(int i=0; i < numObjects(); i++) { const Var* var = m_objs[i]; if ( var->cIdent().find("mandatoryQueue") != string::npos) @@ -735,6 +742,23 @@ void StateMachine::printControllerC(ostream& out, string component) } } + // add here: + if (strncmp(component.c_str(), "L1Cache", 7) == 0) { + if (c_code_string.find("writeCallback") != string::npos) { + string::size_type pos = c_code_string.find("(((*m_L1Cache_sequencer_ptr)).writeCallback"); + assert(pos != string::npos); + string atomics_string = "\n if (servicing_atomic) { \n \ + servicing_atomic = false; \n \ + locked_read_request = Address(-1); \n \ + } \n \ + else if (!servicing_atomic) { \n \ + if (addr == locked_read_request) { \n \ + servicing_atomic = true; \n \ + } \n \ + } \n "; + c_code_string.insert(pos, atomics_string); + } + } out << c_code_string; out << "}" << endl; @@ -772,15 +796,101 @@ void StateMachine::printCWakeup(ostream& out, string component) out << " }" << endl; // InPorts - for(int i=0; i < m_in_ports.size(); i++) { - const Var* port = m_in_ports[i]; + // + // Find the position of the mandatory queue in the vector so that we can print it out first + int j = -1; + if (strncmp(component.c_str(), "L1Cache", 7) == 0) { + for(int i=0; i < m_in_ports.size(); i++) { + const Var* port = m_in_ports[i]; + assert(port->existPair("c_code_in_port")); + if (port->toString().find("mandatoryQueue_in") != string::npos) { + assert (j == -1); + j = i; + } + else { + cout << port->toString() << endl << flush; + } + } + + assert(j != -1); + + // print out the mandatory queue here + const Var* port = m_in_ports[j]; assert(port->existPair("c_code_in_port")); - out << " // " - << component << "InPort " << port->toString() + out << " // " + << component << "InPort " << port->toString() << endl; - out << port->lookupPair("c_code_in_port"); + string output = port->lookupPair("c_code_in_port"); + string::size_type pos = output.find("TransitionResult result = doTransition((L1Cache_mandatory_request_type_to_event(((*in_msg_ptr)).m_Type)), L1Cache_getState(addr), addr);"); + assert(pos != string::npos); + string atomics_string = "\n \ + bool postpone = false; \n \ + if ((((*in_msg_ptr)).m_Type) == CacheRequestType_ATOMIC) { \n \ + if (!servicing_atomic) { \n \ + if (locked_read_request == Address(-1)) { \n \ + locked_read_request = addr; \n \ + } \n \ + else if (addr == locked_read_request) { \n \ + assert (servicing_atomic); \n \ + //servicing_atomic = m_version; \n \ + } \n \ + else { \n \ + postpone = true; \n \ + g_eventQueue_ptr->scheduleEvent(this, 1); \n \ + } \n \ + } \n \ + else if (addr != locked_read_request) { \n \ + postpone = true; \n \ + g_eventQueue_ptr->scheduleEvent(this, 1); \n \ + } \n \ + } \n \ + if (!postpone) { \n \ + "; + + + + output.insert(pos, atomics_string); + string foo = "// Cannot do anything with this transition, go check next doable transition (mostly likely of next port)\n"; + string::size_type next_pos = output.find(foo, pos); + next_pos = next_pos + foo.length(); + + assert(next_pos != string::npos); + string complete = " }\n"; + output.insert(next_pos, complete); + //out << port->lookupPair("c_code_in_port"); + out << output; out << endl; } + for(int i=0; i < m_in_ports.size(); i++) { + const Var* port = m_in_ports[i]; + // don't print out mandatory queue twice + if (i != j) { + if (strncmp(component.c_str(), "L1Cache", 7) == 0) { + if (port->toString().find("forwardRequestNetwork_in") != string::npos) { + out << " bool postpone = false;" << endl; + out << " if ((((*m_L1Cache_forwardToCache_ptr)).isReady())) {" << endl; + out << " const RequestMsg* in_msg_ptr;" << endl; + out << " in_msg_ptr = dynamic_cast<const RequestMsg*>(((*m_L1Cache_forwardToCache_ptr)).peek());" << endl; + out << " if ((servicing_atomic && locked_read_request == ((*in_msg_ptr)).m_Address)) {" << endl; + out << " postpone = true;" << endl; + out << " }" << endl; + out << " }" << endl; + out << " if (!postpone) {" << endl; + } + } + assert(port->existPair("c_code_in_port")); + out << " // " + << component << "InPort " << port->toString() + << endl; + out << port->lookupPair("c_code_in_port"); + if (strncmp(component.c_str(), "L1Cache", 7) == 0) { + if (port->toString().find("forwardRequestNetwork_in") != string::npos) { + out << "}" << endl; + } + } + out << endl; + } + } out << " break; // If we got this far, we have nothing left todo" << endl; out << " }" << endl; |