This commit is contained in:
Derek Hower 2009-07-18 17:40:20 -05:00
commit 926ab6e6db
61 changed files with 1727 additions and 1231 deletions

View file

@ -47,22 +47,22 @@ class ArmLinux : public Linux
//@{ //@{
/// open(2) flag values. /// open(2) flag values.
static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR static const int TGT_O_RDWR = 00000002; //!< O_RDWR
static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT static const int TGT_O_CREAT = 00000100; //!< O_CREAT
static const int TGT_O_EXCL = 0x00000200; //!< O_EXCL static const int TGT_O_EXCL = 00000200; //!< O_EXCL
static const int TGT_O_NOCTTY = 0x00000400; //!< O_NOCTTY static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY
static const int TGT_O_TRUNC = 0x00001000; //!< O_TRUNC static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC
static const int TGT_O_APPEND = 0x00002000; //!< O_APPEND static const int TGT_O_APPEND = 00002000; //!< O_APPEND
static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK static const int TGT_O_NONBLOCK = 00004000; //!< O_NONBLOCK
static const int TGT_O_SYNC = 0x00010000; //!< O_SYNC static const int TGT_O_SYNC = 00010000; //!< O_SYNC
static const int TGT_FASYNC = 0x00020000; //!< FASYNC static const int TGT_FASYNC = 00020000; //!< FASYNC
static const int TGT_O_DIRECT = 0x00040000; //!< O_DIRECT static const int TGT_O_DIRECTORY = 00040000; //!< O_DIRECTORY
static const int TGT_O_LARGEFILE = 0x00100000; //!< O_LARGEFILE static const int TGT_O_NOFOLLOW = 00100000; //!< O_NOFOLLOW
static const int TGT_O_DIRECTORY = 0x00200000; //!< O_DIRECTORY static const int TGT_O_DIRECT = 00200000; //!< O_DIRECT
static const int TGT_O_NOFOLLOW = 0x00400000; //!< O_NOFOLLOW static const int TGT_O_LARGEFILE = 00400000; //!< O_LARGEFILE
static const int TGT_O_NOATIME = 0x01000000; //!< O_NOATIME static const int TGT_O_NOATIME = 01000000; //!< O_NOATIME
//@} //@}
/// For mmap(). /// For mmap().
@ -70,13 +70,13 @@ class ArmLinux : public Linux
//@{ //@{
/// For getsysinfo(). /// For getsysinfo().
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
static const unsigned GSI_CPU_INFO = 59; //!< CPU information static const unsigned GSI_CPU_INFO = 59; //!< CPU information
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type 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_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_CPUS_IN_BOX = 55; //!< number of CPUs in system
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB 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_CLK_TCK = 42; //!< clock freq in Hz
//@} //@}
//@{ //@{

View file

@ -166,7 +166,7 @@ namespace X86ISA
static inline FloatRegIndex static inline FloatRegIndex
FLOATREG_STACK(int index, int top) FLOATREG_STACK(int index, int top)
{ {
return (FloatRegIndex)(NUM_FLOATREGS + ((top + index + 8) % 8)); return FLOATREG_FPR((top + index + 8) % 8);
} }
}; };

View file

@ -80,13 +80,13 @@ namespace X86ISA
const char *mnem, const char *_instMnem, const char *mnem, const char *_instMnem,
bool isMicro, bool isDelayed, bool isMicro, bool isDelayed,
bool isFirst, bool isLast, bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest, InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
uint8_t _dataSize, int8_t _spm, uint8_t _dataSize, int8_t _spm,
OpClass __opClass) : OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, X86MicroopBase(_machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast, isMicro, isDelayed, isFirst, isLast,
__opClass), __opClass),
src1(_src1), src2(_src2), dest(_dest), src1(_src1.idx), src2(_src2.idx), dest(_dest.idx),
dataSize(_dataSize), spm(_spm) dataSize(_dataSize), spm(_spm)
{} {}
/* /*

View file

@ -93,20 +93,21 @@ namespace X86ISA
LdStOp(ExtMachInst _machInst, LdStOp(ExtMachInst _machInst,
const char * mnem, const char * _instMnem, const char * mnem, const char * _instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, bool isMicro, bool isDelayed, bool isFirst, bool isLast,
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, InstRegIndex _segment,
RegIndex _data, InstRegIndex _data,
uint8_t _dataSize, uint8_t _addressSize, uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags, Request::FlagsType _memFlags,
OpClass __opClass) : OpClass __opClass) :
X86MicroopBase(machInst, mnem, _instMnem, X86MicroopBase(machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast, __opClass), isMicro, isDelayed, isFirst, isLast, __opClass),
scale(_scale), index(_index), base(_base), scale(_scale), index(_index.idx), base(_base.idx),
disp(_disp), segment(_segment), disp(_disp), segment(_segment.idx),
data(_data), data(_data.idx),
dataSize(_dataSize), addressSize(_addressSize), 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; foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
foldABit = foldABit =
(addressSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; (addressSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;

View file

@ -67,7 +67,7 @@ namespace X86ISA
bool subtract) const bool subtract) const
{ {
DPRINTF(X86, "flagMask = %#x\n", flagMask); DPRINTF(X86, "flagMask = %#x\n", flagMask);
if (_destRegIdx[0] & (1 << 6)) { if (_destRegIdx[0] & IntFoldBit) {
_dest >>= 8; _dest >>= 8;
} }
uint64_t flags = oldFlags & ~flagMask; uint64_t flags = oldFlags & ~flagMask;

View file

@ -79,13 +79,13 @@ namespace X86ISA
const char *mnem, const char *_instMnem, const char *mnem, const char *_instMnem,
bool isMicro, bool isDelayed, bool isMicro, bool isDelayed,
bool isFirst, bool isLast, bool isFirst, bool isLast,
RegIndex _src1, RegIndex _dest, InstRegIndex _src1, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext, uint8_t _dataSize, uint16_t _ext,
OpClass __opClass) : OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, X86MicroopBase(_machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast, isMicro, isDelayed, isFirst, isLast,
__opClass), __opClass),
src1(_src1), dest(_dest), src1(_src1.idx), dest(_dest.idx),
dataSize(_dataSize), ext(_ext) dataSize(_dataSize), ext(_ext)
{ {
foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
@ -107,14 +107,14 @@ namespace X86ISA
const char *mnem, const char *_instMnem, const char *mnem, const char *_instMnem,
bool isMicro, bool isDelayed, bool isMicro, bool isDelayed,
bool isFirst, bool isLast, bool isFirst, bool isLast,
RegIndex _src1, RegIndex _src2, RegIndex _dest, InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext, uint8_t _dataSize, uint16_t _ext,
OpClass __opClass) : OpClass __opClass) :
RegOpBase(_machInst, mnem, _instMnem, RegOpBase(_machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast, isMicro, isDelayed, isFirst, isLast,
_src1, _dest, _dataSize, _ext, _src1, _dest, _dataSize, _ext,
__opClass), __opClass),
src2(_src2) src2(_src2.idx)
{ {
} }
@ -132,7 +132,7 @@ namespace X86ISA
const char * mnem, const char *_instMnem, const char * mnem, const char *_instMnem,
bool isMicro, bool isDelayed, bool isMicro, bool isDelayed,
bool isFirst, bool isLast, bool isFirst, bool isLast,
RegIndex _src1, uint8_t _imm8, RegIndex _dest, InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext, uint8_t _dataSize, uint16_t _ext,
OpClass __opClass) : OpClass __opClass) :
RegOpBase(_machInst, mnem, _instMnem, RegOpBase(_machInst, mnem, _instMnem,

View file

@ -149,14 +149,11 @@ namespace X86ISA
if (reg < FP_Base_DepTag) { if (reg < FP_Base_DepTag) {
const char * suffix = ""; const char * suffix = "";
bool fold = reg & (1 << 6); bool fold = reg & IntFoldBit;
reg &= ~(1 << 6); reg &= ~IntFoldBit;
if(fold) if(fold)
{
suffix = "h"; suffix = "h";
reg -= 4;
}
else if(reg < 8 && size == 1) else if(reg < 8 && size == 1)
suffix = "l"; suffix = "l";

View file

@ -63,6 +63,18 @@
namespace X86ISA 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. * 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 inline uint64_t merge(uint64_t into, uint64_t val, int size) const
{ {
X86IntReg reg = into; X86IntReg reg = into;
if(_destRegIdx[0] & (1 << 6)) if(_destRegIdx[0] & IntFoldBit)
{ {
reg.H = val; reg.H = val;
return reg; return reg;
@ -127,7 +139,7 @@ namespace X86ISA
{ {
X86IntReg reg = from; X86IntReg reg = from;
DPRINTF(X86, "Picking with size %d\n", size); DPRINTF(X86, "Picking with size %d\n", size);
if(_srcRegIdx[idx] & (1 << 6)) if(_srcRegIdx[idx] & IntFoldBit)
return reg.H; return reg.H;
switch(size) switch(size)
{ {
@ -148,7 +160,7 @@ namespace X86ISA
{ {
X86IntReg reg = from; X86IntReg reg = from;
DPRINTF(X86, "Picking with size %d\n", size); DPRINTF(X86, "Picking with size %d\n", size);
if(_srcRegIdx[idx] & (1 << 6)) if(_srcRegIdx[idx] & IntFoldBit)
return reg.SH; return reg.SH;
switch(size) switch(size)
{ {

View file

@ -60,6 +60,8 @@
#include "arch/x86/x86_traits.hh" #include "arch/x86/x86_traits.hh"
#include "base/bitunion.hh" #include "base/bitunion.hh"
#include "base/misc.hh"
#include "sim/core.hh"
namespace X86ISA namespace X86ISA
{ {
@ -165,6 +167,9 @@ namespace X86ISA
NUM_INTREGS 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 inline static IntRegIndex
INTREG_MICRO(int index) INTREG_MICRO(int index)
{ {
@ -187,7 +192,9 @@ namespace X86ISA
inline static IntRegIndex inline static IntRegIndex
INTREG_FOLDED(int index, int foldBit) 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;
} }
}; };

View file

@ -28,7 +28,6 @@
* Authors: Gabe Black * Authors: Gabe Black
*/ */
#include "arch/x86/floatregs.hh"
#include "arch/x86/isa.hh" #include "arch/x86/isa.hh"
#include "arch/x86/tlb.hh" #include "arch/x86/tlb.hh"
#include "cpu/base.hh" #include "cpu/base.hh"
@ -355,25 +354,4 @@ ISA::unserialize(EventManager *em, Checkpoint * cp,
UNSERIALIZE_ARRAY(regVal, NumMiscRegs); 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;
}
} }

View file

