diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2012-01-07 02:10:34 -0800 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2012-01-07 02:10:34 -0800 |
commit | 36a822f08e88483b41af214ace4fd3dccf3aa8cb (patch) | |
tree | d7c4c08590459d967a1d7638b02c586911826953 /src | |
parent | 85424bef192c02a47c0d46c2d99ac0a5d6e55a99 (diff) | |
parent | f171a29118e1d80c04c72d2fb5f024fed4fb62af (diff) | |
download | gem5-36a822f08e88483b41af214ace4fd3dccf3aa8cb.tar.xz |
Merge with main repository.
Diffstat (limited to 'src')
137 files changed, 1784 insertions, 1055 deletions
diff --git a/src/SConscript b/src/SConscript index 117f21394..0a4bb57f4 100755 --- a/src/SConscript +++ b/src/SConscript @@ -51,7 +51,7 @@ Export('env') build_env = [(opt, env[opt]) for opt in export_vars] -from m5.util import code_formatter +from m5.util import code_formatter, compareVersions ######################################################################## # Code for adding source files of various types @@ -449,7 +449,13 @@ sys.meta_path.remove(importer) sim_objects = m5.SimObject.allClasses all_enums = m5.params.allEnums -all_params = {} +# Find param types that need to be explicitly wrapped with swig. +# These will be recognized because the ParamDesc will have a +# swig_decl() method. Most param types are based on types that don't +# need this, either because they're based on native types (like Int) +# or because they're SimObjects (which get swigged independently). +# For now the only things handled here are VectorParam types. +params_to_swig = {} for name,obj in sorted(sim_objects.iteritems()): for param in obj._params.local.values(): # load the ptype attribute now because it depends on the @@ -461,8 +467,8 @@ for name,obj in sorted(sim_objects.iteritems()): if not hasattr(param, 'swig_decl'): continue pname = param.ptype_str - if pname not in all_params: - all_params[pname] = param + if pname not in params_to_swig: + params_to_swig[pname] = param ######################################################################## # @@ -523,24 +529,23 @@ PySource('m5', 'python/m5/info.py') # Create all of the SimObject param headers and enum headers # -def createSimObjectParam(target, source, env): +def createSimObjectParamStruct(target, source, env): assert len(target) == 1 and len(source) == 1 name = str(source[0].get_contents()) obj = sim_objects[name] code = code_formatter() - obj.cxx_decl(code) + obj.cxx_param_decl(code) code.write(target[0].abspath) -def createSwigParam(target, source, env): +def createParamSwigWrapper(target, source, env): assert len(target) == 1 and len(source) == 1 name = str(source[0].get_contents()) - param = all_params[name] + param = params_to_swig[name] code = code_formatter() - code('%module(package="m5.internal") $0_${name}', param.file_ext) param.swig_decl(code) code.write(target[0].abspath) @@ -554,7 +559,7 @@ def createEnumStrings(target, source, env): obj.cxx_def(code) code.write(target[0].abspath) -def createEnumParam(target, source, env): +def createEnumDecls(target, source, env): assert len(target) == 1 and len(source) == 1 name = str(source[0].get_contents()) @@ -564,25 +569,25 @@ def createEnumParam(target, source, env): obj.cxx_decl(code) code.write(target[0].abspath) -def createEnumSwig(target, source, env): +def createEnumSwigWrapper(target, source, env): assert len(target) == 1 and len(source) == 1 name = str(source[0].get_contents()) obj = all_enums[name] code = code_formatter() - code('''\ -%module(package="m5.internal") enum_$name + obj.swig_decl(code) + code.write(target[0].abspath) -%{ -#include "enums/$name.hh" -%} +def createSimObjectSwigWrapper(target, source, env): + name = source[0].get_contents() + obj = sim_objects[name] -%include "enums/$name.hh" -''') + code = code_formatter() + obj.swig_decl(code) code.write(target[0].abspath) -# Generate all of the SimObject param struct header files +# Generate all of the SimObject param C++ struct header files params_hh_files = [] for name,simobj in sorted(sim_objects.iteritems()): py_source = PySource.modules[simobj.__module__] @@ -591,16 +596,16 @@ for name,simobj in sorted(sim_objects.iteritems()): hh_file = File('params/%s.hh' % name) params_hh_files.append(hh_file) env.Command(hh_file, Value(name), - MakeAction(createSimObjectParam, Transform("SO PARAM"))) + MakeAction(createSimObjectParamStruct, Transform("SO PARAM"))) env.Depends(hh_file, depends + extra_deps) -# Generate any parameter header files needed +# Generate any needed param SWIG wrapper files params_i_files = [] -for name,param in all_params.iteritems(): - i_file = File('python/m5/internal/%s_%s.i' % (param.file_ext, name)) +for name,param in params_to_swig.iteritems(): + i_file = File('python/m5/internal/%s.i' % (param.swig_module_name())) params_i_files.append(i_file) env.Command(i_file, Value(name), - MakeAction(createSwigParam, Transform("SW PARAM"))) + MakeAction(createParamSwigWrapper, Transform("SW PARAM"))) env.Depends(i_file, depends) SwigSource('m5.internal', i_file) @@ -617,54 +622,22 @@ for name,enum in sorted(all_enums.iteritems()): hh_file = File('enums/%s.hh' % name) env.Command(hh_file, Value(name), - MakeAction(createEnumParam, Transform("EN PARAM"))) + MakeAction(createEnumDecls, Transform("ENUMDECL"))) env.Depends(hh_file, depends + extra_deps) i_file = File('python/m5/internal/enum_%s.i' % name) env.Command(i_file, Value(name), - MakeAction(createEnumSwig, Transform("ENUMSWIG"))) + MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG"))) env.Depends(i_file, depends + extra_deps) SwigSource('m5.internal', i_file) -def buildParam(target, source, env): - name = source[0].get_contents() - obj = sim_objects[name] - class_path = obj.cxx_class.split('::') - classname = class_path[-1] - namespaces = class_path[:-1] - params = obj._params.local.values() - - code = code_formatter() - - code('%module(package="m5.internal") param_$name') - code() - code('%{') - code('#include "params/$obj.hh"') - for param in params: - param.cxx_predecls(code) - code('%}') - code() - - for param in params: - param.swig_predecls(code) - - code() - if obj._base: - code('%import "python/m5/internal/param_${{obj._base}}.i"') - code() - obj.swig_objdecls(code) - code() - - code('%include "params/$obj.hh"') - - code.write(target[0].abspath) - +# Generate SimObject SWIG wrapper files for name in sim_objects.iterkeys(): - params_file = File('python/m5/internal/param_%s.i' % name) - env.Command(params_file, Value(name), - MakeAction(buildParam, Transform("BLDPARAM"))) - env.Depends(params_file, depends) - SwigSource('m5.internal', params_file) + i_file = File('python/m5/internal/param_%s.i' % name) + env.Command(i_file, Value(name), + MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG"))) + env.Depends(i_file, depends) + SwigSource('m5.internal', i_file) # Generate the main swig init file def makeEmbeddedSwigInit(target, source, env): @@ -687,7 +660,7 @@ for swig in SwigSource.all: MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} ' '-o ${TARGETS[0]} $SOURCES', Transform("SWIG"))) cc_file = str(swig.tnode) - init_file = '%s/init_%s.cc' % (dirname(cc_file), basename(cc_file)) + init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file)) env.Command(init_file, Value(swig.module), MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW"))) Source(init_file, **swig.guards) @@ -878,6 +851,9 @@ def makeEnv(label, objsfx, strip = False, **kwargs): swig_env.Append(CCFLAGS='-Wno-uninitialized') swig_env.Append(CCFLAGS='-Wno-sign-compare') swig_env.Append(CCFLAGS='-Wno-parentheses') + if compareVersions(env['GCC_VERSION'], '4.6.0') != -1: + swig_env.Append(CCFLAGS='-Wno-unused-label') + swig_env.Append(CCFLAGS='-Wno-unused-but-set-variable') werror_env = new_env.Clone() werror_env.Append(CCFLAGS='-Werror') @@ -904,9 +880,10 @@ def makeEnv(label, objsfx, strip = False, **kwargs): return obj - sources = Source.get(main=False, skip_lib=False) - static_objs = [ make_obj(s, True) for s in sources ] - shared_objs = [ make_obj(s, False) for s in sources ] + static_objs = \ + [ make_obj(s, True) for s in Source.get(main=False, skip_lib=False) ] + shared_objs = \ + [ make_obj(s, False) for s in Source.get(main=False, skip_lib=False) ] static_date = make_obj(date_source, static=True, extra_deps=static_objs) static_objs.append(static_date) diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 9863a7370..4dcc58ffe 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -202,8 +202,6 @@ int break_ipl = -1; void ISA::setIpr(int idx, uint64_t val, ThreadContext *tc) { - uint64_t old; - if (tc->misspeculating()) return; @@ -255,10 +253,9 @@ ISA::setIpr(int idx, uint64_t val, ThreadContext *tc) case IPR_PALtemp23: // write entire quad w/ no side-effect - old = ipr[idx]; - ipr[idx] = val; if (tc->getKernelStats()) - tc->getKernelStats()->context(old, val, tc); + tc->getKernelStats()->context(ipr[idx], val, tc); + ipr[idx] = val; break; case IPR_DTB_PTE: diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa index ed5128204..f286be91c 100644 --- a/src/arch/alpha/isa/mem.isa +++ b/src/arch/alpha/isa/mem.isa @@ -388,7 +388,7 @@ def template MiscExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Addr EA; + Addr EA M5_VAR_USED; Fault fault = NoFault; %(fp_enable_check)s; diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index c728ce1fb..3304816c3 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -69,6 +69,7 @@ class AlphaLinux : public Linux /// For mmap(). static const unsigned TGT_MAP_ANONYMOUS = 0x10; + static const unsigned TGT_MAP_FIXED = 0x100; //@{ /// For getsysinfo(). diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 637fbe065..4a3079264 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -126,7 +126,7 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize) stack_min = roundDown(stack_min, pageSize); stack_size = stack_base - stack_min; // map memory - pTable->allocate(stack_min, roundUp(stack_size, pageSize)); + allocateMem(stack_min, roundUp(stack_size, pageSize)); // map out initial stack contents Addr argv_array_base = stack_min + intSize; // room for argc diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh index 0ee12973c..f0cad8289 100644 --- a/src/arch/alpha/tru64/tru64.hh +++ b/src/arch/alpha/tru64/tru64.hh @@ -64,6 +64,7 @@ class AlphaTru64 : public Tru64 /// For mmap(). static const unsigned TGT_MAP_ANONYMOUS = 0x10; + static const unsigned TGT_MAP_FIXED = 0x100; //@{ /// For getsysinfo(). diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa index 812338c30..0cb27d7f1 100644 --- a/src/arch/arm/isa/formats/fp.isa +++ b/src/arch/arm/isa/formats/fp.isa @@ -561,20 +561,22 @@ let {{ } } case 0xa: + if (q) + return new Unknown(machInst); if (b) { - return decodeNeonUSThreeReg<VpminD, VpminQ>( - q, u, size, machInst, vd, vn, vm); + return decodeNeonUSThreeUSReg<VpminD>( + u, size, machInst, vd, vn, vm); } else { - return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>( - q, u, size, machInst, vd, vn, vm); + return decodeNeonUSThreeUSReg<VpmaxD>( + u, size, machInst, vd, vn, vm); } case 0xb: if (b) { - if (u) { + if (u || q) { return new Unknown(machInst); } else { - return decodeNeonUThreeReg<NVpaddD, NVpaddQ>( - q, size, machInst, vd, vn, vm); + return decodeNeonUThreeUSReg<NVpaddD>( + size, machInst, vd, vn, vm); } } else { if (u) { @@ -1542,7 +1544,7 @@ let {{ else return new NVswpD<uint64_t>(machInst, vd, vm); case 0x1: - return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>( + return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>( q, size, machInst, vd, vm); case 0x2: return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa index f82858bbd..b701995f4 100644 --- a/src/arch/arm/isa/insts/fp.isa +++ b/src/arch/arm/isa/insts/fp.isa @@ -447,7 +447,7 @@ let {{ exec_output = "" singleSimpleCode = vfpEnabledCheckCode + ''' - FPSCR fpscr = (FPSCR) FpscrExc; + FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc; FpDest = %(op)s; ''' singleCode = singleSimpleCode + ''' @@ -457,7 +457,7 @@ let {{ "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)" singleUnaryOp = "unaryOp(fpscr, FpOp1, %(func)s, fpscr.fz, fpscr.rMode)" doubleCode = vfpEnabledCheckCode + ''' - FPSCR fpscr = (FPSCR) FpscrExc; + FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc; double dest = %(op)s; FpDestP0_uw = dblLow(dest); FpDestP1_uw = dblHi(dest); diff --git a/src/arch/arm/isa/insts/macromem.isa b/src/arch/arm/isa/insts/macromem.isa index 815d4c258..db36a3fff 100644 --- a/src/arch/arm/isa/insts/macromem.isa +++ b/src/arch/arm/isa/insts/macromem.isa @@ -563,15 +563,16 @@ let {{ let {{ exec_output = '' - for type in ('uint8_t', 'uint16_t', 'uint32_t'): + for typeSize in (8, 16, 32): for sRegs in 1, 2: - for dRegs in range(sRegs, 5): + for dRegs in range(sRegs, min(sRegs * 64 / typeSize + 1, 5)): for format in ("MicroUnpackNeon%(sRegs)dto%(dRegs)dUop", "MicroUnpackAllNeon%(sRegs)dto%(dRegs)dUop", "MicroPackNeon%(dRegs)dto%(sRegs)dUop"): Name = format % { "sRegs" : sRegs * 2, "dRegs" : dRegs * 2 } - substDict = { "class_name" : Name, "targs" : type } + substDict = { "class_name" : Name, + "targs" : "uint%d_t" % typeSize } exec_output += MicroNeonExecDeclare.subst(substDict) }}; diff --git a/src/arch/arm/isa/insts/neon.isa b/src/arch/arm/isa/insts/neon.isa index 9565ee14a..b1ad1eeb3 100644 --- a/src/arch/arm/isa/insts/neon.isa +++ b/src/arch/arm/isa/insts/neon.isa @@ -1616,10 +1616,8 @@ let {{ threeEqualRegInst("vadd", "NVaddD", "SimdAddOp", unsignedTypes, 2, vaddCode) threeEqualRegInst("vadd", "NVaddQ", "SimdAddOp", unsignedTypes, 4, vaddCode) - threeEqualRegInst("vpadd", "NVpaddD", "SimdAddOp", unsignedTypes, + threeEqualRegInst("vpadd", "NVpaddD", "SimdAddOp", smallUnsignedTypes, 2, vaddCode, pairwise=True) - threeEqualRegInst("vpadd", "NVpaddQ", "SimdAddOp", unsignedTypes, - 4, vaddCode, pairwise=True) vaddlwCode = ''' destElem = (BigElement)srcElem1 + (BigElement)srcElem2; ''' @@ -2110,11 +2108,9 @@ let {{ ''' threeRegLongInst("vmull", "Vmullp", "SimdMultOp", smallUnsignedTypes, vmullpCode) - threeEqualRegInst("vpmax", "VpmaxD", "SimdCmpOp", allTypes, 2, vmaxCode, pairwise=True) - threeEqualRegInst("vpmax", "VpmaxQ", "SimdCmpOp", allTypes, 4, vmaxCode, pairwise=True) + threeEqualRegInst("vpmax", "VpmaxD", "SimdCmpOp", smallTypes, 2, vmaxCode, pairwise=True) - threeEqualRegInst("vpmin", "VpminD", "SimdCmpOp", allTypes, 2, vminCode, pairwise=True) - threeEqualRegInst("vpmin", "VpminQ", "SimdCmpOp", allTypes, 4, vminCode, pairwise=True) + threeEqualRegInst("vpmin", "VpminD", "SimdCmpOp", smallTypes, 2, vminCode, pairwise=True) vqdmulhCode = ''' FPSCR fpscr = (FPSCR) FpscrQc; @@ -3137,8 +3133,10 @@ let {{ destReg.elements[i + 1] = mid; } ''' - twoRegMiscScramble("vtrn", "NVtrnD", "SimdAluOp", unsignedTypes, 2, vtrnCode) - twoRegMiscScramble("vtrn", "NVtrnQ", "SimdAluOp", unsignedTypes, 4, vtrnCode) + twoRegMiscScramble("vtrn", "NVtrnD", "SimdAluOp", + smallUnsignedTypes, 2, vtrnCode) + twoRegMiscScramble("vtrn", "NVtrnQ", "SimdAluOp", + smallUnsignedTypes, 4, vtrnCode) vuzpCode = ''' Element mid[eCount]; diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa index a00114409..a4a740f89 100644 --- a/src/arch/arm/isa/templates/mem.isa +++ b/src/arch/arm/isa/templates/mem.isa @@ -1112,7 +1112,7 @@ def template LoadRegConstructor {{ (IntRegIndex)_index) { %(constructor)s; - bool conditional = false; + bool conditional M5_VAR_USED = false; if (!(condCode == COND_AL || condCode == COND_UC)) { conditional = true; for (int x = 0; x < _numDestRegs; x++) { @@ -1166,7 +1166,7 @@ def template LoadImmConstructor {{ (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm) { %(constructor)s; - bool conditional = false; + bool conditional M5_VAR_USED = false; if (!(condCode == COND_AL || condCode == COND_UC)) { conditional = true; for (int x = 0; x < _numDestRegs; x++) { diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index 33e48fc93..40d586aaf 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -91,6 +91,7 @@ class ArmLinux : public Linux /// For mmap(). static const unsigned TGT_MAP_ANONYMOUS = 0x20; + static const unsigned TGT_MAP_FIXED = 0x10; //@{ /// For getrusage(). diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index f17749252..c65962d00 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -503,7 +503,7 @@ void ArmLinuxProcess::initState() { ArmLiveProcess::initState(); - pTable->allocate(commPage, PageBytes); + allocateMem(commPage, PageBytes); ThreadContext *tc = system->getThreadContext(contextIds[0]); uint8_t swiNeg1[] = { diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc index c3b02744e..aa5d7dfce 100644 --- a/src/arch/arm/process.cc +++ b/src/arch/arm/process.cc @@ -251,8 +251,7 @@ ArmLiveProcess::argsInit(int intSize, int pageSize) stack_size = stack_base - stack_min; // map memory - pTable->allocate(roundDown(stack_min, pageSize), - roundUp(stack_size, pageSize)); + allocateMem(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize)); // map out initial stack contents uint32_t sentry_base = stack_base - sentry_size; diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa index 25b470972..193f050de 100644 --- a/src/arch/mips/isa/decoder.isa +++ b/src/arch/mips/isa/decoder.isa @@ -497,8 +497,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: mttc1({{ uint64_t data = xc->readRegOtherThread(RD + FP_Base_DepTag); - data = insertBits(data, top_bit, - bottom_bit, Rt); + data = insertBits(data, MT_H ? 63 : 31, + MT_H ? 32 : 0, Rt); xc->setRegOtherThread(RD + FP_Base_DepTag, data); }}); @@ -532,7 +532,7 @@ decode OPCODE_HI default Unknown::unknown() { panic("FP Control Value (%d) " "Not Available. Ignoring " "Access to Floating Control " - "Status Register", FS); + "S""tatus Register", FS); } xc->setRegOtherThread(FLOATREG_FCSR + FP_Base_DepTag, data); }}); @@ -776,7 +776,6 @@ decode OPCODE_HI default Unknown::unknown() { bits(pageGrain, pageGrain.esp) == 1) { SP = 1; } - IndexReg index = Index; Ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP); }}); 0x06: tlbwr({{ @@ -842,7 +841,6 @@ decode OPCODE_HI default Unknown::unknown() { bits(pageGrain, pageGrain.esp) == 1) { SP = 1; } - IndexReg index = Index; Ptr->insertAt(newEntry, Random, SP); }}); diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa index 1944d69d3..41f94e129 100644 --- a/src/arch/mips/isa/formats/mt.isa +++ b/src/arch/mips/isa/formats/mt.isa @@ -107,7 +107,7 @@ def template ThreadRegisterExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Fault fault = NoFault; - int64_t data; + int64_t data M5_VAR_USED; %(op_decl)s; %(op_rd)s; @@ -126,17 +126,6 @@ def template ThreadRegisterExecute {{ } else if (vpeControl.targTC > mvpConf0.ptc) { data = -1; } else { - int top_bit = 0; - int bottom_bit = 0; - - if (MT_H == 1) { - top_bit = 63; - bottom_bit = 32; - } else { - top_bit = 31; - bottom_bit = 0; - } - %(code)s; } } else { @@ -203,10 +192,11 @@ def format MT_MFTR(code, *flags) {{ flags += ('IsNonSpeculative', ) # code = 'std::cerr << curTick() << \": T\" << xc->tcBase()->threadId() << \": Executing MT INST: ' + name + '\" << endl;\n' + code - code += 'if (MT_H == 1) {\n' - code += 'data = bits(data, top_bit, bottom_bit);\n' - code += '}\n' - code += 'Rd = data;\n' + code += ''' + if (MT_H) + data = bits(data, 63, 32); + Rd = data; + ''' iop = InstObjParams(name, Name, 'MTOp', code, flags) header_output = BasicDeclare.subst(iop) diff --git a/src/arch/mips/isa/includes.isa b/src/arch/mips/isa/includes.isa index 944254d90..d2e9c797e 100644 --- a/src/arch/mips/isa/includes.isa +++ b/src/arch/mips/isa/includes.isa @@ -52,7 +52,9 @@ output decoder {{ #include "arch/mips/faults.hh" #include "arch/mips/isa_traits.hh" #include "arch/mips/mt_constants.hh" +#include "arch/mips/pagetable.hh" #include "arch/mips/pra_constants.hh" +#include "arch/mips/tlb.hh" #include "arch/mips/utility.hh" #include "base/loader/symtab.hh" #include "base/cprintf.hh" diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index a2418cfb6..949cce8aa 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -65,6 +65,7 @@ class MipsLinux : public Linux /// For mmap(). static const unsigned TGT_MAP_ANONYMOUS = 0x800; + static const unsigned TGT_MAP_FIXED = 0x10; //@{ /// For getsysinfo(). diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index c62b60b98..5643ff18a 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -136,7 +136,7 @@ MipsLiveProcess::argsInit(int pageSize) stack_min = roundDown(stack_min, pageSize); stack_size = stack_base - stack_min; // map memory - pTable->allocate(stack_min, roundUp(stack_size, pageSize)); + allocateMem(stack_min, roundUp(stack_size, pageSize)); // map out initial stack contents IntType argv_array_base = stack_min + intSize; // room for argc diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc index 52e13dfc3..057fb5e76 100644 --- a/src/arch/mips/tlb.cc +++ b/src/arch/mips/tlb.cc @@ -129,7 +129,6 @@ int TLB::probeEntry(Addr vpn, uint8_t asn) const { // assume not found... - PTE *retval = NULL; int Ind = -1; PageTable::const_iterator i = lookupTable.find(vpn); if (i != lookupTable.end()) { @@ -144,7 +143,6 @@ TLB::probeEntry(Addr vpn, uint8_t asn) const if (((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid))) { // We have a VPN + ASID Match - retval = pte; Ind = index; break; } diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa index 0361ee998..a409eefac 100644 --- a/src/arch/power/isa/formats/mem.isa +++ b/src/arch/power/isa/formats/mem.isa @@ -123,7 +123,7 @@ def template LoadCompleteAcc {{ %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Addr EA; + Addr M5_VAR_USED EA; Fault fault = NoFault; %(op_decl)s; diff --git a/src/arch/power/linux/linux.hh b/src/arch/power/linux/linux.hh index 1bfc9cbd8..45ca048a0 100644 --- a/src/arch/power/linux/linux.hh +++ b/src/arch/power/linux/linux.hh @@ -127,6 +127,7 @@ class PowerLinux : public Linux /// For mmap(). static const unsigned TGT_MAP_ANONYMOUS = 0x20; + static const unsigned TGT_MAP_FIXED = 0x10; //@{ /// ioctl() command codes. diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index d12e3eab6..788c7cc0c 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -187,8 +187,7 @@ PowerLiveProcess::argsInit(int intSize, int pageSize) stack_size = stack_base - stack_min; // map memory - pTable->allocate(roundDown(stack_min, pageSize), - roundUp(stack_size, pageSize)); + allocateMem(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize)); // map out initial stack contents uint32_t sentry_base = stack_base - sentry_size; diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc index d9be7fa69..2148e875a 100644 --- a/src/arch/power/tlb.cc +++ b/src/arch/power/tlb.cc @@ -119,7 +119,6 @@ int TLB::probeEntry(Addr vpn,uint8_t asn) const { // assume not found... - PowerISA::PTE *retval = NULL; int Ind = -1; PageTable::const_iterator i = lookupTable.find(vpn); if (i != lookupTable.end()) { @@ -133,7 +132,6 @@ TLB::probeEntry(Addr vpn,uint8_t asn) const && (pte->G || (asn == pte->asid))) { // We have a VPN + ASID Match - retval = pte; Ind = index; break; } diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index d6eee8a4d..a77059181 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -326,8 +326,8 @@ let {{ ''' TruncateEA = ''' - if (!FullSystem) - EA = Pstate<3:> ? EA<31:0> : EA; + if (!FullSystem) + EA = Pstate<3:> ? EA<31:0> : EA; ''' }}; diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index 1f7567d43..8ac408812 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -77,6 +77,7 @@ class SparcLinux : public Linux static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x20; + static const unsigned TGT_MAP_FIXED = 0x10; typedef struct { int64_t uptime; /* Seconds since boot */ diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 3eee3d137..5c594dcbc 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -316,8 +316,7 @@ SparcLiveProcess::argsInit(int pageSize) stack_size = stack_base - stack_min; // Allocate space for the stack - pTable->allocate(roundDown(stack_min, pageSize), - roundUp(stack_size, pageSize)); + allocateMem(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize)); // map out initial stack contents IntType sentry_base = stack_base - sentry_size; diff --git a/src/arch/sparc/solaris/solaris.hh b/src/arch/sparc/solaris/solaris.hh index df2565027..8222addab 100644 --- a/src/arch/sparc/solaris/solaris.hh +++ b/src/arch/sparc/solaris/solaris.hh @@ -59,6 +59,7 @@ class SparcSolaris : public Solaris static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x100; + static const unsigned TGT_MAP_FIXED = 0x10; }; #endif diff --git a/src/arch/x86/isa/insts/general_purpose/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/general_purpose/arithmetic/add_and_subtract.py index 9fc3e9035..68031c76c 100644 --- a/src/arch/x86/isa/insts/general_purpose/arithmetic/add_and_subtract.py +++ b/src/arch/x86/isa/insts/general_purpose/arithmetic/add_and_subtract.py @@ -67,18 +67,22 @@ def macroop ADD_P_I def macroop ADD_LOCKED_M_I { limm t2, imm + mfence ldstl t1, seg, sib, disp add t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop ADD_LOCKED_P_I { rdip t7 limm t2, imm + mfence ldstl t1, seg, riprel, disp add t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop ADD_M_R @@ -98,17 +102,21 @@ def macroop ADD_P_R def macroop ADD_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp add t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop ADD_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp add t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop ADD_R_M @@ -168,18 +176,22 @@ def macroop SUB_P_I def macroop SUB_LOCKED_M_I { limm t2, imm + mfence ldstl t1, seg, sib, disp sub t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop SUB_LOCKED_P_I { rdip t7 limm t2, imm + mfence ldstl t1, seg, riprel, disp sub t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop SUB_M_R @@ -199,17 +211,21 @@ def macroop SUB_P_R def macroop SUB_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp sub t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop SUB_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp sub t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop ADC_R_R @@ -243,18 +259,22 @@ def macroop ADC_P_I def macroop ADC_LOCKED_M_I { limm t2, imm + mfence ldstl t1, seg, sib, disp adc t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop ADC_LOCKED_P_I { rdip t7 limm t2, imm + mfence ldstl t1, seg, riprel, disp adc t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop ADC_M_R @@ -274,17 +294,21 @@ def macroop ADC_P_R def macroop ADC_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp adc t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop ADC_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp adc t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop ADC_R_M @@ -344,18 +368,22 @@ def macroop SBB_P_I def macroop SBB_LOCKED_M_I { limm t2, imm + mfence ldstl t1, seg, sib, disp sbb t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop SBB_LOCKED_P_I { rdip t7 limm t2, imm + mfence ldstl t1, seg, riprel, disp sbb t1, t1, t2, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop SBB_M_R @@ -375,17 +403,21 @@ def macroop SBB_P_R def macroop SBB_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp sbb t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop SBB_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp sbb t1, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop NEG_R @@ -410,16 +442,20 @@ def macroop NEG_P def macroop NEG_LOCKED_M { + mfence ldstl t1, seg, sib, disp sub t1, t0, t1, flags=(CF,OF,SF,ZF,AF,PF) stul t1, seg, sib, disp + mfence }; def macroop NEG_LOCKED_P { rdip t7 + mfence ldstl t1, seg, riprel, disp sub t1, t0, t1, flags=(CF,OF,SF,ZF,AF,PF) stul t1, seg, riprel, disp + mfence }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/arithmetic/increment_and_decrement.py b/src/arch/x86/isa/insts/general_purpose/arithmetic/increment_and_decrement.py index f27cd7008..515082d64 100644 --- a/src/arch/x86/isa/insts/general_purpose/arithmetic/increment_and_decrement.py +++ b/src/arch/x86/isa/insts/general_purpose/arithmetic/increment_and_decrement.py @@ -58,17 +58,21 @@ def macroop INC_P def macroop INC_LOCKED_M { + mfence ldstl t1, seg, sib, disp addi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) stul t1, seg, sib, disp + mfence }; def macroop INC_LOCKED_P { rdip t7 + mfence ldstl t1, seg, riprel, disp addi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) stul t1, seg, riprel, disp + mfence }; def macroop DEC_R @@ -93,16 +97,20 @@ def macroop DEC_P def macroop DEC_LOCKED_M { + mfence ldstl t1, seg, sib, disp subi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) stul t1, seg, sib, disp + mfence }; def macroop DEC_LOCKED_P { rdip t7 + mfence ldstl t1, seg, riprel, disp subi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) stul t1, seg, riprel, disp + mfence }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py index 66eb0f8a2..f69e1dc48 100644 --- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py +++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py @@ -114,10 +114,12 @@ def macroop BTC_LOCKED_M_I { limm t1, imm, dataSize=asz limm t4, 1 roli t4, t4, imm + mfence ldstl t1, seg, sib, disp sexti t0, t1, imm, flags=(CF,) xor t1, t1, t4 stul t1, seg, sib, disp + mfence }; def macroop BTC_LOCKED_P_I { @@ -125,10 +127,12 @@ def macroop BTC_LOCKED_P_I { limm t1, imm, dataSize=asz limm t4, 1 roli t4, t4, imm + mfence ldstl t1, seg, riprel, disp sexti t0, t1, imm, flags=(CF,) xor t1, t1, t4 stul t1, seg, riprel, disp + mfence }; def macroop BTC_R_R { @@ -168,10 +172,12 @@ def macroop BTC_LOCKED_M_R { lea t3, flatseg, [dsz, t3, base], dataSize=asz limm t4, 1 rol t4, t4, reg + mfence ldstl t1, seg, [scale, index, t3], disp sext t0, t1, reg, flags=(CF,) xor t1, t1, t4 stul t1, seg, [scale, index, t3], disp + mfence }; def macroop BTC_LOCKED_P_R { @@ -180,10 +186,12 @@ def macroop BTC_LOCKED_P_R { srai t3, t2, ldsz, dataSize=asz limm t4, 1 rol t4, t4, reg + mfence ldstl t1, seg, [dsz, t3, t7], disp sext t0, t1, reg, flags=(CF,) xor t1, t1, t4 stul t1, seg, [dsz, t3, t7], disp + mfence }; def macroop BTR_R_I { @@ -218,10 +226,12 @@ def macroop BTR_LOCKED_M_I { limm t1, imm, dataSize=asz limm t4, "(uint64_t(-(2ULL)))" roli t4, t4, imm + mfence ldstl t1, seg, sib, disp sexti t0, t1, imm, flags=(CF,) and t1, t1, t4 stul t1, seg, sib, disp + mfence }; def macroop BTR_LOCKED_P_I { @@ -229,10 +239,12 @@ def macroop BTR_LOCKED_P_I { limm t1, imm, dataSize=asz limm t4, "(uint64_t(-(2ULL)))" roli t4, t4, imm + mfence ldstl t1, seg, riprel, disp sexti t0, t1, imm, flags=(CF,) and t1, t1, t4 stul t1, seg, riprel, disp + mfence }; def macroop BTR_R_R { @@ -272,10 +284,12 @@ def macroop BTR_LOCKED_M_R { lea t3, flatseg, [dsz, t3, base], dataSize=asz limm t4, "(uint64_t(-(2ULL)))" rol t4, t4, reg + mfence ldstl t1, seg, [scale, index, t3], disp sext t0, t1, reg, flags=(CF,) and t1, t1, t4 stul t1, seg, [scale, index, t3], disp + mfence }; def macroop BTR_LOCKED_P_R { @@ -284,10 +298,12 @@ def macroop BTR_LOCKED_P_R { srai t3, t2, ldsz, dataSize=asz limm t4, "(uint64_t(-(2ULL)))" rol t4, t4, reg + mfence ldstl t1, seg, [dsz, t3, t7], disp sext t0, t1, reg, flags=(CF,) and t1, t1, t4 stul t1, seg, [dsz, t3, t7], disp + mfence }; def macroop BTS_R_I { @@ -322,10 +338,12 @@ def macroop BTS_LOCKED_M_I { limm t1, imm, dataSize=asz limm t4, 1 roli t4, t4, imm + mfence ldstl t1, seg, sib, disp sexti t0, t1, imm, flags=(CF,) or t1, t1, t4 stul t1, seg, sib, disp + mfence }; def macroop BTS_LOCKED_P_I { @@ -333,10 +351,12 @@ def macroop BTS_LOCKED_P_I { limm t1, imm, dataSize=asz limm t4, 1 roli t4, t4, imm + mfence ldstl t1, seg, riprel, disp sexti t0, t1, imm, flags=(CF,) or t1, t1, t4 stul t1, seg, riprel, disp + mfence }; def macroop BTS_R_R { @@ -377,10 +397,12 @@ def macroop BTS_LOCKED_M_R { lea t3, flatseg, [dsz, t3, base], dataSize=asz limm t4, 1 rol t4, t4, reg + mfence ldstl t1, seg, [scale, index, t3], disp sext t0, t1, reg, flags=(CF,) or t1, t1, t4 stul t1, seg, [scale, index, t3], disp + mfence }; def macroop BTS_LOCKED_P_R { @@ -390,9 +412,11 @@ def macroop BTS_LOCKED_P_R { lea t3, flatseg, [dsz, t3, base], dataSize=asz limm t4, 1 rol t4, t4, reg + mfence ldstl t1, seg, [1, t3, t7], disp sext t0, t1, reg, flags=(CF,) or t1, t1, t4 stul t1, seg, [1, t3, t7], disp + mfence }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/xchg.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/xchg.py index 6504b5ab4..1518ce5e0 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/xchg.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/xchg.py @@ -50,46 +50,58 @@ def macroop XCHG_R_R def macroop XCHG_R_M { + mfence ldstl t1, seg, sib, disp stul reg, seg, sib, disp + mfence mov reg, reg, t1 }; def macroop XCHG_R_P { rdip t7 + mfence ldstl t1, seg, riprel, disp stul reg, seg, riprel, disp + mfence mov reg, reg, t1 }; def macroop XCHG_M_R { + mfence ldstl t1, seg, sib, disp stul reg, seg, sib, disp + mfence mov reg, reg, t1 }; def macroop XCHG_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp stul reg, seg, riprel, disp + mfence mov reg, reg, t1 }; def macroop XCHG_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp stul reg, seg, sib, disp + mfence mov reg, reg, t1 }; def macroop XCHG_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp stul reg, seg, riprel, disp + mfence mov reg, reg, t1 }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/logical.py b/src/arch/x86/isa/insts/general_purpose/logical.py index b8d442a02..49dea86e5 100644 --- a/src/arch/x86/isa/insts/general_purpose/logical.py +++ b/src/arch/x86/isa/insts/general_purpose/logical.py @@ -61,18 +61,22 @@ def macroop OR_P_I def macroop OR_LOCKED_M_I { limm t2, imm + mfence ldstl t1, seg, sib, disp or t1, t1, t2, flags=(OF,SF,ZF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop OR_LOCKED_P_I { limm t2, imm rdip t7 + mfence ldstl t1, seg, riprel, disp or t1, t1, t2, flags=(OF,SF,ZF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop OR_M_R @@ -92,17 +96,21 @@ def macroop OR_P_R def macroop OR_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp or t1, t1, reg, flags=(OF,SF,ZF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop OR_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp or t1, t1, reg, flags=(OF,SF,ZF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop OR_R_M @@ -155,18 +163,22 @@ def macroop XOR_P_I def macroop XOR_LOCKED_M_I { limm t2, imm + mfence ldstl t1, seg, sib, disp xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop XOR_LOCKED_P_I { limm t2, imm rdip t7 + mfence ldstl t1, seg, riprel, disp xor t1, t1, t2, flags=(OF,SF,ZF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop XOR_M_R @@ -186,17 +198,21 @@ def macroop XOR_P_R def macroop XOR_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop XOR_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp xor t1, t1, reg, flags=(OF,SF,ZF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop XOR_R_M @@ -255,19 +271,23 @@ def macroop AND_P_I def macroop AND_LOCKED_M_I { + mfence ldstl t2, seg, sib, disp limm t1, imm and t2, t2, t1, flags=(OF,SF,ZF,PF,CF) stul t2, seg, sib, disp + mfence }; def macroop AND_LOCKED_P_I { rdip t7 + mfence ldstl t2, seg, riprel, disp limm t1, imm and t2, t2, t1, flags=(OF,SF,ZF,PF,CF) stul t2, seg, riprel, disp + mfence }; def macroop AND_M_R @@ -287,17 +307,21 @@ def macroop AND_P_R def macroop AND_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp and t1, t1, reg, flags=(OF,SF,ZF,PF,CF) stul t1, seg, sib, disp + mfence }; def macroop AND_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp and t1, t1, reg, flags=(OF,SF,ZF,PF,CF) stul t1, seg, riprel, disp + mfence }; def macroop NOT_R @@ -326,17 +350,21 @@ def macroop NOT_P def macroop NOT_LOCKED_M { limm t1, -1 + mfence ldstl t2, seg, sib, disp xor t2, t2, t1 stul t2, seg, sib, disp + mfence }; def macroop NOT_LOCKED_P { limm t1, -1 rdip t7 + mfence ldstl t2, seg, riprel, disp xor t2, t2, t1 stul t2, seg, riprel, disp + mfence }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/semaphores.py b/src/arch/x86/isa/insts/general_purpose/semaphores.py index 072e28de6..17bee7fb7 100644 --- a/src/arch/x86/isa/insts/general_purpose/semaphores.py +++ b/src/arch/x86/isa/insts/general_purpose/semaphores.py @@ -62,21 +62,25 @@ def macroop CMPXCHG_P_R { }; def macroop CMPXCHG_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp sub t0, rax, t1, flags=(OF, SF, ZF, AF, PF, CF) mov t1, t1, reg, flags=(CZF,) stul t1, seg, sib, disp + mfence mov rax, rax, t1, flags=(nCZF,) }; def macroop CMPXCHG_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp sub t0, rax, t1, flags=(OF, SF, ZF, AF, PF, CF) mov t1, t1, reg, flags=(CZF,) stul t1, seg, riprel, disp + mfence mov rax, rax, t1, flags=(nCZF,) }; @@ -96,17 +100,21 @@ def macroop XADD_P_R { }; def macroop XADD_LOCKED_M_R { + mfence ldstl t1, seg, sib, disp add t2, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t2, seg, sib, disp + mfence mov reg, reg, t1 }; def macroop XADD_LOCKED_P_R { rdip t7 + mfence ldstl t1, seg, riprel, disp add t2, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) stul t2, seg, riprel, disp + mfence mov reg, reg, t1 }; diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index 664f91860..5798ac4b0 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -59,7 +59,8 @@ let {{ ''' + generatorNameTemplate + '''(StaticInstPtr curMacroop) { static const char *macrocodeBlock = romMnemonic; - static const ExtMachInst dummyExtMachInst; + static const ExtMachInst dummyExtMachInst = \ + X86ISA::NoopMachInst; static const EmulEnv dummyEmulEnv(0, 0, 1, 1, 1); Macroop * macroop = dynamic_cast<Macroop *>(curMacroop.get()); diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa index 52420f175..5c242e2c9 100644 --- a/src/arch/x86/isa/microops/specop.isa +++ b/src/arch/x86/isa/microops/specop.isa @@ -1,4 +1,5 @@ // Copyright (c) 2007-2008 The Hewlett-Packard Development Company +// Copyright (c) 2011 Mark D. Hill and David A. Wood // All rights reserved. // // The license below extends only to copyright in the software and shall @@ -203,3 +204,55 @@ let {{ microopClasses["halt"] = Halt }}; + +def template MicroFenceOpDeclare {{ + class %(class_name)s : public X86ISA::X86MicroopBase + { + public: + %(class_name)s(ExtMachInst _machInst, + const char * instMnem, + uint64_t setFlags); + + %(BasicExecDeclare)s + }; +}}; + +def template MicroFenceOpConstructor {{ + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, uint64_t setFlags) : + %(base_class)s(machInst, "%(mnemonic)s", instMnem, + setFlags, %(op_class)s) + { + %(constructor)s; + } +}}; + +let {{ + class MfenceOp(X86Microop): + def __init__(self): + self.className = "Mfence" + self.mnemonic = "mfence" + self.instFlags = "| (1ULL << StaticInst::IsMemBarrier)" + + def getAllocator(self, microFlags): + allocString = ''' + (StaticInstPtr)(new %(class_name)s(machInst, + macrocodeBlock, %(flags)s)) + ''' + allocator = allocString % { + "class_name" : self.className, + "mnemonic" : self.mnemonic, + "flags" : self.microFlagsText(microFlags) + self.instFlags} + return allocator + + microopClasses["mfence"] = MfenceOp +}}; + +let {{ + # Build up the all register version of this micro op + iop = InstObjParams("mfence", "Mfence", 'X86MicroopBase', + {"code" : ""}) + header_output += MicroFenceOpDeclare.subst(iop) + decoder_output += MicroFenceOpConstructor.subst(iop) + exec_output += BasicExecute.subst(iop) +}}; diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index 99b09f405..4e5d43d45 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -88,6 +88,7 @@ class X86Linux64 : public Linux static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x20; + static const unsigned TGT_MAP_FIXED = 0x10; typedef struct { uint64_t iov_base; // void * @@ -158,6 +159,7 @@ class X86Linux32 : public Linux static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x20; + static const unsigned TGT_MAP_FIXED = 0x10; typedef struct { int32_t uptime; /* Seconds since boot */ diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 79a140776..f5ba787c9 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -167,7 +167,7 @@ X86_64LiveProcess::initState() argsInit(sizeof(uint64_t), VMPageSize); // Set up the vsyscall page for this process. - pTable->allocate(vsyscallPage.base, vsyscallPage.size); + allocateMem(vsyscallPage.base, vsyscallPage.size); uint8_t vtimeBlob[] = { 0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00, // mov $0xc9,%rax 0x0f,0x05, // syscall @@ -265,7 +265,7 @@ I386LiveProcess::initState() * Set up a GDT for this process. The whole GDT wouldn't really be for * this process, but the only parts we care about are. */ - pTable->allocate(_gdtStart, _gdtSize); + allocateMem(_gdtStart, _gdtSize); uint64_t zero = 0; assert(_gdtSize % sizeof(zero) == 0); for (Addr gdtCurrent = _gdtStart; @@ -274,7 +274,7 @@ I386LiveProcess::initState() } // Set up the vsyscall page for this process. - pTable->allocate(vsyscallPage.base, vsyscallPage.size); + allocateMem(vsyscallPage.base, vsyscallPage.size); uint8_t vsyscallBlob[] = { 0x51, // push %ecx 0x52, // push %edp @@ -577,8 +577,7 @@ X86LiveProcess::argsInit(int pageSize, stack_size = stack_base - stack_min; // map memory - pTable->allocate(roundDown(stack_min, pageSize), - roundUp(stack_size, pageSize)); + allocateMem(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize)); // map out initial stack contents IntType sentry_base = stack_base - sentry_size; diff --git a/src/base/inet.cc b/src/base/inet.cc index 0fb864dab..7d7eb3f5a 100644 --- a/src/base/inet.cc +++ b/src/base/inet.cc @@ -30,6 +30,7 @@ * Gabe Black */ +#include <cstddef> #include <cstdio> #include <sstream> #include <string> diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 8a755a4bf..6e2de0baf 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -234,8 +234,7 @@ BaseCPU::startup() if (params()->progress_interval) { Tick num_ticks = ticks(params()->progress_interval); - Event *event; - event = new CPUProgressEvent(this, num_ticks); + new CPUProgressEvent(this, num_ticks); } } diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index 9d6ecc7e1..010bdb512 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -206,7 +206,6 @@ InOrderCPU::InOrderCPU(Params *params) lastRunningCycle(0), instsPerSwitch(0) { - ThreadID active_threads; cpu_params = params; resPool = new ResourcePool(this, params); @@ -214,6 +213,7 @@ InOrderCPU::InOrderCPU(Params *params) // Resize for Multithreading CPUs thread.resize(numThreads); + ThreadID active_threads = params->workload.size(); if (FullSystem) { active_threads = 1; } else { @@ -1110,7 +1110,6 @@ InOrderCPU::updateThreadPriority() //DEFAULT TO ROUND ROBIN SCHEME //e.g. Move highest priority to end of thread list list<ThreadID>::iterator list_begin = activeThreads.begin(); - list<ThreadID>::iterator list_end = activeThreads.end(); unsigned high_thread = *list_begin; diff --git a/src/cpu/legiontrace.cc b/src/cpu/legiontrace.cc index 5e4c978a6..75d30c894 100644 --- a/src/cpu/legiontrace.cc +++ b/src/cpu/legiontrace.cc @@ -158,7 +158,7 @@ Trace::LegionTraceRecord::dump() bool diffTnpc = false; bool diffTstate = false; bool diffTt = false; - bool diffTba = false; + bool diffTba M5_VAR_USED = false; bool diffHpstate = false; bool diffHtstate = false; bool diffHtba = false; diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 16e78f8ec..bb5ccc17e 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -1639,7 +1639,6 @@ FullO3CPU<Impl>::updateThreadPriority() //DEFAULT TO ROUND ROBIN SCHEME //e.g. Move highest priority to end of thread list list<ThreadID>::iterator list_begin = activeThreads.begin(); - list<ThreadID>::iterator list_end = activeThreads.end(); unsigned high_thread = *list_begin; diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index 6dbafb56c..4106bbef9 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -1214,24 +1214,16 @@ template <class Impl> void DefaultRename<Impl>::readFreeEntries(ThreadID tid) { - bool updated = false; - if (fromIEW->iewInfo[tid].usedIQ) { - freeEntries[tid].iqEntries = - fromIEW->iewInfo[tid].freeIQEntries; - updated = true; - } + if (fromIEW->iewInfo[tid].usedIQ) + freeEntries[tid].iqEntries = fromIEW->iewInfo[tid].freeIQEntries; - if (fromIEW->iewInfo[tid].usedLSQ) { - freeEntries[tid].lsqEntries = - fromIEW->iewInfo[tid].freeLSQEntries; - updated = true; - } + if (fromIEW->iewInfo[tid].usedLSQ) + freeEntries[tid].lsqEntries = fromIEW->iewInfo[tid].freeLSQEntries; if (fromCommit->commitInfo[tid].usedROB) { freeEntries[tid].robEntries = fromCommit->commitInfo[tid].freeROBEntries; emptyROB[tid] = fromCommit->commitInfo[tid].emptyROB; - updated = true; } DPRINTF(Rename, "[tid:%i]: Free IQ: %i, Free ROB: %i, Free LSQ: %i\n", diff --git a/src/cpu/testers/rubytest/Check.hh b/src/cpu/testers/rubytest/Check.hh index 6861a74d3..db1485548 100644 --- a/src/cpu/testers/rubytest/Check.hh +++ b/src/cpu/testers/rubytest/Check.hh @@ -37,7 +37,6 @@ #include "mem/protocol/TesterStatus.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" class SubBlock; diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 3c64e2717..62e4a9c37 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -75,6 +75,18 @@ PioDevice::init() pioPort->sendStatusChange(Port::RangeChange); } +Port * +PioDevice::getPort(const std::string &if_name, int idx) +{ + if (if_name == "pio") { + if (pioPort != NULL) + fatal("%s: pio port already connected to %s", + name(), pioPort->getPeer()->name()); + pioPort = new PioPort(this, sys); + return pioPort; + } + return NULL; +} unsigned int PioDevice::drain(Event *de) @@ -349,3 +361,19 @@ DmaDevice::~DmaDevice() if (dmaPort) delete dmaPort; } + + +Port * +DmaDevice::getPort(const std::string &if_name, int idx) +{ + if (if_name == "dma") { + if (dmaPort != NULL) + fatal("%s: dma port already connected to %s", + name(), dmaPort->getPeer()->name()); + dmaPort = new DmaPort(this, sys, params()->min_backoff_delay, + params()->max_backoff_delay); + return dmaPort; + } + return PioDevice::getPort(if_name, idx); +} + diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index bdafc34a0..a92402bfe 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -209,17 +209,8 @@ class PioDevice : public MemObject virtual unsigned int drain(Event *de); - virtual Port *getPort(const std::string &if_name, int idx = -1) - { - if (if_name == "pio") { - if (pioPort != NULL) - fatal("%s: pio port already connected to %s", - name(), pioPort->getPeer()->name()); - pioPort = new PioPort(this, sys); - return pioPort; - } else - return NULL; - } + virtual Port *getPort(const std::string &if_name, int idx = -1); + friend class PioPort; }; @@ -285,24 +276,7 @@ class DmaDevice : public PioDevice unsigned cacheBlockSize() const { return dmaPort->cacheBlockSize(); } - virtual Port *getPort(const std::string &if_name, int idx = -1) - { - if (if_name == "pio") { - if (pioPort != NULL) - fatal("%s: pio port already connected to %s", - name(), pioPort->getPeer()->name()); - pioPort = new PioPort(this, sys); - return pioPort; - } else if (if_name == "dma") { - if (dmaPort != NULL) - fatal("%s: dma port already connected to %s", - name(), dmaPort->getPeer()->name()); - dmaPort = new DmaPort(this, sys, params()->min_backoff_delay, - params()->max_backoff_delay); - return dmaPort; - } else - return NULL; - } + virtual Port *getPort(const std::string &if_name, int idx = -1); friend class DmaPort; }; diff --git a/src/dev/mc146818.cc b/src/dev/mc146818.cc index 9397a599b..b0aaf6e64 100644 --- a/src/dev/mc146818.cc +++ b/src/dev/mc146818.cc @@ -217,7 +217,7 @@ MC146818::serialize(const string &base, ostream &os) // Tick rtcTimerInterruptTickOffset = event.when() - curTick(); SERIALIZE_SCALAR(rtcTimerInterruptTickOffset); - Tick rtcClockTickOffset = event.when() - curTick(); + Tick rtcClockTickOffset = tickEvent.when() - curTick(); SERIALIZE_SCALAR(rtcClockTickOffset); } diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh index d56b32cf0..8b8091f0d 100644 --- a/src/kern/tru64/tru64.hh +++ b/src/kern/tru64/tru64.hh @@ -557,7 +557,7 @@ class Tru64 : public OperatingSystem stack_base, stack_size); // map memory - process->pTable->allocate(rounded_stack_base, rounded_stack_size); + process->allocateMem(rounded_stack_base, rounded_stack_size); argp->address = gtoh(rounded_stack_base); argp.copyOut(tc->getMemPort()); @@ -676,7 +676,7 @@ class Tru64 : public OperatingSystem // Register this as a valid address range with the process base_addr = roundDown(base_addr, VMPageSize); int size = cur_addr - base_addr; - process->pTable->allocate(base_addr, roundUp(size, VMPageSize)); + process->allocateMem(base_addr, roundUp(size, VMPageSize)); config.copyOut(tc->getMemPort()); slot_state.copyOut(tc->getMemPort()); diff --git a/src/mem/SConscript b/src/mem/SConscript index da37edb57..2aa7d0323 100644 --- a/src/mem/SConscript +++ b/src/mem/SConscript @@ -65,10 +65,11 @@ DebugFlag('RubyMemory') DebugFlag('RubyNetwork') DebugFlag('RubyPort') DebugFlag('RubyQueue') +DebugFlag('RubySequencer') DebugFlag('RubySlicc') DebugFlag('RubyStorebuffer') DebugFlag('RubyTester') CompoundFlag('Ruby', [ 'RubyQueue', 'RubyNetwork', 'RubyTester', - 'RubyGenerated', 'RubySlicc', 'RubyStorebuffer', 'RubyCache', - 'RubyMemory', 'RubyDma', 'RubyPort']) + 'RubyGenerated', 'RubySlicc', 'RubyStorebuffer', 'RubyCache', + 'RubyMemory', 'RubyDma', 'RubyPort', 'RubySequencer']) diff --git a/src/mem/cache/tags/iic.cc b/src/mem/cache/tags/iic.cc index 113ad8b4d..71c3ba48c 100644 --- a/src/mem/cache/tags/iic.cc +++ b/src/mem/cache/tags/iic.cc @@ -393,10 +393,8 @@ IIC::freeReplacementBlock(PacketList & writebacks) unsigned long IIC::getFreeDataBlock(PacketList & writebacks) { - struct IICTag *tag_ptr; unsigned long data_ptr; - tag_ptr = NULL; /* find data block */ while (blkFreelist.empty()) { freeReplacementBlock(writebacks); diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index c260ba2d4..0ec2dbc07 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -45,16 +45,14 @@ #include "debug/MMU.hh" #include "mem/page_table.hh" #include "sim/faults.hh" -#include "sim/process.hh" #include "sim/sim_object.hh" -#include "sim/system.hh" using namespace std; using namespace TheISA; -PageTable::PageTable(Process *_process, Addr _pageSize) +PageTable::PageTable(const std::string &__name, uint64_t _pid, Addr _pageSize) : pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))), - process(_process) + pid(_pid), _name(__name) { assert(isPowerOf2(pageSize)); pTableCache[0].vaddr = 0; @@ -67,24 +65,20 @@ PageTable::~PageTable() } void -PageTable::allocate(Addr vaddr, int64_t size) +PageTable::map(Addr vaddr, Addr paddr, int64_t size, bool clobber) { // starting address must be page aligned assert(pageOffset(vaddr) == 0); DPRINTF(MMU, "Allocating Page: %#x-%#x\n", vaddr, vaddr+ size); - for (; size > 0; size -= pageSize, vaddr += pageSize) { - PTableItr iter = pTable.find(vaddr); - - if (iter != pTable.end()) { + for (; size > 0; size -= pageSize, vaddr += pageSize, paddr += pageSize) { + if (!clobber && (pTable.find(vaddr) != pTable.end())) { // already mapped - fatal("PageTable::allocate: address 0x%x already mapped", - vaddr); + fatal("PageTable::allocate: address 0x%x already mapped", vaddr); } - pTable[vaddr] = TheISA::TlbEntry(process->M5_pid, vaddr, - process->system->new_page()); + pTable[vaddr] = TheISA::TlbEntry(pid, vaddr, paddr); updateCache(vaddr, pTable[vaddr]); } } @@ -111,11 +105,11 @@ PageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr) } void -PageTable::deallocate(Addr vaddr, int64_t size) +PageTable::unmap(Addr vaddr, int64_t size) { assert(pageOffset(vaddr) == 0); - DPRINTF(MMU, "Deallocating page: %#x-%#x\n", vaddr, vaddr+ size); + DPRINTF(MMU, "Unmapping page: %#x-%#x\n", vaddr, vaddr+ size); for (; size > 0; size -= pageSize, vaddr += pageSize) { PTableItr iter = pTable.find(vaddr); @@ -128,6 +122,21 @@ PageTable::deallocate(Addr vaddr, int64_t size) } bool +PageTable::isUnmapped(Addr vaddr, int64_t size) +{ + // starting address must be page aligned + assert(pageOffset(vaddr) == 0); + + for (; size > 0; size -= pageSize, vaddr += pageSize) { + if (pTable.find(vaddr) != pTable.end()) { + return false; + } + } + + return true; +} + +bool PageTable::lookup(Addr vaddr, TheISA::TlbEntry &entry) { Addr page_addr = pageAlign(vaddr); @@ -196,7 +205,7 @@ PageTable::serialize(std::ostream &os) PTableItr iter = pTable.begin(); PTableItr end = pTable.end(); while (iter != end) { - os << "\n[" << csprintf("%s.Entry%d", process->name(), count) << "]\n"; + os << "\n[" << csprintf("%s.Entry%d", name(), count) << "]\n"; paramOut(os, "vaddr", iter->first); iter->second.serialize(os); @@ -219,9 +228,9 @@ PageTable::unserialize(Checkpoint *cp, const std::string §ion) TheISA::TlbEntry *entry; Addr vaddr; - paramIn(cp, csprintf("%s.Entry%d", process->name(), i), "vaddr", vaddr); + paramIn(cp, csprintf("%s.Entry%d", name(), i), "vaddr", vaddr); entry = new TheISA::TlbEntry(); - entry->unserialize(cp, csprintf("%s.Entry%d", process->name(), i)); + entry->unserialize(cp, csprintf("%s.Entry%d", name(), i)); pTable[vaddr] = *entry; ++i; } diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index 61da5f322..b1b5227be 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -46,8 +46,6 @@ #include "mem/request.hh" #include "sim/serialize.hh" -class Process; - /** * Page Table Declaration. */ @@ -68,20 +66,33 @@ class PageTable const Addr pageSize; const Addr offsetMask; - Process *process; + const uint64_t pid; + const std::string _name; public: - PageTable(Process *_process, Addr _pageSize = TheISA::VMPageSize); + PageTable(const std::string &__name, uint64_t _pid, + Addr _pageSize = TheISA::VMPageSize); ~PageTable(); + // for DPRINTF compatibility + const std::string name() const { return _name; } + Addr pageAlign(Addr a) { return (a & ~offsetMask); } Addr pageOffset(Addr a) { return (a & offsetMask); } - void allocate(Addr vaddr, int64_t size); + void map(Addr vaddr, Addr paddr, int64_t size, bool clobber = false); void remap(Addr vaddr, int64_t size, Addr new_vaddr); - void deallocate(Addr vaddr, int64_t size); + void unmap(Addr vaddr, int64_t size); + + /** + * Check if any pages in a region are already allocated + * @param vaddr The starting virtual address of the region. + * @param size The length of the region. + * @return True if no pages in the region are mapped. + */ + bool isUnmapped(Addr vaddr, int64_t size); /** * Lookup function diff --git a/src/mem/protocol/MESI_CMP_directory-L1cache.sm b/src/mem/protocol/MESI_CMP_directory-L1cache.sm index b2ba0872e..f0be1fd34 100644 --- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm @@ -679,6 +679,17 @@ machine(L1Cache, "MSI Directory L1 Cache CMP") mandatoryQueue_in.recycle(); } + action(uu_profileInstMiss, "\ui", desc="Profile the demand miss") { + peek(mandatoryQueue_in, RubyRequest) { + L1IcacheMemory.profileMiss(in_msg); + } + } + + action(uu_profileDataMiss, "\ud", desc="Profile the demand miss") { + peek(mandatoryQueue_in, RubyRequest) { + L1DcacheMemory.profileMiss(in_msg); + } + } //***************************************************** // TRANSITIONS @@ -698,6 +709,7 @@ machine(L1Cache, "MSI Directory L1 Cache CMP") oo_allocateL1DCacheBlock; i_allocateTBE; a_issueGETS; + uu_profileDataMiss; k_popMandatoryQueue; } @@ -705,6 +717,7 @@ machine(L1Cache, "MSI Directory L1 Cache CMP") pp_allocateL1ICacheBlock; i_allocateTBE; ai_issueGETINSTR; + uu_profileInstMiss; k_popMandatoryQueue; } @@ -712,6 +725,7 @@ machine(L1Cache, "MSI Directory L1 Cache CMP") oo_allocateL1DCacheBlock; i_allocateTBE; b_issueGETX; + uu_profileDataMiss; k_popMandatoryQueue; } @@ -729,6 +743,7 @@ machine(L1Cache, "MSI Directory L1 Cache CMP") transition(S, Store, SM) { i_allocateTBE; c_issueUPGRADE; + uu_profileDataMiss; k_popMandatoryQueue; } diff --git a/src/mem/protocol/MESI_CMP_directory-L2cache.sm b/src/mem/protocol/MESI_CMP_directory-L2cache.sm index a8fcb07d1..2d8ae4ca8 100644 --- a/src/mem/protocol/MESI_CMP_directory-L2cache.sm +++ b/src/mem/protocol/MESI_CMP_directory-L2cache.sm @@ -716,9 +716,25 @@ machine(L2Cache, "MESI Directory L2 Cache CMP") } } + GenericRequestType convertToGenericType(CoherenceRequestType type) { + if(type == CoherenceRequestType:GETS) { + return GenericRequestType:GETS; + } else if(type == CoherenceRequestType:GETX) { + return GenericRequestType:GETX; + } else if(type == CoherenceRequestType:GET_INSTR) { + return GenericRequestType:GET_INSTR; + } else if(type == CoherenceRequestType:UPGRADE) { + return GenericRequestType:UPGRADE; + } else { + DPRINTF(RubySlicc, "%s\n", type); + error("Invalid CoherenceRequestType\n"); + } + } + action(uu_profileMiss, "\u", desc="Profile the demand miss") { peek(L1RequestIntraChipL2Network_in, RequestMsg) { - //profile_L2Cache_miss(convertToGenericType(in_msg.Type), in_msg.AccessMode, MessageSizeTypeToInt(in_msg.MessageSize), in_msg.Prefetch, L1CacheMachIDToProcessorNum(in_msg.Requestor)); + L2cacheMemory.profileGenericRequest(convertToGenericType(in_msg.Type), + in_msg.AccessMode, in_msg.Prefetch); } } diff --git a/src/mem/protocol/MESI_CMP_directory.slicc b/src/mem/protocol/MESI_CMP_directory.slicc index 07b55620b..37ac0a424 100644 --- a/src/mem/protocol/MESI_CMP_directory.slicc +++ b/src/mem/protocol/MESI_CMP_directory.slicc @@ -5,4 +5,3 @@ include "MESI_CMP_directory-L1cache.sm"; include "MESI_CMP_directory-L2cache.sm"; include "MESI_CMP_directory-dir.sm"; include "MESI_CMP_directory-dma.sm"; -include "standard_CMP-protocol.sm"; diff --git a/src/mem/protocol/MI_example.slicc b/src/mem/protocol/MI_example.slicc index 00508673b..70614787a 100644 --- a/src/mem/protocol/MI_example.slicc +++ b/src/mem/protocol/MI_example.slicc @@ -4,4 +4,3 @@ include "MI_example-msg.sm"; include "MI_example-cache.sm"; include "MI_example-dir.sm"; include "MI_example-dma.sm"; -include "standard_1level_CMP-protocol.sm"; diff --git a/src/mem/protocol/MOESI_CMP_directory.slicc b/src/mem/protocol/MOESI_CMP_directory.slicc index 199ea174d..0bba349b5 100644 --- a/src/mem/protocol/MOESI_CMP_directory.slicc +++ b/src/mem/protocol/MOESI_CMP_directory.slicc @@ -5,4 +5,3 @@ include "MOESI_CMP_directory-L2cache.sm"; include "MOESI_CMP_directory-L1cache.sm"; include "MOESI_CMP_directory-dma.sm"; include "MOESI_CMP_directory-dir.sm"; -include "standard_CMP-protocol.sm"; diff --git a/src/mem/protocol/MOESI_CMP_token.slicc b/src/mem/protocol/MOESI_CMP_token.slicc index 9818561d6..5bc3a5700 100644 --- a/src/mem/protocol/MOESI_CMP_token.slicc +++ b/src/mem/protocol/MOESI_CMP_token.slicc @@ -5,4 +5,3 @@ include "MOESI_CMP_token-L1cache.sm"; include "MOESI_CMP_token-L2cache.sm"; include "MOESI_CMP_token-dir.sm"; include "MOESI_CMP_token-dma.sm"; -include "standard_CMP-protocol.sm"; diff --git a/src/mem/protocol/MOESI_hammer.slicc b/src/mem/protocol/MOESI_hammer.slicc index 66d217c9c..ab8eb730a 100644 --- a/src/mem/protocol/MOESI_hammer.slicc +++ b/src/mem/protocol/MOESI_hammer.slicc @@ -4,4 +4,3 @@ include "MOESI_hammer-msg.sm"; include "MOESI_hammer-cache.sm"; include "MOESI_hammer-dir.sm"; include "MOESI_hammer-dma.sm"; -include "standard_1level_CMP-protocol.sm"; diff --git a/src/mem/protocol/RubySlicc_ComponentMapping.sm b/src/mem/protocol/RubySlicc_ComponentMapping.sm index 3c777e965..4f6f0e3d1 100644 --- a/src/mem/protocol/RubySlicc_ComponentMapping.sm +++ b/src/mem/protocol/RubySlicc_ComponentMapping.sm @@ -30,34 +30,12 @@ // Mapping functions int machineCount(MachineType machType); - -// NodeID map_address_to_node(Address addr); MachineID mapAddressToRange(Address addr, MachineType type, int low, int high); NetDest broadcast(MachineType type); MachineID map_Address_to_DMA(Address addr); MachineID map_Address_to_Directory(Address addr); NodeID map_Address_to_DirectoryNode(Address addr); - - -MachineID getL1MachineID(NodeID L1RubyNode); -NodeID getChipID(MachineID L2machID); -MachineID getCollectorDest(MachineID L1machID); -MachineID getCollectorL1Cache(MachineID colID); -NetDest getMultiStaticL2BankNetDest(Address addr, Set sharers); -bool isL1OnChip(MachineID L1machID, NodeID L2NodeID); -bool isL2OnChip(MachineID L2machID, NodeID L2NodeID); - -int getNumBanksInBankSet(); NodeID machineIDToNodeID(MachineID machID); NodeID machineIDToVersion(MachineID machID); MachineType machineIDToMachineType(MachineID machID); -NodeID L1CacheMachIDToProcessorNum(MachineID machID); -NodeID L2CacheMachIDToChipID(MachineID machID); -Set getOtherLocalL1IDs(MachineID L1); -Set getLocalL1IDs(MachineID L1); -Set getExternalL1IDs(MachineID L1); -NetDest getAllPertinentL2Banks(Address addr); -bool isLocalProcessor(MachineID thisId, MachineID tarId); - GenericMachineType ConvertMachToGenericMach(MachineType machType); - diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index a2f8abfaa..cc404394d 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -48,7 +48,7 @@ structure(InPort, external = "yes", primitive="yes") { bool isEmpty(); } -external_type(NodeID, default="0"); +external_type(NodeID, default="0", primitive="yes"); external_type(MachineID); MessageBuffer getMandatoryQueue(int core_id); diff --git a/src/mem/protocol/standard_1level_CMP-protocol.sm b/src/mem/protocol/standard_1level_CMP-protocol.sm deleted file mode 100644 index 34da6201f..000000000 --- a/src/mem/protocol/standard_1level_CMP-protocol.sm +++ /dev/null @@ -1,40 +0,0 @@ - -/* - * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -// global protocol features -global(Protocol, desc="Global properties of this protocol", - interface = "AbstractProtocol") { - bool TwoLevelCache := false; - bool CMP := true; -} - diff --git a/src/mem/protocol/standard_CMP-protocol.sm b/src/mem/protocol/standard_CMP-protocol.sm deleted file mode 100644 index dbd7e4ef5..000000000 --- a/src/mem/protocol/standard_CMP-protocol.sm +++ /dev/null @@ -1,36 +0,0 @@ - -/* - * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// global protocol features -global(Protocol, desc="Global properties of this protocol", - interface = "AbstractProtocol") { - bool TwoLevelCache := true; - bool CMP := true; -} - diff --git a/src/mem/ruby/SConscript b/src/mem/ruby/SConscript index 64dd83bb0..06f6abd9f 100644 --- a/src/mem/ruby/SConscript +++ b/src/mem/ruby/SConscript @@ -109,7 +109,6 @@ MakeInclude('system/DirectoryMemory.hh') MakeInclude('system/MachineID.hh') MakeInclude('system/MemoryControl.hh') MakeInclude('system/WireBuffer.hh') -MakeInclude('system/NodeID.hh') MakeInclude('system/PerfectCacheMemory.hh') MakeInclude('system/PersistentTable.hh') MakeInclude('system/Sequencer.hh') diff --git a/src/mem/ruby/common/Address.hh b/src/mem/ruby/common/Address.hh index 4a9a3adb2..7ab3d1251 100644 --- a/src/mem/ruby/common/Address.hh +++ b/src/mem/ruby/common/Address.hh @@ -33,8 +33,7 @@ #include <iomanip> #include "base/hashmap.hh" -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" +#include "mem/ruby/common/TypeDefines.hh" const int ADDRESS_WIDTH = 64; // address width in bytes diff --git a/src/mem/ruby/common/DataBlock.hh b/src/mem/ruby/common/DataBlock.hh index 1d6abcfee..7bd92710d 100644 --- a/src/mem/ruby/common/DataBlock.hh +++ b/src/mem/ruby/common/DataBlock.hh @@ -32,7 +32,7 @@ #include <iomanip> #include <iostream> -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/TypeDefines.hh" class DataBlock { diff --git a/src/mem/ruby/common/Driver.hh b/src/mem/ruby/common/Driver.hh index 8d687ef4f..477b90927 100644 --- a/src/mem/ruby/common/Driver.hh +++ b/src/mem/ruby/common/Driver.hh @@ -34,7 +34,6 @@ #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" class Driver { diff --git a/src/mem/ruby/common/Global.hh b/src/mem/ruby/common/Global.hh index 357825465..cae7cb16b 100644 --- a/src/mem/ruby/common/Global.hh +++ b/src/mem/ruby/common/Global.hh @@ -29,16 +29,7 @@ #ifndef __MEM_RUBY_COMMON_GLOBAL_HH__ #define __MEM_RUBY_COMMON_GLOBAL_HH__ -// external includes for all classes -#include "mem/ruby/common/TypeDefines.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; +#include "base/str.hh" class RubyEventQueue; extern RubyEventQueue* g_eventQueue_ptr; diff --git a/src/mem/ruby/common/Histogram.hh b/src/mem/ruby/common/Histogram.hh index 81cfbd477..bfc0e4293 100644 --- a/src/mem/ruby/common/Histogram.hh +++ b/src/mem/ruby/common/Histogram.hh @@ -32,7 +32,7 @@ #include <iostream> #include <vector> -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/TypeDefines.hh" class Histogram { diff --git a/src/mem/ruby/common/NetDest.hh b/src/mem/ruby/common/NetDest.hh index 8006045d8..5ad1b6100 100644 --- a/src/mem/ruby/common/NetDest.hh +++ b/src/mem/ruby/common/NetDest.hh @@ -42,7 +42,6 @@ #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Set.hh" #include "mem/ruby/system/MachineID.hh" -#include "mem/ruby/system/NodeID.hh" class NetDest { diff --git a/src/mem/ruby/common/Set.hh b/src/mem/ruby/common/Set.hh index b76c3409d..ea10b83f1 100644 --- a/src/mem/ruby/common/Set.hh +++ b/src/mem/ruby/common/Set.hh @@ -36,7 +36,6 @@ #include <limits> #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/System.hh" class Set diff --git a/src/mem/ruby/common/TypeDefines.hh b/src/mem/ruby/common/TypeDefines.hh index 2e8d308e2..233c9146a 100644 --- a/src/mem/ruby/common/TypeDefines.hh +++ b/src/mem/ruby/common/TypeDefines.hh @@ -44,4 +44,9 @@ typedef long long integer_t; typedef int64 Time; typedef uint64 physical_address_t; +typedef int64 Index; // what the address bit ripper returns +typedef int LinkID; +typedef int NodeID; +typedef int SwitchID; + #endif diff --git a/src/mem/ruby/eventqueue/RubyEventQueue.hh b/src/mem/ruby/eventqueue/RubyEventQueue.hh index 3e2bc3f89..20b44362a 100644 --- a/src/mem/ruby/eventqueue/RubyEventQueue.hh +++ b/src/mem/ruby/eventqueue/RubyEventQueue.hh @@ -59,7 +59,7 @@ #include <iostream> #include "config/no_vector_bounds_checks.hh" -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/TypeDefines.hh" #include "sim/eventq.hh" class Consumer; diff --git a/src/mem/ruby/network/Network.hh b/src/mem/ruby/network/Network.hh index 309560921..157849149 100644 --- a/src/mem/ruby/network/Network.hh +++ b/src/mem/ruby/network/Network.hh @@ -47,7 +47,6 @@ #include "mem/protocol/LinkDirection.hh" #include "mem/protocol/MessageSizeType.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/System.hh" #include "params/RubyNetwork.hh" #include "sim/sim_object.hh" diff --git a/src/mem/ruby/network/Topology.hh b/src/mem/ruby/network/Topology.hh index 7b7439686..e8510f810 100644 --- a/src/mem/ruby/network/Topology.hh +++ b/src/mem/ruby/network/Topology.hh @@ -45,8 +45,7 @@ #include <vector> #include "mem/protocol/LinkDirection.hh" -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" +#include "mem/ruby/common/TypeDefines.hh" #include "params/Topology.hh" #include "sim/sim_object.hh" diff --git a/src/mem/ruby/network/fault_model/FaultModel.cc b/src/mem/ruby/network/fault_model/FaultModel.cc new file mode 100644 index 000000000..195f7c66c --- /dev/null +++ b/src/mem/ruby/network/fault_model/FaultModel.cc @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2011 Massachusetts Institute of Technology + * 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. + * + * Authors: Konstantinos Aisopos + */ + +/* + * Official Tool Website: www.mit.edu/~kaisopos/FaultModel + * + * If you use our tool for academic research, we request that you cite: + * Konstantinos Aisopos, Chia-Hsin Owen Chen, and Li-Shiuan Peh. Enabling + * System-Level Modeling of Variation-Induced Faults in Networks-on-Chip. + * Proceedings of the 48th Design Automation Conference (DAC'11) + */ + +// C includes +#include <assert.h> +#include <stdio.h> + +// C++ includes +#include <fstream> +#include <iostream> +#include <vector> + +// GEM5 includes +#include "FaultModel.hh" +#include "base/misc.hh" + +#define MAX(a,b) ((a > b) ? (a) : (b)) + + +FaultModel::FaultModel(const Params *p) : SimObject(p) +{ + // read configurations into "configurations" vector + // format: <buff/vc> <vcs> <10 fault types> + bool more_records = true; + for (int i = 0; more_records; i += (fields_per_conf_record)){ + system_conf configuration; + configuration.buff_per_vc = + p->baseline_fault_vector_database[i + conf_record_buff_per_vc]; + configuration.vcs = + p->baseline_fault_vector_database[i + conf_record_vcs]; + for (int fault_index = 0; fault_index < number_of_fault_types; + fault_index++){ + configuration.fault_type[fault_index] = + p->baseline_fault_vector_database[i + + conf_record_first_fault_type + fault_index] / 100; + } + configurations.push_back(configuration); + if (p->baseline_fault_vector_database[i+fields_per_conf_record] < 0){ + more_records = false; + } + } + + // read temperature weights into "temperature_weights" vector + // format: <temperature> <weight> + more_records = true; + for (int i = 0; more_records; i += (fields_per_temperature_record)){ + int record_temperature = + p->temperature_weights_database[i + temperature_record_temp]; + int record_weight = + p->temperature_weights_database[i + temperature_record_weight]; + static int first_record = true; + if (first_record){ + for (int temperature = 0; temperature < record_temperature; + temperature++){ + temperature_weights.push_back(0); + } + first_record = false; + } + assert(record_temperature == temperature_weights.size()); + temperature_weights.push_back(record_weight); + if (p->temperature_weights_database[i + + fields_per_temperature_record] < 0){ + more_records = false; + } + } +} + +string +FaultModel::fault_type_to_string(int ft) +{ + if (ft == data_corruption__few_bits){ + return "data_corruption__few_bits"; + } else if (ft == data_corruption__all_bits){ + return "data_corruption__all_bits"; + } else if (ft == flit_conservation__flit_duplication){ + return "flit_conservation__flit_duplication"; + } else if (ft == flit_conservation__flit_loss_or_split){ + return "flit_conservation__flit_loss_or_split"; + } else if (ft == misrouting){ + return "misrouting"; + } else if (ft == credit_conservation__credit_generation){ + return "credit_conservation__credit_generation"; + } else if (ft == credit_conservation__credit_loss){ + return "credit_conservation__credit_loss"; + } else if (ft == erroneous_allocation__VC){ + return "erroneous_allocation__VC"; + } else if (ft == erroneous_allocation__switch){ + return "erroneous_allocation__switch"; + } else if (ft == unfair_arbitration){ + return "unfair_arbitration"; + } else if (ft == number_of_fault_types){ + return "none"; + } else { + return "none"; + } +} + + +int +FaultModel::declare_router(int number_of_inputs, + int number_of_outputs, + int number_of_vcs_per_input, + int number_of_buff_per_data_vc, + int number_of_buff_per_ctrl_vc) +{ + // check inputs (are they legal?) + if (number_of_inputs <= 0 || number_of_outputs <= 0 || + number_of_vcs_per_input <= 0 || number_of_buff_per_data_vc <= 0 || + number_of_buff_per_ctrl_vc <= 0){ + fatal("Fault Model: ERROR in argument of FaultModel_declare_router!"); + } + int number_of_buffers_per_vc = MAX(number_of_buff_per_data_vc, + number_of_buff_per_ctrl_vc); + int total_vcs = number_of_inputs * number_of_vcs_per_input; + if (total_vcs > MAX_VCs){ + fatal("Fault Model: ERROR! Number inputs*VCs (MAX_VCs) unsupported"); + } + if (number_of_buffers_per_vc > MAX_BUFFERS_per_VC){ + fatal("Fault Model: ERROR! buffers/VC (MAX_BUFFERS_per_VC) too high"); + } + + // link the router to a DB record + int record_hit = -1; + for (int record = 0; record < configurations.size(); record++){ + if ((configurations[record].buff_per_vc == number_of_buffers_per_vc)&& + (configurations[record].vcs == total_vcs)){ + record_hit = record; + } + } + if (record_hit == -1){ + panic("Fault Model: ERROR! configuration not found in DB. BUG?"); + } + + // remember the router and return its ID + routers.push_back(configurations[record_hit]); + static int router_index = 0; + return router_index++; +} + +bool +FaultModel::fault_vector(int routerID, + int temperature_input, + float fault_vector[]) +{ + bool ok = true; + + // is the routerID recorded? + if (routerID < 0 || routerID >= ((int) routers.size())){ + warn("Fault Model: ERROR! unknown router ID argument."); + fatal("Fault Model: Did you enable the fault model flag)?"); + } + + // is the temperature too high/too low? + int temperature = temperature_input; + if (temperature_input >= ((int) temperature_weights.size())){ + ok = false; + warn_once("Fault Model: Temperature exceeded simulated upper bound."); + warn_once("Fault Model: The fault model is not accurate any more."); + temperature = (temperature_weights.size() - 1); + } else if (temperature_input < 0){ + ok = false; + warn_once("Fault Model: Temperature exceeded simulated lower bound."); + warn_once("Fault Model: The fault model is not accurate any more."); + temperature = 0; + } + + // recover the router record and return its fault vector + for (int i = 0; i < number_of_fault_types; i++){ + fault_vector[i] = routers[routerID].fault_type[i] * + ((float)temperature_weights[temperature]); + } + return ok; +} + +bool +FaultModel::fault_prob(int routerID, + int temperature_input, + float *aggregate_fault_prob) +{ + *aggregate_fault_prob = 1.0; + bool ok = true; + + // is the routerID recorded? + if (routerID < 0 || routerID >= ((int) routers.size())){ + warn("Fault Model: ERROR! unknown router ID argument."); + fatal("Fault Model: Did you enable the fault model flag)?"); + } + + // is the temperature too high/too low? + int temperature = temperature_input; + if (temperature_input >= ((int) temperature_weights.size()) ){ + ok = false; + warn_once("Fault Model: Temperature exceeded simulated upper bound."); + warn_once("Fault Model: The fault model is not accurate any more."); + temperature = (temperature_weights.size()-1); + } else if (temperature_input < 0){ + ok = false; + warn_once("Fault Model: Temperature exceeded simulated lower bound."); + warn_once("Fault Model: The fault model is not accurate any more."); + temperature = 0; + } + + // recover the router record and return its aggregate fault probability + for (int i = 0; i < number_of_fault_types; i++){ + *aggregate_fault_prob= *aggregate_fault_prob * + ( 1.0 - (routers[routerID].fault_type[i] * + ((float)temperature_weights[temperature])) ); + } + *aggregate_fault_prob = 1.0 - *aggregate_fault_prob; + return ok; +} + +// this function is used only for debugging purposes +void +FaultModel::print(void) +{ + cout << "--- PRINTING configurations ---\n"; + for (int record = 0; record < configurations.size(); record++){ + cout << "(" << record << ") "; + cout << "VCs=" << configurations[record].vcs << " "; + cout << "Buff/VC=" << configurations[record].buff_per_vc << " ["; + for (int fault_type_num = 0; + fault_type_num < number_of_fault_types; + fault_type_num++){ + cout << (100 * configurations[record].fault_type[fault_type_num]); + cout << "% "; + } + cout << "]\n"; + } + cout << "--- PRINTING temperature weights ---\n"; + for (int record = 0; record < temperature_weights.size(); record++){ + cout << "temperature=" << record << " => "; + cout << "weight=" << temperature_weights[record]; + cout << "\n"; + } +} + +FaultModel * +FaultModelParams::create() +{ + return new FaultModel(this); +} diff --git a/src/mem/ruby/network/fault_model/FaultModel.hh b/src/mem/ruby/network/fault_model/FaultModel.hh new file mode 100644 index 000000000..12a3f3844 --- /dev/null +++ b/src/mem/ruby/network/fault_model/FaultModel.hh @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2011 Massachusetts Institute of Technology + * 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. + * + * Authors: Konstantinos Aisopos + */ + +/* + * Official Tool Website: www.mit.edu/~kaisopos/FaultModel + * + * If you use our tool for academic research, we request that you cite: + * Konstantinos Aisopos, Chia-Hsin Owen Chen, and Li-Shiuan Peh. Enabling + * System-Level Modeling of Variation-Induced Faults in Networks-on-Chip. + * Proceedings of the 48th Design Automation Conference (DAC'11) + */ + +#ifndef __MEM_RUBY_NETWORK_FAULT_MODEL_HH__ +#define __MEM_RUBY_NETWORK_FAULT_MODEL_HH__ + +// tool limitations and fixed inputs +#define MAX_VCs 40 +#define MAX_BUFFERS_per_VC 5 +#define BASELINE_TEMPERATURE_CELCIUS 71 + +// C++ includes +#include <string> +using namespace std; + +// GEM5 includes +#include "params/FaultModel.hh" +#include "sim/sim_object.hh" + +class FaultModel : public SimObject +{ + public: + typedef FaultModelParams Params; + FaultModel(const Params *p); + const Params *params() const { return (const Params *)_params; } + + /************************************************************************/ + /********** THE FAULT TYPES SUPPORTED BY THE FAULT MODEL ***************/ + /************************************************************************/ + + enum fault_type + { + data_corruption__few_bits, + data_corruption__all_bits, + flit_conservation__flit_duplication, + flit_conservation__flit_loss_or_split, + misrouting, + credit_conservation__credit_generation, + credit_conservation__credit_loss, + erroneous_allocation__VC, + erroneous_allocation__switch, + unfair_arbitration, + number_of_fault_types + }; + + /************************************************************************/ + /******************** INTERFACE OF THE FAULT MODEL *********************/ + /************************************************************************/ + + enum conf_record_format + { + conf_record_buff_per_vc, + conf_record_vcs, + conf_record_first_fault_type, + conf_record_last_fault_type = conf_record_first_fault_type + number_of_fault_types - 1, + fields_per_conf_record + }; + + enum temperature_record_format + { + temperature_record_temp, + temperature_record_weight, + fields_per_temperature_record + }; + + struct system_conf + { + int vcs; + int buff_per_vc; + float fault_type[number_of_fault_types]; + }; + + int declare_router(int number_of_inputs, + int number_of_outputs, + int number_of_vcs_per_vnet, + int number_of_buff_per_data_vc, + int number_of_buff_per_ctrl_vc); + + string fault_type_to_string(int fault_type_index); + + // the following 2 functions are called at runtime, to get the probability + // of each fault type (fault_vector) or the aggregate fault probability + // (fault_prob). Note: the probability values are provided by reference + // (in the variables fault_vector[] & aggregate_fault_prob respectively). + // Both functions also return a success flag (which is always true if + // temperature ranges from 0C to 125C) + + bool fault_vector(int routerID, + int temperature, + float fault_vector[]); + + bool fault_prob(int routerID, + int temperature, + float *aggregate_fault_prob); + + // for debugging purposes + + void print(void); + + private: + vector <system_conf> configurations; + vector <system_conf> routers; + vector <int> temperature_weights; +}; + +#endif // __MEM_RUBY_NETWORK_FAULT_MODEL_HH__ diff --git a/src/mem/ruby/network/fault_model/FaultModel.py b/src/mem/ruby/network/fault_model/FaultModel.py new file mode 100644 index 000000000..5117491f2 --- /dev/null +++ b/src/mem/ruby/network/fault_model/FaultModel.py @@ -0,0 +1,302 @@ +# Copyright (c) 2011 Massachusetts Institute of Technology +# 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. +# +# Authors: Konstantinos Aisopos + +# Official Tool Website: www.mit.edu/~kaisopos/FaultModel +# +# If you use our tool for academic research, we request that you cite: +# Konstantinos Aisopos, Chia-Hsin Owen Chen, and Li-Shiuan Peh. Enabling +# System-Level Modeling of Variation-Induced Faults in Networks-on-Chip. +# Proceedings of the 48th Design Automation Conference (DAC'11) + +from m5.params import * +from m5.SimObject import SimObject + +class FaultModel(SimObject): + type = 'FaultModel' + cxx_class = 'FaultModel' + + baseline_fault_vector_database = VectorParam.Float([ + 5, 40, 0.080892, 0.109175, 0.018864, 0.130408, 0.059724, 0.077571, 0.034830, 0.083430, 0.067500, 0.121500, + 5, 39, 0.062640, 0.089100, 0.016821, 0.109620, 0.051462, 0.060210, 0.029700, 0.076140, 0.062100, 0.116100, + 5, 38, 0.050490, 0.076950, 0.015782, 0.091530, 0.044550, 0.046170, 0.025920, 0.070200, 0.057294, 0.110700, + 5, 37, 0.042120, 0.067770, 0.014191, 0.082890, 0.040986, 0.037800, 0.023760, 0.065880, 0.053568, 0.104490, + 5, 36, 0.035910, 0.061020, 0.013211, 0.075600, 0.035100, 0.030240, 0.021060, 0.061560, 0.049815, 0.100710, + 5, 35, 0.032130, 0.054810, 0.011964, 0.071550, 0.031860, 0.026730, 0.019710, 0.057510, 0.047169, 0.094230, + 5, 34, 0.028890, 0.051030, 0.011054, 0.067500, 0.030510, 0.023450, 0.018630, 0.054000, 0.045900, 0.088290, + 5, 33, 0.026460, 0.047250, 0.010160, 0.062640, 0.028971, 0.021600, 0.017280, 0.049410, 0.042903, 0.082080, + 5, 32, 0.024300, 0.042930, 0.009312, 0.057780, 0.027000, 0.019710, 0.016470, 0.045360, 0.041310, 0.075600, + 5, 31, 0.022410, 0.037260, 0.008910, 0.054540, 0.024732, 0.018171, 0.015660, 0.043470, 0.039447, 0.070740, + 5, 30, 0.021870, 0.032130, 0.008162, 0.050220, 0.023625, 0.016762, 0.013770, 0.039150, 0.037557, 0.065880, + 5, 29, 0.020790, 0.028080, 0.007657, 0.042660, 0.020061, 0.016043, 0.012690, 0.036720, 0.035451, 0.062370, + 5, 28, 0.019440, 0.025650, 0.007123, 0.037800, 0.018900, 0.015363, 0.011880, 0.033480, 0.032400, 0.057780, + 5, 27, 0.018473, 0.023760, 0.006737, 0.034830, 0.018036, 0.014153, 0.011232, 0.030240, 0.030645, 0.055890, + 5, 26, 0.017550, 0.021330, 0.006440, 0.032130, 0.016497, 0.013511, 0.010031, 0.027621, 0.028242, 0.051030, + 5, 25, 0.016462, 0.020520, 0.006210, 0.028890, 0.015822, 0.013095, 0.009442, 0.021600, 0.026379, 0.046170, + 5, 24, 0.015930, 0.018360, 0.005940, 0.026730, 0.015047, 0.012377, 0.008918, 0.018360, 0.023193, 0.037800, + 5, 23, 0.015390, 0.017931, 0.005594, 0.025488, 0.013365, 0.012037, 0.008775, 0.015120, 0.018657, 0.031590, + 5, 22, 0.014804, 0.017167, 0.005338, 0.023976, 0.012258, 0.011734, 0.008087, 0.013500, 0.015444, 0.026190, + 5, 21, 0.014180, 0.016548, 0.004995, 0.022194, 0.011807, 0.011073, 0.007236, 0.011070, 0.013500, 0.021870, + 5, 20, 0.013743, 0.016176, 0.004613, 0.020414, 0.011070, 0.010415, 0.006220, 0.010415, 0.010800, 0.019077, + 5, 19, 0.011877, 0.015412, 0.003861, 0.016659, 0.008235, 0.008640, 0.005400, 0.009720, 0.008532, 0.013770, + 5, 18, 0.011097, 0.014310, 0.003483, 0.014526, 0.006912, 0.007560, 0.003780, 0.008640, 0.006885, 0.010260, + 5, 17, 0.010419, 0.011939, 0.002700, 0.011394, 0.005400, 0.006318, 0.003038, 0.008100, 0.005400, 0.009450, + 5, 16, 0.009887, 0.009720, 0.002395, 0.010152, 0.004023, 0.005400, 0.002743, 0.007020, 0.004590, 0.008370, + 5, 15, 0.009617, 0.007825, 0.002079, 0.008289, 0.003780, 0.004806, 0.002236, 0.006480, 0.003996, 0.008127, + 5, 14, 0.008710, 0.006820, 0.001817, 0.007749, 0.003240, 0.004185, 0.001760, 0.005400, 0.002538, 0.006615, + 5, 13, 0.008116, 0.006566, 0.001566, 0.006426, 0.002741, 0.003564, 0.001299, 0.004590, 0.001917, 0.005994, + 5, 12, 0.007908, 0.006151, 0.001350, 0.005400, 0.002471, 0.003132, 0.000794, 0.004050, 0.001323, 0.005940, + 5, 11, 0.007690, 0.005627, 0.001094, 0.005076, 0.002363, 0.002052, 0.000567, 0.003510, 0.001188, 0.004860, + 5, 10, 0.007560, 0.005038, 0.000805, 0.004536, 0.001985, 0.000540, 0.000000, 0.002430, 0.000999, 0.003240, + 5, 9, 0.007314, 0.004193, 0.000540, 0.003834, 0.001715, 0.000000, 0.000000, 0.002160, 0.000945, 0.002700, + 5, 8, 0.006750, 0.003240, 0.000000, 0.003240, 0.001323, 0.000000, 0.000000, 0.001350, 0.000837, 0.002646, + 5, 7, 0.006461, 0.002700, 0.000000, 0.002700, 0.001215, 0.000000, 0.000000, 0.000000, 0.000810, 0.001809, + 5, 6, 0.006240, 0.001796, 0.000000, 0.002052, 0.001013, 0.000000, 0.000000, 0.000000, 0.000756, 0.001620, + 5, 5, 0.005430, 0.000675, 0.000000, 0.000864, 0.000864, 0.000000, 0.000000, 0.000000, 0.000729, 0.001593, + 5, 4, 0.003780, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.001080, + 5, 3, 0.001350, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000540, + 5, 2, 0.000540, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000270, + 5, 1, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 4, 40, 0.079484, 0.106785, 0.018198, 0.122699, 0.057538, 0.076974, 0.034813, 0.079276, 0.061426, 0.112509, + 4, 39, 0.062146, 0.088671, 0.016205, 0.108082, 0.050454, 0.059905, 0.029600, 0.075465, 0.057362, 0.106596, + 4, 38, 0.050047, 0.076478, 0.014924, 0.090994, 0.043475, 0.045808, 0.025794, 0.069220, 0.054351, 0.101993, + 4, 37, 0.041712, 0.067272, 0.013551, 0.082516, 0.040026, 0.037390, 0.023580, 0.064897, 0.051395, 0.097511, + 4, 36, 0.035384, 0.060487, 0.012434, 0.075287, 0.034229, 0.029784, 0.020859, 0.060167, 0.048222, 0.094055, + 4, 35, 0.031455, 0.054259, 0.011290, 0.071141, 0.031259, 0.026055, 0.019560, 0.055478, 0.045887, 0.088965, + 4, 34, 0.028307, 0.050427, 0.010342, 0.067048, 0.029835, 0.022525, 0.018495, 0.052523, 0.044253, 0.083727, + 4, 33, 0.025847, 0.046687, 0.009384, 0.062196, 0.028000, 0.020646, 0.017102, 0.048735, 0.041837, 0.079286, + 4, 32, 0.023688, 0.042449, 0.008645, 0.057303, 0.026070, 0.018765, 0.016315, 0.045001, 0.040163, 0.073143, + 4, 31, 0.021905, 0.036781, 0.008235, 0.054011, 0.024200, 0.017496, 0.015528, 0.042795, 0.038273, 0.068675, + 4, 30, 0.021195, 0.031563, 0.007456, 0.049545, 0.022757, 0.016081, 0.013646, 0.038817, 0.036410, 0.063086, + 4, 29, 0.020115, 0.027494, 0.006992, 0.042302, 0.019517, 0.015096, 0.012562, 0.035562, 0.034223, 0.059954, + 4, 28, 0.018889, 0.025040, 0.006472, 0.037295, 0.018383, 0.014540, 0.011760, 0.032949, 0.032022, 0.055782, + 4, 27, 0.017630, 0.023150, 0.006055, 0.034262, 0.017183, 0.013759, 0.010949, 0.029876, 0.030294, 0.053339, + 4, 26, 0.016875, 0.020762, 0.005743, 0.031664, 0.016002, 0.013123, 0.009740, 0.026487, 0.027824, 0.048681, + 4, 25, 0.015930, 0.019660, 0.005516, 0.028215, 0.015147, 0.012420, 0.009311, 0.020643, 0.025988, 0.043443, + 4, 24, 0.015425, 0.017790, 0.005211, 0.026190, 0.014530, 0.011838, 0.008783, 0.017314, 0.022518, 0.035681, + 4, 23, 0.014947, 0.017314, 0.004878, 0.024813, 0.012897, 0.011507, 0.008451, 0.014445, 0.017982, 0.029673, + 4, 22, 0.014430, 0.016278, 0.004610, 0.023077, 0.011945, 0.011148, 0.007918, 0.012825, 0.015107, 0.023814, + 4, 21, 0.013643, 0.015699, 0.004320, 0.021686, 0.011598, 0.010383, 0.007113, 0.010395, 0.013176, 0.019197, + 4, 20, 0.013023, 0.015244, 0.003995, 0.019155, 0.010935, 0.009227, 0.005914, 0.009227, 0.010665, 0.016234, + 4, 19, 0.011185, 0.014467, 0.003186, 0.015718, 0.007822, 0.007965, 0.005273, 0.008374, 0.008262, 0.012623, + 4, 18, 0.010399, 0.013419, 0.002808, 0.013696, 0.006681, 0.006885, 0.003579, 0.007579, 0.006197, 0.009315, + 4, 17, 0.009773, 0.011089, 0.002025, 0.010882, 0.005054, 0.005881, 0.002928, 0.007101, 0.004914, 0.008100, + 4, 16, 0.009054, 0.009054, 0.001743, 0.009477, 0.003799, 0.005081, 0.002365, 0.006345, 0.003942, 0.007061, + 4, 15, 0.008575, 0.006882, 0.001404, 0.007792, 0.003449, 0.004131, 0.001793, 0.005327, 0.002903, 0.006264, + 4, 14, 0.008069, 0.005655, 0.001169, 0.006920, 0.002808, 0.003510, 0.001277, 0.004307, 0.001782, 0.005184, + 4, 13, 0.007668, 0.005173, 0.000986, 0.005751, 0.002336, 0.002889, 0.000919, 0.003609, 0.001283, 0.004631, + 4, 12, 0.007403, 0.004563, 0.000675, 0.004852, 0.002066, 0.002457, 0.000532, 0.003083, 0.000662, 0.004374, + 4, 11, 0.007152, 0.004127, 0.000547, 0.004401, 0.001937, 0.001377, 0.000284, 0.002473, 0.000594, 0.003456, + 4, 10, 0.006885, 0.003530, 0.000402, 0.003920, 0.001613, 0.000405, 0.000000, 0.001755, 0.000500, 0.002565, + 4, 9, 0.006746, 0.002920, 0.000270, 0.003159, 0.001404, 0.000000, 0.000000, 0.001485, 0.000473, 0.002025, + 4, 8, 0.006257, 0.002290, 0.000000, 0.002565, 0.001107, 0.000000, 0.000000, 0.000675, 0.000419, 0.001971, + 4, 7, 0.005931, 0.001825, 0.000000, 0.002025, 0.000999, 0.000000, 0.000000, 0.000000, 0.000405, 0.001134, + 4, 6, 0.005585, 0.001199, 0.000000, 0.001463, 0.000844, 0.000000, 0.000000, 0.000000, 0.000378, 0.000945, + 4, 5, 0.004967, 0.000545, 0.000000, 0.000637, 0.000695, 0.000000, 0.000000, 0.000000, 0.000405, 0.000864, + 4, 4, 0.003105, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000540, + 4, 3, 0.000888, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000270, + 4, 2, 0.000270, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000135, + 4, 1, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 3, 40, 0.078075, 0.104396, 0.017531, 0.114991, 0.055352, 0.076378, 0.034795, 0.075122, 0.055352, 0.103518, + 3, 39, 0.061652, 0.088241, 0.015590, 0.106545, 0.049445, 0.059600, 0.029500, 0.074790, 0.052623, 0.097092, + 3, 38, 0.049604, 0.076005, 0.014067, 0.090458, 0.042401, 0.045446, 0.025669, 0.068240, 0.051408, 0.093285, + 3, 37, 0.041305, 0.066774, 0.012911, 0.082142, 0.039066, 0.036979, 0.023401, 0.063914, 0.049221, 0.090531, + 3, 36, 0.034857, 0.059954, 0.011656, 0.074974, 0.033359, 0.029327, 0.020658, 0.058774, 0.046629, 0.087399, + 3, 35, 0.030780, 0.053708, 0.010616, 0.070732, 0.030659, 0.025380, 0.019410, 0.053447, 0.044604, 0.083700, + 3, 34, 0.027724, 0.049823, 0.009631, 0.066596, 0.029160, 0.021600, 0.018360, 0.051046, 0.042606, 0.079164, + 3, 33, 0.025234, 0.046124, 0.008608, 0.061752, 0.027030, 0.019691, 0.016924, 0.048060, 0.040770, 0.076491, + 3, 32, 0.023077, 0.041969, 0.007979, 0.056827, 0.025140, 0.017820, 0.016160, 0.044642, 0.039015, 0.070686, + 3, 31, 0.021400, 0.036302, 0.007560, 0.053482, 0.023668, 0.016821, 0.015395, 0.042120, 0.037098, 0.066609, + 3, 30, 0.020520, 0.030996, 0.006750, 0.048870, 0.021889, 0.015401, 0.013522, 0.038483, 0.035262, 0.060291, + 3, 29, 0.019440, 0.026908, 0.006326, 0.041945, 0.018973, 0.014148, 0.012434, 0.034403, 0.032994, 0.057537, + 3, 28, 0.018338, 0.024430, 0.005821, 0.036790, 0.017866, 0.013716, 0.011640, 0.032419, 0.031644, 0.053784, + 3, 27, 0.016786, 0.022540, 0.005373, 0.033693, 0.016330, 0.013365, 0.010665, 0.029511, 0.029943, 0.050787, + 3, 26, 0.016200, 0.020193, 0.005046, 0.031199, 0.015506, 0.012736, 0.009450, 0.025353, 0.027405, 0.046332, + 3, 25, 0.015398, 0.018800, 0.004822, 0.027540, 0.014472, 0.011745, 0.009180, 0.019686, 0.025596, 0.040716, + 3, 24, 0.014920, 0.017221, 0.004482, 0.025650, 0.014013, 0.011300, 0.008648, 0.016268, 0.021843, 0.033561, + 3, 23, 0.014504, 0.016697, 0.004161, 0.024138, 0.012428, 0.010978, 0.008127, 0.013770, 0.017307, 0.027756, + 3, 22, 0.014056, 0.015390, 0.003883, 0.022178, 0.011632, 0.010562, 0.007749, 0.012150, 0.014769, 0.021438, + 3, 21, 0.013106, 0.014850, 0.003645, 0.021179, 0.011389, 0.009693, 0.006990, 0.009720, 0.012852, 0.016524, + 3, 20, 0.012304, 0.014313, 0.003378, 0.017896, 0.010800, 0.008039, 0.005608, 0.008039, 0.010530, 0.013392, + 3, 19, 0.010492, 0.013522, 0.002511, 0.014777, 0.007409, 0.007290, 0.005146, 0.007028, 0.007992, 0.011475, + 3, 18, 0.009701, 0.012528, 0.002133, 0.012866, 0.006450, 0.006210, 0.003378, 0.006518, 0.005508, 0.008370, + 3, 17, 0.009126, 0.010238, 0.001350, 0.010371, 0.004709, 0.005443, 0.002819, 0.006102, 0.004428, 0.006750, + 3, 16, 0.008222, 0.008389, 0.001091, 0.008802, 0.003575, 0.004763, 0.001987, 0.005670, 0.003294, 0.005751, + 3, 15, 0.007533, 0.005940, 0.000729, 0.007295, 0.003119, 0.003456, 0.001350, 0.004174, 0.001809, 0.004401, + 3, 14, 0.007428, 0.004490, 0.000521, 0.006091, 0.002376, 0.002835, 0.000794, 0.003213, 0.001026, 0.003753, + 3, 13, 0.007220, 0.003780, 0.000405, 0.005076, 0.001931, 0.002214, 0.000540, 0.002627, 0.000648, 0.003267, + 3, 12, 0.006899, 0.002975, 0.000000, 0.004304, 0.001661, 0.001782, 0.000270, 0.002117, 0.000000, 0.002808, + 3, 11, 0.006615, 0.002627, 0.000000, 0.003726, 0.001512, 0.000702, 0.000000, 0.001436, 0.000000, 0.002052, + 3, 10, 0.006210, 0.002022, 0.000000, 0.003305, 0.001242, 0.000270, 0.000000, 0.001080, 0.000000, 0.001890, + 3, 9, 0.006178, 0.001647, 0.000000, 0.002484, 0.001094, 0.000000, 0.000000, 0.000810, 0.000000, 0.001350, + 3, 8, 0.005765, 0.001339, 0.000000, 0.001890, 0.000891, 0.000000, 0.000000, 0.000000, 0.000000, 0.001296, + 3, 7, 0.005400, 0.000950, 0.000000, 0.001350, 0.000783, 0.000000, 0.000000, 0.000000, 0.000000, 0.000459, + 3, 6, 0.004930, 0.000602, 0.000000, 0.000875, 0.000675, 0.000000, 0.000000, 0.000000, 0.000000, 0.000270, + 3, 5, 0.004504, 0.000416, 0.000000, 0.000410, 0.000527, 0.000000, 0.000000, 0.000000, 0.000081, 0.000135, + 3, 4, 0.002430, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 3, 3, 0.000427, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 3, 2, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 3, 1, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 2, 40, 0.077418, 0.103451, 0.016828, 0.109064, 0.054341, 0.075962, 0.034795, 0.075122, 0.051976, 0.081459, + 2, 39, 0.060720, 0.087215, 0.014756, 0.103532, 0.048041, 0.059297, 0.029376, 0.074115, 0.050193, 0.077382, + 2, 38, 0.048859, 0.074947, 0.013362, 0.089180, 0.041598, 0.045021, 0.025537, 0.066803, 0.048722, 0.074655, + 2, 37, 0.040158, 0.065781, 0.012126, 0.080282, 0.038175, 0.036686, 0.023178, 0.062884, 0.047088, 0.072630, + 2, 36, 0.033881, 0.058774, 0.011001, 0.072895, 0.032542, 0.028434, 0.020461, 0.057424, 0.045225, 0.069728, + 2, 35, 0.030294, 0.052831, 0.009800, 0.069422, 0.029587, 0.024311, 0.019232, 0.052294, 0.043254, 0.067311, + 2, 34, 0.026957, 0.048824, 0.008847, 0.065224, 0.028054, 0.020655, 0.018095, 0.049876, 0.041553, 0.064112, + 2, 33, 0.024349, 0.045159, 0.007976, 0.060371, 0.026226, 0.018652, 0.016776, 0.047385, 0.039704, 0.061695, + 2, 32, 0.022078, 0.040951, 0.007202, 0.055330, 0.024365, 0.017145, 0.016065, 0.043944, 0.037719, 0.057699, + 2, 31, 0.020733, 0.035223, 0.006791, 0.052327, 0.022850, 0.015790, 0.015233, 0.041124, 0.035964, 0.054810, + 2, 30, 0.019626, 0.029984, 0.006021, 0.046551, 0.021086, 0.014673, 0.013133, 0.037757, 0.034007, 0.049923, + 2, 29, 0.018765, 0.025923, 0.005677, 0.039731, 0.018291, 0.013707, 0.011973, 0.033543, 0.031847, 0.047048, + 2, 28, 0.017539, 0.023491, 0.005192, 0.035180, 0.017033, 0.013349, 0.011092, 0.031296, 0.029970, 0.044240, + 2, 27, 0.016270, 0.021488, 0.004753, 0.032258, 0.015628, 0.012909, 0.010419, 0.028179, 0.028202, 0.041756, + 2, 26, 0.015525, 0.019557, 0.004390, 0.029942, 0.014652, 0.012207, 0.009339, 0.024975, 0.025745, 0.037679, + 2, 25, 0.014638, 0.018036, 0.004146, 0.026314, 0.013797, 0.011314, 0.009099, 0.018864, 0.023517, 0.032832, + 2, 24, 0.014075, 0.016575, 0.003788, 0.024444, 0.013045, 0.010780, 0.008541, 0.015587, 0.019710, 0.028013, + 2, 23, 0.013597, 0.015638, 0.003430, 0.022970, 0.011632, 0.010471, 0.008031, 0.012675, 0.015296, 0.023004, + 2, 22, 0.012968, 0.014715, 0.003089, 0.021096, 0.010990, 0.009929, 0.007642, 0.010846, 0.012825, 0.017253, + 2, 21, 0.012088, 0.014175, 0.002884, 0.020046, 0.010148, 0.009032, 0.006813, 0.008261, 0.010449, 0.013500, + 2, 20, 0.010976, 0.013381, 0.002693, 0.016732, 0.009381, 0.007742, 0.005400, 0.006437, 0.008100, 0.010841, + 2, 19, 0.009566, 0.012631, 0.001836, 0.013686, 0.007125, 0.006782, 0.003923, 0.005431, 0.005589, 0.008613, + 2, 18, 0.008982, 0.011349, 0.001458, 0.011744, 0.005708, 0.005742, 0.002724, 0.004884, 0.003618, 0.006764, + 2, 17, 0.008273, 0.009439, 0.000845, 0.009291, 0.004250, 0.004857, 0.002327, 0.004469, 0.002673, 0.004847, + 2, 16, 0.007679, 0.007704, 0.000545, 0.007737, 0.003394, 0.003988, 0.001534, 0.004045, 0.001742, 0.003834, + 2, 15, 0.007236, 0.005265, 0.000365, 0.006442, 0.002565, 0.003089, 0.000675, 0.003023, 0.000959, 0.002808, + 2, 14, 0.007090, 0.003787, 0.000261, 0.004990, 0.001802, 0.002400, 0.000397, 0.002249, 0.000608, 0.002457, + 2, 13, 0.006877, 0.003029, 0.000203, 0.004076, 0.001404, 0.001835, 0.000270, 0.001814, 0.000324, 0.002012, + 2, 12, 0.006575, 0.002311, 0.000000, 0.003502, 0.001249, 0.001458, 0.000135, 0.001436, 0.000000, 0.001850, + 2, 11, 0.006314, 0.001836, 0.000000, 0.003051, 0.001114, 0.000597, 0.000000, 0.000841, 0.000000, 0.001350, + 2, 10, 0.005971, 0.001434, 0.000000, 0.002570, 0.000945, 0.000230, 0.000000, 0.000540, 0.000000, 0.001215, + 2, 9, 0.005627, 0.001172, 0.000000, 0.001809, 0.000783, 0.000019, 0.000000, 0.000405, 0.000000, 0.000675, + 2, 8, 0.005144, 0.000940, 0.000000, 0.001276, 0.000668, 0.000038, 0.000000, 0.000000, 0.000000, 0.000648, + 2, 7, 0.004686, 0.000622, 0.000000, 0.000890, 0.000581, 0.000009, 0.000000, 0.000000, 0.000000, 0.000230, + 2, 6, 0.004247, 0.000428, 0.000000, 0.000541, 0.000473, 0.000019, 0.000000, 0.000000, 0.000000, 0.000135, + 2, 5, 0.003857, 0.000269, 0.000000, 0.000320, 0.000419, 0.000000, 0.000000, 0.000000, 0.000041, 0.000068, + 2, 4, 0.001459, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 2, 3, 0.000213, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 2, 2, 0.000011, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 2, 1, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 1, 40, 0.076761, 0.102506, 0.016124, 0.103138, 0.053330, 0.075546, 0.034795, 0.075122, 0.048600, 0.059400, + 1, 39, 0.059789, 0.086189, 0.013921, 0.100518, 0.046637, 0.058995, 0.029252, 0.073440, 0.047763, 0.057672, + 1, 38, 0.048114, 0.073888, 0.012658, 0.087901, 0.040794, 0.044596, 0.025404, 0.065367, 0.046035, 0.056025, + 1, 37, 0.039012, 0.064789, 0.011340, 0.078422, 0.037284, 0.036393, 0.022955, 0.061854, 0.044955, 0.054729, + 1, 36, 0.032905, 0.057594, 0.010346, 0.070816, 0.031725, 0.027540, 0.020264, 0.056074, 0.043821, 0.052056, + 1, 35, 0.029808, 0.051953, 0.008983, 0.068113, 0.028515, 0.023242, 0.019054, 0.051141, 0.041904, 0.050922, + 1, 34, 0.026190, 0.047825, 0.008062, 0.063852, 0.026949, 0.019710, 0.017831, 0.048705, 0.040500, 0.049059, + 1, 33, 0.023463, 0.044194, 0.007344, 0.058990, 0.025423, 0.017612, 0.016629, 0.046710, 0.038637, 0.046899, + 1, 32, 0.021079, 0.039933, 0.006426, 0.053833, 0.023590, 0.016470, 0.015971, 0.043246, 0.036423, 0.044712, + 1, 31, 0.020066, 0.034144, 0.006021, 0.051173, 0.022032, 0.014758, 0.015071, 0.040127, 0.034830, 0.043011, + 1, 30, 0.018733, 0.028971, 0.005292, 0.044231, 0.020282, 0.013946, 0.012744, 0.037031, 0.032751, 0.039555, + 1, 29, 0.018090, 0.024937, 0.005027, 0.037517, 0.017609, 0.013265, 0.011513, 0.032684, 0.030699, 0.036558, + 1, 28, 0.016740, 0.022553, 0.004563, 0.033569, 0.016200, 0.012982, 0.010544, 0.030173, 0.028296, 0.034695, + 1, 27, 0.015755, 0.020436, 0.004134, 0.030823, 0.014926, 0.012452, 0.010174, 0.026846, 0.026460, 0.032724, + 1, 26, 0.014850, 0.018922, 0.003734, 0.028685, 0.013797, 0.011678, 0.009229, 0.024597, 0.024084, 0.029025, + 1, 25, 0.013878, 0.017272, 0.003470, 0.025088, 0.013122, 0.010884, 0.009018, 0.018041, 0.021438, 0.024948, + 1, 24, 0.013230, 0.015930, 0.003094, 0.023239, 0.012077, 0.010260, 0.008435, 0.014907, 0.017577, 0.022464, + 1, 23, 0.012690, 0.014580, 0.002700, 0.021803, 0.010835, 0.009963, 0.007935, 0.011580, 0.013284, 0.018252, + 1, 22, 0.011880, 0.014040, 0.002295, 0.020015, 0.010349, 0.009296, 0.007536, 0.009542, 0.010881, 0.013068, + 1, 21, 0.011070, 0.013500, 0.002122, 0.018914, 0.008907, 0.008370, 0.006637, 0.006801, 0.008046, 0.010476, + 1, 20, 0.009647, 0.012450, 0.002009, 0.015568, 0.007962, 0.007444, 0.005192, 0.004836, 0.005670, 0.008289, + 1, 19, 0.008640, 0.011740, 0.001161, 0.012596, 0.006842, 0.006275, 0.002700, 0.003834, 0.003186, 0.005751, + 1, 18, 0.008262, 0.010171, 0.000783, 0.010622, 0.004965, 0.005273, 0.002071, 0.003251, 0.001728, 0.005157, + 1, 17, 0.007420, 0.008640, 0.000340, 0.008211, 0.003791, 0.004271, 0.001836, 0.002835, 0.000918, 0.002943, + 1, 16, 0.007136, 0.007020, 0.000000, 0.006672, 0.003213, 0.003213, 0.001080, 0.002419, 0.000189, 0.001917, + 1, 15, 0.006939, 0.004590, 0.000000, 0.005589, 0.002012, 0.002722, 0.000000, 0.001871, 0.000108, 0.001215, + 1, 14, 0.006753, 0.003083, 0.000000, 0.003888, 0.001229, 0.001966, 0.000000, 0.001285, 0.000189, 0.001161, + 1, 13, 0.006534, 0.002279, 0.000000, 0.003075, 0.000878, 0.001455, 0.000000, 0.001002, 0.000000, 0.000756, + 1, 12, 0.006251, 0.001647, 0.000000, 0.002700, 0.000837, 0.001134, 0.000000, 0.000756, 0.000000, 0.000891, + 1, 11, 0.006013, 0.001045, 0.000000, 0.002376, 0.000716, 0.000491, 0.000000, 0.000246, 0.000000, 0.000648, + 1, 10, 0.005732, 0.000845, 0.000000, 0.001836, 0.000648, 0.000189, 0.000000, 0.000000, 0.000000, 0.000540, + 1, 9, 0.005076, 0.000697, 0.000000, 0.001134, 0.000473, 0.000038, 0.000000, 0.000000, 0.000000, 0.000000, + 1, 8, 0.004523, 0.000540, 0.000000, 0.000662, 0.000446, 0.000076, 0.000000, 0.000000, 0.000000, 0.000000, + 1, 7, 0.003972, 0.000294, 0.000000, 0.000429, 0.000378, 0.000019, 0.000000, 0.000000, 0.000000, 0.000000, + 1, 6, 0.003564, 0.000254, 0.000000, 0.000208, 0.000270, 0.000038, 0.000000, 0.000000, 0.000000, 0.000000, + 1, 5, 0.003210, 0.000122, 0.000000, 0.000230, 0.000311, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 1, 4, 0.000489, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 1, 3, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 1, 2, 0.000022, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + 1, 1, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, + -1], ""); + + temperature_weights_database = VectorParam.Int([ + 71, 1, + 72, 2, + 73, 3, + 74, 4, + 75, 5, + 76, 5, + 77, 6, + 78, 7, + 79, 8, + 80, 10, + 81, 11, + 82, 12, + 83, 12, + 84, 13, + 85, 14, + 86, 16, + 87, 17, + 88, 18, + 89, 19, + 90, 20, + 91, 22, + 92, 24, + 93, 26, + 94, 27, + 95, 29, + 96, 30, + 97, 32, + 98, 35, + 99, 37, + 100, 39, + 101, 42, + 102, 45, + 103, 47, + 104, 50, + 105, 53, + 106, 56, + 107, 61, + 108, 65, + 109, 70, + 110, 74, + 111, 78, + 112, 82, + 113, 89, + 114, 95, + 115, 100, + 116, 106, + 117, 115, + 118, 122, + 119, 130, + 120, 139, + 121, 147, + 122, 156, + 123, 169, + 124, 178, + 125, 190, + -1], ""); diff --git a/src/mem/ruby/network/fault_model/SConscript b/src/mem/ruby/network/fault_model/SConscript new file mode 100644 index 000000000..ade3eca64 --- /dev/null +++ b/src/mem/ruby/network/fault_model/SConscript @@ -0,0 +1,43 @@ +# Copyright (c) 2011 Massachusetts Institute of Technology +# 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. +# +# Authors: Konstantinos Aisopos + +# Official Tool Website: www.mit.edu/~kaisopos/FaultModel +# +# If you use our tool for academic research, we request that you cite: +# Konstantinos Aisopos, Chia-Hsin Owen Chen, and Li-Shiuan Peh. Enabling +# System-Level Modeling of Variation-Induced Faults in Networks-on-Chip. +# Proceedings of the 48th Design Automation Conference (DAC'11) + +Import('*') + +if env['PROTOCOL'] == 'None': + Return() + +SimObject('FaultModel.py') +Source('FaultModel.cc') + diff --git a/src/mem/ruby/network/garnet/BaseGarnetNetwork.cc b/src/mem/ruby/network/garnet/BaseGarnetNetwork.cc index e3eb73b0a..cd4ca0af1 100644 --- a/src/mem/ruby/network/garnet/BaseGarnetNetwork.cc +++ b/src/mem/ruby/network/garnet/BaseGarnetNetwork.cc @@ -38,6 +38,9 @@ BaseGarnetNetwork::BaseGarnetNetwork(const Params *p) { m_ni_flit_size = p->ni_flit_size; m_vcs_per_vnet = p->vcs_per_vnet; + m_enable_fault_model = p->enable_fault_model; + if (m_enable_fault_model) + fault_model = p->fault_model; m_ruby_start = 0; m_flits_received = 0; diff --git a/src/mem/ruby/network/garnet/BaseGarnetNetwork.hh b/src/mem/ruby/network/garnet/BaseGarnetNetwork.hh index 95d4c5f5c..52079d8f6 100644 --- a/src/mem/ruby/network/garnet/BaseGarnetNetwork.hh +++ b/src/mem/ruby/network/garnet/BaseGarnetNetwork.hh @@ -38,6 +38,7 @@ #include "mem/ruby/network/garnet/NetworkHeader.hh" #include "mem/ruby/network/Network.hh" +#include "mem/ruby/network/fault_model/FaultModel.hh" #include "params/BaseGarnetNetwork.hh" #include "math.h" @@ -50,10 +51,13 @@ class BaseGarnetNetwork : public Network void init(); int getNiFlitSize() {return m_ni_flit_size; } int getVCsPerVnet() {return m_vcs_per_vnet; } + bool isFaultModelEnabled() {return m_enable_fault_model;} + FaultModel* fault_model; protected: int m_ni_flit_size; int m_vcs_per_vnet; + bool m_enable_fault_model; int m_flits_received; int m_flits_injected; diff --git a/src/mem/ruby/network/garnet/BaseGarnetNetwork.py b/src/mem/ruby/network/garnet/BaseGarnetNetwork.py index 8073131f4..2431db203 100644 --- a/src/mem/ruby/network/garnet/BaseGarnetNetwork.py +++ b/src/mem/ruby/network/garnet/BaseGarnetNetwork.py @@ -36,3 +36,5 @@ class BaseGarnetNetwork(RubyNetwork): abstract = True ni_flit_size = Param.Int(16, "network interface flit size in bytes") vcs_per_vnet = Param.Int(4, "virtual channels per virtual network"); + enable_fault_model = Param.Bool(False, "enable network fault model"); + fault_model = Param.FaultModel(NULL, "network fault model"); diff --git a/src/mem/ruby/network/garnet/NetworkHeader.hh b/src/mem/ruby/network/garnet/NetworkHeader.hh index 713c49439..eccb4b31c 100644 --- a/src/mem/ruby/network/garnet/NetworkHeader.hh +++ b/src/mem/ruby/network/garnet/NetworkHeader.hh @@ -31,9 +31,6 @@ #ifndef __MEM_RUBY_NETWORK_GARNET_NETWORKHEADER_HH__ #define __MEM_RUBY_NETWORK_GARNET_NETWORKHEADER_HH__ -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" - enum flit_type {HEAD_, BODY_, TAIL_, HEAD_TAIL_, NUM_FLIT_TYPE_}; enum VC_state_type {IDLE_, VC_AB_, ACTIVE_, NUM_VC_STATE_TYPE_}; enum VNET_type {CTRL_VNET_, DATA_VNET_, NULL_VNET_, NUM_VNET_TYPE_}; diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc index be9a92305..fccd73ee2 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc @@ -97,6 +97,23 @@ GarnetNetwork_d::init() NetworkLink_d* net_link = safe_cast<NetworkLink_d*>(*i); net_link->init_net_ptr(this); } + + // FaultModel: declare each router to the fault model + if(isFaultModelEnabled()){ + for (vector<Router_d*>::const_iterator i= m_router_ptr_vector.begin(); + i != m_router_ptr_vector.end(); ++i) { + Router_d* router = safe_cast<Router_d*>(*i); + int router_id=fault_model->declare_router(router->get_num_inports(), + router->get_num_outports(), + router->get_vc_per_vnet(), + getBuffersPerDataVC(), + getBuffersPerCtrlVC()); + assert(router_id == router->get_id()); + router->printAggregateFaultProbability(cout); + router->printFaultVector(cout); + } + } + } GarnetNetwork_d::~GarnetNetwork_d() diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh index 2030bb4f0..a7fe05a64 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh +++ b/src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh @@ -39,6 +39,7 @@ #include "mem/ruby/network/Network.hh" #include "params/GarnetNetwork_d.hh" +class FaultModel; class NetworkInterface_d; class MessageBuffer; class Router_d; diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc index 62ab5ce07..b638c9aca 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc @@ -189,6 +189,35 @@ Router_d::printConfig(ostream& out) out << "]" << endl; } +void +Router_d::printFaultVector(ostream& out) +{ + int temperature_celcius = BASELINE_TEMPERATURE_CELCIUS; + int num_fault_types = m_network_ptr->fault_model->number_of_fault_types; + float fault_vector[num_fault_types]; + get_fault_vector(temperature_celcius, fault_vector); + out << "Router-" << m_id << " fault vector: " << endl; + for (int fault_type_index = 0; fault_type_index < num_fault_types; + fault_type_index++){ + out << " - probability of ("; + out << + m_network_ptr->fault_model->fault_type_to_string(fault_type_index); + out << ") = "; + out << fault_vector[fault_type_index] << endl; + } +} + +void +Router_d::printAggregateFaultProbability(std::ostream& out) +{ + int temperature_celcius = BASELINE_TEMPERATURE_CELCIUS; + float aggregate_fault_prob; + get_aggregate_fault_probability(temperature_celcius, + &aggregate_fault_prob); + out << "Router-" << m_id << " fault probability: "; + out << aggregate_fault_prob << endl; +} + Router_d * GarnetRouter_dParams::create() { diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh index e5a3a0ce2..babc0d443 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh +++ b/src/mem/ruby/network/garnet/fixed-pipeline/Router_d.hh @@ -50,6 +50,7 @@ class RoutingUnit_d; class VCallocator_d; class SWallocator_d; class Switch_d; +class FaultModel; class Router_d : public BasicRouter { @@ -86,6 +87,8 @@ class Router_d : public BasicRouter void vcarb_req(); void swarb_req(); void printConfig(std::ostream& out); + void printFaultVector(std::ostream& out); + void printAggregateFaultProbability(std::ostream& out); double calculate_power(); void calculate_performance_numbers(); @@ -93,6 +96,15 @@ class Router_d : public BasicRouter double get_dynamic_power(){return m_power_dyn;} double get_static_power(){return m_power_sta;} double get_clk_power(){return m_clk_power;} + bool get_fault_vector(int temperature, float fault_vector[]){ + return m_network_ptr->fault_model->fault_vector(m_id, temperature, + fault_vector); + } + bool get_aggregate_fault_probability(int temperature, + float *aggregate_fault_prob){ + return m_network_ptr->fault_model->fault_prob(m_id, temperature, + aggregate_fault_prob); + } private: int m_virtual_networks, m_num_vcs, m_vc_per_vnet; diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/InVcState.hh b/src/mem/ruby/network/garnet/flexible-pipeline/InVcState.hh index 829509f64..e98bf3f7b 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/InVcState.hh +++ b/src/mem/ruby/network/garnet/flexible-pipeline/InVcState.hh @@ -31,6 +31,7 @@ #ifndef __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_IN_VC_STATE_HH__ #define __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_IN_VC_STATE_HH__ +#include "mem/ruby/common/TypeDefines.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh" class InVcState diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/OutVcState.hh b/src/mem/ruby/network/garnet/flexible-pipeline/OutVcState.hh index 17fa9141e..03ea14076 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/OutVcState.hh +++ b/src/mem/ruby/network/garnet/flexible-pipeline/OutVcState.hh @@ -31,6 +31,7 @@ #ifndef __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_OUT_VC_STATE_HH__ #define __MEM_RUBY_NETWORK_GARNET_FLEXIBLE_PIPELINE_OUT_VC_STATE_HH__ +#include "mem/ruby/common/TypeDefines.hh" #include "mem/ruby/network/garnet/NetworkHeader.hh" class OutVcState diff --git a/src/mem/ruby/network/orion/Clock.cc b/src/mem/ruby/network/orion/Clock.cc index 500d6580b..fda18cd64 100644 --- a/src/mem/ruby/network/orion/Clock.cc +++ b/src/mem/ruby/network/orion/Clock.cc @@ -137,13 +137,10 @@ void Clock::init() double router_diagonal = m_orion_cfg_ptr->get<double>("ROUTER_DIAGONAL"); double Clockwire = m_tech_param_ptr->get_ClockCap(); - double Reswire = m_tech_param_ptr->get_Reswire(); double htree_clockcap; - double htree_res; int k; double h; - double cap_clock_buf = 0; double BufferNMOSOffCurrent = m_tech_param_ptr->get_BufferNMOSOffCurrent(); double BufferPMOSOffCurrent = m_tech_param_ptr->get_BufferPMOSOffCurrent(); @@ -151,7 +148,6 @@ void Clock::init() if (m_tech_param_ptr->is_trans_type_hvt() || m_tech_param_ptr->is_trans_type_nvt()) { htree_clockcap = (4+4+2+2)*(router_diagonal*1e-6)*Clockwire; - htree_res = (4+4+2+2)*(router_diagonal*1e-6)*Reswire; wire.calc_opt_buffering(&k, &h, ((4+4+2+2)*router_diagonal*1e-6)); i_static_nmos = BufferNMOSOffCurrent*h*k*15; @@ -160,15 +156,12 @@ void Clock::init() else { htree_clockcap = (8+4+4+4+4)*(router_diagonal*1e-6)*Clockwire; - htree_res = (8+4+4+4+4)*(router_diagonal*1e-6)*Reswire; wire.calc_opt_buffering(&k, &h, ((4+4+2+2)*router_diagonal*1e-6)); i_static_nmos = BufferNMOSOffCurrent*h*k*29; i_static_pmos = BufferPMOSOffCurrent*h*k*15; } - cap_clock_buf = ((double)k)*cap_clock*h; - m_e_htree = (htree_clockcap+cap_clock)*e_factor; } else diff --git a/src/mem/ruby/network/simple/PerfectSwitch.cc b/src/mem/ruby/network/simple/PerfectSwitch.cc index 06c4ace91..f8b08d551 100644 --- a/src/mem/ruby/network/simple/PerfectSwitch.cc +++ b/src/mem/ruby/network/simple/PerfectSwitch.cc @@ -71,8 +71,7 @@ PerfectSwitch::addInPort(const vector<MessageBuffer*>& in) for (int j = 0; j < m_virtual_networks; j++) { m_in[port][j]->setConsumer(this); string desc = csprintf("[Queue from port %s %s %s to PerfectSwitch]", - NodeIDToString(m_switch_id), NodeIDToString(port), - NodeIDToString(j)); + to_string(m_switch_id), to_string(port), to_string(j)); m_in[port][j]->setDescription(desc); m_in[port][j]->setIncomingLink(port); m_in[port][j]->setVnet(j); diff --git a/src/mem/ruby/network/simple/PerfectSwitch.hh b/src/mem/ruby/network/simple/PerfectSwitch.hh index 15abec020..d761c398d 100644 --- a/src/mem/ruby/network/simple/PerfectSwitch.hh +++ b/src/mem/ruby/network/simple/PerfectSwitch.hh @@ -42,7 +42,6 @@ #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" class MessageBuffer; class NetDest; diff --git a/src/mem/ruby/network/simple/SimpleNetwork.hh b/src/mem/ruby/network/simple/SimpleNetwork.hh index fb5481b46..54e1ee36e 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.hh +++ b/src/mem/ruby/network/simple/SimpleNetwork.hh @@ -34,7 +34,6 @@ #include "mem/ruby/common/Global.hh" #include "mem/ruby/network/Network.hh" -#include "mem/ruby/system/NodeID.hh" #include "params/SimpleNetwork.hh" #include "sim/sim_object.hh" diff --git a/src/mem/ruby/network/simple/Throttle.cc b/src/mem/ruby/network/simple/Throttle.cc index 822989204..b248c6c6c 100644 --- a/src/mem/ruby/network/simple/Throttle.cc +++ b/src/mem/ruby/network/simple/Throttle.cc @@ -113,8 +113,8 @@ Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr) // Set consumer and description m_in[m_vnets]->setConsumer(this); - string desc = "[Queue to Throttle " + NodeIDToString(m_sID) + " " + - NodeIDToString(m_node) + "]"; + string desc = "[Queue to Throttle " + to_string(m_sID) + " " + + to_string(m_node) + "]"; m_in[m_vnets]->setDescription(desc); m_vnets++; } diff --git a/src/mem/ruby/network/simple/Throttle.hh b/src/mem/ruby/network/simple/Throttle.hh index 09eac79a8..28fe046b4 100644 --- a/src/mem/ruby/network/simple/Throttle.hh +++ b/src/mem/ruby/network/simple/Throttle.hh @@ -45,7 +45,6 @@ #include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/network/Network.hh" -#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/System.hh" class MessageBuffer; diff --git a/src/mem/ruby/profiler/AccessTraceForAddress.hh b/src/mem/ruby/profiler/AccessTraceForAddress.hh index 228ebcade..289b83a3a 100644 --- a/src/mem/ruby/profiler/AccessTraceForAddress.hh +++ b/src/mem/ruby/profiler/AccessTraceForAddress.hh @@ -36,7 +36,6 @@ #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Set.hh" -#include "mem/ruby/system/NodeID.hh" class Histogram; diff --git a/src/mem/ruby/profiler/AddressProfiler.hh b/src/mem/ruby/profiler/AddressProfiler.hh index e525a792f..5bce34bbb 100644 --- a/src/mem/ruby/profiler/AddressProfiler.hh +++ b/src/mem/ruby/profiler/AddressProfiler.hh @@ -38,7 +38,6 @@ #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Histogram.hh" #include "mem/ruby/profiler/AccessTraceForAddress.hh" -#include "mem/ruby/system/NodeID.hh" class Set; diff --git a/src/mem/ruby/profiler/CacheProfiler.hh b/src/mem/ruby/profiler/CacheProfiler.hh index 33cb45e85..c53db7ea8 100644 --- a/src/mem/ruby/profiler/CacheProfiler.hh +++ b/src/mem/ruby/profiler/CacheProfiler.hh @@ -39,7 +39,6 @@ #include "mem/protocol/RubyRequestType.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/Histogram.hh" -#include "mem/ruby/system/NodeID.hh" class CacheProfiler { diff --git a/src/mem/ruby/profiler/MemCntrlProfiler.hh b/src/mem/ruby/profiler/MemCntrlProfiler.hh index e6d64a2b5..a594e0d96 100644 --- a/src/mem/ruby/profiler/MemCntrlProfiler.hh +++ b/src/mem/ruby/profiler/MemCntrlProfiler.hh @@ -33,7 +33,7 @@ #include <string> #include <vector> -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/TypeDefines.hh" class MemCntrlProfiler { diff --git a/src/mem/ruby/profiler/Profiler.hh b/src/mem/ruby/profiler/Profiler.hh index 9efaf4be1..258fc6f98 100644 --- a/src/mem/ruby/profiler/Profiler.hh +++ b/src/mem/ruby/profiler/Profiler.hh @@ -64,7 +64,6 @@ #include "mem/ruby/common/Set.hh" #include "mem/ruby/system/MachineID.hh" #include "mem/ruby/system/MemoryControl.hh" -#include "mem/ruby/system/NodeID.hh" #include "params/RubyProfiler.hh" #include "sim/sim_object.hh" diff --git a/src/mem/ruby/recorder/CacheRecorder.hh b/src/mem/ruby/recorder/CacheRecorder.hh index 97a20af28..9f96f4fa0 100644 --- a/src/mem/ruby/recorder/CacheRecorder.hh +++ b/src/mem/ruby/recorder/CacheRecorder.hh @@ -41,7 +41,6 @@ #include "mem/protocol/RubyRequestType.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/recorder/TraceRecord.hh" -#include "mem/ruby/system/NodeID.hh" class Address; class TraceRecord; diff --git a/src/mem/ruby/recorder/TraceRecord.cc b/src/mem/ruby/recorder/TraceRecord.cc index aa54ee53c..79186d33b 100644 --- a/src/mem/ruby/recorder/TraceRecord.cc +++ b/src/mem/ruby/recorder/TraceRecord.cc @@ -73,17 +73,15 @@ void TraceRecord::issueRequest() const { assert(m_sequencer_ptr != NULL); - - RubyRequest request(m_data_address.getAddress(), NULL, - RubySystem::getBlockSizeBytes(), m_pc_address.getAddress(), - m_type, RubyAccessMode_User, NULL); + Request req(m_data_address.getAddress(), 0, 0); + Packet *pkt = new Packet(&req, MemCmd(MemCmd::InvalidCmd), -1); // Clear out the sequencer while (!m_sequencer_ptr->empty()) { g_eventQueue_ptr->triggerEvents(g_eventQueue_ptr->getTime() + 100); } - m_sequencer_ptr->makeRequest(request); + m_sequencer_ptr->makeRequest(pkt); // Clear out the sequencer while (!m_sequencer_ptr->empty()) { diff --git a/src/mem/ruby/recorder/TraceRecord.hh b/src/mem/ruby/recorder/TraceRecord.hh index 9ec2bdb99..42f213564 100644 --- a/src/mem/ruby/recorder/TraceRecord.hh +++ b/src/mem/ruby/recorder/TraceRecord.hh @@ -38,7 +38,6 @@ #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/Sequencer.hh" class CacheMsg; diff --git a/src/mem/ruby/recorder/Tracer.hh b/src/mem/ruby/recorder/Tracer.hh index e050b3812..cad47b28c 100644 --- a/src/mem/ruby/recorder/Tracer.hh +++ b/src/mem/ruby/recorder/Tracer.hh @@ -39,7 +39,6 @@ #include "mem/protocol/RubyRequestType.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/NodeID.hh" #include "params/RubyTracer.hh" #include "sim/sim_object.hh" #include "gzstream.hh" diff --git a/src/mem/ruby/slicc_interface/Message.hh b/src/mem/ruby/slicc_interface/Message.hh index 7fcfabe9c..c57857adb 100644 --- a/src/mem/ruby/slicc_interface/Message.hh +++ b/src/mem/ruby/slicc_interface/Message.hh @@ -33,6 +33,7 @@ #include "base/refcnt.hh" #include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/TypeDefines.hh" #include "mem/ruby/eventqueue/RubyEventQueue.hh" class Message; diff --git a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh index 18e7ad6fc..cb9830446 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh @@ -29,38 +29,12 @@ #ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_COMPONENTMAPPINGS_HH__ #define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_COMPONENTMAPPINGS_HH__ -#include "mem/protocol/GenericMachineType.hh" #include "mem/protocol/MachineType.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/system/DirectoryMemory.hh" #include "mem/ruby/system/MachineID.hh" -#include "mem/ruby/system/NodeID.hh" - -#ifdef MACHINETYPE_L1Cache -#define MACHINETYPE_L1CACHE_ENUM MachineType_L1Cache -#else -#define MACHINETYPE_L1CACHE_ENUM MachineType_NUM -#endif - -#ifdef MACHINETYPE_L2Cache -#define MACHINETYPE_L2CACHE_ENUM MachineType_L2Cache -#else -#define MACHINETYPE_L2CACHE_ENUM MachineType_NUM -#endif - -#ifdef MACHINETYPE_L3Cache -#define MACHINETYPE_L3CACHE_ENUM MachineType_L3Cache -#else -#define MACHINETYPE_L3CACHE_ENUM MachineType_NUM -#endif - -#ifdef MACHINETYPE_DMA -#define MACHINETYPE_DMA_ENUM MachineType_DMA -#else -#define MACHINETYPE_DMA_ENUM MachineType_NUM -#endif // used to determine the home directory // returns a value between 0 and total_directories_within_the_system @@ -80,13 +54,6 @@ map_Address_to_Directory(const Address &addr) return mach; } -inline MachineID -map_Address_to_DMA(const Address & addr) -{ - MachineID dma = {MACHINETYPE_DMA_ENUM, 0}; - return dma; -} - inline NetDest broadcast(MachineType type) { @@ -121,41 +88,6 @@ machineIDToMachineType(MachineID machID) return machID.type; } -inline NodeID -L1CacheMachIDToProcessorNum(MachineID machID) -{ - assert(machID.type == MACHINETYPE_L1CACHE_ENUM); - return machID.num; -} - -inline MachineID -getL1MachineID(NodeID L1RubyNode) -{ - MachineID mach = {MACHINETYPE_L1CACHE_ENUM, L1RubyNode}; - return mach; -} - -inline GenericMachineType -ConvertMachToGenericMach(MachineType machType) -{ - if (machType == MACHINETYPE_L1CACHE_ENUM) - return GenericMachineType_L1Cache; - - if (machType == MACHINETYPE_L2CACHE_ENUM) - return GenericMachineType_L2Cache; - - if (machType == MACHINETYPE_L3CACHE_ENUM) - return GenericMachineType_L3Cache; - - if (machType == MachineType_Directory) - return GenericMachineType_Directory; - - if (machType == MACHINETYPE_DMA_ENUM) - return GenericMachineType_DMA; - - panic("cannot convert to a GenericMachineType"); -} - inline int machineCount(MachineType machType) { diff --git a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh index b2e612bd4..bed42018b 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.hh @@ -39,7 +39,6 @@ #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/profiler/Profiler.hh" -#include "mem/ruby/system/NodeID.hh" class Set; diff --git a/src/mem/ruby/slicc_interface/RubySlicc_Util.hh b/src/mem/ruby/slicc_interface/RubySlicc_Util.hh index 9b284dab4..d535ba7cd 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_Util.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_Util.hh @@ -45,7 +45,6 @@ #include "mem/ruby/network/Network.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" #include "mem/ruby/system/MachineID.hh" -#include "mem/ruby/system/NodeID.hh" #include "mem/ruby/system/System.hh" class Set; diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc index f8e4cf810..0e82ba3eb 100644 --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -48,27 +48,16 @@ DMASequencer::init() } RequestStatus -DMASequencer::makeRequest(const RubyRequest &request) +DMASequencer::makeRequest(PacketPtr pkt) { if (m_is_busy) { return RequestStatus_BufferFull; } - uint64_t paddr = request.m_PhysicalAddress.getAddress(); - uint8_t* data = request.data; - int len = request.m_Size; - bool write = false; - switch(request.m_Type) { - case RubyRequestType_LD: - write = false; - break; - case RubyRequestType_ST: - write = true; - break; - default: - panic("DMASequencer::makeRequest does not support RubyRequestType"); - return RequestStatus_NULL; - } + uint64_t paddr = pkt->getAddr(); + uint8_t* data = pkt->getPtr<uint8_t>(true); + int len = pkt->getSize(); + bool write = pkt->isWrite(); assert(!m_is_busy); // only support one outstanding DMA request m_is_busy = true; @@ -79,7 +68,7 @@ DMASequencer::makeRequest(const RubyRequest &request) active_request.len = len; active_request.bytes_completed = 0; active_request.bytes_issued = 0; - active_request.pkt = request.pkt; + active_request.pkt = pkt; SequencerMsg *msg = new SequencerMsg; msg->getPhysicalAddress() = Address(paddr); diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh index 61d7ef1c6..5f6b9f100 100644 --- a/src/mem/ruby/system/DMASequencer.hh +++ b/src/mem/ruby/system/DMASequencer.hh @@ -53,7 +53,7 @@ class DMASequencer : public RubyPort DMASequencer(const Params *); void init(); /* external interface */ - RequestStatus makeRequest(const RubyRequest & request); + RequestStatus makeRequest(PacketPtr pkt); bool busy() { return m_is_busy;} /* SLICC callback */ diff --git a/src/mem/ruby/system/MachineID.hh b/src/mem/ruby/system/MachineID.hh index 567d1f004..18beac5d8 100644 --- a/src/mem/ruby/system/MachineID.hh +++ b/src/mem/ruby/system/MachineID.hh @@ -34,7 +34,6 @@ #include "base/cprintf.hh" #include "mem/protocol/MachineType.hh" -#include "mem/ruby/common/Global.hh" struct MachineID { diff --git a/src/mem/ruby/system/NodeID.hh b/src/mem/ruby/system/NodeID.hh deleted file mode 100644 index ed3486aaf..000000000 --- a/src/mem/ruby/system/NodeID.hh +++ /dev/null @@ -1,45 +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. - */ - -#ifndef __MEM_RUBY_SYSTEM_NODEID_HH__ -#define __MEM_RUBY_SYSTEM_NODEID_HH__ - -#include <string> - -#include "base/str.hh" -#include "mem/ruby/common/Global.hh" - -typedef int NodeID; - -inline std::string -NodeIDToString(NodeID node) -{ - return to_string(node); -} - -#endif // __MEM_RUBY_SYSTEM_NODEID_HH__ diff --git a/src/mem/ruby/system/PersistentTable.hh b/src/mem/ruby/system/PersistentTable.hh index 356406cbd..d2f58b0db 100644 --- a/src/mem/ruby/system/PersistentTable.hh +++ b/src/mem/ruby/system/PersistentTable.hh @@ -41,6 +41,7 @@ class PersistentTableEntry { public: + PersistentTableEntry() {} void print(std::ostream& out) const {} NetDest m_starving; diff --git a/src/mem/ruby/system/PseudoLRUPolicy.hh b/src/mem/ruby/system/PseudoLRUPolicy.hh index 1e1e68188..3cc2a5dfe 100644 --- a/src/mem/ruby/system/PseudoLRUPolicy.hh +++ b/src/mem/ruby/system/PseudoLRUPolicy.hh @@ -64,8 +64,6 @@ inline PseudoLRUPolicy::PseudoLRUPolicy(Index num_sets, Index assoc) : AbstractReplacementPolicy(num_sets, assoc) { - int num_tree_nodes; - // associativity cannot exceed capacity of tree representation assert(num_sets > 0 && assoc > 1 && assoc <= (Index) sizeof(uint64)*4); @@ -84,7 +82,6 @@ PseudoLRUPolicy::PseudoLRUPolicy(Index num_sets, Index assoc) m_num_levels++; } assert(m_num_levels < sizeof(unsigned int)*4); - num_tree_nodes = (1 << m_num_levels) - 1; m_trees = new uint64[m_num_sets]; for (unsigned i = 0; i < m_num_sets; i++) { m_trees[i] = 0; diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index c2661bcf2..f7bde739e 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -26,10 +26,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config/the_isa.hh" -#if THE_ISA == X86_ISA -#include "arch/x86/insts/microldstop.hh" -#endif // X86_ISA #include "cpu/testers/rubytest/RubyTester.hh" #include "debug/Ruby.hh" #include "mem/protocol/AccessPermission.hh" @@ -199,73 +195,11 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt) return ruby_port->pio_port->sendTiming(pkt); } - // For DMA and CPU requests, translate them to ruby requests before - // sending them to our assigned ruby port. - RubyRequestType type = RubyRequestType_NULL; - - // If valid, copy the pc to the ruby request - Addr pc = 0; - if (pkt->req->hasPC()) { - pc = pkt->req->getPC(); - } - - if (pkt->isLLSC()) { - if (pkt->isWrite()) { - DPRINTF(RubyPort, "Issuing SC\n"); - type = RubyRequestType_Store_Conditional; - } else { - DPRINTF(RubyPort, "Issuing LL\n"); - assert(pkt->isRead()); - type = RubyRequestType_Load_Linked; - } - } else if (pkt->req->isLocked()) { - if (pkt->isWrite()) { - DPRINTF(RubyPort, "Issuing Locked RMW Write\n"); - type = RubyRequestType_Locked_RMW_Write; - } else { - DPRINTF(RubyPort, "Issuing Locked RMW Read\n"); - assert(pkt->isRead()); - type = RubyRequestType_Locked_RMW_Read; - } - } else { - if (pkt->isRead()) { - if (pkt->req->isInstFetch()) { - type = RubyRequestType_IFETCH; - } else { -#if THE_ISA == X86_ISA - uint32_t flags = pkt->req->getFlags(); - bool storeCheck = flags & - (TheISA::StoreCheck << TheISA::FlagShift); -#else - bool storeCheck = false; -#endif // X86_ISA - if (storeCheck) { - type = RubyRequestType_RMW_Read; - } else { - type = RubyRequestType_LD; - } - } - } else if (pkt->isWrite()) { - // - // Note: M5 packets do not differentiate ST from RMW_Write - // - type = RubyRequestType_ST; - } else if (pkt->isFlush()) { - type = RubyRequestType_FLUSH; - } else { - panic("Unsupported ruby packet type\n"); - } - } - - RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(true), - pkt->getSize(), pc, type, - RubyAccessMode_Supervisor, pkt); - - assert(ruby_request.m_PhysicalAddress.getOffset() + ruby_request.m_Size <= - RubySystem::getBlockSizeBytes()); + assert(Address(pkt->getAddr()).getOffset() + pkt->getSize() <= + RubySystem::getBlockSizeBytes()); // Submit the ruby request - RequestStatus requestStatus = ruby_port->makeRequest(ruby_request); + RequestStatus requestStatus = ruby_port->makeRequest(pkt); // If the request successfully issued then we should return true. // Otherwise, we need to delete the senderStatus we just created and return diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index e1ba2f7d1..88e865766 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -114,7 +114,7 @@ class RubyPort : public MemObject Port *getPort(const std::string &if_name, int idx); - virtual RequestStatus makeRequest(const RubyRequest & request) = 0; + virtual RequestStatus makeRequest(PacketPtr pkt) = 0; // // Called by the controller to give the sequencer a pointer. diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 711ef12ed..9010178be 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -28,15 +28,21 @@ #include "base/misc.hh" #include "base/str.hh" +#include "config/the_isa.hh" +#if THE_ISA == X86_ISA +#include "arch/x86/insts/microldstop.hh" +#endif // X86_ISA #include "cpu/testers/rubytest/RubyTester.hh" #include "debug/MemoryAccess.hh" #include "debug/ProtocolTrace.hh" +#include "debug/RubySequencer.hh" +#include "mem/protocol/PrefetchBit.hh" +#include "mem/protocol/RubyAccessMode.hh" #include "mem/ruby/buffers/MessageBuffer.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/common/SubBlock.hh" #include "mem/ruby/profiler/Profiler.hh" #include "mem/ruby/recorder/Tracer.hh" -#include "mem/ruby/slicc_interface/AbstractController.hh" #include "mem/ruby/slicc_interface/RubyRequest.hh" #include "mem/ruby/system/CacheMemory.hh" #include "mem/ruby/system/Sequencer.hh" @@ -62,7 +68,6 @@ Sequencer::Sequencer(const Params *p) m_outstanding_count = 0; - m_max_outstanding_requests = 0; m_deadlock_threshold = 0; m_instCache_ptr = NULL; m_dataCache_ptr = NULL; @@ -103,7 +108,7 @@ Sequencer::wakeup() panic("Possible Deadlock detected. Aborting!\n" "version: %d request.paddr: 0x%x m_readRequestTable: %d " "current time: %u issue_time: %d difference: %d\n", m_version, - request->ruby_request.m_PhysicalAddress, m_readRequestTable.size(), + Address(request->pkt->getAddr()), m_readRequestTable.size(), current_time, request->issue_time, current_time - request->issue_time); } @@ -118,7 +123,7 @@ Sequencer::wakeup() panic("Possible Deadlock detected. Aborting!\n" "version: %d request.paddr: 0x%x m_writeRequestTable: %d " "current time: %u issue_time: %d difference: %d\n", m_version, - request->ruby_request.m_PhysicalAddress, m_writeRequestTable.size(), + Address(request->pkt->getAddr()), m_writeRequestTable.size(), current_time, request->issue_time, current_time - request->issue_time); } @@ -213,8 +218,8 @@ Sequencer::printConfig(ostream& out) const // Insert the request on the correct request table. Return true if // the entry was already present. -bool -Sequencer::insertRequest(SequencerRequest* request) +RequestStatus +Sequencer::insertRequest(PacketPtr pkt, RubyRequestType request_type) { int total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size(); @@ -226,52 +231,64 @@ Sequencer::insertRequest(SequencerRequest* request) schedule(deadlockCheckEvent, m_deadlock_threshold + curTick()); } - Address line_addr(request->ruby_request.m_PhysicalAddress); + Address line_addr(pkt->getAddr()); line_addr.makeLineAddress(); - if ((request->ruby_request.m_Type == RubyRequestType_ST) || - (request->ruby_request.m_Type == RubyRequestType_ATOMIC) || - (request->ruby_request.m_Type == RubyRequestType_RMW_Read) || - (request->ruby_request.m_Type == RubyRequestType_RMW_Write) || - (request->ruby_request.m_Type == RubyRequestType_Load_Linked) || - (request->ruby_request.m_Type == RubyRequestType_Store_Conditional) || - (request->ruby_request.m_Type == RubyRequestType_Locked_RMW_Read) || - (request->ruby_request.m_Type == RubyRequestType_Locked_RMW_Write) || - (request->ruby_request.m_Type == RubyRequestType_FLUSH)) { + if ((request_type == RubyRequestType_ST) || + (request_type == RubyRequestType_RMW_Read) || + (request_type == RubyRequestType_RMW_Write) || + (request_type == RubyRequestType_Load_Linked) || + (request_type == RubyRequestType_Store_Conditional) || + (request_type == RubyRequestType_Locked_RMW_Read) || + (request_type == RubyRequestType_Locked_RMW_Write) || + (request_type == RubyRequestType_FLUSH)) { + + // Check if there is any outstanding read request for the same + // cache line. + if (m_readRequestTable.count(line_addr) > 0) { + m_store_waiting_on_load_cycles++; + return RequestStatus_Aliased; + } + pair<RequestTable::iterator, bool> r = m_writeRequestTable.insert(RequestTable::value_type(line_addr, 0)); - bool success = r.second; - RequestTable::iterator i = r.first; - if (!success) { - i->second = request; - // return true; - - // drh5: isn't this an error? do you lose the initial request? - assert(0); + if (r.second) { + RequestTable::iterator i = r.first; + i->second = new SequencerRequest(pkt, request_type, + g_eventQueue_ptr->getTime()); + m_outstanding_count++; + } else { + // There is an outstanding write request for the cache line + m_store_waiting_on_store_cycles++; + return RequestStatus_Aliased; } - i->second = request; - m_outstanding_count++; } else { + // Check if there is any outstanding write request for the same + // cache line. + if (m_writeRequestTable.count(line_addr) > 0) { + m_load_waiting_on_store_cycles++; + return RequestStatus_Aliased; + } + pair<RequestTable::iterator, bool> r = m_readRequestTable.insert(RequestTable::value_type(line_addr, 0)); - bool success = r.second; - RequestTable::iterator i = r.first; - if (!success) { - i->second = request; - // return true; - - // drh5: isn't this an error? do you lose the initial request? - assert(0); + + if (r.second) { + RequestTable::iterator i = r.first; + i->second = new SequencerRequest(pkt, request_type, + g_eventQueue_ptr->getTime()); + m_outstanding_count++; + } else { + // There is an outstanding read request for the cache line + m_load_waiting_on_load_cycles++; + return RequestStatus_Aliased; } - i->second = request; - m_outstanding_count++; } g_system_ptr->getProfiler()->sequencerRequests(m_outstanding_count); - total_outstanding = m_writeRequestTable.size() + m_readRequestTable.size(); assert(m_outstanding_count == total_outstanding); - return false; + return RequestStatus_Ready; } void @@ -288,16 +305,15 @@ Sequencer::removeRequest(SequencerRequest* srequest) assert(m_outstanding_count == m_writeRequestTable.size() + m_readRequestTable.size()); - const RubyRequest & ruby_request = srequest->ruby_request; - Address line_addr(ruby_request.m_PhysicalAddress); + Address line_addr(srequest->pkt->getAddr()); line_addr.makeLineAddress(); - if ((ruby_request.m_Type == RubyRequestType_ST) || - (ruby_request.m_Type == RubyRequestType_RMW_Read) || - (ruby_request.m_Type == RubyRequestType_RMW_Write) || - (ruby_request.m_Type == RubyRequestType_Load_Linked) || - (ruby_request.m_Type == RubyRequestType_Store_Conditional) || - (ruby_request.m_Type == RubyRequestType_Locked_RMW_Read) || - (ruby_request.m_Type == RubyRequestType_Locked_RMW_Write)) { + if ((srequest->m_type == RubyRequestType_ST) || + (srequest->m_type == RubyRequestType_RMW_Read) || + (srequest->m_type == RubyRequestType_RMW_Write) || + (srequest->m_type == RubyRequestType_Load_Linked) || + (srequest->m_type == RubyRequestType_Store_Conditional) || + (srequest->m_type == RubyRequestType_Locked_RMW_Read) || + (srequest->m_type == RubyRequestType_Locked_RMW_Write)) { m_writeRequestTable.erase(line_addr); } else { m_readRequestTable.erase(line_addr); @@ -315,32 +331,33 @@ Sequencer::handleLlsc(const Address& address, SequencerRequest* request) // longer locked. // bool success = true; - if (request->ruby_request.m_Type == RubyRequestType_Store_Conditional) { + if (request->m_type == RubyRequestType_Store_Conditional) { if (!m_dataCache_ptr->isLocked(address, m_version)) { // // For failed SC requests, indicate the failure to the cpu by // setting the extra data to zero. // - request->ruby_request.pkt->req->setExtraData(0); + request->pkt->req->setExtraData(0); success = false; } else { // // For successful SC requests, indicate the success to the cpu by // setting the extra data to one. // - request->ruby_request.pkt->req->setExtraData(1); + request->pkt->req->setExtraData(1); } // // Independent of success, all SC operations must clear the lock // m_dataCache_ptr->clearLocked(address); - } else if (request->ruby_request.m_Type == RubyRequestType_Load_Linked) { + } else if (request->m_type == RubyRequestType_Load_Linked) { // // Note: To fully follow Alpha LLSC semantics, should the LL clear any // previously locked cache lines? // m_dataCache_ptr->setLocked(address, m_version); - } else if ((m_dataCache_ptr->isTagPresent(address)) && (m_dataCache_ptr->isLocked(address, m_version))) { + } else if ((m_dataCache_ptr->isTagPresent(address)) && + (m_dataCache_ptr->isLocked(address, m_version))) { // // Normal writes should clear the locked address // @@ -381,15 +398,15 @@ Sequencer::writeCallback(const Address& address, m_writeRequestTable.erase(i); markRemoved(); - assert((request->ruby_request.m_Type == RubyRequestType_ST) || - (request->ruby_request.m_Type == RubyRequestType_ATOMIC) || - (request->ruby_request.m_Type == RubyRequestType_RMW_Read) || - (request->ruby_request.m_Type == RubyRequestType_RMW_Write) || - (request->ruby_request.m_Type == RubyRequestType_Load_Linked) || - (request->ruby_request.m_Type == RubyRequestType_Store_Conditional) || - (request->ruby_request.m_Type == RubyRequestType_Locked_RMW_Read) || - (request->ruby_request.m_Type == RubyRequestType_Locked_RMW_Write) || - (request->ruby_request.m_Type == RubyRequestType_FLUSH)); + assert((request->m_type == RubyRequestType_ST) || + (request->m_type == RubyRequestType_ATOMIC) || + (request->m_type == RubyRequestType_RMW_Read) || + (request->m_type == RubyRequestType_RMW_Write) || + (request->m_type == RubyRequestType_Load_Linked) || + (request->m_type == RubyRequestType_Store_Conditional) || + (request->m_type == RubyRequestType_Locked_RMW_Read) || + (request->m_type == RubyRequestType_Locked_RMW_Write) || + (request->m_type == RubyRequestType_FLUSH)); // @@ -402,9 +419,9 @@ Sequencer::writeCallback(const Address& address, if(!m_usingNetworkTester) success = handleLlsc(address, request); - if (request->ruby_request.m_Type == RubyRequestType_Locked_RMW_Read) { + if (request->m_type == RubyRequestType_Locked_RMW_Read) { m_controller->blockOnQueue(address, m_mandatory_q_ptr); - } else if (request->ruby_request.m_Type == RubyRequestType_Locked_RMW_Write) { + } else if (request->m_type == RubyRequestType_Locked_RMW_Write) { m_controller->unblock(address); } @@ -444,8 +461,8 @@ Sequencer::readCallback(const Address& address, m_readRequestTable.erase(i); markRemoved(); - assert((request->ruby_request.m_Type == RubyRequestType_LD) || - (request->ruby_request.m_Type == RubyRequestType_IFETCH)); + assert((request->m_type == RubyRequestType_LD) || + (request->m_type == RubyRequestType_IFETCH)); hitCallback(request, mach, data, true, initialRequestTime, forwardRequestTime, firstResponseTime); @@ -460,11 +477,11 @@ Sequencer::hitCallback(SequencerRequest* srequest, Time forwardRequestTime, Time firstResponseTime) { - const RubyRequest & ruby_request = srequest->ruby_request; - Address request_address(ruby_request.m_PhysicalAddress); - Address request_line_address(ruby_request.m_PhysicalAddress); + PacketPtr pkt = srequest->pkt; + Address request_address(pkt->getAddr()); + Address request_line_address(pkt->getAddr()); request_line_address.makeLineAddress(); - RubyRequestType type = ruby_request.m_Type; + RubyRequestType type = srequest->m_type; Time issued_time = srequest->issue_time; // Set this cache entry to the most recently used @@ -502,22 +519,22 @@ Sequencer::hitCallback(SequencerRequest* srequest, DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %d cycles\n", curTick(), m_version, "Seq", success ? "Done" : "SC_Failed", "", "", - ruby_request.m_PhysicalAddress, miss_latency); + request_address, miss_latency); } // update the data - if (ruby_request.data != NULL) { + if (pkt->getPtr<uint8_t>(true) != NULL) { if ((type == RubyRequestType_LD) || (type == RubyRequestType_IFETCH) || (type == RubyRequestType_RMW_Read) || (type == RubyRequestType_Locked_RMW_Read) || (type == RubyRequestType_Load_Linked)) { - memcpy(ruby_request.data, - data.getData(request_address.getOffset(), ruby_request.m_Size), - ruby_request.m_Size); + memcpy(pkt->getPtr<uint8_t>(true), + data.getData(request_address.getOffset(), pkt->getSize()), + pkt->getSize()); } else { - data.setData(ruby_request.data, request_address.getOffset(), - ruby_request.m_Size); + data.setData(pkt->getPtr<uint8_t>(true), + request_address.getOffset(), pkt->getSize()); } } else { DPRINTF(MemoryAccess, @@ -532,50 +549,16 @@ Sequencer::hitCallback(SequencerRequest* srequest, // RubyTester. if (m_usingRubyTester) { RubyPort::SenderState *requestSenderState = - safe_cast<RubyPort::SenderState*>(ruby_request.pkt->senderState); + safe_cast<RubyPort::SenderState*>(pkt->senderState); RubyTester::SenderState* testerSenderState = safe_cast<RubyTester::SenderState*>(requestSenderState->saved); testerSenderState->subBlock->mergeFrom(data); } - ruby_hit_callback(ruby_request.pkt); + ruby_hit_callback(pkt); delete srequest; } -// Returns true if the sequencer already has a load or store outstanding -RequestStatus -Sequencer::getRequestStatus(const RubyRequest& request) -{ - bool is_outstanding_store = - !!m_writeRequestTable.count(line_address(request.m_PhysicalAddress)); - bool is_outstanding_load = - !!m_readRequestTable.count(line_address(request.m_PhysicalAddress)); - if (is_outstanding_store) { - if ((request.m_Type == RubyRequestType_LD) || - (request.m_Type == RubyRequestType_IFETCH) || - (request.m_Type == RubyRequestType_RMW_Read)) { - m_store_waiting_on_load_cycles++; - } else { - m_store_waiting_on_store_cycles++; - } - return RequestStatus_Aliased; - } else if (is_outstanding_load) { - if ((request.m_Type == RubyRequestType_ST) || - (request.m_Type == RubyRequestType_RMW_Write)) { - m_load_waiting_on_store_cycles++; - } else { - m_load_waiting_on_load_cycles++; - } - return RequestStatus_Aliased; - } - - if (m_outstanding_count >= m_max_outstanding_requests) { - return RequestStatus_BufferFull; - } - - return RequestStatus_Ready; -} - bool Sequencer::empty() const { @@ -583,109 +566,118 @@ Sequencer::empty() const } RequestStatus -Sequencer::makeRequest(const RubyRequest &request) +Sequencer::makeRequest(PacketPtr pkt) { - assert(request.m_PhysicalAddress.getOffset() + request.m_Size <= - RubySystem::getBlockSizeBytes()); - RequestStatus status = getRequestStatus(request); - if (status != RequestStatus_Ready) - return status; + if (m_outstanding_count >= m_max_outstanding_requests) { + return RequestStatus_BufferFull; + } - SequencerRequest *srequest = - new SequencerRequest(request, g_eventQueue_ptr->getTime()); - bool found = insertRequest(srequest); - if (found) { - panic("Sequencer::makeRequest should never be called if the " - "request is already outstanding\n"); - return RequestStatus_NULL; + RubyRequestType primary_type = RubyRequestType_NULL; + RubyRequestType secondary_type = RubyRequestType_NULL; + + if (pkt->isLLSC()) { + // + // Alpha LL/SC instructions need to be handled carefully by the cache + // coherence protocol to ensure they follow the proper semantics. In + // particular, by identifying the operations as atomic, the protocol + // should understand that migratory sharing optimizations should not + // be performed (i.e. a load between the LL and SC should not steal + // away exclusive permission). + // + if (pkt->isWrite()) { + DPRINTF(RubySequencer, "Issuing SC\n"); + primary_type = RubyRequestType_Store_Conditional; + } else { + DPRINTF(RubySequencer, "Issuing LL\n"); + assert(pkt->isRead()); + primary_type = RubyRequestType_Load_Linked; + } + secondary_type = RubyRequestType_ATOMIC; + } else if (pkt->req->isLocked()) { + // + // x86 locked instructions are translated to store cache coherence + // requests because these requests should always be treated as read + // exclusive operations and should leverage any migratory sharing + // optimization built into the protocol. + // + if (pkt->isWrite()) { + DPRINTF(RubySequencer, "Issuing Locked RMW Write\n"); + primary_type = RubyRequestType_Locked_RMW_Write; + } else { + DPRINTF(RubySequencer, "Issuing Locked RMW Read\n"); + assert(pkt->isRead()); + primary_type = RubyRequestType_Locked_RMW_Read; + } + secondary_type = RubyRequestType_ST; + } else { + if (pkt->isRead()) { + if (pkt->req->isInstFetch()) { + primary_type = secondary_type = RubyRequestType_IFETCH; + } else { +#if THE_ISA == X86_ISA + uint32_t flags = pkt->req->getFlags(); + bool storeCheck = flags & + (TheISA::StoreCheck << TheISA::FlagShift); +#else + bool storeCheck = false; +#endif // X86_ISA + if (storeCheck) { + primary_type = RubyRequestType_RMW_Read; + secondary_type = RubyRequestType_ST; + } else { + primary_type = secondary_type = RubyRequestType_LD; + } + } + } else if (pkt->isWrite()) { + // + // Note: M5 packets do not differentiate ST from RMW_Write + // + primary_type = secondary_type = RubyRequestType_ST; + } else if (pkt->isFlush()) { + primary_type = secondary_type = RubyRequestType_FLUSH; + } else { + panic("Unsupported ruby packet type\n"); + } } - issueRequest(request); + RequestStatus status = insertRequest(pkt, primary_type); + if (status != RequestStatus_Ready) + return status; + + issueRequest(pkt, secondary_type); // TODO: issue hardware prefetches here return RequestStatus_Issued; } void -Sequencer::issueRequest(const RubyRequest& request) +Sequencer::issueRequest(PacketPtr pkt, RubyRequestType secondary_type) { - // TODO: Eliminate RubyRequest being copied again. - - RubyRequestType ctype = RubyRequestType_NUM; - switch(request.m_Type) { - case RubyRequestType_IFETCH: - ctype = RubyRequestType_IFETCH; - break; - case RubyRequestType_LD: - ctype = RubyRequestType_LD; - break; - case RubyRequestType_FLUSH: - ctype = RubyRequestType_FLUSH; - break; - case RubyRequestType_ST: - case RubyRequestType_RMW_Read: - case RubyRequestType_RMW_Write: - // - // x86 locked instructions are translated to store cache coherence - // requests because these requests should always be treated as read - // exclusive operations and should leverage any migratory sharing - // optimization built into the protocol. - // - case RubyRequestType_Locked_RMW_Read: - case RubyRequestType_Locked_RMW_Write: - ctype = RubyRequestType_ST; - break; - // - // Alpha LL/SC instructions need to be handled carefully by the cache - // coherence protocol to ensure they follow the proper semantics. In - // particular, by identifying the operations as atomic, the protocol - // should understand that migratory sharing optimizations should not be - // performed (i.e. a load between the LL and SC should not steal away - // exclusive permission). - // - case RubyRequestType_Load_Linked: - case RubyRequestType_Store_Conditional: - case RubyRequestType_ATOMIC: - ctype = RubyRequestType_ATOMIC; - break; - default: - assert(0); + int proc_id = -1; + if (pkt != NULL && pkt->req->hasContextId()) { + proc_id = pkt->req->contextId(); } - RubyAccessMode amtype = RubyAccessMode_NUM; - switch(request.m_AccessMode){ - case RubyAccessMode_User: - amtype = RubyAccessMode_User; - break; - case RubyAccessMode_Supervisor: - amtype = RubyAccessMode_Supervisor; - break; - case RubyAccessMode_Device: - amtype = RubyAccessMode_User; - break; - default: - assert(0); + // If valid, copy the pc to the ruby request + Addr pc = 0; + if (pkt->req->hasPC()) { + pc = pkt->req->getPC(); } - Address line_addr(request.m_PhysicalAddress); - line_addr.makeLineAddress(); - int proc_id = -1; - if (request.pkt != NULL && request.pkt->req->hasContextId()) { - proc_id = request.pkt->req->contextId(); - } - RubyRequest *msg = new RubyRequest(request.m_PhysicalAddress.getAddress(), - request.data, request.m_Size, - request.m_ProgramCounter.getAddress(), - ctype, amtype, request.pkt, + RubyRequest *msg = new RubyRequest(pkt->getAddr(), + pkt->getPtr<uint8_t>(true), + pkt->getSize(), pc, secondary_type, + RubyAccessMode_Supervisor, pkt, PrefetchBit_No, proc_id); DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %s\n", curTick(), m_version, "Seq", "Begin", "", "", - request.m_PhysicalAddress, RubyRequestType_to_string(request.m_Type)); + msg->getPhysicalAddress(), + RubyRequestType_to_string(secondary_type)); Time latency = 0; // initialzed to an null value - if (request.m_Type == RubyRequestType_IFETCH) + if (secondary_type == RubyRequestType_IFETCH) latency = m_instCache_ptr->getLatency(); else latency = m_dataCache_ptr->getLatency(); diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh index 0589d8bbc..7c2d0af13 100644 --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -33,12 +33,9 @@ #include "base/hashmap.hh" #include "mem/protocol/GenericMachineType.hh" -#include "mem/protocol/PrefetchBit.hh" -#include "mem/protocol/RubyAccessMode.hh" #include "mem/protocol/RubyRequestType.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" -#include "mem/ruby/common/Global.hh" #include "mem/ruby/system/RubyPort.hh" class DataBlock; @@ -50,11 +47,12 @@ class RubySequencerParams; struct SequencerRequest { - RubyRequest ruby_request; + PacketPtr pkt; + RubyRequestType m_type; Time issue_time; - SequencerRequest(const RubyRequest & _ruby_request, Time _issue_time) - : ruby_request(_ruby_request), issue_time(_issue_time) + SequencerRequest(PacketPtr _pkt, RubyRequestType _m_type, Time _issue_time) + : pkt(_pkt), m_type(_m_type), issue_time(_issue_time) {} }; @@ -100,8 +98,7 @@ class Sequencer : public RubyPort, public Consumer Time forwardRequestTime, Time firstResponseTime); - RequestStatus makeRequest(const RubyRequest & request); - RequestStatus getRequestStatus(const RubyRequest& request); + RequestStatus makeRequest(PacketPtr pkt); bool empty() const; void print(std::ostream& out) const; @@ -112,7 +109,7 @@ class Sequencer : public RubyPort, public Consumer void removeRequest(SequencerRequest* request); private: - void issueRequest(const RubyRequest& request); + void issueRequest(PacketPtr pkt, RubyRequestType type); void hitCallback(SequencerRequest* request, GenericMachineType mach, @@ -122,7 +119,7 @@ class Sequencer : public RubyPort, public Consumer Time forwardRequestTime, Time firstResponseTime); - bool insertRequest(SequencerRequest* request); + RequestStatus insertRequest(PacketPtr pkt, RubyRequestType request_type); bool handleLlsc(const Address& address, SequencerRequest* request); diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py index fbd090d49..4d3618093 100644 --- a/src/mem/slicc/symbols/StateMachine.py +++ b/src/mem/slicc/symbols/StateMachine.py @@ -1355,7 +1355,7 @@ ${ident}_ProfileDumper::dumpStats(std::ostream& out) const #include "mem/protocol/${ident}_Event.hh" #include "mem/protocol/${ident}_State.hh" -#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/TypeDefines.hh" class ${ident}_Profiler { diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py index b41ecc00f..ad00f2ac1 100644 --- a/src/mem/slicc/symbols/Type.py +++ b/src/mem/slicc/symbols/Type.py @@ -439,11 +439,16 @@ ${{self.c_ident}}::print(ostream& out) const #include <iostream> #include <string> -#include "mem/ruby/common/Global.hh" ''') if self.isStateDecl: code('#include "mem/protocol/AccessPermission.hh"') + if self.isMachineType: + code('#include "base/misc.hh"') + code('#include "mem/protocol/GenericMachineType.hh"') + code('#include "mem/ruby/common/Address.hh"') + code('struct MachineID;') + code(''' // Class definition @@ -488,7 +493,29 @@ int ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj); ''') for enum in self.enums.itervalues(): - code('#define MACHINETYPE_${{enum.ident}} 1') + if enum.ident == "DMA": + code(''' +MachineID map_Address_to_DMA(const Address &addr); +''') + code(''' + +MachineID get${{enum.ident}}MachineID(NodeID RubyNode); +''') + + code(''' +inline GenericMachineType +ConvertMachToGenericMach(MachineType machType) +{ +''') + for enum in self.enums.itervalues(): + code(''' + if (machType == MachineType_${{enum.ident}}) + return GenericMachineType_${{enum.ident}}; +''') + code(''' + panic("cannot convert to a GenericMachineType"); +} +''') if self.isStateDecl: code(''' @@ -550,6 +577,7 @@ AccessPermission ${{self.c_ident}}_to_permission(const ${{self.c_ident}}& obj) if self.isMachineType: for enum in self.enums.itervalues(): code('#include "mem/protocol/${{enum.ident}}_Controller.hh"') + code('#include "mem/ruby/system/MachineID.hh"') code(''' // Code for output operator @@ -723,6 +751,27 @@ ${{self.c_ident}}_base_count(const ${{self.c_ident}}& obj) } ''') + for enum in self.enums.itervalues(): + if enum.ident == "DMA": + code(''' +MachineID +map_Address_to_DMA(const Address &addr) +{ + MachineID dma = {MachineType_DMA, 0}; + return dma; +} +''') + + code(''' + +MachineID +get${{enum.ident}}MachineID(NodeID RubyNode) +{ + MachineID mach = {MachineType_${{enum.ident}}, RubyNode}; + return mach; +} +''') + # Write the file code.write(path, "%s.cc" % self.c_ident) diff --git a/src/mem/translating_port.cc b/src/mem/translating_port.cc index 6a383a2bb..7d3123012 100644 --- a/src/mem/translating_port.cc +++ b/src/mem/translating_port.cc @@ -85,8 +85,8 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size) if (!pTable->translate(gen.addr(), paddr)) { if (allocating == Always) { - pTable->allocate(roundDown(gen.addr(), VMPageSize), - VMPageSize); + process->allocateMem(roundDown(gen.addr(), VMPageSize), + VMPageSize); } else if (allocating == NextPage) { // check if we've accessed the next page on the stack if (!process->fixupStackFault(gen.addr())) @@ -121,8 +121,8 @@ TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size) if (!pTable->translate(gen.addr(), paddr)) { if (allocating == Always) { - pTable->allocate(roundDown(gen.addr(), VMPageSize), - VMPageSize); + process->allocateMem(roundDown(gen.addr(), VMPageSize), + VMPageSize); pTable->translate(gen.addr(), paddr); } else { return false; diff --git a/src/python/SConscript b/src/python/SConscript index cbb37d0c5..c20389344 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -66,6 +66,7 @@ PySource('m5.util', 'm5/util/terminal.py') SwigSource('m5.internal', 'swig/core.i') SwigSource('m5.internal', 'swig/debug.i') SwigSource('m5.internal', 'swig/event.i') +SwigSource('m5.internal', 'swig/pyobject.i') SwigSource('m5.internal', 'swig/range.i') SwigSource('m5.internal', 'swig/stats.i') SwigSource('m5.internal', 'swig/trace.i') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 9729fd30f..60693758c 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -97,37 +97,6 @@ allClasses = {} # dict to look up SimObjects based on path instanceDict = {} -def default_cxx_predecls(cls, code): - code('#include "params/$cls.hh"') - -def default_swig_predecls(cls, code): - code('%import "python/m5/internal/param_$cls.i"') - -def default_swig_objdecls(cls, code): - class_path = cls.cxx_class.split('::') - classname = class_path[-1] - namespaces = class_path[:-1] - - for ns in namespaces: - code('namespace $ns {') - - if namespaces: - code('// avoid name conflicts') - sep_string = '_COLONS_' - flat_name = sep_string.join(class_path) - code('%rename($flat_name) $classname;') - - code() - code('// stop swig from creating/wrapping default ctor/dtor') - code('%nodefault $classname;') - code('class $classname') - if cls._base: - code(' : public ${{cls._base.cxx_class}}') - code('{};') - - for ns in reversed(namespaces): - code('} // namespace $ns') - def public_value(key, value): return key.startswith('_') or \ isinstance(value, (FunctionType, MethodType, ModuleType, @@ -142,9 +111,6 @@ class MetaSimObject(type): init_keywords = { 'abstract' : bool, 'cxx_class' : str, 'cxx_type' : str, - 'cxx_predecls' : MethodType, - 'swig_objdecls' : MethodType, - 'swig_predecls' : MethodType, 'type' : str } # Attributes that can be set any time keywords = { 'check' : FunctionType } @@ -223,18 +189,20 @@ class MetaSimObject(type): cls._value_dict['cxx_class'] = cls._value_dict['type'] cls._value_dict['cxx_type'] = '%s *' % cls._value_dict['cxx_class'] - - if 'cxx_predecls' not in cls.__dict__: - m = MethodType(default_cxx_predecls, cls, MetaSimObject) - setattr(cls, 'cxx_predecls', m) - - if 'swig_predecls' not in cls.__dict__: - m = MethodType(default_swig_predecls, cls, MetaSimObject) - setattr(cls, 'swig_predecls', m) - if 'swig_objdecls' not in cls.__dict__: - m = MethodType(default_swig_objdecls, cls, MetaSimObject) - setattr(cls, 'swig_objdecls', m) + # Export methods are automatically inherited via C++, so we + # don't want the method declarations to get inherited on the + # python side (and thus end up getting repeated in the wrapped + # versions of derived classes). The code below basicallly + # suppresses inheritance by substituting in the base (null) + # versions of these methods unless a different version is + # explicitly supplied. + for method_name in ('export_methods', 'export_method_cxx_predecls', + 'export_method_swig_predecls'): + if method_name not in cls.__dict__: + base_method = getattr(MetaSimObject, method_name) + m = MethodType(base_method, cls, MetaSimObject) + setattr(cls, method_name, m) # Now process the _value_dict items. They could be defining # new (or overriding existing) parameters or ports, setting @@ -378,8 +346,99 @@ class MetaSimObject(type): def __str__(cls): return cls.__name__ - def cxx_decl(cls, code): - # The 'dict' attribute restricts us to the params declared in + # See ParamValue.cxx_predecls for description. + def cxx_predecls(cls, code): + code('#include "params/$cls.hh"') + + # See ParamValue.swig_predecls for description. + def swig_predecls(cls, code): + code('%import "python/m5/internal/param_$cls.i"') + + # Hook for exporting additional C++ methods to Python via SWIG. + # Default is none, override using @classmethod in class definition. + def export_methods(cls, code): + pass + + # Generate the code needed as a prerequisite for the C++ methods + # exported via export_methods() to be compiled in the _wrap.cc + # file. Typically generates one or more #include statements. If + # any methods are exported, typically at least the C++ header + # declaring the relevant SimObject class must be included. + def export_method_cxx_predecls(cls, code): + pass + + # Generate the code needed as a prerequisite for the C++ methods + # exported via export_methods() to be processed by SWIG. + # Typically generates one or more %include or %import statements. + # If any methods are exported, typically at least the C++ header + # declaring the relevant SimObject class must be included. + def export_method_swig_predecls(cls, code): + pass + + # Generate the declaration for this object for wrapping with SWIG. + # Generates code that goes into a SWIG .i file. Called from + # src/SConscript. + def swig_decl(cls, code): + class_path = cls.cxx_class.split('::') + classname = class_path[-1] + namespaces = class_path[:-1] + + # The 'local' attribute restricts us to the params declared in + # the object itself, not including inherited params (which + # will also be inherited from the base class's param struct + # here). + params = cls._params.local.values() + + code('%module(package="m5.internal") param_$cls') + code() + code('%{') + code('#include "params/$cls.hh"') + for param in params: + param.cxx_predecls(code) + cls.export_method_cxx_predecls(code) + code('%}') + code() + + for param in params: + param.swig_predecls(code) + cls.export_method_swig_predecls(code) + + code() + if cls._base: + code('%import "python/m5/internal/param_${{cls._base}}.i"') + code() + + for ns in namespaces: + code('namespace $ns {') + + if namespaces: + code('// avoid name conflicts') + sep_string = '_COLONS_' + flat_name = sep_string.join(class_path) + code('%rename($flat_name) $classname;') + + code() + code('// stop swig from creating/wrapping default ctor/dtor') + code('%nodefault $classname;') + code('class $classname') + if cls._base: + code(' : public ${{cls._base.cxx_class}}') + code('{') + code(' public:') + cls.export_methods(code) + code('};') + + for ns in reversed(namespaces): + code('} // namespace $ns') + + code() + code('%include "params/$cls.hh"') + + + # Generate the C++ declaration (.hh file) for this SimObject's + # param struct. Called from src/SConscript. + def cxx_param_decl(cls, code): + # The 'local' attribute restricts us to the params declared in # the object itself, not including inherited params (which # will also be inherited from the base class's param struct # here). @@ -408,6 +467,20 @@ class MetaSimObject(type): code('} // namespace $ns') code() + # The base SimObject has a couple of params that get + # automatically set from Python without being declared through + # the normal Param mechanism; we slip them in here (needed + # predecls now, actual declarations below) + if cls == SimObject: + code(''' +#ifndef PY_VERSION +struct PyObject; +#endif + +#include <string> + +struct EventQueue; +''') for param in params: param.cxx_predecls(code) code() @@ -421,65 +494,39 @@ class MetaSimObject(type): code('#include "enums/${{ptype.__name__}}.hh"') code() - cls.cxx_struct(code, cls._base, params) - - code() - code('#endif // __PARAMS__${cls}__') - return code - - def cxx_struct(cls, code, base, params): - if cls == SimObject: - code('#include "sim/sim_object_params.hh"') - return - # now generate the actual param struct code("struct ${cls}Params") - if base: - code(" : public ${{base.type}}Params") + if cls._base: + code(" : public ${{cls._base.type}}Params") code("{") if not hasattr(cls, 'abstract') or not cls.abstract: if 'type' in cls.__dict__: code(" ${{cls.cxx_type}} create();") code.indent() + if cls == SimObject: + code(''' + SimObjectParams() + { + extern EventQueue mainEventQueue; + eventq = &mainEventQueue; + } + virtual ~SimObjectParams() {} + + std::string name; + PyObject *pyobj; + EventQueue *eventq; + ''') for param in params: param.cxx_decl(code) code.dedent() code('};') - def swig_decl(cls, code): - code('''\ -%module $cls - -%{ -#include "params/$cls.hh" -%} - -''') - - # The 'dict' attribute restricts us to the params declared in - # the object itself, not including inherited params (which - # will also be inherited from the base class's param struct - # here). - params = cls._params.local.values() - ptypes = [p.ptype for p in params] - - # get all predeclarations - for param in params: - param.swig_predecls(code) code() + code('#endif // __PARAMS__${cls}__') + return code - if cls._base: - code('%import "python/m5/internal/param_${{cls._base.type}}.i"') - code() - - for ptype in ptypes: - if issubclass(ptype, Enum): - code('%import "enums/${{ptype.__name__}}.hh"') - code() - code('%import "params/${cls}_type.hh"') - code('%include "params/${cls}.hh"') # The SimObject class is the root of the special hierarchy. Most of # the code in this class deals with the configuration hierarchy itself @@ -492,8 +539,42 @@ class SimObject(object): abstract = True @classmethod - def swig_objdecls(cls, code): - code('%include "python/swig/sim_object.i"') + def export_method_cxx_predecls(cls, code): + code(''' +#include <Python.h> + +#include "sim/serialize.hh" +#include "sim/sim_object.hh" +''') + + @classmethod + def export_method_swig_predecls(cls, code): + code(''' +%include <std_string.i> +''') + + @classmethod + def export_methods(cls, code): + code(''' + enum State { + Running, + Draining, + Drained + }; + + void init(); + void loadState(Checkpoint *cp); + void initState(); + void regStats(); + void regFormulas(); + void resetStats(); + void startup(); + + unsigned int drain(Event *drain_event); + void resume(); + void switchOut(); + void takeOverFrom(BaseCPU *cpu); +''') # Initialize new instance. For objects with SimObject-valued # children, we need to recursively clone the classes represented diff --git a/src/python/m5/internal/__init__.py b/src/python/m5/internal/__init__.py index 4aa76cca7..ca09ab468 100644 --- a/src/python/m5/internal/__init__.py +++ b/src/python/m5/internal/__init__.py @@ -29,6 +29,5 @@ import core import debug import event -import random import stats import trace diff --git a/src/python/m5/params.py b/src/python/m5/params.py index ee94ae004..ee3678dc9 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -81,10 +81,17 @@ class MetaParamValue(type): class ParamValue(object): __metaclass__ = MetaParamValue + + # Generate the code needed as a prerequisite for declaring a C++ + # object of this type. Typically generates one or more #include + # statements. Used when declaring parameters of this type. @classmethod def cxx_predecls(cls, code): pass + # Generate the code needed as a prerequisite for including a + # reference to a C++ object of this type in a SWIG .i file. + # Typically generates one or more %import or %include statements. @classmethod def swig_predecls(cls, code): pass @@ -101,8 +108,6 @@ class ParamValue(object): # Regular parameter description. class ParamDesc(object): - file_ext = 'ptype' - def __init__(self, ptype_str, ptype, *args, **kwargs): self.ptype_str = ptype_str # remember ptype only if it is provided @@ -159,6 +164,7 @@ class ParamDesc(object): return self.ptype(value) def cxx_predecls(self, code): + code('#include <cstddef>') self.ptype.cxx_predecls(code) def swig_predecls(self, code): @@ -223,8 +229,6 @@ class SimObjectVector(VectorParamValue): yield obj class VectorParamDesc(ParamDesc): - file_ext = 'vptype' - # Convert assigned value to appropriate type. If the RHS is not a # list or tuple, it generates a single-element list. def convert(self, value): @@ -240,10 +244,14 @@ class VectorParamDesc(ParamDesc): else: return VectorParamValue(tmp_list) + def swig_module_name(self): + return "%s_vector" % self.ptype_str + def swig_predecls(self, code): - code('%import "vptype_${{self.ptype_str}}.i"') + code('%import "${{self.swig_module_name()}}.i"') def swig_decl(self, code): + code('%module(package="m5.internal") ${{self.swig_module_name()}}') code('%{') self.ptype.cxx_predecls(code) code('%}') @@ -1043,6 +1051,19 @@ namespace Enums { } // namespace Enums ''') + def swig_decl(cls, code): + name = cls.__name__ + code('''\ +%module(package="m5.internal") enum_$name + +%{ +#include "enums/$name.hh" +%} + +%include "enums/$name.hh" +''') + + # Base class for enum types. class Enum(ParamValue): __metaclass__ = MetaEnum @@ -1362,7 +1383,7 @@ class PortRef(object): # Call C++ to create corresponding port connection between C++ objects def ccConnect(self): - from m5.internal.params import connectPorts + from m5.internal.pyobject import connectPorts if self.ccConnected: # already done this return diff --git a/src/python/swig/pyobject.cc b/src/python/swig/pyobject.cc index 82a54545f..3478310b1 100644 --- a/src/python/swig/pyobject.cc +++ b/src/python/swig/pyobject.cc @@ -88,16 +88,11 @@ int connectPorts(SimObject *o1, const std::string &name1, int i1, SimObject *o2, const std::string &name2, int i2) { - MemObject *mo1, *mo2; - mo1 = dynamic_cast<MemObject*>(o1); - mo2 = dynamic_cast<MemObject*>(o2); - if (FullSystem) { EtherObject *eo1, *eo2; EtherDevice *ed1, *ed2; eo1 = dynamic_cast<EtherObject*>(o1); ed1 = dynamic_cast<EtherDevice*>(o1); - eo2 = dynamic_cast<EtherObject*>(o2); ed2 = dynamic_cast<EtherDevice*>(o2); diff --git a/src/python/swig/sim_object.i b/src/python/swig/pyobject.i index 06f683aa1..a26f569ce 100644 --- a/src/python/swig/sim_object.i +++ b/src/python/swig/pyobject.i @@ -28,6 +28,8 @@ * Authors: Nathan Binkert */ +%module(package="m5.internal") pyobject + %{ #include "python/swig/pyobject.hh" %} @@ -36,34 +38,6 @@ %include <std_string.i> %include <stdint.i> -%include "base/types.hh" -%include "sim/sim_object_params.hh" - -class BaseCPU; - -class SimObject { - public: - enum State { - Running, - Draining, - Drained - }; - - void init(); - void loadState(Checkpoint *cp); - void initState(); - void regStats(); - void regFormulas(); - void resetStats(); - void startup(); - - unsigned int drain(Event *drain_event); - void resume(); - void switchOut(); - void takeOverFrom(BaseCPU *cpu); - SimObject(const SimObjectParams *p); -}; - int connectPorts(SimObject *o1, const std::string &name1, int i1, SimObject *o2, const std::string &name2, int i2); diff --git a/src/python/swig/system.i b/src/python/swig/system.i deleted file mode 100644 index 1aadcecc6..000000000 --- a/src/python/swig/system.i +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2006 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Nathan Binkert - */ - -%{ -#include "sim/system.hh" -%} - -%import "enums/MemoryMode.hh" -%import "python/swig/sim_object.i" - -class System : public SimObject -{ - private: - System(); - public: - Enums::MemoryMode getMemoryMode(); - void setMemoryMode(Enums::MemoryMode mode); -}; - diff --git a/src/sim/System.py b/src/sim/System.py index 25643099d..db214abc0 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -41,8 +41,15 @@ class System(SimObject): type = 'System' @classmethod - def swig_objdecls(cls, code): - code('%include "python/swig/system.i"') + def export_method_cxx_predecls(cls, code): + code('#include "sim/system.hh"') + + @classmethod + def export_methods(cls, code): + code(''' + Enums::MemoryMode getMemoryMode(); + void setMemoryMode(Enums::MemoryMode mode); +''') physmem = Param.PhysicalMemory("Physical Memory") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") diff --git a/src/sim/process.cc b/src/sim/process.cc index ba43a6b77..468f42955 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -159,7 +159,7 @@ Process::Process(ProcessParams * params) mmap_start = mmap_end = 0; nxm_start = nxm_end = 0; - pTable = new PageTable(this); + pTable = new PageTable(name(), M5_pid); // other parameters will be initialized when the program is loaded } @@ -318,13 +318,21 @@ Process::sim_fd_obj(int tgt_fd) return &fd_map[tgt_fd]; } +void +Process::allocateMem(Addr vaddr, int64_t size, bool clobber) +{ + int npages = divCeil(size, (int64_t)VMPageSize); + Addr paddr = system->allocPhysPages(npages); + pTable->map(vaddr, paddr, size, clobber); +} + bool Process::fixupStackFault(Addr vaddr) { // Check if this is already on the stack and there's just no page there // yet. if (vaddr >= stack_min && vaddr < stack_base) { - pTable->allocate(roundDown(vaddr, VMPageSize), VMPageSize); + allocateMem(roundDown(vaddr, VMPageSize), VMPageSize); return true; } @@ -337,7 +345,7 @@ Process::fixupStackFault(Addr vaddr) fatal("Maximum stack size exceeded\n"); if (stack_base - stack_min > 8 * 1024 * 1024) fatal("Over max stack size for one thread\n"); - pTable->allocate(stack_min, TheISA::PageBytes); + allocateMem(stack_min, TheISA::PageBytes); inform("Increasing stack size by one page."); }; return true; diff --git a/src/sim/process.hh b/src/sim/process.hh index 82879c0e6..f738bb38a 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -203,6 +203,8 @@ class Process : public SimObject virtual void syscall(int64_t callnum, ThreadContext *tc) = 0; + void allocateMem(Addr vaddr, int64_t size, bool clobber = false); + /// Attempt to fix up a fault at vaddr by allocating a page on the stack. /// @return Whether the fault has been fixed. bool fixupStackFault(Addr vaddr); diff --git a/src/sim/sim_object_params.hh b/src/sim/sim_object_params.hh deleted file mode 100644 index 750181135..000000000 --- a/src/sim/sim_object_params.hh +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2001-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Steve Reinhardt - * Nathan Binkert - */ - -#ifndef __SIM_SIM_OBJECT_PARAMS_HH__ -#define __SIM_SIM_OBJECT_PARAMS_HH__ - -#ifndef PY_VERSION -struct PyObject; -#endif - -#include <string> - -struct EventQueue; - -struct SimObjectParams -{ - SimObjectParams() - { - extern EventQueue mainEventQueue; - eventq = &mainEventQueue; - } - virtual ~SimObjectParams() {} - - std::string name; - PyObject *pyobj; - EventQueue *eventq; -}; - - -#endif // __SIM_SIM_OBJECT_PARAMS_HH__ diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index 6873d4aa4..203eaff2a 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -166,8 +166,7 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point, VMPageSize); !gen.done(); gen.next()) { if (!p->pTable->translate(gen.addr())) - p->pTable->allocate(roundDown(gen.addr(), VMPageSize), - VMPageSize); + p->allocateMem(roundDown(gen.addr(), VMPageSize), VMPageSize); // if the address is already there, zero it out else { diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index aff66ae9c..5c480272d 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -678,7 +678,7 @@ mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext * if (new_length > old_length) { if ((start + old_length) == process->mmap_end) { uint64_t diff = new_length - old_length; - process->pTable->allocate(process->mmap_end, diff); + process->allocateMem(process->mmap_end, diff); process->mmap_end += diff; return start; } else { @@ -692,15 +692,15 @@ mremapFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext * process->mmap_end, process->mmap_end + new_length, new_length); start = process->mmap_end; // add on the remaining unallocated pages - process->pTable->allocate(start + old_length, new_length - old_length); + process->allocateMem(start + old_length, + new_length - old_length); process->mmap_end += new_length; warn("returning %08p as start\n", start); return start; } } } else { - process->pTable->deallocate(start + new_length, old_length - - new_length); + process->pTable->unmap(start + new_length, old_length - new_length); return start; } } @@ -1028,20 +1028,45 @@ mmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) return -EINVAL; } - if (start != 0) { - warn("mmap: ignoring suggested map address 0x%x, using 0x%x", - start, p->mmap_end); + // are we ok with clobbering existing mappings? only set this to + // true if the user has been warned. + bool clobber = false; + + // try to use the caller-provided address if there is one + bool use_provided_address = (start != 0); + + if (use_provided_address) { + // check to see if the desired address is already in use + if (!p->pTable->isUnmapped(start, length)) { + // there are existing mappings in the desired range + // whether we clobber them or not depends on whether the caller + // specified MAP_FIXED + if (flags & OS::TGT_MAP_FIXED) { + // MAP_FIXED specified: clobber existing mappings + warn("mmap: MAP_FIXED at 0x%x overwrites existing mappings\n", + start); + clobber = true; + } else { + // MAP_FIXED not specified: ignore suggested start address + warn("mmap: ignoring suggested map address 0x%x\n", start); + use_provided_address = false; + } + } } - // pick next address from our "mmap region" - if (OS::mmapGrowsDown()) { - start = p->mmap_end - length; - p->mmap_end = start; - } else { - start = p->mmap_end; - p->mmap_end += length; + if (!use_provided_address) { + // no address provided, or provided address unusable: + // pick next address from our "mmap region" + if (OS::mmapGrowsDown()) { + start = p->mmap_end - length; + p->mmap_end = start; + } else { + start = p->mmap_end; + p->mmap_end += length; + } } - p->pTable->allocate(start, length); + + p->allocateMem(start, length, clobber); return start; } diff --git a/src/sim/system.cc b/src/sim/system.cc index 654bcef80..3051cb64b 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -261,10 +261,10 @@ System::replaceThreadContext(ThreadContext *tc, int context_id) } Addr -System::new_page() +System::allocPhysPages(int npages) { Addr return_addr = pagePtr << LogVMPageSize; - ++pagePtr; + pagePtr += npages; if (return_addr >= physmem->size()) fatal("Out of memory, please increase size of physical memory."); return return_addr; diff --git a/src/sim/system.hh b/src/sim/system.hh index a8d336d03..00d8360e0 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -271,7 +271,9 @@ class System : public SimObject */ Addr getKernelEntry() const { return kernelEntry; } - Addr new_page(); + /// Allocate npages contiguous unused physical pages + /// @return Starting address of first page + Addr allocPhysPages(int npages); int registerThreadContext(ThreadContext *tc, int assigned=-1); void replaceThreadContext(ThreadContext *tc, int context_id); |