diff options
-rw-r--r-- | SConscript | 2 | ||||
-rw-r--r-- | arch/alpha/alpha_tru64_process.cc | 2 | ||||
-rw-r--r-- | build/SConstruct | 5 | ||||
-rw-r--r-- | cpu/base_cpu.cc | 3 | ||||
-rw-r--r-- | dev/pcidev.cc | 10 | ||||
-rw-r--r-- | python/SConscript | 39 | ||||
-rw-r--r-- | python/m5/__init__.py | 34 | ||||
-rw-r--r-- | python/m5/config.py | 260 | ||||
-rw-r--r-- | python/m5/objects/BaseCPU.mpy | 2 | ||||
-rw-r--r-- | python/m5/objects/Pci.mpy | 5 | ||||
-rw-r--r-- | python/m5/smartdict.py | 23 | ||||
-rw-r--r-- | sim/sim_object.hh | 4 | ||||
-rwxr-xr-x | test/genini.py | 5 | ||||
-rw-r--r-- | util/stats/display.py | 2 | ||||
-rw-r--r-- | util/stats/info.py | 36 | ||||
-rw-r--r-- | util/stats/print.py | 2 |
16 files changed, 255 insertions, 179 deletions
diff --git a/SConscript b/SConscript index cff240a69..3b3c871bc 100644 --- a/SConscript +++ b/SConscript @@ -378,7 +378,7 @@ env.Command(Split('''arch/alpha/decoder.cc # header files into a place where they can be found. SConscript('libelf/SConscript-local', exports = 'env', duplicate=0) SConscript('python/SConscript', exports = ['env'], duplicate=0) - +SConscript('simobj/SConscript', exports = 'env', duplicate=0) # This function adds the specified sources to the given build # environment, and returns a list of all the corresponding SCons diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 22e74cb40..1722b658e 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -953,7 +953,7 @@ class Tru64 { Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[thread_index]; if (ssp->nxm_u.nxm_active != 0) - return Tru64::KERN_NOT_RECEIVER; + return (int) Tru64::KERN_NOT_RECEIVER; ssp->nxm_u.pth_id = attrp->pthid; ssp->nxm_u.nxm_active = uniq_val | 1; diff --git a/build/SConstruct b/build/SConstruct index 3d7db1db2..e33373243 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -62,6 +62,9 @@ if not os.path.isdir('ext'): % EXT_SRCDIR sys.exit(1) +# tell python where to find m5 python code +sys.path.append(os.path.join(SRCDIR, 'python')) + ################################################### # @@ -289,7 +292,7 @@ for build_dir in build_dirs: ################################################### # # Let SCons do its thing. At this point SCons will use the defined -# build enviornments to build the requested targets. +# build environments to build the requested targets. # ################################################### diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc index 181b484e7..74e57baa6 100644 --- a/cpu/base_cpu.cc +++ b/cpu/base_cpu.cc @@ -197,8 +197,7 @@ BaseCPU::registerExecContexts() void BaseCPU::switchOut(SamplingCPU *sampler) { - // default: do nothing, signal done - sampler->signalSwitched(); + panic("This CPU doesn't support sampling!"); } void diff --git a/dev/pcidev.cc b/dev/pcidev.cc index c45afadd4..76b42390a 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -285,11 +285,6 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigData) - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> io_bus; - Param<Tick> pio_latency; - Param<uint16_t> VendorID; Param<uint16_t> DeviceID; Param<uint16_t> Command; @@ -327,11 +322,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(PciConfigData) BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigData) - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM(VendorID, "Vendor ID"), INIT_PARAM(DeviceID, "Device ID"), INIT_PARAM_DFLT(Command, "Command Register", 0x00), diff --git a/python/SConscript b/python/SConscript index 81bc52286..9c15c6d50 100644 --- a/python/SConscript +++ b/python/SConscript @@ -26,7 +26,11 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import os, os.path, re +import os, os.path, re, sys + +Import('env') + +import m5scons def WriteEmbeddedPyFile(target, source, path, name, ext, filename): if isinstance(source, str): @@ -89,7 +93,6 @@ def splitpath(path): path.insert(0, base) return path, file -Import('env') def MakeEmbeddedPyFile(target, source, env): target = file(str(target[0]), 'w') @@ -145,27 +148,11 @@ def MakeEmbeddedPyFile(target, source, env): WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename) def MakeDefinesPyFile(target, source, env): - target = file(str(target[0]), 'w') - - print >>target, "import os" - defines = env['CPPDEFINES'] - if isinstance(defines, list): - for var in defines: - if isinstance(var, tuple): - key,val = var - else: - key,val = var,'True' - - if not isinstance(key, basestring): - panic("invalid type for define: %s" % type(key)) - - print >>target, "os.environ['%s'] = '%s'" % (key, val) - - elif isinstance(defines, dict): - for key,val in defines.iteritems(): - print >>target, "os.environ['%s'] = '%s'" % (key, val) - else: - panic("invalid type for defines: %s" % type(defines)) + f = file(str(target[0]), 'w') + print >>f, "import __main__" + print >>f, "__main__.m5_build_env = ", + print >>f, m5scons.flatten_defines(env['CPPDEFINES']) + f.close() CFileCounter = 0 def MakePythonCFile(target, source, env): @@ -193,8 +180,10 @@ EmbedMap %(name)s("%(fname)s", /* namespace */ } ''' -embedded_py_files = [ 'mpy_importer.py', '../util/pbs/jobfile.py' ] -objpath = os.path.join(env['SRCDIR'], 'python/m5') +# base list of .py files to embed +embedded_py_files = [ '../util/pbs/jobfile.py' ] +# add all .py and .mpy files in python/m5 +objpath = os.path.join(env['SRCDIR'], 'python', 'm5') for root, dirs, files in os.walk(objpath, topdown=True): for i,dir in enumerate(dirs): if dir == 'SCCS': diff --git a/python/m5/__init__.py b/python/m5/__init__.py index 7cb3a32c6..16f48dba3 100644 --- a/python/m5/__init__.py +++ b/python/m5/__init__.py @@ -1,7 +1,37 @@ -from mpy_importer import * +import sys, os + +# the mpy import code is added to the global import meta_path as a +# side effect of this import +from mpy_importer import AddToPath, LoadMpyFile + +# define this here so we can use it right away if necessary +def panic(string): + print >>sys.stderr, 'panic:', string + sys.exit(1) + +# find the m5 compile options: must be specified as a dict in +# __main__.m5_build_env. +import __main__ +if not hasattr(__main__, 'm5_build_env'): + panic("__main__ must define m5_build_env") + +# make a SmartDict out of the build options for our local use +import smartdict +build_env = smartdict.SmartDict() +build_env.update(__main__.m5_build_env) + +# make a SmartDict out of the OS environment too +env = smartdict.SmartDict() +env.update(os.environ) + +# import the main m5 config code from config import * +config.add_param_types(config) + +# import the built-in object definitions from objects import * +config.add_param_types(objects) -cpp_classes = MetaSimObject.cpp_classes +cpp_classes = config.MetaSimObject.cpp_classes cpp_classes.sort() diff --git a/python/m5/config.py b/python/m5/config.py index 2c5a70b25..182acf393 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -27,8 +27,6 @@ from __future__ import generators import os, re, sys, types, inspect -from mpy_importer import AddToPath, LoadMpyFile -from smartdict import SmartDict from convert import * noDot = False @@ -37,16 +35,6 @@ try: except: noDot = True -env = SmartDict() -env.update(os.environ) - -def panic(string): - print >>sys.stderr, 'panic:', string - sys.exit(1) - -def issequence(value): - return isinstance(value, tuple) or isinstance(value, list) - class Singleton(type): def __call__(cls, *args, **kwargs): if hasattr(cls, '_instance'): @@ -190,7 +178,7 @@ def isSimObject(value): return False def isSimObjSequence(value): - if not issequence(value): + if not isinstance(value, (list, tuple)): return False for val in value: @@ -210,6 +198,28 @@ class_decorator = 'M5M5_SIMOBJECT_' expr_decorator = 'M5M5_EXPRESSION_' dot_decorator = '_M5M5_DOT_' +# 'Global' map of legitimate types for SimObject parameters. +param_types = {} + +# Dummy base class to identify types that are legitimate for SimObject +# parameters. +class ParamType(object): + pass + +# Add types defined in given context (dict or module) that are derived +# from ParamType to param_types map. +def add_param_types(ctx): + if isinstance(ctx, types.DictType): + source_dict = ctx + elif isinstance(ctx, types.ModuleType): + source_dict = ctx.__dict__ + else: + raise TypeError, \ + "m5.config.add_param_types requires dict or module as arg" + for key,val in source_dict.iteritems(): + if isinstance(val, type) and issubclass(val, ParamType): + param_types[key] = val + # The metaclass for ConfigNode (and thus for everything that derives # from ConfigNode, including SimObject). This class controls how new # classes that derive from ConfigNode are instantiated, and provides @@ -247,7 +257,7 @@ class MetaConfigNode(type): # initialize required attributes cls._params = {} cls._values = {} - cls._enums = {} + cls._param_types = {} cls._bases = [c for c in cls.__mro__ if isConfigNode(c)] cls._anon_subclass_counter = 0 @@ -270,19 +280,26 @@ class MetaConfigNode(type): elif isNullPointer(val): cls._values[key] = val - # now process _init_dict items + # process param types from _init_dict, as these may be needed + # by param descriptions also in _init_dict + for key,val in cls._init_dict.items(): + if isinstance(val, type) and issubclass(val, ParamType): + cls._param_types[key] = val + if not issubclass(val, ConfigNode): + del cls._init_dict[key] + + # now process remaining _init_dict items for key,val in cls._init_dict.items(): + # param descriptions if isinstance(val, _Param): cls._params[key] = val + # try to resolve local param types in local param_types scope + val.maybe_resolve_type(cls._param_types) # init-time-only keywords elif cls.init_keywords.has_key(key): cls._set_keyword(key, val, cls.init_keywords[key]) - # enums - elif isinstance(val, type) and issubclass(val, Enum): - cls._enums[key] = val - # See description of decorators in the importer.py file. # We just strip off the expr_decorator now since we don't # need from this point on. @@ -419,7 +436,11 @@ class MetaConfigNode(type): # It's ok: set attribute by delegating to 'object' class. # Note the use of param.make_value() to verify/canonicalize # the assigned value - param.valid(value) + try: + param.valid(value) + except: + panic("Error setting param %s.%s to %s\n" % \ + (cls.__name__, attr, value)) cls._setvalue(attr, value) elif isConfigNode(value) or isSimObjSequence(value): cls._setvalue(attr, value) @@ -431,7 +452,7 @@ class MetaConfigNode(type): if isNullPointer(child) or instance.top_child_names.has_key(name): return - if issequence(child): + if isinstance(child, (list, tuple)): kid = [] for i,c in enumerate(child): n = '%s%d' % (name, i) @@ -459,10 +480,10 @@ class MetaConfigNode(type): for key,value in cls._getvalues().iteritems(): if isConfigNode(value): cls.add_child(instance, key, value) - if issequence(value): - list = [ v for v in value if isConfigNode(v) ] - if len(list): - cls.add_child(instance, key, list) + if isinstance(value, (list, tuple)): + vals = [ v for v in value if isConfigNode(v) ] + if len(vals): + cls.add_child(instance, key, vals) for pname,param in cls._getparams().iteritems(): try: @@ -473,7 +494,7 @@ class MetaConfigNode(type): try: if isConfigNode(value): value = instance.child_objects[value] - elif issequence(value): + elif isinstance(value, (list, tuple)): v = [] for val in value: if isConfigNode(val): @@ -562,7 +583,7 @@ class MetaSimObject(MetaConfigNode): def _cpp_decl(cls): name = cls.__name__ code = "" - code += "\n".join([e.cpp_declare() for e in cls._enums.values()]) + code += "\n".join([e.cpp_declare() for e in cls._param_types.values()]) code += "\n" param_names = cls._params.keys() param_names.sort() @@ -675,7 +696,7 @@ class Node(object): pval = param.value try: - if issequence(pval): + if isinstance(pval, (list, tuple)): param.value = [ self.unproxy(ptype, pv) for pv in pval ] else: param.value = self.unproxy(ptype, pval) @@ -854,13 +875,24 @@ class _Param(object): if not hasattr(self, 'desc'): raise TypeError, 'desc attribute missing' + def maybe_resolve_type(self, context): + # check if already resolved... don't use hasattr(), + # as that calls __getattr__() + if self.__dict__.has_key('ptype'): + return + try: + self.ptype = context[self.ptype_string] + except KeyError: + # no harm in trying... we'll try again later using global scope + pass + def __getattr__(self, attr): if attr == 'ptype': try: - self.ptype = eval(self.ptype_string) + self.ptype = param_types[self.ptype_string] return self.ptype except: - raise TypeError, 'Param.%s: undefined type' % self.ptype_string + panic("undefined Param type %s" % self.ptype_string) else: raise AttributeError, "'%s' object has no attribute '%s'" % \ (type(self).__name__, attr) @@ -887,19 +919,10 @@ class _ParamProxy(object): # E.g., Param.Int(5, "number of widgets") def __call__(self, *args, **kwargs): - # Param type could be defined only in context of caller (e.g., - # for locally defined Enum subclass). Need to go look up the - # type in that enclosing scope. - caller_frame = inspect.stack()[1][0] - ptype = caller_frame.f_locals.get(self.ptype, None) - if not ptype: ptype = caller_frame.f_globals.get(self.ptype, None) - if not ptype: ptype = globals().get(self.ptype, None) - # ptype could still be None due to circular references... we'll - # try one more time to evaluate lazily when ptype is first needed. - # In the meantime we'll save the type name as a string. - if not ptype: ptype = self.ptype - return _Param(ptype, *args, **kwargs) + return _Param(self.ptype, *args, **kwargs) + # Strange magic to theoretically allow dotted names as Param classes, + # e.g., Param.Foo.Bar(...) to have a param of type Foo.Bar def __getattr__(self, attr): if attr == '__bases__': raise AttributeError, '' @@ -926,7 +949,7 @@ class _VectorParam(_Param): if value == None: return True - if issequence(value): + if isinstance(value, (list, tuple)): for val in value: if not isinstance(val, Proxy): self.ptype._convert(val) @@ -939,7 +962,7 @@ class _VectorParam(_Param): if value == None: return [] - if issequence(value): + if isinstance(value, (list, tuple)): # list: coerce each element into new list return [ self.ptype._convert(v) for v in value ] else: @@ -947,7 +970,7 @@ class _VectorParam(_Param): return self.ptype._convert(value) def string(self, value): - if issequence(value): + if isinstance(value, (list, tuple)): return ' '.join([ self.ptype._string(v) for v in value]) else: return self.ptype._string(value) @@ -975,8 +998,33 @@ VectorParam = _VectorParamProxy(None) # to correspond to distinct C++ types as well. # ##################################################################### -# Integer parameter type. -class _CheckedInt(object): + + +# Metaclass for bounds-checked integer parameters. See CheckedInt. +class CheckedIntType(type): + def __init__(cls, name, bases, dict): + super(CheckedIntType, cls).__init__(name, bases, dict) + + # CheckedInt is an abstract base class, so we actually don't + # want to do any processing on it... the rest of this code is + # just for classes that derive from CheckedInt. + if name == 'CheckedInt': + return + + if not (hasattr(cls, 'min') and hasattr(cls, 'max')): + if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')): + panic("CheckedInt subclass %s must define either\n" \ + " 'min' and 'max' or 'size' and 'unsigned'\n" \ + % name); + if cls.unsigned: + cls.min = 0 + cls.max = 2 ** cls.size - 1 + else: + cls.min = -(2 ** (cls.size - 1)) + cls.max = (2 ** (cls.size - 1)) - 1 + + cls._cpp_param_decl = cls.cppname + def _convert(cls, value): if isinstance(value, bool): return int(value) @@ -987,86 +1035,72 @@ class _CheckedInt(object): if isinstance(value, (str, float)): value = long(float(value)) - if not cls._min <= value <= cls._max: + if not cls.min <= value <= cls.max: raise TypeError, 'Integer param out of bounds %d < %d < %d' % \ - (cls._min, value, cls._max) + (cls.min, value, cls.max) return value - _convert = classmethod(_convert) def _string(cls, value): return str(value) - _string = classmethod(_string) - -class CheckedInt(type): - def __new__(cls, cppname, min, max): - # New class derives from _CheckedInt base with proper bounding - # parameters - dict = { '_cpp_param_decl' : cppname, '_min' : min, '_max' : max } - return type.__new__(cls, cppname, (_CheckedInt, ), dict) - -class CheckedIntType(CheckedInt): - def __new__(cls, cppname, size, unsigned): - dict = {} - if unsigned: - min = 0 - max = 2 ** size - 1 - else: - min = -(2 ** (size - 1)) - max = (2 ** (size - 1)) - 1 - return super(cls, CheckedIntType).__new__(cls, cppname, min, max) +# Abstract superclass for bounds-checked integer parameters. This +# class is subclassed to generate parameter classes with specific +# bounds. Initialization of the min and max bounds is done in the +# metaclass CheckedIntType.__init__. +class CheckedInt(ParamType): + __metaclass__ = CheckedIntType -Int = CheckedIntType('int', 32, False) -Unsigned = CheckedIntType('unsigned', 32, True) +class Int(CheckedInt): cppname = 'int'; size = 32; unsigned = False +class Unsigned(CheckedInt): cppname = 'unsigned'; size = 32; unsigned = True -Int8 = CheckedIntType('int8_t', 8, False) -UInt8 = CheckedIntType('uint8_t', 8, True) -Int16 = CheckedIntType('int16_t', 16, False) -UInt16 = CheckedIntType('uint16_t', 16, True) -Int32 = CheckedIntType('int32_t', 32, False) -UInt32 = CheckedIntType('uint32_t', 32, True) -Int64 = CheckedIntType('int64_t', 64, False) -UInt64 = CheckedIntType('uint64_t', 64, True) +class Int8(CheckedInt): cppname = 'int8_t'; size = 8; unsigned = False +class UInt8(CheckedInt): cppname = 'uint8_t'; size = 8; unsigned = True +class Int16(CheckedInt): cppname = 'int16_t'; size = 16; unsigned = False +class UInt16(CheckedInt): cppname = 'uint16_t'; size = 16; unsigned = True +class Int32(CheckedInt): cppname = 'int32_t'; size = 32; unsigned = False +class UInt32(CheckedInt): cppname = 'uint32_t'; size = 32; unsigned = True +class Int64(CheckedInt): cppname = 'int64_t'; size = 64; unsigned = False +class UInt64(CheckedInt): cppname = 'uint64_t'; size = 64; unsigned = True -Counter = CheckedIntType('Counter', 64, True) -Addr = CheckedIntType('Addr', 64, True) -Tick = CheckedIntType('Tick', 64, True) +class Counter(CheckedInt): cppname = 'Counter'; size = 64; unsigned = True +class Addr(CheckedInt): cppname = 'Addr'; size = 64; unsigned = True +class Tick(CheckedInt): cppname = 'Tick'; size = 64; unsigned = True -Percent = CheckedInt('int', 0, 100) +class Percent(CheckedInt): cppname = 'int'; min = 0; max = 100 class Pair(object): def __init__(self, first, second): self.first = first self.second = second -class _Range(object): +class MetaRange(type): + def __init__(cls, name, bases, dict): + super(MetaRange, cls).__init__(name, bases, dict) + if name == 'Range': + return + cls._cpp_param_decl = 'Range<%s>' % cls.type._cpp_param_decl + def _convert(cls, value): if not isinstance(value, Pair): raise TypeError, 'value %s is not a Pair' % value - return Pair(cls._type._convert(value.first), - cls._type._convert(value.second)) - _convert = classmethod(_convert) + return Pair(cls.type._convert(value.first), + cls.type._convert(value.second)) def _string(cls, value): - return '%s:%s' % (cls._type._string(value.first), - cls._type._string(value.second)) - _string = classmethod(_string) + return '%s:%s' % (cls.type._string(value.first), + cls.type._string(value.second)) + +class Range(ParamType): + __metaclass__ = MetaRange def RangeSize(start, size): return Pair(start, start + size - 1) -class Range(type): - def __new__(cls, type): - dict = { '_cpp_param_decl' : 'Range<%s>' % type._cpp_param_decl, - '_type' : type } - clsname = 'Range_' + type.__name__ - return super(cls, Range).__new__(cls, clsname, (_Range, ), dict) - -AddrRange = Range(Addr) +class AddrRange(Range): type = Addr # Boolean parameter type. -class Bool(object): +class Bool(ParamType): _cpp_param_decl = 'bool' def _convert(value): t = type(value) @@ -1094,7 +1128,7 @@ class Bool(object): _string = staticmethod(_string) # String-valued parameter. -class String(object): +class String(ParamType): _cpp_param_decl = 'string' # Constructor. Value must be Python string. @@ -1134,7 +1168,7 @@ class NextEthernetAddr(object): self.value = self.addr self.addr = IncEthernetAddr(self.addr, inc) -class EthernetAddr(object): +class EthernetAddr(ParamType): _cpp_param_decl = 'EthAddr' def _convert(cls, value): @@ -1241,7 +1275,7 @@ class MetaEnum(type): return s # Base class for enum types. -class Enum(object): +class Enum(ParamType): __metaclass__ = MetaEnum vals = [] @@ -1261,8 +1295,8 @@ class Enum(object): # # Some memory range specifications use this as a default upper bound. -MAX_ADDR = Addr._max -MaxTick = Tick._max +MAX_ADDR = Addr.max +MaxTick = Tick.max # For power-of-two sizing, e.g. 64*K gives an integer value 65536. K = 1024 @@ -1274,9 +1308,6 @@ G = K*M # The final hook to generate .ini files. Called from configuration # script once config is built. def instantiate(root): - if not issubclass(root, Root): - raise AttributeError, 'Can only instantiate the Root of the tree' - instance = root.instantiate('root') instance.fixup() instance.display() @@ -1297,8 +1328,19 @@ def instantiate(root): # parameters to be set by keyword in the constructor. Note that most # of the heavy lifting for the SimObject param handling is done in the # MetaConfigNode metaclass. -class SimObject(ConfigNode): +class SimObject(ConfigNode, ParamType): __metaclass__ = MetaSimObject type = 'SimObject' -from objects import * + +# __all__ defines the list of symbols that get exported when +# 'from config import *' is invoked. Try to keep this reasonably +# short to avoid polluting other namespaces. +__all__ = ['ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', + 'Super', 'Enum', + 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', + 'Int32', 'UInt32', 'Int64', 'UInt64', + 'Counter', 'Addr', 'Tick', 'Percent', + 'Pair', 'RangeSize', 'AddrRange', 'MAX_ADDR', 'NULL', 'K', 'M', + 'NextEthernetAddr', + 'instantiate'] diff --git a/python/m5/objects/BaseCPU.mpy b/python/m5/objects/BaseCPU.mpy index be93e8ad1..5d8305d88 100644 --- a/python/m5/objects/BaseCPU.mpy +++ b/python/m5/objects/BaseCPU.mpy @@ -4,7 +4,7 @@ simobj BaseCPU(SimObject): icache = Param.BaseMem(NULL, "L1 instruction cache object") dcache = Param.BaseMem(NULL, "L1 data cache object") - if env.get('FULL_SYSTEM', 'False'): + if build_env['FULL_SYSTEM']: dtb = Param.AlphaDTB("Data TLB") itb = Param.AlphaITB("Instruction TLB") mem = Param.FunctionalMemory("memory") diff --git a/python/m5/objects/Pci.mpy b/python/m5/objects/Pci.mpy index caa3c52ff..f7c6674f7 100644 --- a/python/m5/objects/Pci.mpy +++ b/python/m5/objects/Pci.mpy @@ -1,8 +1,7 @@ from Device import FooPioDevice, DmaDevice -simobj PciConfigData(FooPioDevice): +simobj PciConfigData(SimObject): type = 'PciConfigData' - addr = 0xffffffffffffffffL VendorID = Param.UInt16("Vendor ID") DeviceID = Param.UInt16("Device ID") Command = Param.UInt16(0, "Command") @@ -44,9 +43,9 @@ simobj PciConfigAll(FooPioDevice): simobj PciDevice(DmaDevice): type = 'PciDevice' abstract = True + addr = 0xffffffffL pci_bus = Param.Int("PCI bus") pci_dev = Param.Int("PCI device number") pci_func = Param.Int("PCI function code") configdata = Param.PciConfigData(Super, "PCI Config data") configspace = Param.PciConfigAll(Super, "PCI Configspace") - addr = 0xffffffffffffffffL diff --git a/python/m5/smartdict.py b/python/m5/smartdict.py index e282bc07b..4ea8210d3 100644 --- a/python/m5/smartdict.py +++ b/python/m5/smartdict.py @@ -1,6 +1,23 @@ +# The SmartDict class fixes a couple of issues with using the content +# of os.environ or similar dicts of strings as Python variables: +# +# 1) Undefined variables should return False rather than raising KeyError. +# +# 2) String values of 'False', '0', etc., should evaluate to False +# (not just the empty string). +# +# #1 is solved by overriding __getitem__, and #2 is solved by using a +# proxy class for values and overriding __nonzero__ on the proxy. +# Everything else is just to (a) make proxies behave like normal +# values otherwise, (b) make sure any dict operation returns a proxy +# rather than a normal value, and (c) coerce values written to the +# dict to be strings. + + from convert import * class SmartDict(dict): + class Proxy(str): def __int__(self): return int(to_integer(str(self))) @@ -58,7 +75,7 @@ class SmartDict(dict): def __getitem__(self, key): - return self.Proxy(dict.__getitem__(self, key)) + return self.Proxy(dict.get(self, key, 'False')) def __setitem__(self, key, item): dict.__setitem__(self, key, str(item)) @@ -77,9 +94,9 @@ class SmartDict(dict): for key,value in dict.iteritems(self): yield key, self.Proxy(value) - def get(self, key, default=''): + def get(self, key, default='False'): return self.Proxy(dict.get(self, key, str(default))) - def setdefault(self, key, default=''): + def setdefault(self, key, default='False'): return self.Proxy(dict.setdefault(self, key, str(default))) diff --git a/sim/sim_object.hh b/sim/sim_object.hh index f4b316ebb..b8a3090ad 100644 --- a/sim/sim_object.hh +++ b/sim/sim_object.hh @@ -60,6 +60,10 @@ class SimObject : public Serializable, protected StartupCallback static SimObjectList simObjectList; public: + +// for Params struct +#include "simobj/param/SimObject.hh" + SimObject(const std::string &_name); virtual ~SimObject() {} diff --git a/test/genini.py b/test/genini.py index 025ba998a..b8eda5d46 100755 --- a/test/genini.py +++ b/test/genini.py @@ -35,6 +35,8 @@ sys.path.append(joinpath(mypath, '../util/pbs')) pathlist = [ '.' ] +m5_build_env = {} + try: opts, args = getopt.getopt(sys.argv[1:], '-E:I:') for opt,arg in opts: @@ -42,11 +44,12 @@ try: offset = arg.find('=') if offset == -1: name = arg - value = True + value = '1' else: name = arg[:offset] value = arg[offset+1:] os.environ[name] = value + m5_build_env[name] = value if opt == '-I': pathlist.append(arg) except getopt.GetoptError: diff --git a/util/stats/display.py b/util/stats/display.py index 68a26852d..4c17d4427 100644 --- a/util/stats/display.py +++ b/util/stats/display.py @@ -68,7 +68,7 @@ class VectorDisplay: p.flags = self.flags p.precision = self.precision - if issequence(self.value): + if isinstance(self.value, (list, tuple)): if not len(self.value): return diff --git a/util/stats/info.py b/util/stats/info.py index 01d7bdb0f..3f6a8dbc3 100644 --- a/util/stats/info.py +++ b/util/stats/info.py @@ -6,9 +6,6 @@ display_run = 0 global globalTicks globalTicks = None -def issequence(t): - return isinstance(t, types.TupleType) or isinstance(t, types.ListType) - def total(f): if isinstance(f, FormulaStat): v = f.value @@ -16,7 +13,7 @@ def total(f): v = f f = FormulaStat() - if issequence(v): + if isinstance(v, (list, tuple)): f.value = reduce(operator.add, v) else: f.value = v @@ -29,7 +26,7 @@ def unaryop(op, f): else: v = f - if issequence(v): + if isinstance(v, (list, tuple)): return map(op, v) else: return op(v) @@ -109,19 +106,19 @@ def binaryop(op, lf, rf): return result def sums(x, y): - if issequence(x): + if isinstance(x, (list, tuple)): return map(lambda x, y: x + y, x, y) else: return x + y -def alltrue(list): - return reduce(lambda x, y: x and y, list) +def alltrue(seq): + return reduce(lambda x, y: x and y, seq) -def allfalse(list): - return not reduce(lambda x, y: x or y, list) +def allfalse(seq): + return not reduce(lambda x, y: x or y, seq) -def enumerate(list): - return map(None, range(len(list)), list) +def enumerate(seq): + return map(None, range(len(seq)), seq) def cmp(a, b): if a < b: @@ -323,10 +320,11 @@ class Vector(Statistic,FormulaStat): len(self.value) == len(other.value) def __eq__(self, other): - if issequence(self.value) != issequence(other.value): + if isinstance(self.value, (list, tuple)) != \ + isinstance(other.value, (list, tuple)): return False - if issequence(self.value): + if isinstance(self.value, (list, tuple)): if len(self.value) != len(other.value): return False else: @@ -348,7 +346,7 @@ class Vector(Statistic,FormulaStat): def __itruediv__(self, other): if not other: return self - if issequence(self.value): + if isinstance(self.value, (list, tuple)): for i in xrange(len(self.value)): self.value[i] /= other else: @@ -642,7 +640,8 @@ class VectorDist(Statistic): return alltrue(map(lambda x, y : x == y, self.dist, other.dist)) def __isub__(self, other): - if issequence(self.dist) and issequence(other.dist): + if isinstance(self.dist, (list, tuple)) and \ + isinstance(other.dist, (list, tuple)): for sd,od in zip(self.dist, other.dist): sd -= od else: @@ -650,7 +649,8 @@ class VectorDist(Statistic): return self def __iadd__(self, other): - if issequence(self.dist) and issequence(other.dist): + if isinstance(self.dist, (list, tuple)) and \ + isinstance(other.dist, (list, tuple)): for sd,od in zip(self.dist, other.dist): sd += od else: @@ -660,7 +660,7 @@ class VectorDist(Statistic): def __itruediv__(self, other): if not other: return self - if issequence(self.dist): + if isinstance(self.dist, (list, tuple)): for dist in self.dist: dist /= other else: diff --git a/util/stats/print.py b/util/stats/print.py index f4492cd2b..1ed50eef0 100644 --- a/util/stats/print.py +++ b/util/stats/print.py @@ -71,7 +71,7 @@ class VectorDisplay: p.flags = self.flags p.precision = self.precision - if issequence(self.value): + if isinstance(self.value, (list, tuple)): if not len(self.value): return |