@ -31,6 +31,7 @@
#ifndef __ARCH_X86_ISA_HH__ #ifndef __ARCH_X86_ISA_HH__
#define __ARCH_X86_ISA_HH__ #define __ARCH_X86_ISA_HH__
#include "arch/x86/floatregs.hh"
#include "arch/x86/miscregs.hh" #include "arch/x86/miscregs.hh"
#include "arch/x86/registers.hh" #include "arch/x86/registers.hh"
#include "base/types.hh" #include "base/types.hh"
@ -65,8 +66,21 @@ namespace X86ISA
void setMiscRegNoEffect(int miscReg, MiscReg val); void setMiscRegNoEffect(int miscReg, MiscReg val);
void setMiscReg(int miscReg, MiscReg val, ThreadContext *tc); void setMiscReg(int miscReg, MiscReg val, ThreadContext *tc);
int flattenIntIndex(int reg); int
int flattenFloatIndex(int reg); 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 serialize(EventManager *em, std::ostream &os);
void unserialize(EventManager *em, Checkpoint *cp, void unserialize(EventManager *em, Checkpoint *cp,

View file

@ -109,6 +109,8 @@ output header {{
#include "cpu/static_inst.hh" #include "cpu/static_inst.hh"
#include "mem/packet.hh" #include "mem/packet.hh"
#include "sim/faults.hh" #include "sim/faults.hh"
using X86ISA::InstRegIndex;
}}; }};
output decoder {{ output decoder {{

View file

@ -84,7 +84,7 @@
microcode = ''' microcode = '''
def macroop BSR_R_R { def macroop BSR_R_R {
# Determine if the input was zero, and also move it to a temp reg. # 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,) and t1, regm, regm, flags=(ZF,)
br label("end"), flags=(CZF,) br label("end"), flags=(CZF,)
@ -132,7 +132,7 @@ end:
def macroop BSR_R_M { def macroop BSR_R_M {
movi t1, t1, t0, dataSize=8 mov t1, t1, t0, dataSize=8
ld t1, seg, sib, disp ld t1, seg, sib, disp
# Determine if the input was zero, and also move it to a temp reg. # Determine if the input was zero, and also move it to a temp reg.
@ -184,7 +184,7 @@ end:
def macroop BSR_R_P { def macroop BSR_R_P {
rdip t7 rdip t7
movi t1, t1, t0, dataSize=8 mov t1, t1, t0, dataSize=8
ld t1, seg, riprel, disp ld t1, seg, riprel, disp
# Determine if the input was zero, and also move it to a temp reg. # Determine if the input was zero, and also move it to a temp reg.

View file

@ -143,7 +143,7 @@ processCSDescriptor:
# appropriate/other RIP checks. # appropriate/other RIP checks.
# if temp_RIP > CS.limit throw #GP(0) # if temp_RIP > CS.limit throw #GP(0)
rdlimit t6, cs, dataSize=8 rdlimit t6, cs, dataSize=8
subi t0, t1, t6, flags=(ECF,) sub t0, t1, t6, flags=(ECF,)
fault "new GeneralProtection(0)", flags=(CECF,) fault "new GeneralProtection(0)", flags=(CECF,)
#(temp_CPL!=CPL) #(temp_CPL!=CPL)

View file

@ -118,7 +118,7 @@ def macroop JMP_FAR_I
limm t2, imm, dataSize=8 limm t2, imm, dataSize=8
# Figure out the width of the offset. # Figure out the width of the offset.
limm t3, dsz, dataSize=8 limm t3, dsz, dataSize=8
sll t3, t3, 3, dataSize=8 slli t3, t3, 3, dataSize=8
# Get the selector into t1. # Get the selector into t1.
sll t1, t2, t3, dataSize=8 sll t1, t2, t3, dataSize=8
mov t1, t0, t1, dataSize=2 mov t1, t0, t1, dataSize=2
@ -178,7 +178,7 @@ def macroop JMP_FAR_REAL_I
limm t2, imm, dataSize=8 limm t2, imm, dataSize=8
# Figure out the width of the offset. # Figure out the width of the offset.
limm t3, dsz, dataSize=8 limm t3, dsz, dataSize=8
sll t3, t3, 3, dataSize=8 slli t3, t3, 3, dataSize=8
# Get the selector into t1. # Get the selector into t1.
sll t1, t2, t3, dataSize=8 sll t1, t2, t3, dataSize=8
mov t1, t0, t1, dataSize=2 mov t1, t0, t1, dataSize=2

View file

@ -163,7 +163,7 @@ def macroop ENTER_I_I {
# Pull the different components out of the immediate # Pull the different components out of the immediate
limm t1, imm limm t1, imm
zexti t2, t1, 15, dataSize=8 zexti t2, t1, 15, dataSize=8
srl t1, t1, 16 srli t1, t1, 16
zexti t1, t1, 5, dataSize=8 zexti t1, t1, 5, dataSize=8
# t1 is now the masked nesting level, and t2 is the amount of storage. # 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 mov t6, t6, rsp, dataSize=asz
# If the nesting level is zero, skip all this stuff. # 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,) br label("skipLoop"), flags=(CEZF,)
# If the level was 1, only push the saved rbp # If the level was 1, only push the saved rbp

View file

@ -65,7 +65,7 @@ def macroop SYSCALL_64
# Stick rflags with RF masked into r11. # Stick rflags with RF masked into r11.
rflags t2 rflags t2
limm t3, "~RFBit", dataSize=8 limm t3, "~RFBit", dataSize=8
andi r11, t2, t3, dataSize=8 and r11, t2, t3, dataSize=8
rdval t3, star rdval t3, star
srli t3, t3, 32, dataSize=8 srli t3, t3, 32, dataSize=8
@ -118,7 +118,7 @@ def macroop SYSCALL_COMPAT
# Stick rflags with RF masked into r11. # Stick rflags with RF masked into r11.
rflags t2 rflags t2
limm t3, "~RFBit", dataSize=8 limm t3, "~RFBit", dataSize=8
andi r11, t2, t3, dataSize=8 and r11, t2, t3, dataSize=8
rdval t3, star rdval t3, star
srli t3, t3, 32, dataSize=8 srli t3, t3, 32, dataSize=8

View file

@ -28,58 +28,58 @@
microcode = ''' microcode = '''
def macroop CLTS { def macroop CLTS {
rdcr t1, 0, dataSize=8 rdcr t1, regIdx(0), dataSize=8
andi t1, t1, 0xF7, dataSize=1 andi t1, t1, 0xF7, dataSize=1
wrcr 0, t1, dataSize=8 wrcr regIdx(0), t1, dataSize=8
}; };
def macroop LMSW_R { 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 # This logic sets MP, EM, and TS to whatever is in the operand. It will
# set PE but not clear it. # set PE but not clear it.
limm t2, "~ULL(0xe)", dataSize=8 limm t2, "~ULL(0xe)", dataSize=8
and t1, t1, t2, dataSize=8 and t1, t1, t2, dataSize=8
andi t2, reg, 0xf, dataSize=8 andi t2, reg, 0xf, dataSize=8
or t1, t1, t2, dataSize=8 or t1, t1, t2, dataSize=8
wrcr 0, t1, dataSize=8 wrcr regIdx(0), t1, dataSize=8
}; };
def macroop LMSW_M { def macroop LMSW_M {
ld t3, seg, sib, disp, dataSize=2 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 # This logic sets MP, EM, and TS to whatever is in the operand. It will
# set PE but not clear it. # set PE but not clear it.
limm t2, "~ULL(0xe)", dataSize=8 limm t2, "~ULL(0xe)", dataSize=8
and t1, t1, t2, dataSize=8 and t1, t1, t2, dataSize=8
andi t2, t3, 0xf, dataSize=8 andi t2, t3, 0xf, dataSize=8
or t1, t1, t2, dataSize=8 or t1, t1, t2, dataSize=8
wrcr 0, t1, dataSize=8 wrcr regIdx(0), t1, dataSize=8
}; };
def macroop LMSW_P { def macroop LMSW_P {
rdip t7, dataSize=asz rdip t7, dataSize=asz
ld t3, seg, riprel, disp, dataSize=2 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 # This logic sets MP, EM, and TS to whatever is in the operand. It will
# set PE but not clear it. # set PE but not clear it.
limm t2, "~ULL(0xe)", dataSize=8 limm t2, "~ULL(0xe)", dataSize=8
and t1, t1, t2, dataSize=8 and t1, t1, t2, dataSize=8
andi t2, t3, 0xf, dataSize=8 andi t2, t3, 0xf, dataSize=8
or t1, t1, t2, dataSize=8 or t1, t1, t2, dataSize=8
wrcr 0, t1, dataSize=8 wrcr regIdx(0), t1, dataSize=8
}; };
def macroop SMSW_R { def macroop SMSW_R {
rdcr reg, 0 rdcr reg, regIdx(0)
}; };
def macroop SMSW_M { def macroop SMSW_M {
rdcr t1, 0 rdcr t1, regIdx(0)
st t1, seg, sib, disp, dataSize=2 st t1, seg, sib, disp, dataSize=2
}; };
def macroop SMSW_P { def macroop SMSW_P {
rdcr t1, 0 rdcr t1, regIdx(0)
rdip t7, dataSize=asz rdip t7, dataSize=asz
st t1, seg, riprel, disp, dataSize=2 st t1, seg, riprel, disp, dataSize=2
}; };

View file

@ -75,14 +75,22 @@ let {{
from micro_asm import MicroAssembler, Rom_Macroop from micro_asm import MicroAssembler, Rom_Macroop
mainRom = X86MicrocodeRom('main ROM') mainRom = X86MicrocodeRom('main ROM')
assembler = MicroAssembler(X86Macroop, microopClasses, mainRom, Rom_Macroop) 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 # Add in symbols for the microcode registers
for num in range(16): 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): 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 # Add in symbols for the segment descriptor registers
for letter in ("C", "D", "E", "F", "G", "H", "S"): 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. # Add in symbols for the various checks of segment selectors.
for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck", for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck",
@ -91,25 +99,25 @@ let {{
assembler.symbols[check] = "Seg%s" % check assembler.symbols[check] = "Seg%s" % check
for reg in ("TR", "IDTR"): 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"): for reg in ("TSL", "TSG"):
assembler.symbols[reg.lower()] = "SEGMENT_REG_%s" % reg assembler.symbols[reg.lower()] = regIdx("SEGMENT_REG_%s" % reg)
# Miscellaneous symbols # Miscellaneous symbols
symbols = { symbols = {
"reg" : "env.reg", "reg" : regIdx("env.reg"),
"xmml" : "FLOATREG_XMM_LOW(env.reg)", "xmml" : regIdx("FLOATREG_XMM_LOW(env.reg)"),
"xmmh" : "FLOATREG_XMM_HIGH(env.reg)", "xmmh" : regIdx("FLOATREG_XMM_HIGH(env.reg)"),
"regm" : "env.regm", "regm" : regIdx("env.regm"),
"xmmlm" : "FLOATREG_XMM_LOW(env.regm)", "xmmlm" : regIdx("FLOATREG_XMM_LOW(env.regm)"),
"xmmhm" : "FLOATREG_XMM_HIGH(env.regm)", "xmmhm" : regIdx("FLOATREG_XMM_HIGH(env.regm)"),
"imm" : "adjustedImm", "imm" : "adjustedImm",
"disp" : "adjustedDisp", "disp" : "adjustedDisp",
"seg" : "env.seg", "seg" : regIdx("env.seg"),
"scale" : "env.scale", "scale" : "env.scale",
"index" : "env.index", "index" : regIdx("env.index"),
"base" : "env.base", "base" : regIdx("env.base"),
"dsz" : "env.dataSize", "dsz" : "env.dataSize",
"asz" : "env.addressSize", "asz" : "env.addressSize",
"ssz" : "env.stackSize" "ssz" : "env.stackSize"
@ -133,17 +141,18 @@ let {{
# This segment selects an internal address space mapped to MSRs, # This segment selects an internal address space mapped to MSRs,
# CPUID info, etc. # 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 # This segment always has base 0, and doesn't imply any special handling
# like the internal segment above # 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', \ for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di', \
'8', '9', '10', '11', '12', '13', '14', '15'): '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): 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', \ for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF', \
'TF', 'IF', 'NT', 'RF', 'VM', 'AC', 'VIF', 'VIP', 'ID'): 'TF', 'IF', 'NT', 'RF', 'VM', 'AC', 'VIF', 'VIP', 'ID'):
@ -164,7 +173,7 @@ let {{
for reg in ('sysenter_cs', 'sysenter_esp', 'sysenter_eip', for reg in ('sysenter_cs', 'sysenter_esp', 'sysenter_eip',
'star', 'lstar', 'cstar', 'sf_mask', 'star', 'lstar', 'cstar', 'sf_mask',
'kernel_gs_base'): '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. # Code literal which forces a default 64 bit operand size in 64 bit mode.
assembler.symbols["oszIn64Override"] = ''' assembler.symbols["oszIn64Override"] = '''
@ -201,7 +210,7 @@ let {{
assembler.symbols["rom_local_label"] = rom_local_labeler assembler.symbols["rom_local_label"] = rom_local_labeler
def stack_index(index): def stack_index(index):
return "(NUM_FLOATREGS + (((%s) + 8) %% 8))" % index return regIdx("NUM_FLOATREGS + (((%s) + 8) %% 8)" % index)
assembler.symbols["st"] = stack_index assembler.symbols["st"] = stack_index

View file

@ -86,7 +86,7 @@ let {{
const EmulEnv &env = const EmulEnv &env =
macroop ? macroop->getEmulEnv() : dummyEmulEnv; macroop ? macroop->getEmulEnv() : dummyEmulEnv;
// env may not be used in the microop's constructor. // env may not be used in the microop's constructor.
RegIndex reg = env.reg; InstRegIndex reg(env.reg);
reg = reg; reg = reg;
using namespace RomLabels; using namespace RomLabels;
return %s; return %s;

View file

@ -99,12 +99,12 @@ def template MicroFpOpDeclare {{
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, 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); uint8_t _dataSize, int8_t _spm);
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest, InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
uint8_t _dataSize, int8_t _spm); uint8_t _dataSize, int8_t _spm);
%(BasicExecDeclare)s %(BasicExecDeclare)s
@ -120,7 +120,7 @@ def template MicroFpOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, ExtMachInst machInst, const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest, InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
uint8_t _dataSize, int8_t _spm) : uint8_t _dataSize, int8_t _spm) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false, false, false, false, false,
@ -133,7 +133,7 @@ def template MicroFpOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, 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) : uint8_t _dataSize, int8_t _spm) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast, isMicro, isDelayed, isFirst, isLast,
@ -256,9 +256,9 @@ let {{
"spm" : self.spm} "spm" : self.spm}
class Movfp(FpOp): class Movfp(FpOp):
def __init__(self, dest, src1, flags=0, spm=0, \ def __init__(self, dest, src1, spm=0, \
SetStatus=False, dataSize="env.dataSize"): SetStatus=False, dataSize="env.dataSize"):
super(Movfp, self).__init__(dest, src1, flags, \ super(Movfp, self).__init__(dest, src1, "InstRegIndex(0)", \
spm, SetStatus, dataSize) spm, SetStatus, dataSize)
code = 'FpDestReg.uqw = FpSrcReg1.uqw;' code = 'FpDestReg.uqw = FpSrcReg1.uqw;'
else_code = 'FpDestReg.uqw = FpDestReg.uqw;' else_code = 'FpDestReg.uqw = FpDestReg.uqw;'
@ -274,7 +274,8 @@ let {{
class ConvOp(FpOp): class ConvOp(FpOp):
abstract = True abstract = True
def __init__(self, dest, src1): 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 # 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 # out what size to use and should instead delegate that to the macroop's
@ -318,7 +319,7 @@ let {{
class Compfp(FpOp): class Compfp(FpOp):
def __init__(self, src1, src2, spm=0, setStatus=False, \ def __init__(self, src1, src2, spm=0, setStatus=False, \
dataSize="env.dataSize"): dataSize="env.dataSize"):
super(Compfp, self).__init__("(int)FLOATREG_MICROFP0", \ super(Compfp, self).__init__("InstRegIndex(FLOATREG_MICROFP0)", \
src1, src2, spm, setStatus, dataSize) src1, src2, spm, setStatus, dataSize)
# This class sets the condition codes in rflags according to the # This class sets the condition codes in rflags according to the
# rules for comparing floating point. # rules for comparing floating point.

View file

@ -121,17 +121,17 @@ def template MicroLeaDeclare {{
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, bool isMicro, bool isDelayed, bool isFirst, bool isLast,
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, InstRegIndex _segment,
RegIndex _data, InstRegIndex _data,
uint8_t _dataSize, uint8_t _addressSize, uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags); Request::FlagsType _memFlags);
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, InstRegIndex _segment,
RegIndex _data, InstRegIndex _data,
uint8_t _dataSize, uint8_t _addressSize, uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags); Request::FlagsType _memFlags);
@ -297,17 +297,17 @@ def template MicroLdStOpDeclare {{
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, bool isMicro, bool isDelayed, bool isFirst, bool isLast,
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, InstRegIndex _segment,
RegIndex _data, InstRegIndex _data,
uint8_t _dataSize, uint8_t _addressSize, uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags); Request::FlagsType _memFlags);
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, InstRegIndex _segment,
RegIndex _data, InstRegIndex _data,
uint8_t _dataSize, uint8_t _addressSize, uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags); Request::FlagsType _memFlags);
@ -328,9 +328,9 @@ def template MicroLdStOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, ExtMachInst machInst, const char * instMnem,
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, InstRegIndex _segment,
RegIndex _data, InstRegIndex _data,
uint8_t _dataSize, uint8_t _addressSize, uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags) : Request::FlagsType _memFlags) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
@ -345,9 +345,9 @@ def template MicroLdStOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, bool isMicro, bool isDelayed, bool isFirst, bool isLast,
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, InstRegIndex _segment,
RegIndex _data, InstRegIndex _data,
uint8_t _dataSize, uint8_t _addressSize, uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags) : Request::FlagsType _memFlags) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
@ -517,7 +517,7 @@ let {{
def __init__(self, segment, addr, disp = 0, def __init__(self, segment, addr, disp = 0,
dataSize="env.dataSize", dataSize="env.dataSize",
addressSize="env.addressSize"): 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) addr, disp, dataSize, addressSize, "0", False, False)
self.className = "Tia" self.className = "Tia"
self.mnemonic = "tia" self.mnemonic = "tia"
@ -528,7 +528,7 @@ let {{
def __init__(self, segment, addr, disp = 0, def __init__(self, segment, addr, disp = 0,
dataSize="env.dataSize", dataSize="env.dataSize",
addressSize="env.addressSize", atCPL0=False): 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) addr, disp, dataSize, addressSize, "0", atCPL0, False)
self.className = "Cda" self.className = "Cda"
self.mnemonic = "cda" self.mnemonic = "cda"

View file

@ -88,11 +88,11 @@ def template MicroLimmOpDeclare {{
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, 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, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
RegIndex _dest, uint64_t _imm, uint8_t _dataSize); InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize);
%(BasicExecDeclare)s %(BasicExecDeclare)s
}; };
@ -122,10 +122,10 @@ def template MicroLimmOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, 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, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false, %(op_class)s), false, false, false, false, %(op_class)s),
dest(_dest), imm(_imm), dataSize(_dataSize) dest(_dest.idx), imm(_imm), dataSize(_dataSize)
{ {
buildMe(); buildMe();
} }
@ -133,10 +133,10 @@ def template MicroLimmOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, 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, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast, %(op_class)s), isMicro, isDelayed, isFirst, isLast, %(op_class)s),
dest(_dest), imm(_imm), dataSize(_dataSize) dest(_dest.idx), imm(_imm), dataSize(_dataSize)
{ {
buildMe(); buildMe();
} }

View file

@ -126,12 +126,12 @@ def template MicroRegOpDeclare {{
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, 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); uint8_t _dataSize, uint16_t _ext);
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest, InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext); uint8_t _dataSize, uint16_t _ext);
%(BasicExecDeclare)s %(BasicExecDeclare)s
@ -149,12 +149,12 @@ def template MicroRegOpImmDeclare {{
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, 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); uint8_t _dataSize, uint16_t _ext);
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
RegIndex _src1, uint16_t _imm8, RegIndex _dest, InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext); uint8_t _dataSize, uint16_t _ext);
%(BasicExecDeclare)s %(BasicExecDeclare)s
@ -170,7 +170,7 @@ def template MicroRegOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, ExtMachInst machInst, const char * instMnem,
RegIndex _src1, RegIndex _src2, RegIndex _dest, InstRegIndex _src1, InstRegIndex _src2, InstRegIndex _dest,
uint8_t _dataSize, uint16_t _ext) : uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false, false, false, false, false,
@ -183,7 +183,7 @@ def template MicroRegOpConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, 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) : uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast, isMicro, isDelayed, isFirst, isLast,
@ -203,7 +203,7 @@ def template MicroRegOpImmConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, 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) : uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false, false, false, false, false,
@ -216,7 +216,7 @@ def template MicroRegOpImmConstructor {{
inline %(class_name)s::%(class_name)s( inline %(class_name)s::%(class_name)s(
ExtMachInst machInst, const char * instMnem, ExtMachInst machInst, const char * instMnem,
bool isMicro, bool isDelayed, bool isFirst, bool isLast, 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) : uint8_t _dataSize, uint16_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast, isMicro, isDelayed, isFirst, isLast,
@ -481,12 +481,14 @@ let {{
def __init__(self, dest, src1=None, dataSize="env.dataSize"): def __init__(self, dest, src1=None, dataSize="env.dataSize"):
if not src1: if not src1:
src1 = dest 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): class WrRegOp(RegOp):
abstract = True abstract = True
def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"): 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): class Add(FlagRegOp):
code = 'DestReg = merge(DestReg, psrc1 + op2, dataSize);' code = 'DestReg = merge(DestReg, psrc1 + op2, dataSize);'
@ -553,7 +555,8 @@ let {{
def __init__(self, dest, src1=None, flags=None, dataSize="env.dataSize"): def __init__(self, dest, src1=None, flags=None, dataSize="env.dataSize"):
if not src1: if not src1:
src1 = dest 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);' code = 'DestReg = merge(SrcReg1, ProdHi, dataSize);'
flag_code = ''' flag_code = '''
if (ProdHi) if (ProdHi)
@ -885,7 +888,7 @@ let {{
def __init__(self, dest, imm, flags=None, \ def __init__(self, dest, imm, flags=None, \
dataSize="env.dataSize"): dataSize="env.dataSize"):
super(Ruflag, self).__init__(dest, \ super(Ruflag, self).__init__(dest, \
"NUM_INTREGS", imm, flags, dataSize) "InstRegIndex(NUM_INTREGS)", imm, flags, dataSize)
class Rflag(RegOp): class Rflag(RegOp):
code = ''' code = '''
@ -899,7 +902,7 @@ let {{
def __init__(self, dest, imm, flags=None, \ def __init__(self, dest, imm, flags=None, \
dataSize="env.dataSize"): dataSize="env.dataSize"):
super(Rflag, self).__init__(dest, \ super(Rflag, self).__init__(dest, \
"NUM_INTREGS", imm, flags, dataSize) "InstRegIndex(NUM_INTREGS)", imm, flags, dataSize)
class Sext(RegOp): class Sext(RegOp):
code = ''' code = '''
@ -926,7 +929,7 @@ let {{
class Rddr(RegOp): class Rddr(RegOp):
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
super(Rddr, self).__init__(dest, \ super(Rddr, self).__init__(dest, \
src1, "NUM_INTREGS", flags, dataSize) src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize)
code = ''' code = '''
CR4 cr4 = CR4Op; CR4 cr4 = CR4Op;
DR7 dr7 = DR7Op; DR7 dr7 = DR7Op;
@ -942,14 +945,13 @@ let {{
class Wrdr(RegOp): class Wrdr(RegOp):
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
super(Wrdr, self).__init__(dest, \ super(Wrdr, self).__init__(dest, \
src1, "NUM_INTREGS", flags, dataSize) src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize)
code = ''' code = '''
CR4 cr4 = CR4Op; CR4 cr4 = CR4Op;
DR7 dr7 = DR7Op; DR7 dr7 = DR7Op;
if ((cr4.de == 1 && (dest == 4 || dest == 5)) || dest >= 8) { if ((cr4.de == 1 && (dest == 4 || dest == 5)) || dest >= 8) {
fault = new InvalidOpcode(); fault = new InvalidOpcode();
} else if ((dest == 6 || dest == 7) && } else if ((dest == 6 || dest == 7) && bits(psrc1, 63, 32) &&
bits(psrc1, 63, 32) &&
machInst.mode.mode == LongMode) { machInst.mode.mode == LongMode) {
fault = new GeneralProtection(0); fault = new GeneralProtection(0);
} else if (dr7.gd) { } else if (dr7.gd) {
@ -962,7 +964,7 @@ let {{
class Rdcr(RegOp): class Rdcr(RegOp):
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
super(Rdcr, self).__init__(dest, \ super(Rdcr, self).__init__(dest, \
src1, "NUM_INTREGS", flags, dataSize) src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize)
code = ''' code = '''
if (src1 == 1 || (src1 > 4 && src1 < 8) || (src1 > 8)) { if (src1 == 1 || (src1 > 4 && src1 < 8) || (src1 > 8)) {
fault = new InvalidOpcode(); fault = new InvalidOpcode();
@ -974,7 +976,7 @@ let {{
class Wrcr(RegOp): class Wrcr(RegOp):
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
super(Wrcr, self).__init__(dest, \ super(Wrcr, self).__init__(dest, \
src1, "NUM_INTREGS", flags, dataSize) src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize)
code = ''' code = '''
if (dest == 1 || (dest > 4 && dest < 8) || (dest > 8)) { if (dest == 1 || (dest > 4 && dest < 8) || (dest > 8)) {
fault = new InvalidOpcode(); fault = new InvalidOpcode();
@ -1028,7 +1030,7 @@ let {{
abstract = True abstract = True
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
super(SegOp, self).__init__(dest, \ super(SegOp, self).__init__(dest, \
src1, "NUM_INTREGS", flags, dataSize) src1, "InstRegIndex(NUM_INTREGS)", flags, dataSize)
class Wrbase(SegOp): class Wrbase(SegOp):
code = ''' code = '''
@ -1072,16 +1074,16 @@ let {{
class Rdval(RegOp): class Rdval(RegOp):
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
super(Rdval, self).__init__(dest, \ super(Rdval, self).__init__(dest, src1, \
src1, "NUM_INTREGS", flags, dataSize) "InstRegIndex(NUM_INTREGS)", flags, dataSize)
code = ''' code = '''
DestReg = MiscRegSrc1; DestReg = MiscRegSrc1;
''' '''
class Wrval(RegOp): class Wrval(RegOp):
def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
super(Wrval, self).__init__(dest, \ super(Wrval, self).__init__(dest, src1, \
src1, "NUM_INTREGS", flags, dataSize) "InstRegIndex(NUM_INTREGS)", flags, dataSize)
code = ''' code = '''
MiscRegDest = SrcReg1; MiscRegDest = SrcReg1;
''' '''

View file

@ -94,75 +94,94 @@ def operand_types {{
'df' : ('float', 64), '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 {{ def operands {{
'SrcReg1': ('IntReg', 'uqw', 'INTREG_FOLDED(src1, foldOBit)', 'IsInteger', 1), 'SrcReg1': foldInt('src1', 'foldOBit', 1),
'SSrcReg1': ('IntReg', 'uqw', 'src1', 'IsInteger', 1), 'SSrcReg1': intReg('src1', 1),
'SrcReg2': ('IntReg', 'uqw', 'INTREG_FOLDED(src2, foldOBit)', 'IsInteger', 2), 'SrcReg2': foldInt('src2', 'foldOBit', 2),
'SSrcReg2': ('IntReg', 'uqw', 'src2', 'IsInteger', 1), 'SSrcReg2': intReg('src2', 1),
'Index': ('IntReg', 'uqw', 'INTREG_FOLDED(index, foldABit)', 'IsInteger', 3), 'Index': foldInt('index', 'foldABit', 3),
'Base': ('IntReg', 'uqw', 'INTREG_FOLDED(base, foldABit)', 'IsInteger', 4), 'Base': foldInt('base', 'foldABit', 4),
'DestReg': ('IntReg', 'uqw', 'INTREG_FOLDED(dest, foldOBit)', 'IsInteger', 5), 'DestReg': foldInt('dest', 'foldOBit', 5),
'SDestReg': ('IntReg', 'uqw', 'dest', 'IsInteger', 5), 'SDestReg': intReg('dest', 5),
'Data': ('IntReg', 'uqw', 'INTREG_FOLDED(data, foldOBit)', 'IsInteger', 6), 'Data': foldInt('data', 'foldOBit', 6),
'ProdLow': ('IntReg', 'uqw', 'INTREG_IMPLICIT(0)', 'IsInteger', 7), 'ProdLow': impIntReg(0, 7),
'ProdHi': ('IntReg', 'uqw', 'INTREG_IMPLICIT(1)', 'IsInteger', 8), 'ProdHi': impIntReg(1, 8),
'Quotient': ('IntReg', 'uqw', 'INTREG_IMPLICIT(2)', 'IsInteger', 9), 'Quotient': impIntReg(2, 9),
'Remainder': ('IntReg', 'uqw', 'INTREG_IMPLICIT(3)', 'IsInteger', 10), 'Remainder': impIntReg(3, 10),
'Divisor': ('IntReg', 'uqw', 'INTREG_IMPLICIT(4)', 'IsInteger', 11), 'Divisor': impIntReg(4, 11),
'Rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 12), 'Rax': intReg('(INTREG_RAX)', 12),
'Rbx': ('IntReg', 'uqw', '(INTREG_RBX)', 'IsInteger', 13), 'Rbx': intReg('(INTREG_RBX)', 13),
'Rcx': ('IntReg', 'uqw', '(INTREG_RCX)', 'IsInteger', 14), 'Rcx': intReg('(INTREG_RCX)', 14),
'Rdx': ('IntReg', 'uqw', '(INTREG_RDX)', 'IsInteger', 15), 'Rdx': intReg('(INTREG_RDX)', 15),
'Rsp': ('IntReg', 'uqw', '(INTREG_RSP)', 'IsInteger', 16), 'Rsp': intReg('(INTREG_RSP)', 16),
'Rbp': ('IntReg', 'uqw', '(INTREG_RBP)', 'IsInteger', 17), 'Rbp': intReg('(INTREG_RBP)', 17),
'Rsi': ('IntReg', 'uqw', '(INTREG_RSI)', 'IsInteger', 18), 'Rsi': intReg('(INTREG_RSI)', 18),
'Rdi': ('IntReg', 'uqw', '(INTREG_RDI)', 'IsInteger', 19), 'Rdi': intReg('(INTREG_RDI)', 19),
'FpSrcReg1': ('FloatReg', 'df', 'src1', 'IsFloating', 20), 'FpSrcReg1': floatReg('src1', 20),
'FpSrcReg2': ('FloatReg', 'df', 'src2', 'IsFloating', 21), 'FpSrcReg2': floatReg('src2', 21),
'FpDestReg': ('FloatReg', 'df', 'dest', 'IsFloating', 22), 'FpDestReg': floatReg('dest', 22),
'FpData': ('FloatReg', 'df', 'data', 'IsFloating', 23), 'FpData': floatReg('data', 23),
'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 50), 'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 50),
'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51), 'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51),
'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52), 'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52),
# This holds the condition code portion of the flag register. The # This holds the condition code portion of the flag register. The
# nccFlagBits version holds the rest. # 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 # These register should needs to be more protected so that later
# instructions don't map their indexes with an old value. # instructions don't map their indexes with an old value.
'nccFlagBits': ('ControlReg', 'uqw', 'MISCREG_RFLAGS', None, 61), 'nccFlagBits': controlReg('MISCREG_RFLAGS', 61),
'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 62), 'TOP': controlReg('MISCREG_X87_TOP', 62, ctype='ub'),
# The segment base as used by memory instructions. # 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 # Operands to get and set registers indexed by the operands of the
# original instruction. # original instruction.
'ControlDest': ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 100), 'ControlDest': controlReg('MISCREG_CR(dest)', 100),
'ControlSrc1': ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 101), 'ControlSrc1': controlReg('MISCREG_CR(src1)', 101),
'DebugDest': ('ControlReg', 'uqw', 'MISCREG_DR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 102), 'DebugDest': controlReg('MISCREG_DR(dest)', 102),
'DebugSrc1': ('ControlReg', 'uqw', 'MISCREG_DR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 103), 'DebugSrc1': controlReg('MISCREG_DR(src1)', 103),
'SegBaseDest': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 104), 'SegBaseDest': controlReg('MISCREG_SEG_BASE(dest)', 104),
'SegBaseSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 105), 'SegBaseSrc1': controlReg('MISCREG_SEG_BASE(src1)', 105),
'SegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 106), 'SegLimitDest': controlReg('MISCREG_SEG_LIMIT(dest)', 106),
'SegLimitSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 107), 'SegLimitSrc1': controlReg('MISCREG_SEG_LIMIT(src1)', 107),
'SegSelDest': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 108), 'SegSelDest': controlReg('MISCREG_SEG_SEL(dest)', 108),
'SegSelSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 109), 'SegSelSrc1': controlReg('MISCREG_SEG_SEL(src1)', 109),
'SegAttrDest': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 110), 'SegAttrDest': controlReg('MISCREG_SEG_ATTR(dest)', 110),
'SegAttrSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 111), 'SegAttrSrc1': controlReg('MISCREG_SEG_ATTR(src1)', 111),
# Operands to access specific control registers directly. # Operands to access specific control registers directly.
'EferOp': ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 200), 'EferOp': controlReg('MISCREG_EFER', 200),
'CR4Op': ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 201), 'CR4Op': controlReg('MISCREG_CR4', 201),
'DR7Op': ('ControlReg', 'uqw', 'MISCREG_DR7', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 202), 'DR7Op': controlReg('MISCREG_DR7', 202),
'LDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSL_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 203), 'LDTRBase': controlReg('MISCREG_TSL_BASE', 203),
'LDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSL_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 204), 'LDTRLimit': controlReg('MISCREG_TSL_LIMIT', 204),
'LDTRSel': ('ControlReg', 'uqw', 'MISCREG_TSL', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205), 'LDTRSel': controlReg('MISCREG_TSL', 205),
'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206), 'GDTRBase': controlReg('MISCREG_TSG_BASE', 206),
'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207), 'GDTRLimit': controlReg('MISCREG_TSG_LIMIT', 207),
'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208), 'CSBase': controlReg('MISCREG_CS_EFF_BASE', 208),
'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 209), 'CSAttr': controlReg('MISCREG_CS_ATTR', 209),
'MiscRegDest': ('ControlReg', 'uqw', 'dest', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 210), 'MiscRegDest': controlReg('dest', 210),
'MiscRegSrc1': ('ControlReg', 'uqw', 'src1', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 211), 'MiscRegSrc1': controlReg('src1', 211),
'TscOp': ('ControlReg', 'uqw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 212), 'TscOp': controlReg('MISCREG_TSC', 212),
'M5Reg': ('ControlReg', 'uqw', 'MISCREG_M5_REG', (None, None, None), 213), 'M5Reg': controlReg('MISCREG_M5_REG', 213),
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300) 'Mem': ('Mem', 'uqw', None, \
('IsMemRef', 'IsLoad', 'IsStore'), 300)
}}; }};

View file

@ -165,8 +165,9 @@ namespace X86ISA
MISCREG_MTRR_PHYS_BASE_5, MISCREG_MTRR_PHYS_BASE_5,
MISCREG_MTRR_PHYS_BASE_6, MISCREG_MTRR_PHYS_BASE_6,
MISCREG_MTRR_PHYS_BASE_7, 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_0 = MISCREG_MTRR_PHYS_MASK_BASE,
MISCREG_MTRR_PHYS_MASK_1, MISCREG_MTRR_PHYS_MASK_1,
MISCREG_MTRR_PHYS_MASK_2, MISCREG_MTRR_PHYS_MASK_2,
@ -175,8 +176,9 @@ namespace X86ISA
MISCREG_MTRR_PHYS_MASK_5, MISCREG_MTRR_PHYS_MASK_5,
MISCREG_MTRR_PHYS_MASK_6, MISCREG_MTRR_PHYS_MASK_6,
MISCREG_MTRR_PHYS_MASK_7, 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_80000,
MISCREG_MTRR_FIX_16K_A0000, MISCREG_MTRR_FIX_16K_A0000,
MISCREG_MTRR_FIX_4K_C0000, MISCREG_MTRR_FIX_4K_C0000,
@ -201,8 +203,9 @@ namespace X86ISA
MISCREG_MC5_CTL, MISCREG_MC5_CTL,
MISCREG_MC6_CTL, MISCREG_MC6_CTL,
MISCREG_MC7_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_MC0_STATUS = MISCREG_MC_STATUS_BASE,
MISCREG_MC1_STATUS, MISCREG_MC1_STATUS,
MISCREG_MC2_STATUS, MISCREG_MC2_STATUS,
@ -211,8 +214,9 @@ namespace X86ISA
MISCREG_MC5_STATUS, MISCREG_MC5_STATUS,
MISCREG_MC6_STATUS, MISCREG_MC6_STATUS,
MISCREG_MC7_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_MC0_ADDR = MISCREG_MC_ADDR_BASE,
MISCREG_MC1_ADDR, MISCREG_MC1_ADDR,
MISCREG_MC2_ADDR, MISCREG_MC2_ADDR,
@ -221,8 +225,9 @@ namespace X86ISA
MISCREG_MC5_ADDR, MISCREG_MC5_ADDR,
MISCREG_MC6_ADDR, MISCREG_MC6_ADDR,
MISCREG_MC7_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_MC0_MISC = MISCREG_MC_MISC_BASE,
MISCREG_MC1_MISC, MISCREG_MC1_MISC,
MISCREG_MC2_MISC, MISCREG_MC2_MISC,
@ -231,9 +236,10 @@ namespace X86ISA
MISCREG_MC5_MISC, MISCREG_MC5_MISC,
MISCREG_MC6_MISC, MISCREG_MC6_MISC,
MISCREG_MC7_MISC, MISCREG_MC7_MISC,
MISCREG_MC_MISC_END,
// Extended feature enable register // Extended feature enable register
MISCREG_EFER, MISCREG_EFER = MISCREG_MC_MISC_END,
MISCREG_STAR, MISCREG_STAR,
MISCREG_LSTAR, MISCREG_LSTAR,
@ -250,24 +256,28 @@ namespace X86ISA
MISCREG_PERF_EVT_SEL1, MISCREG_PERF_EVT_SEL1,
MISCREG_PERF_EVT_SEL2, MISCREG_PERF_EVT_SEL2,
MISCREG_PERF_EVT_SEL3, 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_CTR0 = MISCREG_PERF_EVT_CTR_BASE,
MISCREG_PERF_EVT_CTR1, MISCREG_PERF_EVT_CTR1,
MISCREG_PERF_EVT_CTR2, MISCREG_PERF_EVT_CTR2,
MISCREG_PERF_EVT_CTR3, MISCREG_PERF_EVT_CTR3,
MISCREG_PERF_EVT_CTR_END,
MISCREG_SYSCFG, MISCREG_SYSCFG = MISCREG_PERF_EVT_CTR_END,
MISCREG_IORR_BASE_BASE, MISCREG_IORR_BASE_BASE,
MISCREG_IORR_BASE0 = MISCREG_IORR_BASE_BASE, MISCREG_IORR_BASE0 = MISCREG_IORR_BASE_BASE,
MISCREG_IORR_BASE1, 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_MASK0 = MISCREG_IORR_MASK_BASE,
MISCREG_IORR_MASK1, MISCREG_IORR_MASK1,
MISCREG_IORR_MASK_END,
MISCREG_TOP_MEM, MISCREG_TOP_MEM = MISCREG_IORR_MASK_END,
MISCREG_TOP_MEM2, MISCREG_TOP_MEM2,
MISCREG_VM_CR, MISCREG_VM_CR,
@ -377,102 +387,129 @@ namespace X86ISA
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_CR(int index) MISCREG_CR(int index)
{ {
assert(index >= 0 && index < NumCRegs);
return (MiscRegIndex)(MISCREG_CR_BASE + index); return (MiscRegIndex)(MISCREG_CR_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_DR(int index) MISCREG_DR(int index)
{ {
assert(index >= 0 && index < NumDRegs);
return (MiscRegIndex)(MISCREG_DR_BASE + index); return (MiscRegIndex)(MISCREG_DR_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_MTRR_PHYS_BASE(int index) 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); return (MiscRegIndex)(MISCREG_MTRR_PHYS_BASE_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_MTRR_PHYS_MASK(int index) 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); return (MiscRegIndex)(MISCREG_MTRR_PHYS_MASK_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_MC_CTL(int index) MISCREG_MC_CTL(int index)
{ {
assert(index >= 0 && index < (MISCREG_MC_CTL_END -
MISCREG_MC_CTL_BASE));
return (MiscRegIndex)(MISCREG_MC_CTL_BASE + index); return (MiscRegIndex)(MISCREG_MC_CTL_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_MC_STATUS(int index) MISCREG_MC_STATUS(int index)
{ {
assert(index >= 0 && index < (MISCREG_MC_STATUS_END -
MISCREG_MC_STATUS_BASE));
return (MiscRegIndex)(MISCREG_MC_STATUS_BASE + index); return (MiscRegIndex)(MISCREG_MC_STATUS_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_MC_ADDR(int index) MISCREG_MC_ADDR(int index)
{ {
assert(index >= 0 && index < (MISCREG_MC_ADDR_END -
MISCREG_MC_ADDR_BASE));
return (MiscRegIndex)(MISCREG_MC_ADDR_BASE + index); return (MiscRegIndex)(MISCREG_MC_ADDR_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_MC_MISC(int index) MISCREG_MC_MISC(int index)
{ {
assert(index >= 0 && index < (MISCREG_MC_MISC_END -
MISCREG_MC_MISC_BASE));
return (MiscRegIndex)(MISCREG_MC_MISC_BASE + index); return (MiscRegIndex)(MISCREG_MC_MISC_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_PERF_EVT_SEL(int index) 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); return (MiscRegIndex)(MISCREG_PERF_EVT_SEL_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_PERF_EVT_CTR(int index) 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); return (MiscRegIndex)(MISCREG_PERF_EVT_CTR_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_IORR_BASE(int index) MISCREG_IORR_BASE(int index)
{ {
assert(index >= 0 && index < (MISCREG_IORR_BASE_END -
MISCREG_IORR_BASE_BASE));
return (MiscRegIndex)(MISCREG_IORR_BASE_BASE + index); return (MiscRegIndex)(MISCREG_IORR_BASE_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_IORR_MASK(int index) MISCREG_IORR_MASK(int index)
{ {
assert(index >= 0 && index < (MISCREG_IORR_MASK_END -
MISCREG_IORR_MASK_BASE));
return (MiscRegIndex)(MISCREG_IORR_MASK_BASE + index); return (MiscRegIndex)(MISCREG_IORR_MASK_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_SEG_SEL(int index) MISCREG_SEG_SEL(int index)
{ {
assert(index >= 0 && index < NUM_SEGMENTREGS);
return (MiscRegIndex)(MISCREG_SEG_SEL_BASE + index); return (MiscRegIndex)(MISCREG_SEG_SEL_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_SEG_BASE(int index) MISCREG_SEG_BASE(int index)
{ {
assert(index >= 0 && index < NUM_SEGMENTREGS);
return (MiscRegIndex)(MISCREG_SEG_BASE_BASE + index); return (MiscRegIndex)(MISCREG_SEG_BASE_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_SEG_EFF_BASE(int index) MISCREG_SEG_EFF_BASE(int index)
{ {
assert(index >= 0 && index < NUM_SEGMENTREGS);
return (MiscRegIndex)(MISCREG_SEG_EFF_BASE_BASE + index); return (MiscRegIndex)(MISCREG_SEG_EFF_BASE_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_SEG_LIMIT(int index) MISCREG_SEG_LIMIT(int index)
{ {
assert(index >= 0 && index < NUM_SEGMENTREGS);
return (MiscRegIndex)(MISCREG_SEG_LIMIT_BASE + index); return (MiscRegIndex)(MISCREG_SEG_LIMIT_BASE + index);
} }
static inline MiscRegIndex static inline MiscRegIndex
MISCREG_SEG_ATTR(int index) MISCREG_SEG_ATTR(int index)
{ {
assert(index >= 0 && index < NUM_SEGMENTREGS);
return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index); return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index);
} }

View file

@ -40,13 +40,8 @@
#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/system/NodeID.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 { class Driver {
public: public:
@ -58,15 +53,12 @@ public:
// Public Methods // Public Methods
virtual void get_network_config() {} virtual void get_network_config() {}
virtual void dmaHitCallback() = 0; virtual void dmaHitCallback() {};
virtual void hitCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread) = 0; // Called by sequencer virtual void hitCallback(int64_t id) = 0; // Called by sequencer
virtual void conflictCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread) { assert(0); }; // Called by sequencer virtual void go() = 0;
virtual integer_t getInstructionCount(int procID) const { return 1; } virtual integer_t getInstructionCount(int procID) const { return 1; }
virtual integer_t getCycleCount(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 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 printDebug(){} //called by Sequencer
virtual void printStats(ostream& out) const = 0; 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 printConfig(ostream& out) const = 0;
//virtual void abortCallback(NodeID proc){}
virtual integer_t readPhysicalMemory(int procID, physical_address_t address, virtual integer_t readPhysicalMemory(int procID, physical_address_t address,
int len ){ ASSERT(0); return 0; } int len ){ ASSERT(0); return 0; }

View file

@ -9,6 +9,7 @@
#include "mem/ruby/eventqueue/RubyEventQueue.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/ruby/system/MemoryVector.hh" #include "mem/ruby/system/MemoryVector.hh"
#include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Address.hh"
#include "mem/ruby/recorder/Tracer.hh"
string RubyRequestType_to_string(const RubyRequestType& obj) string RubyRequestType_to_string(const RubyRequestType& obj)
{ {
@ -19,8 +20,14 @@ string RubyRequestType_to_string(const RubyRequestType& obj)
return "LD"; return "LD";
case RubyRequestType_ST: case RubyRequestType_ST:
return "ST"; return "ST";
case RubyRequestType_RMW: case RubyRequestType_Locked_Read:
return "RMW"; 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: case RubyRequestType_NULL:
default: default:
assert(0); assert(0);
@ -36,8 +43,14 @@ RubyRequestType string_to_RubyRequestType(std::string str)
return RubyRequestType_LD; return RubyRequestType_LD;
else if (str == "ST") else if (str == "ST")
return RubyRequestType_ST; return RubyRequestType_ST;
else if (str == "RMW") else if (str == "Locked_Read")
return RubyRequestType_RMW; 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 else
assert(0); assert(0);
return RubyRequestType_NULL; return RubyRequestType_NULL;
@ -200,6 +213,20 @@ void libruby_print_stats(std::ostream & out)
{ {
RubySystem::printStats(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() { uint64_t libruby_get_time() {
return RubySystem::getCycleCount(0); return RubySystem::getCycleCount(0);

View file

@ -11,7 +11,10 @@ enum RubyRequestType {
RubyRequestType_IFETCH, RubyRequestType_IFETCH,
RubyRequestType_LD, RubyRequestType_LD,
RubyRequestType_ST, RubyRequestType_ST,
RubyRequestType_RMW RubyRequestType_Locked_Read,
RubyRequestType_Locked_Write,
RubyRequestType_RMW_Read,
RubyRequestType_RMW_Write
}; };
enum RubyAccessMode { enum RubyAccessMode {
@ -101,6 +104,20 @@ void libruby_print_config(std::ostream & out);
*/ */
void libruby_print_stats(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 * get time

View file

@ -47,7 +47,10 @@ TraceRecord::TraceRecord(const string & sequencer_name, const Address& data_addr
// Don't differentiate between store misses and atomic requests in // Don't differentiate between store misses and atomic requests in
// the trace // 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; m_type = RubyRequestType_ST;
} }
} }

View file

@ -92,10 +92,11 @@ void Tracer::startTrace(string filename)
void Tracer::stopTrace() void Tracer::stopTrace()
{ {
assert(m_enabled == true); if (m_enabled == true) {
m_trace_file.close(); m_trace_file.close();
cout << "Request trace file closed." << endl; cout << "Request trace file closed." << endl;
m_enabled = false; m_enabled = false;
}
} }
void Tracer::traceRequest(const string & sequencer_name, const Address& data_addr, const Address& pc_addr, RubyRequestType type, Time time) void Tracer::traceRequest(const string & sequencer_name, const Address& data_addr, const Address& pc_addr, RubyRequestType type, Time time)

View file

@ -116,6 +116,9 @@ public:
void setMemoryValue(const Address& addr, char* value, void setMemoryValue(const Address& addr, char* value,
unsigned int size_in_bytes ); 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 // Print cache contents
void print(ostream& out) const; void print(ostream& out) const;
void printData(ostream& out) const; void printData(ostream& out) const;
@ -147,6 +150,7 @@ private:
// The first index is the # of cache lines. // The first index is the # of cache lines.
// The second index is the the amount associativity. // The second index is the the amount associativity.
Vector<Vector<AbstractCacheEntry*> > m_cache; Vector<Vector<AbstractCacheEntry*> > m_cache;
Vector<Vector<int> > m_locked;
AbstractReplacementPolicy *m_replacementPolicy_ptr; AbstractReplacementPolicy *m_replacementPolicy_ptr;
@ -252,10 +256,13 @@ void CacheMemory::init(const vector<string> & argv)
assert(false); assert(false);
m_cache.setSize(m_cache_num_sets); m_cache.setSize(m_cache_num_sets);
m_locked.setSize(m_cache_num_sets);
for (int i = 0; i < m_cache_num_sets; i++) { for (int i = 0; i < m_cache_num_sets; i++) {
m_cache[i].setSize(m_cache_assoc); m_cache[i].setSize(m_cache_assoc);
m_locked[i].setSize(m_cache_assoc);
for (int j = 0; j < m_cache_assoc; j++) { for (int j = 0; j < m_cache_assoc; j++) {
m_cache[i][j] = NULL; 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] = entry; // Init entry
m_cache[cacheSet][i]->m_Address = address; m_cache[cacheSet][i]->m_Address = address;
m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid;
m_locked[cacheSet][i] = -1;
m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime()); m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime());
@ -494,6 +502,7 @@ void CacheMemory::deallocate(const Address& address)
if (location != -1){ if (location != -1){
delete m_cache[cacheSet][location]; delete m_cache[cacheSet][location];
m_cache[cacheSet][location] = NULL; 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)); assert(address == line_address(address));
lookup(address).m_Permission = new_perm; 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); assert(getPermission(address) == new_perm);
} }
@ -630,5 +642,38 @@ void CacheMemory::setMemoryValue(const Address& addr, char* value,
// entry = lookup(line_address(addr)); // 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 #endif //CACHEMEMORY_H

View file

@ -47,7 +47,10 @@ int64_t DMASequencer::makeRequest(const RubyRequest & request)
break; break;
case RubyRequestType_NULL: case RubyRequestType_NULL:
case RubyRequestType_IFETCH: case RubyRequestType_IFETCH:
case RubyRequestType_RMW: case RubyRequestType_Locked_Read:
case RubyRequestType_Locked_Write:
case RubyRequestType_RMW_Read:
case RubyRequestType_RMW_Write:
assert(0); assert(0);
} }

View file

@ -43,6 +43,8 @@
//Sequencer::Sequencer(int core_id, MessageBuffer* mandatory_q) //Sequencer::Sequencer(int core_id, MessageBuffer* mandatory_q)
#define LLSC_FAIL -2
Sequencer::Sequencer(const string & name) Sequencer::Sequencer(const string & name)
:RubyPort(name) :RubyPort(name)
{ {
@ -201,7 +203,10 @@ bool Sequencer::insertRequest(SequencerRequest* request) {
Address line_addr(request->ruby_request.paddr); Address line_addr(request->ruby_request.paddr);
line_addr.makeLineAddress(); line_addr.makeLineAddress();
if ((request->ruby_request.type == RubyRequestType_ST) || 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)) { if (m_writeRequestTable.exist(line_addr)) {
m_writeRequestTable.lookup(line_addr) = request; m_writeRequestTable.lookup(line_addr) = request;
// return true; // return true;
@ -237,7 +242,10 @@ void Sequencer::removeRequest(SequencerRequest* srequest) {
Address line_addr(ruby_request.paddr); Address line_addr(ruby_request.paddr);
line_addr.makeLineAddress(); line_addr.makeLineAddress();
if ((ruby_request.type == RubyRequestType_ST) || 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); m_writeRequestTable.deallocate(line_addr);
} else { } else {
m_readRequestTable.deallocate(line_addr); m_readRequestTable.deallocate(line_addr);
@ -256,7 +264,14 @@ void Sequencer::writeCallback(const Address& address, DataBlock& data) {
removeRequest(request); removeRequest(request);
assert((request->ruby_request.type == RubyRequestType_ST) || 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); hitCallback(request, data);
} }
@ -347,6 +362,7 @@ bool Sequencer::empty() const {
return (m_writeRequestTable.size() == 0) && (m_readRequestTable.size() == 0); return (m_writeRequestTable.size() == 0) && (m_readRequestTable.size() == 0);
} }
int64_t Sequencer::makeRequest(const RubyRequest & request) int64_t Sequencer::makeRequest(const RubyRequest & request)
{ {
assert(Address(request.paddr).getOffset() + request.len <= RubySystem::getBlockSizeBytes()); 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()); SequencerRequest *srequest = new SequencerRequest(request, id, g_eventQueue_ptr->getTime());
bool found = insertRequest(srequest); bool found = insertRequest(srequest);
if (!found) 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); issueRequest(request);
// TODO: issue hardware prefetches here // TODO: issue hardware prefetches here
@ -379,7 +405,16 @@ void Sequencer::issueRequest(const RubyRequest& request) {
case RubyRequestType_ST: case RubyRequestType_ST:
ctype = CacheRequestType_ST; ctype = CacheRequestType_ST;
break; 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; ctype = CacheRequestType_ATOMIC;
break; break;
default: default:

View file

@ -106,7 +106,7 @@ public:
static int getNumberOfSequencers() { return m_sequencers.size(); } static int getNumberOfSequencers() { return m_sequencers.size(); }
Profiler* getProfiler() {assert(m_profiler_ptr != NULL); return m_profiler_ptr; } 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;} static MemoryVector* getMemoryVector() { assert(m_mem_vec_ptr != NULL); return m_mem_vec_ptr;}
void recordCacheContents(CacheRecorder& tr) const; void recordCacheContents(CacheRecorder& tr) const;

View file

@ -1,31 +1,58 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
@ -38,7 +65,8 @@
#include "mem/ruby/tester/DetermGETXGenerator.hh" #include "mem/ruby/tester/DetermGETXGenerator.hh"
#include "mem/protocol/DetermGETXGeneratorStatus.hh" #include "mem/protocol/DetermGETXGeneratorStatus.hh"
#include "mem/ruby/tester/DeterministicDriver.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 "mem/ruby/tester/SpecifiedGenerator.hh"
//#include "DMAController.hh" //#include "DMAController.hh"
#include "mem/ruby/libruby.hh" #include "mem/ruby/libruby.hh"
@ -48,9 +76,11 @@ DetermGETXGenerator::DetermGETXGenerator(NodeID node, DeterministicDriver * driv
{ {
m_status = DetermGETXGeneratorStatus_Thinking; m_status = DetermGETXGeneratorStatus_Thinking;
m_last_transition = 0; m_last_transition = 0;
counter = 0;
m_node = node; m_node = node;
m_address = Address(9999); // initialize to null value m_address = Address(1); // initialize to null value
m_counter = 0; m_counter = 0;
issued_load = false;
parent_driver = driver; parent_driver = driver;
// don't know exactly when this node needs to request so just guess randomly // don't know exactly when this node needs to request so just guess randomly
parent_driver->eventQueue->scheduleEvent(this, 1+(random() % 200)); 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 // determine if this node is next for the GETX round robin request
if (m_status == DetermGETXGeneratorStatus_Thinking) { if (m_status == DetermGETXGeneratorStatus_Thinking) {
if (parent_driver->isStoreReady(m_node)) { if (parent_driver->isStoreReady(m_node)) {
pickAddress(); if (!issued_load) {
pickAddress();
}
m_status = DetermGETXGeneratorStatus_Store_Pending; // Store Pending m_status = DetermGETXGeneratorStatus_Store_Pending; // Store Pending
m_last_transition = parent_driver->eventQueue->getTime(); m_last_transition = parent_driver->eventQueue->getTime();
initiateStore(); // GETX initiateStore(); // GETX
@ -85,13 +117,13 @@ void DetermGETXGenerator::wakeup()
void DetermGETXGenerator::performCallback(NodeID proc, Address address) void DetermGETXGenerator::performCallback(NodeID proc, Address address)
{ {
assert(proc == m_node); assert(proc == m_node);
assert(address == m_address); assert(address == m_address);
DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, proc);
DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status);
DEBUG_EXPR(TESTER_COMP, LowPrio, address); 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->recordStoreLatency(parent_driver->eventQueue->getTime() - m_last_transition);
parent_driver->storeCompleted(m_node, address); // advance the store queue parent_driver->storeCompleted(m_node, address); // advance the store queue
@ -104,7 +136,7 @@ void DetermGETXGenerator::performCallback(NodeID proc, Address address)
parent_driver->reportDone(); parent_driver->reportDone();
m_status = DetermGETXGeneratorStatus_Done; m_status = DetermGETXGeneratorStatus_Done;
m_last_transition = parent_driver->eventQueue->getTime(); m_last_transition = parent_driver->eventQueue->getTime();
} }
} else { } else {
WARN_EXPR(m_status); WARN_EXPR(m_status);
@ -132,7 +164,6 @@ void DetermGETXGenerator::pickAddress()
void DetermGETXGenerator::initiateStore() void DetermGETXGenerator::initiateStore()
{ {
DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store"); DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store");
uint8_t *write_data = new uint8_t[64]; uint8_t *write_data = new uint8_t[64];
for(int i=0; i < 64; i++) { for(int i=0; i < 64; i++) {
write_data[i] = m_node; write_data[i] = m_node;
@ -141,12 +172,29 @@ void DetermGETXGenerator::initiateStore()
char name [] = "Sequencer_"; char name [] = "Sequencer_";
char port_name [13]; char port_name [13];
sprintf(port_name, "%s%d", name, m_node); sprintf(port_name, "%s%d", name, m_node);
int64_t request_id;
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)); 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; // 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))); parent_driver->requests.insert(make_pair(request_id, make_pair(m_node, m_address)));
} }

View file

@ -1,36 +1,63 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
* *
* Description: * Description:
* *
*/ */
@ -40,11 +67,12 @@
#ifndef DETERMGETXGENERATOR_H #ifndef DETERMGETXGENERATOR_H
#define 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/ruby/common/Consumer.hh"
#include "mem/protocol/DetermGETXGeneratorStatus.hh" #include "mem/protocol/DetermGETXGeneratorStatus.hh"
#include "Address_Tester.hh"
#include "mem/ruby/tester/SpecifiedGenerator.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/Address.hh"
class DeterministicDriver; class DeterministicDriver;
class DMAController; class DMAController;
@ -56,7 +84,7 @@ public:
// Destructor // Destructor
~DetermGETXGenerator(); ~DetermGETXGenerator();
// Public Methods // Public Methods
void wakeup(); void wakeup();
void performCallback(NodeID proc, Address address); void performCallback(NodeID proc, Address address);
@ -80,8 +108,10 @@ private:
// Data Members (m_ prefix) // Data Members (m_ prefix)
DetermGETXGeneratorStatus m_status; DetermGETXGeneratorStatus m_status;
int m_counter; int m_counter;
bool issued_load;
Address m_address; Address m_address;
NodeID m_node; NodeID m_node;
long int counter;
Time m_last_transition; Time m_last_transition;
}; };
@ -91,7 +121,7 @@ ostream& operator<<(ostream& out, const DetermGETXGenerator& obj);
// ******************* Definitions ******************* // ******************* Definitions *******************
// Output operator definition // Output operator definition
extern inline extern inline
ostream& operator<<(ostream& out, const DetermGETXGenerator& obj) ostream& operator<<(ostream& out, const DetermGETXGenerator& obj)
{ {
obj.print(out); obj.print(out);

View file

@ -1,31 +1,58 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
@ -36,10 +63,11 @@
// then Invalidates them with a GETX. The GETS and GETX request are generated one // 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. // 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/ruby/tester/DetermInvGenerator.hh"
#include "mem/protocol/DetermInvGeneratorStatus.hh" #include "mem/protocol/DetermInvGeneratorStatus.hh"
#include "mem/ruby/tester/DeterministicDriver.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 "DMAController.hh"
#include "mem/ruby/libruby.hh" #include "mem/ruby/libruby.hh"
@ -75,7 +103,7 @@ void DetermInvGenerator::wakeup()
} else { // I'll check again later } else { // I'll check again later
m_driver.eventQueue->scheduleEvent(this, thinkTime()); 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.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 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; m_status = DetermInvGeneratorStatus_Store_Pending;
@ -98,13 +126,13 @@ void DetermInvGenerator::wakeup()
void DetermInvGenerator::performCallback(NodeID proc, Address address) void DetermInvGenerator::performCallback(NodeID proc, Address address)
{ {
assert(proc == m_node); assert(proc == m_node);
assert(address == m_address); assert(address == m_address);
DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, proc);
DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status);
DEBUG_EXPR(TESTER_COMP, LowPrio, address); 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); m_driver.recordLoadLatency(m_driver.eventQueue->getTime() - m_last_transition);
//NodeID firstByte = data.readByte(); // dummy read //NodeID firstByte = data.readByte(); // dummy read
@ -121,9 +149,9 @@ void DetermInvGenerator::performCallback(NodeID proc, Address address)
m_driver.reportDone(); m_driver.reportDone();
m_status = DetermInvGeneratorStatus_Done; m_status = DetermInvGeneratorStatus_Done;
m_last_transition = m_driver.eventQueue->getTime(); 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); m_driver.recordStoreLatency(m_driver.eventQueue->getTime() - m_last_transition);
//data.writeByte(m_node); //data.writeByte(m_node);
m_driver.storeCompleted(m_node, address); // advance the store queue 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_driver.reportDone();
m_status = DetermInvGeneratorStatus_Done; m_status = DetermInvGeneratorStatus_Done;
m_last_transition = m_driver.eventQueue->getTime(); m_last_transition = m_driver.eventQueue->getTime();
} }
} else { } else {
WARN_EXPR(m_status); WARN_EXPR(m_status);
ERROR_MSG("Invalid status"); ERROR_MSG("Invalid status");
@ -174,7 +202,7 @@ void DetermInvGenerator::pickLoadAddress()
void DetermInvGenerator::initiateLoad() void DetermInvGenerator::initiateLoad()
{ {
DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Load"); 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]; uint8_t * read_data = new uint8_t[64];
char name [] = "Sequencer_"; char name [] = "Sequencer_";
@ -185,7 +213,7 @@ void DetermInvGenerator::initiateLoad()
//delete [] read_data; //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))); m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address)));
} }
@ -193,7 +221,7 @@ void DetermInvGenerator::initiateLoad()
void DetermInvGenerator::initiateStore() void DetermInvGenerator::initiateStore()
{ {
DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store"); 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]; uint8_t *write_data = new uint8_t[64];
for(int i=0; i < 64; i++) { for(int i=0; i < 64; i++) {
write_data[i] = m_node; write_data[i] = m_node;
@ -207,7 +235,7 @@ void DetermInvGenerator::initiateStore()
//delete [] write_data; //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))); m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address)));
} }

View file

@ -1,36 +1,63 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
* *
* Description: * Description:
* *
*/ */
@ -41,8 +68,10 @@
#ifndef DETERMINVGENERATOR_H #ifndef DETERMINVGENERATOR_H
#define 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/Consumer.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/protocol/DetermInvGeneratorStatus.hh" #include "mem/protocol/DetermInvGeneratorStatus.hh"
#include "Address_Tester.hh" #include "Address_Tester.hh"
#include "mem/ruby/tester/SpecifiedGenerator.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh"
@ -56,7 +85,7 @@ public:
// Destructor // Destructor
~DetermInvGenerator(); ~DetermInvGenerator();
// Public Methods // Public Methods
void wakeup(); void wakeup();
void performCallback(NodeID proc, Address address); void performCallback(NodeID proc, Address address);
@ -71,7 +100,7 @@ private:
void initiateStore(); void initiateStore();
void pickLoadAddress(); void pickLoadAddress();
void pickStoreAddress(); void pickStoreAddress();
// copy constructor and assignment operator // copy constructor and assignment operator
DetermInvGenerator(const DetermInvGenerator& obj); DetermInvGenerator(const DetermInvGenerator& obj);
DetermInvGenerator& operator=(const DetermInvGenerator& obj); DetermInvGenerator& operator=(const DetermInvGenerator& obj);
@ -92,7 +121,7 @@ ostream& operator<<(ostream& out, const DetermInvGenerator& obj);
// ******************* Definitions ******************* // ******************* Definitions *******************
// Output operator definition // Output operator definition
extern inline extern inline
ostream& operator<<(ostream& out, const DetermInvGenerator& obj) ostream& operator<<(ostream& out, const DetermInvGenerator& obj)
{ {
obj.print(out); obj.print(out);

View file

@ -1,31 +1,58 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
@ -44,7 +71,7 @@ DetermSeriesGETSGenerator::DetermSeriesGETSGenerator(NodeID node, DeterministicD
m_node = node; m_node = node;
m_address = Address(9999); // initialize to null value m_address = Address(9999); // initialize to null value
m_counter = 0; m_counter = 0;
// don't know exactly when this node needs to request so just guess randomly // don't know exactly when this node needs to request so just guess randomly
m_driver.eventQueue->scheduleEvent(this, 1+(random() % 200)); m_driver.eventQueue->scheduleEvent(this, 1+(random() % 200));
@ -79,13 +106,13 @@ void DetermSeriesGETSGenerator::wakeup()
void DetermSeriesGETSGenerator::performCallback(NodeID proc, Address address) void DetermSeriesGETSGenerator::performCallback(NodeID proc, Address address)
{ {
assert(proc == m_node); assert(proc == m_node);
assert(address == m_address); assert(address == m_address);
DEBUG_EXPR(TESTER_COMP, LowPrio, proc); DEBUG_EXPR(TESTER_COMP, LowPrio, proc);
DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); DEBUG_EXPR(TESTER_COMP, LowPrio, m_status);
DEBUG_EXPR(TESTER_COMP, LowPrio, address); 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); m_driver.recordLoadLatency(m_driver.eventQueue->getTime() - m_last_transition);
//data.writeByte(m_node); //data.writeByte(m_node);
m_driver.loadCompleted(m_node, address); // advance the load queue 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_driver.reportDone();
m_status = DetermSeriesGETSGeneratorStatus_Done; m_status = DetermSeriesGETSGeneratorStatus_Done;
m_last_transition = m_driver.eventQueue->getTime(); m_last_transition = m_driver.eventQueue->getTime();
} }
} else { } else {
WARN_EXPR(m_status); WARN_EXPR(m_status);
@ -128,7 +155,7 @@ void DetermSeriesGETSGenerator::pickAddress()
void DetermSeriesGETSGenerator::initiateLoad() void DetermSeriesGETSGenerator::initiateLoad()
{ {
DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Load"); 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]; uint8_t *read_data = new uint8_t[64];
@ -140,7 +167,7 @@ void DetermSeriesGETSGenerator::initiateLoad()
//delete [] read_data; //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))); m_driver.requests.insert(make_pair(request_id, make_pair(m_node, m_address)));
} }

View file

@ -1,36 +1,63 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
* *
* Description: * Description:
* *
*/ */
@ -42,10 +69,11 @@
#ifndef DETERMSERIESGETSGENERATOR_H #ifndef DETERMSERIESGETSGENERATOR_H
#define 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/Consumer.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/protocol/DetermSeriesGETSGeneratorStatus.hh" #include "mem/protocol/DetermSeriesGETSGeneratorStatus.hh"
#include "Address_Tester.hh"
#include "mem/ruby/tester/SpecifiedGenerator.hh" #include "mem/ruby/tester/SpecifiedGenerator.hh"
class DeterministicDriver; class DeterministicDriver;
@ -57,7 +85,7 @@ public:
// Destructor // Destructor
~DetermSeriesGETSGenerator(); ~DetermSeriesGETSGenerator();
// Public Methods // Public Methods
void wakeup(); void wakeup();
void performCallback(NodeID proc, Address address); void performCallback(NodeID proc, Address address);
@ -89,7 +117,7 @@ ostream& operator<<(ostream& out, const DetermSeriesGETSGenerator& obj);
// ******************* Definitions ******************* // ******************* Definitions *******************
// Output operator definition // Output operator definition
extern inline extern inline
ostream& operator<<(ostream& out, const DetermSeriesGETSGenerator& obj) ostream& operator<<(ostream& out, const DetermSeriesGETSGenerator& obj)
{ {
obj.print(out); obj.print(out);

View file

@ -1,40 +1,68 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $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/DeterministicDriver.hh"
#include "mem/ruby/tester/EventQueue_Tester.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh"
//#include "DMAGenerator.hh" //#include "DMAGenerator.hh"
#include "mem/ruby/tester/DetermGETXGenerator.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) 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_finish_time = 0;
m_last_issue = -11; m_last_issue = -11;
m_done_counter = 0; m_done_counter = 0;
m_loads_completed = 0; m_loads_completed = 0;
m_stores_completed = 0; m_stores_completed = 0;
m_numCompletionsPerNode = num_completions; m_numCompletionsPerNode = num_completions;
m_num_procs = num_procs; m_num_procs = num_procs;
m_think_time = g_think_time; m_think_time = g_think_time;
m_wait_time = g_wait_time; m_wait_time = g_wait_time;
m_tester_length = g_tester_length; m_tester_length = g_tester_length;
m_last_progress_vector.setSize(num_procs); m_last_progress_vector.setSize(num_procs);
for (int i=0; i<m_last_progress_vector.size(); i++) { for (int i=0; i<m_last_progress_vector.size(); i++) {
m_last_progress_vector[i] = 0; m_last_progress_vector[i] = 0;
@ -129,7 +156,7 @@ void DeterministicDriver::hitCallback(int64_t request_id)
Address address = requests[request_id].second; Address address = requests[request_id].second;
m_generator_vector[proc]->performCallback(proc, address); m_generator_vector[proc]->performCallback(proc, address);
m_last_progress_vector[proc] = eventQueue->getTime(); m_last_progress_vector[proc] = eventQueue->getTime();
requests.erase(request_id); requests.erase(request_id);
@ -153,7 +180,7 @@ bool DeterministicDriver::isLoadReady(NodeID node)
} }
bool DeterministicDriver::isLoadReady(NodeID node, Address addr) bool DeterministicDriver::isLoadReady(NodeID node, Address addr)
{ {
return isAddrReady(node, m_load_vector, 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++) { for (int i=0; i<addr_vector.size(); i++) {
if (((addr_vector[i]+1)%m_num_procs == node) && if (((addr_vector[i]+1)%m_num_procs == node) &&
(m_loads_completed+m_stores_completed >= m_numCompletionsPerNode*node) && // is this node next (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; 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) && if (((addr_vector[addr_number]+1)%m_num_procs == node) &&
(m_loads_completed+m_stores_completed >= m_numCompletionsPerNode*node) && // is this node next (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; return true;
} else { } else {
return false; 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 // mark the addr vector that this proc was the last to use the particular address
int addr_number = addr.getAddress()/DATA_BLOCK_BYTES; int addr_number = addr.getAddress()/DATA_BLOCK_BYTES;
addr_vector[addr_number] = node; addr_vector[addr_number] = node;
} }
Address DeterministicDriver::getNextLoadAddr(NodeID 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 // This method deterministically picks the next addr the node should acquirer
// The addrs cycle through according to NodeID 0->1->...->lastID->0... // The addrs cycle through according to NodeID 0->1->...->lastID->0...
Address addr; Address addr;
// should only be called if we know a addr is ready for the node // should only be called if we know a addr is ready for the node
ASSERT(isAddrReady(node, addr_vector)); ASSERT(isAddrReady(node, addr_vector));
for (int addr_number=0; addr_number<addr_vector.size(); addr_number++) { for (int addr_number=0; addr_number<addr_vector.size(); addr_number++) {
// is this node next in line for the addr // 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 // One addr per cache line
addr.setAddress(addr_number * DATA_BLOCK_BYTES); addr.setAddress(addr_number * DATA_BLOCK_BYTES);

View file

@ -1,58 +1,86 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
* *
* Description: * Description:
* *
*/ */
#ifndef DETERMINISTICDRIVER_H #ifndef DETERMINISTICDRIVER_H
#define DETERMINISTICDRIVER_H #define DETERMINISTICDRIVER_H
#include <map> #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/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 "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/DetermGETXGenerator.hh" // this is our file
#include "mem/ruby/tester/DetermSeriesGETSGenerator.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/tester/DetermInvGenerator.hh" // this is our file
#include "mem/ruby/libruby.hh" #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/common/Consumer.hh"
#include "mem/ruby/tester/EventQueue_Tester.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh"
#include "mem/protocol/SpecifiedGeneratorType.hh" #include "mem/protocol/SpecifiedGeneratorType.hh"
//class DMAGenerator; //class DMAGenerator;
class DeterministicDriver : public Driver_Tester, public Consumer { class DeterministicDriver : public Driver, public Consumer {
public: public:
friend class DetermGETXGenerator; friend class DetermGETXGenerator;
friend class DetermSeriesGETSGenerator; friend class DetermSeriesGETSGenerator;
@ -62,7 +90,7 @@ public:
// Destructor // Destructor
~DeterministicDriver(); ~DeterministicDriver();
// Public Methods // Public Methods
void go(); void go();
bool isStoreReady(NodeID node); bool isStoreReady(NodeID node);
@ -100,7 +128,7 @@ private:
bool isAddrReady(NodeID node, Vector<NodeID> addr_vector, Address addr); bool isAddrReady(NodeID node, Vector<NodeID> addr_vector, Address addr);
void setNextAddr(NodeID node, Address addr, Vector<NodeID>& addr_vector); void setNextAddr(NodeID node, Address addr, Vector<NodeID>& addr_vector);
// Data Members (m_ prefix) // Data Members (m_ prefix)
Vector<Time> m_last_progress_vector; Vector<Time> m_last_progress_vector;
Vector<SpecifiedGenerator*> m_generator_vector; Vector<SpecifiedGenerator*> m_generator_vector;
@ -114,14 +142,14 @@ private:
int m_stores_completed; int m_stores_completed;
// enforces the previous node to have a certain # of completions // enforces the previous node to have a certain # of completions
// before next node starts // before next node starts
map <int64_t, pair <int, Address> > requests; map <int64_t, pair <int, Address> > requests;
Time m_think_time; Time m_think_time;
Time m_wait_time; Time m_wait_time;
int m_tester_length; int m_tester_length;
int m_num_procs; int m_num_procs;
RubyEventQueue * eventQueue; RubyEventQueue * eventQueue;
int m_numCompletionsPerNode; int m_numCompletionsPerNode;
Histogram m_load_latency; Histogram m_load_latency;
Histogram m_store_latency; Histogram m_store_latency;
@ -135,7 +163,7 @@ ostream& operator<<(ostream& out, const DeterministicDriver& obj);
// ******************* Definitions ******************* // ******************* Definitions *******************
// Output operator definition // Output operator definition
extern inline extern inline
ostream& operator<<(ostream& out, const DeterministicDriver& obj) ostream& operator<<(ostream& out, const DeterministicDriver& obj)
{ {
obj.print(out); obj.print(out);

View file

@ -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() {
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,40 +1,67 @@
/* /*
* Copyright (c) 1999-2005 Mark D. Hill and David A. Wood Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
* *
*/ */
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Global_Tester.hh" #include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/tester/RaceyDriver.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" #include "mem/ruby/tester/RaceyPseudoThread.hh"
RaceyDriver::RaceyDriver(int num_procs, int tester_length) 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]; uint8_t * data = new uint8_t[4];
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
data[i] = requests[request_id].second.data[i]; data[i] = requests[request_id].second.data[i];
} }
requests[request_id].second.data; requests[request_id].second.data;
m_racey_pseudo_threads[proc]->performCallback(proc, address, data); m_racey_pseudo_threads[proc]->performCallback(proc, address, data);
requests.erase(request_id); requests.erase(request_id);

View file

@ -1,31 +1,58 @@
/* /*
* Copyright (c) 1999-2005 Mark D. Hill and David A. Wood Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
@ -38,8 +65,9 @@
#ifndef RACEYDRIVER_H #ifndef RACEYDRIVER_H
#define RACEYDRIVER_H #define RACEYDRIVER_H
#include "mem/ruby/tester/Global_Tester.hh" #include "mem/ruby/common/Global.hh"
#include "mem/ruby/tester/Driver_Tester.hh" #include "mem/ruby/tester/Tester_Globals.hh"
#include "mem/ruby/common/Driver.hh"
#include "mem/ruby/tester/RaceyPseudoThread.hh" #include "mem/ruby/tester/RaceyPseudoThread.hh"
#include <map> #include <map>
#include "mem/ruby/libruby.hh" #include "mem/ruby/libruby.hh"
@ -52,7 +80,7 @@ struct address_data {
uint8_t * data; uint8_t * data;
}; };
class RaceyDriver : public Driver_Tester, public Consumer { class RaceyDriver : public Driver, public Consumer {
public: public:
friend class RaceyPseudoThread; friend class RaceyPseudoThread;
// Constructors // Constructors
@ -92,13 +120,13 @@ public:
} }
void print(ostream& out) const; void print(ostream& out) const;
private: private:
// Private copy constructor and assignment operator // Private copy constructor and assignment operator
RaceyDriver(const RaceyDriver& obj); RaceyDriver(const RaceyDriver& obj);
RaceyDriver& operator=(const RaceyDriver& obj); RaceyDriver& operator=(const RaceyDriver& obj);
// Data Members (m_ prefix) // Data Members (m_ prefix)
Vector<RaceyPseudoThread*> m_racey_pseudo_threads; Vector<RaceyPseudoThread*> m_racey_pseudo_threads;
int m_done_counter; int m_done_counter;
@ -116,7 +144,7 @@ ostream& operator<<(ostream& out, const RaceyDriver& obj);
// ******************* Definitions ******************* // ******************* Definitions *******************
// Output operator definition // Output operator definition
extern inline extern inline
ostream& operator<<(ostream& out, const RaceyDriver& obj) ostream& operator<<(ostream& out, const RaceyDriver& obj)
{ {
obj.print(out); obj.print(out);

View file

@ -1,33 +1,23 @@
/* /*
* Copyright (c) 1999 Mark D. Hill and David A. Wood * Copyright (c) 1999 by Mark Hill and David Wood for the Wisconsin
* All rights reserved. * Multifacet Project. ALL RIGHTS RESERVED.
* *
* Redistribution and use in source and binary forms, with or without * ##HEADER##
* 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 * This software is furnished under a license and may be used and
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * copied only in accordance with the terms of such license and the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * inclusion of the above copyright notice. This software or any
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * other copies thereof or any derivative works may not be provided or
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * otherwise made available to any other persons. Title to and
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * ownership of the software is retained by Mark Hill and David Wood.
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * Any use of this software must include the above copyright notice.
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THIS SOFTWARE IS PROVIDED "AS IS". THE LICENSOR MAKES NO
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * WARRANTIES ABOUT ITS CORRECTNESS OR PERFORMANCE.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */
*/
/* /*
* Description: see RaceyPseudoThread.hh * Description: see RaceyPseudoThread.h
*/ */
#include "mem/ruby/tester/RaceyPseudoThread.hh" #include "mem/ruby/tester/RaceyPseudoThread.hh"
@ -225,18 +215,18 @@ void RaceyPseudoThread::load_sig(unsigned index) {
// pc is zero, problem? // 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)); 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()); ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end());
struct address_data request_data; struct address_data request_data;
request_data.address = Address(sig(index)); request_data.address = Address(sig(index));
request_data.data = read_data; request_data.data = read_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_LD, /*sequencer()->makeRequest(CacheMsg(Address(sig(index)), Address(sig(index)), CacheRequestType_LD,
Address(physical_address_t(1)), Address(physical_address_t(1)),
AccessModeType_UserMode, 4, AccessModeType_UserMode, 4,
PrefetchBit_No, 0, Address(0), PrefetchBit_No, 0, Address(0),
0, 0 , false)); */ 0, 0 , false)); */
} }
@ -252,18 +242,18 @@ void RaceyPseudoThread::load_m(unsigned index) {
// pc is zero, problem? // 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)); 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()); ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end());
struct address_data request_data; struct address_data request_data;
request_data.address = Address(m(index)); request_data.address = Address(m(index));
request_data.data = read_data; request_data.data = read_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_LD, /*sequencer()->makeRequest(CacheMsg(Address(m(index)), Address(m(index)), CacheRequestType_LD,
Address(physical_address_t(1)), Address(physical_address_t(1)),
AccessModeType_UserMode, 4, AccessModeType_UserMode, 4,
PrefetchBit_No, 0, Address(0), PrefetchBit_No, 0, Address(0),
0, 0, false)); */ 0, 0, false)); */
} }
@ -273,6 +263,8 @@ void RaceyPseudoThread::store_sig(unsigned index, unsigned value) {
m_read = false; m_read = false;
m_value = value; m_value = value;
uint8_t * write_data = new uint8_t[4]; uint8_t * write_data = new uint8_t[4];
uint8_t * read_data = new uint8_t[4];
memcpy(write_data, &value, 4); memcpy(write_data, &value, 4);
@ -282,13 +274,15 @@ void RaceyPseudoThread::store_sig(unsigned index, unsigned value) {
// pc is zero, problem? // 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), 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()); ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end());
struct address_data request_data; struct address_data request_data;
request_data.address = Address(sig(index)); request_data.address = Address(sig(index));
request_data.data = write_data; 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, /*sequencer()->makeRequest(CacheMsg(Address(sig(index)), Address(sig(index)), CacheRequestType_ST,
Address(physical_address_t(1)), Address(physical_address_t(1)),
@ -303,6 +297,7 @@ void RaceyPseudoThread::store_m(unsigned index, unsigned value) {
m_read = false; m_read = false;
m_value = value; m_value = value;
uint8_t * write_data = new uint8_t[4]; uint8_t * write_data = new uint8_t[4];
uint8_t * read_data = new uint8_t[4];
memcpy(write_data, &value, 4); memcpy(write_data, &value, 4);
char name [] = "Sequencer_"; char name [] = "Sequencer_";
@ -311,13 +306,15 @@ void RaceyPseudoThread::store_m(unsigned index, unsigned value) {
// pc is zero, problem? // 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), 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()); ASSERT(m_driver.requests.find(request_id) == m_driver.requests.end());
struct address_data request_data; struct address_data request_data;
request_data.address = Address(m(index)); request_data.address = Address(m(index));
request_data.data = write_data; 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, /*sequencer()->makeRequest(CacheMsg(Address(m(index)), Address(m(index)), CacheRequestType_ST,
Address(physical_address_t(1)), Address(physical_address_t(1)),

View file

@ -1,30 +1,20 @@
/* /*
* Copyright (c) 1999 Mark D. Hill and David A. Wood * Copyright (c) 1999 by Mark Hill and David Wood for the Wisconsin
* All rights reserved. * Multifacet Project. ALL RIGHTS RESERVED.
* *
* Redistribution and use in source and binary forms, with or without * ##HEADER##
* 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 * This software is furnished under a license and may be used and
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * copied only in accordance with the terms of such license and the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * inclusion of the above copyright notice. This software or any
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * other copies thereof or any derivative works may not be provided or
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * otherwise made available to any other persons. Title to and
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * ownership of the software is retained by Mark Hill and David Wood.
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * Any use of this software must include the above copyright notice.
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THIS SOFTWARE IS PROVIDED "AS IS". THE LICENSOR MAKES NO
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * WARRANTIES ABOUT ITS CORRECTNESS OR PERFORMANCE.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */
*/
/* /*
* Description: This implements a pseudo racey thread which drives ruby timing * Description: This implements a pseudo racey thread which drives ruby timing
@ -35,10 +25,11 @@
#ifndef RACEYPSEUDOTHREAD_H #ifndef RACEYPSEUDOTHREAD_H
#define 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/common/Consumer.hh"
#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/NodeID.hh"
#include "Address_Tester.hh" #include "mem/ruby/common/Address.hh"
#include "mem/ruby/libruby.hh" #include "mem/ruby/libruby.hh"
class RaceyDriver; class RaceyDriver;
@ -69,7 +60,7 @@ public:
// Destructor // Destructor
~RaceyPseudoThread(); ~RaceyPseudoThread();
// Public Methods // Public Methods
void performCallback(int proc, Address address, uint8_t * data); void performCallback(int proc, Address address, uint8_t * data);
@ -106,7 +97,7 @@ private:
// Private copy constructor and assignment operator // Private copy constructor and assignment operator
RaceyPseudoThread(const RaceyPseudoThread& obj); RaceyPseudoThread(const RaceyPseudoThread& obj);
RaceyPseudoThread& operator=(const RaceyPseudoThread& obj); RaceyPseudoThread& operator=(const RaceyPseudoThread& obj);
// Data Members (m_ prefix) // Data Members (m_ prefix)
RaceyDriver& m_driver; RaceyDriver& m_driver;
NodeID m_proc_id; NodeID m_proc_id;
@ -139,7 +130,7 @@ ostream& operator<<(ostream& out, const RaceyPseudoThread& obj);
// ******************* Definitions ******************* // ******************* Definitions *******************
// Output operator definition // Output operator definition
extern inline extern inline
ostream& operator<<(ostream& out, const RaceyPseudoThread& obj) ostream& operator<<(ostream& out, const RaceyPseudoThread& obj)
{ {
obj.print(out); obj.print(out);

View file

@ -1,31 +1,58 @@
/* /*
* Copyright (c) 1999-2005 Mark D. Hill and David A. Wood Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$

View file

@ -1,46 +1,74 @@
/* /*
* Copyright (c) 1999-2005 Mark D. Hill and David A. Wood Copyright (C) 1999-2005 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Ross Dickson, Pacia Harper, Milo Martin, Michael Marty,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Carl Mauer, Kevin Moore, Manoj Plakal, Daniel Sorin, Min Xu, and
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
* *
* Description: * Description:
* *
*/ */
#ifndef SPECIFIEDGENERATOR_H #ifndef SPECIFIEDGENERATOR_H
#define 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/common/Consumer.hh"
#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/NodeID.hh"
#include "Address_Tester.hh" #include "mem/ruby/common/Address.hh"
class SpecifiedGenerator : public Consumer { class SpecifiedGenerator : public Consumer {
public: public:
@ -49,7 +77,7 @@ public:
// Destructor // Destructor
virtual ~SpecifiedGenerator() = 0; virtual ~SpecifiedGenerator() = 0;
// Public Methods // Public Methods
virtual void wakeup() = 0; virtual void wakeup() = 0;
virtual void performCallback(NodeID proc, Address address) = 0; virtual void performCallback(NodeID proc, Address address) = 0;

View file

@ -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;

View file

@ -1,31 +1,58 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$

View file

@ -1,42 +1,70 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
* *
* Description: * Description:
* *
*/ */
#ifndef MAIN_H #ifndef MAIN_H
#define 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 #endif //MAIN_H

View file

@ -1,31 +1,58 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
@ -39,7 +66,9 @@ using namespace std;
#include "getopt.hh" #include "getopt.hh"
#include "mem/ruby/tester/DeterministicDriver.hh" #include "mem/ruby/tester/DeterministicDriver.hh"
#include "mem/ruby/tester/RaceyDriver.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 <string>
#include <map> #include <map>
@ -53,37 +82,37 @@ using namespace std;
#include "mem/ruby/libruby.hh" #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 // 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 set_defaults();
static void parseOptions(int argc, char **argv); static void parseOptions(int argc, char **argv);
static void usageInstructions(); static void usageInstructions();
static void checkArg(char ch); static void checkArg(char ch);
static void tester_initialize(int argc, char **argv); static void tester_initialize(int argc, char **argv);
static void tester_playback_trace();
static void tester_destroy(); static void tester_destroy();
static void hit_callback(int64_t request_id); static void hit_callback(int64_t request_id);
// Tester variables // Tester variables
string driver_type; string driver_type;
string generator_type; string generator_type;
Driver_Tester * m_driver_ptr; Driver * m_driver_ptr;
int g_tester_length; int g_tester_length;
int num_completions; int num_completions;
Time g_think_time; Time g_think_time;
Time g_wait_time; Time g_wait_time;
int num_procs; int num_procs;
static string trace_filename;
// Debugger variables bool replaying;
Debug * debug_ptr;
string g_debug_verbosity_string;
string g_debug_filter_string;
string g_debug_output_filename;
Time g_debug_start_time;
void tester_main(int argc, char **argv) void tester_main(int argc, char **argv)
{ {
tester_initialize(argc, argv); tester_initialize(argc, argv);
if (trace_filename != "") {
// playback a trace (for multicast-mask prediction)
replaying = true;
tester_playback_trace();
}
tester_destroy(); tester_destroy();
} }
@ -117,7 +146,7 @@ vector<string> getPorts(const char* cfg_script, int cfg_script_argc, char* cfg_s
perror("Error Creating Pipe"); perror("Error Creating Pipe");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
pid = fork(); pid = fork();
if (pid == -1){ if (pid == -1){
perror("Error forking"); perror("Error forking");
@ -139,7 +168,7 @@ vector<string> getPorts(const char* cfg_script, int cfg_script_argc, char* cfg_s
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else { } else {
close(fd[1]); close(fd[1]);
int child_status; int child_status;
if (wait(&child_status) == -1) { 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) { if (child_status != EXIT_SUCCESS) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
char buf[100]; char buf[100];
int bytes_read; int bytes_read;
while( (bytes_read = read(fd[0], buf, 100)) > 0 ) { while( (bytes_read = read(fd[0], buf, 100)) > 0 ) {
for (int i=0;i<bytes_read;i++) { for (int i=0;i<bytes_read;i++) {
cfg_output << buf[i]; cfg_output << buf[i];
} }
} }
assert(bytes_read == 0); 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++) 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)); 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") { if (driver_type == "Deterministic") {
m_driver_ptr = new DeterministicDriver(generator_type, num_completions, num_procs, g_think_time, g_wait_time, g_tester_length); 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() void tester_destroy()
@ -213,7 +252,9 @@ void tester_destroy()
void hit_callback(int64_t request_id) 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'}, {"help", no_argument, NULL, 'h'},
{"number of processors", required_argument, NULL, 'p'}, {"number of processors", required_argument, NULL, 'p'},
{"test run length", required_argument, NULL, 'l'}, {"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 think time", required_argument, NULL, 'k'},
{"generator wait time", required_argument, NULL, 'w'}, {"generator wait time", required_argument, NULL, 'w'},
{"driver type", required_argument, NULL, 'd'}, {"driver type", required_argument, NULL, 'd'},
{"generator type", required_argument, NULL, 'g'}, {"generator type", required_argument, NULL, 'g'},
{"num completions before pass", required_argument, NULL, 'n'}, {"num completions before pass", required_argument, NULL, 'n'},
{"test tracer", required_argument, NULL, 'z'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
// This is awkward and temporary, need the defaults config, and also need functions to // This is awkward and temporary, need the defaults config, and also need functions to
// just lookup a parameter in the configuration file // 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 // set values at run-time
static void set_defaults() { static void set_defaults() {
replaying = false;
g_tester_length = 0; g_tester_length = 0;
g_think_time = 5; g_think_time = 10;
g_wait_time = 20; g_wait_time = 10;
num_procs = 1; num_procs = 1;
trace_filename = "";
num_completions = 1; num_completions = 1;
driver_type = "Deterministic"; driver_type = "Deterministic";
generator_type = "DetermInvGenerator"; generator_type = "DetermSeriesGETSGenerator";
g_debug_verbosity_string = "none";
g_debug_filter_string = "none";
g_debug_output_filename = "none";
g_debug_start_time = 0;
} }
static void parseOptions(int argc, char **argv) static void parseOptions(int argc, char **argv)
@ -289,15 +325,6 @@ static void parseOptions(int argc, char **argv)
cout << " number of processors = " << optarg << endl; cout << " number of processors = " << optarg << endl;
num_procs = atoi( optarg ); num_procs = atoi( optarg );
break; 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': { case 'l': {
checkArg(c); checkArg(c);
g_tester_length = atoi(optarg); g_tester_length = atoi(optarg);
@ -306,25 +333,6 @@ static void parseOptions(int argc, char **argv)
usageInstructions(); usageInstructions();
} }
break; 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': { case 'k': {
checkArg(c); checkArg(c);
@ -336,11 +344,6 @@ static void parseOptions(int argc, char **argv)
g_wait_time = atoi(optarg); g_wait_time = atoi(optarg);
break; break;
} }
case 'o':
checkArg(c);
cout << " output file = " << optarg << endl;
g_debug_output_filename = strdup( optarg );
break;
case 'd': case 'd':
checkArg(c); checkArg(c);
cout << " driver type = " << optarg << endl; cout << " driver type = " << optarg << endl;
@ -356,6 +359,12 @@ static void parseOptions(int argc, char **argv)
cout << " num completions before pass = " << optarg << endl; cout << " num completions before pass = " << optarg << endl;
num_completions = atoi( optarg ); num_completions = atoi( optarg );
break; break;
case 'z':
checkArg(c);
trace_filename = string(optarg);
cout << " tracefile = " << trace_filename << endl;
break;
default: default:
cerr << "parameter '" << c << "' unknown" << endl; cerr << "parameter '" << c << "' unknown" << endl;
usageInstructions(); usageInstructions();
@ -384,7 +393,7 @@ static void usageInstructions()
} }
cerr << endl; cerr << endl;
debug_ptr->usageInstructions(); g_debug_ptr->usageInstructions();
cerr << endl; cerr << endl;
exit(1); exit(1);

View file

@ -1,43 +1,71 @@
/* /*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood Copyright (C) 1999-2008 by Mark D. Hill and David A. Wood for the
* All rights reserved. Wisconsin Multifacet Project. Contact: gems@cs.wisc.edu
* http://www.cs.wisc.edu/gems/
* 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; This file is part of the Ruby Multiprocessor Memory System Simulator,
* redistributions in binary form must reproduce the above copyright a component of the Multifacet GEMS (General Execution-driven
* notice, this list of conditions and the following disclaimer in the Multiprocessor Simulator) software toolset originally developed at
* documentation and/or other materials provided with the distribution; the University of Wisconsin-Madison.
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from Ruby was originally developed primarily by Milo Martin and Daniel
* this software without specific prior written permission. Sorin with contributions from Ross Dickson, Carl Mauer, and Manoj
* Plakal.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT Substantial further development of Multifacet GEMS at the
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR University of Wisconsin was performed by Alaa Alameldeen, Brad
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT Beckmann, Jayaram Bobba, Ross Dickson, Dan Gibson, Pacia Harper,
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, Derek Hower, Milo Martin, Michael Marty, Carl Mauer, Michelle Moravan,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT Kevin Moore, Andrew Phelps, Manoj Plakal, Daniel Sorin, Haris Volos,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, Min Xu, and Luke Yen.
* 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 If your use of this software contributes to a published paper, we
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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$ * $Id$
* *
* Description: * Description:
* *
*/ */
#ifndef TESTFRAMEWORK_H #ifndef TESTFRAMEWORK_H
#define 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); void tester_main(int argc, char **argv);

View file

@ -231,7 +231,7 @@ RubyMemory::Port::recvTiming(PacketPtr pkt)
} else if (pkt->isWrite()) { } else if (pkt->isWrite()) {
type = RubyRequestType_ST; type = RubyRequestType_ST;
} else if (pkt->isReadWrite()) { } else if (pkt->isReadWrite()) {
type = RubyRequestType_RMW; // type = RubyRequestType_RMW;
} }
RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(), RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),

View file

@ -282,13 +282,16 @@ void StateMachine::printControllerH(ostream& out, string component)
out << " void printStats(ostream& out) const { s_profiler.dumpStats(out); }" << endl; out << " void printStats(ostream& out) const { s_profiler.dumpStats(out); }" << endl;
out << " void clearStats() { s_profiler.clearStats(); }" << endl; out << " void clearStats() { s_profiler.clearStats(); }" << endl;
out << "private:" << endl; out << "private:" << endl;
//added by SS //added by SS
// found_to_mem = 0; // found_to_mem = 0;
std::vector<std::string*>::const_iterator it; std::vector<std::string*>::const_iterator it;
for(it=m_latency_vector.begin();it!=m_latency_vector.end();it++){ for(it=m_latency_vector.begin();it!=m_latency_vector.end();it++){
out << " int m_" << (*it)->c_str() << ";" << endl; 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 << " int m_number_of_TBEs;" << endl;
out << " TransitionResult doTransition(" << component << "_Event event, " << component out << " TransitionResult doTransition(" << component << "_Event event, " << component
@ -395,7 +398,11 @@ void StateMachine::printControllerC(ostream& out, string component)
<< "_Controller(const string & name)" << endl; << "_Controller(const string & name)" << endl;
out << " : m_name(name)" << endl; out << " : m_name(name)" << endl;
out << "{ " << 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++) { for(int i=0; i < numObjects(); i++) {
const Var* var = m_objs[i]; const Var* var = m_objs[i];
if ( var->cIdent().find("mandatoryQueue") != string::npos) 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 << c_code_string;
out << "}" << endl; out << "}" << endl;
@ -772,14 +796,100 @@ void StateMachine::printCWakeup(ostream& out, string component)
out << " }" << endl; out << " }" << endl;
// InPorts // InPorts
//
// 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()
<< endl;
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++) { for(int i=0; i < m_in_ports.size(); i++) {
const Var* port = m_in_ports[i]; const Var* port = m_in_ports[i];
assert(port->existPair("c_code_in_port")); // don't print out mandatory queue twice
out << " // " if (i != j) {
<< component << "InPort " << port->toString() if (strncmp(component.c_str(), "L1Cache", 7) == 0) {
<< endl; if (port->toString().find("forwardRequestNetwork_in") != string::npos) {
out << port->lookupPair("c_code_in_port"); out << " bool postpone = false;" << endl;
out << 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 << " break; // If we got this far, we have nothing left todo" << endl;

0
tests/quick/40.m5threads-test-atomic/test.py Normal file → Executable file
View file