summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/alpha_tru64_process.cc4
-rw-r--r--configs/splash2/run.mpy4
-rw-r--r--python/m5/__init__.py8
-rw-r--r--python/m5/config.py221
-rw-r--r--python/m5/convert.py16
-rw-r--r--python/m5/multidict.py158
-rw-r--r--python/m5/smartdict.py8
-rw-r--r--sim/process.cc1
-rw-r--r--sim/process.hh9
-rw-r--r--sim/syscall_emul.hh4
10 files changed, 273 insertions, 160 deletions
diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc
index 1722b658e..a211e0ae8 100644
--- a/arch/alpha/alpha_tru64_process.cc
+++ b/arch/alpha/alpha_tru64_process.cc
@@ -877,6 +877,10 @@ class Tru64 {
*configptr_ptr = config_addr;
configptr_ptr.copyOut(xc->mem);
+ // Register this as a valid address range with the process
+ process->nxm_start = base_addr;
+ process->nxm_end = cur_addr;
+
return 0;
}
diff --git a/configs/splash2/run.mpy b/configs/splash2/run.mpy
index a19dcdc93..800bff6f8 100644
--- a/configs/splash2/run.mpy
+++ b/configs/splash2/run.mpy
@@ -5,12 +5,12 @@ if 'SYSTEM' not in env:
if env['SYSTEM'] == 'Simple':
from SimpleConfig import *
- BaseCPU.workload = Super.workload
+ BaseCPU.workload = parent.workload
SimpleStandAlone.cpu = [ CPU() for i in xrange(int(env['NP'])) ]
root = SimpleStandAlone
elif env['SYSTEM'] == 'Detailed':
from DetailedConfig import *
- BaseCPU.workload = Super.workload
+ BaseCPU.workload = parent.workload
DetailedStandAlone.cpu = [ DetailedCPU() for i in xrange(int(env['NP'])) ]
root = DetailedStandAlone
else:
diff --git a/python/m5/__init__.py b/python/m5/__init__.py
index 16f48dba3..27bd91749 100644
--- a/python/m5/__init__.py
+++ b/python/m5/__init__.py
@@ -1,14 +1,14 @@
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)
+# 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
+
# find the m5 compile options: must be specified as a dict in
# __main__.m5_build_env.
import __main__
diff --git a/python/m5/config.py b/python/m5/config.py
index e6ad5a0ba..f696adc79 100644
--- a/python/m5/config.py
+++ b/python/m5/config.py
@@ -27,7 +27,9 @@
from __future__ import generators
import os, re, sys, types, inspect
+from m5 import panic
from convert import *
+from multidict import multidict
noDot = False
try:
@@ -150,8 +152,11 @@ class Proxy(object):
self._multiplier = None
def __getattr__(self, attr):
+ # python uses __bases__ internally for inheritance
if attr == '__bases__':
return super(Proxy, self).__getattr__(self, attr)
+ if (self._path == None):
+ panic("Can't add attributes to 'any' proxy")
self._path.append((attr,None))
return self
@@ -197,12 +202,14 @@ class Proxy(object):
raise AttributeError, \
'Parent of %s type %s not found at path %s' \
% (base.name, ptype, self._path)
- found, done = obj.find(ptype, self._path)
- if isinstance(found, Proxy):
- done = False
+
+ result, done = obj.find(ptype, self._path)
obj = obj.parent
- return self._mulcheck(found)
+ if isinstance(result, Proxy):
+ result = result.unproxy(obj, ptype)
+
+ return self._mulcheck(result)
def getindex(obj, index):
if index == None:
@@ -320,17 +327,20 @@ class MetaConfigNode(type):
super(MetaConfigNode, cls).__init__(name, bases, dict)
# initialize required attributes
- cls._params = {}
- cls._values = {}
+ cls._params = multidict()
+ cls._values = multidict()
cls._param_types = {}
cls._bases = [c for c in cls.__mro__ if isConfigNode(c)]
cls._anon_subclass_counter = 0
- # If your parent has a value in it that's a config node, clone
- # it. Do this now so if we update any of the values'
- # attributes we are updating the clone and not the original.
- for base in cls._bases:
- for key,val in base._values.iteritems():
+ # We don't support multiple inheritence. If you want to, you
+ # must fix multidict to deal with it properly.
+ cnbase = [ base for base in bases if isConfigNode(base) ]
+ if len(cnbase) == 1:
+ # If your parent has a value in it that's a config node, clone
+ # it. Do this now so if we update any of the values'
+ # attributes we are updating the clone and not the original.
+ for key,val in cnbase[0]._values.iteritems():
# don't clone if (1) we're about to overwrite it with
# a local setting or (2) we've already cloned a copy
@@ -340,10 +350,17 @@ class MetaConfigNode(type):
if isConfigNode(val):
cls._values[key] = val()
- elif isSimObjSequence(val):
+ elif isSimObjSequence(val) and len(val):
cls._values[key] = [ v() for v in val ]
- elif isNullPointer(val):
- cls._values[key] = val
+
+ cls._params.parent = cnbase[0]._params
+ cls._values.parent = cnbase[0]._values
+
+ elif len(cnbase) > 1:
+ panic("""\
+The config hierarchy only supports single inheritence of SimObject
+classes. You're trying to derive from:
+%s""" % str(cnbase))
# process param types from _init_dict, as these may be needed
# by param descriptions also in _init_dict
@@ -357,9 +374,7 @@ class MetaConfigNode(type):
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)
+ cls._new_param(key, val)
# init-time-only keywords
elif cls.init_keywords.has_key(key):
@@ -382,99 +397,6 @@ class MetaConfigNode(type):
else:
setattr(cls, key, val)
-
- def _isvalue(cls, name):
- for c in cls._bases:
- if c._params.has_key(name):
- return True
-
- for c in cls._bases:
- if c._values.has_key(name):
- return True
-
- return False
-
- # generator that iterates across all parameters for this class and
- # all classes it inherits from
- def _getparams(cls):
- params = {}
- for c in cls._bases:
- for p,v in c._params.iteritems():
- if not params.has_key(p):
- params[p] = v
- return params
-
- # Lookup a parameter description by name in the given class.
- def _getparam(cls, name, default = AttributeError):
- for c in cls._bases:
- if c._params.has_key(name):
- return c._params[name]
- if isSubClass(default, Exception):
- raise default, \
- "object '%s' has no attribute '%s'" % (cls.__name__, name)
- else:
- return default
-
- def _hasvalue(cls, name):
- for c in cls._bases:
- if c._values.has_key(name):
- return True
-
- return False
-
- def _getvalues(cls):
- values = {}
- for i,c in enumerate(cls._bases):
- for p,v in c._values.iteritems():
- if not values.has_key(p):
- values[p] = v
- for p,v in c._params.iteritems():
- if not values.has_key(p) and hasattr(v, 'default'):
- try:
- v.valid(v.default)
- except TypeError:
- panic("Invalid default %s for param %s in node %s"
- % (v.default,p,cls.__name__))
- v = v.default
- cls._setvalue(p, v)
- values[p] = v
-
- return values
-
- def _getvalue(cls, name, default = AttributeError):
- value = None
- for c in cls._bases:
- if c._values.has_key(name):
- value = c._values[name]
- break
- if value is not None:
- return value
-
- param = cls._getparam(name, None)
- if param is not None and hasattr(param, 'default'):
- param.valid(param.default)
- value = param.default
- cls._setvalue(name, value)
- return value
-
- if isSubClass(default, Exception):
- raise default, 'value for %s not found' % name
- else:
- return default
-
- def _setvalue(cls, name, value):
- cls._values[name] = value
-
- def __getattr__(cls, attr):
- if cls._isvalue(attr):
- return Value(cls, attr)
-
- if attr == '_cpp_param_decl' and hasattr(cls, 'type'):
- return cls.type + '*'
-
- raise AttributeError, \
- "object '%s' has no attribute '%s'" % (cls.__name__, attr)
-
def _set_keyword(cls, keyword, val, kwtype):
if not isinstance(val, kwtype):
raise TypeError, 'keyword %s has bad type %s (expecting %s)' % \
@@ -483,6 +405,13 @@ class MetaConfigNode(type):
val = classmethod(val)
type.__setattr__(cls, keyword, val)
+ def _new_param(cls, name, value):
+ cls._params[name] = value
+ if hasattr(value, 'default'):
+ cls._values[name] = value.default
+ # try to resolve local param types in local param_types scope
+ value.maybe_resolve_type(cls._param_types)
+
# Set attribute (called on foo.attr = value when foo is an
# instance of class cls).
def __setattr__(cls, attr, value):
@@ -496,23 +425,33 @@ class MetaConfigNode(type):
return
# must be SimObject param
- param = cls._getparam(attr, None)
+ param = cls._params.get(attr, None)
if param:
# It's ok: set attribute by delegating to 'object' class.
# Note the use of param.make_value() to verify/canonicalize
# the assigned value
try:
param.valid(value)
- except:
- panic("Error setting param %s.%s to %s\n" % \
- (cls.__name__, attr, value))
- cls._setvalue(attr, value)
+ except Exception, e:
+ panic("Exception: %s\nError setting param %s.%s to %s\n" % \
+ (e, cls.__name__, attr, value))
+ cls._values[attr] = value
elif isConfigNode(value) or isSimObjSequence(value):
- cls._setvalue(attr, value)
+ cls._values[attr] = value
else:
raise AttributeError, \
"Class %s has no parameter %s" % (cls.__name__, attr)
+ def __getattr__(cls, attr):
+ if cls._params.has_key(attr) or cls._values.has_key(attr):
+ return Value(cls, attr)
+
+ if attr == '_cpp_param_decl' and hasattr(cls, 'type'):
+ return cls.type + '*'
+
+ raise AttributeError, \
+ "object '%s' has no attribute '%s'" % (cls.__name__, attr)
+
def add_child(cls, instance, name, child):
if isNullPointer(child) or instance.top_child_names.has_key(name):
return
@@ -542,7 +481,7 @@ class MetaConfigNode(type):
if hasattr(cls, 'check'):
cls.check()
- for key,value in cls._getvalues().iteritems():
+ for key,value in cls._values.iteritems():
if isConfigNode(value):
cls.add_child(instance, key, value)
if isinstance(value, (list, tuple)):
@@ -550,11 +489,10 @@ class MetaConfigNode(type):
if len(vals):
cls.add_child(instance, key, vals)
- for pname,param in cls._getparams().iteritems():
- try:
- value = cls._getvalue(pname)
- except:
- panic('Error getting %s' % pname)
+ for pname,param in cls._params.iteritems():
+ value = cls._values.get(pname, None)
+ if value is None:
+ panic('Error getting %s from %s' % (pname, name))
try:
if isConfigNode(value):
@@ -571,10 +509,9 @@ class MetaConfigNode(type):
p = NodeParam(pname, param, value)
instance.params.append(p)
instance.param_names[pname] = p
- except:
- print 'Exception while evaluating %s.%s' % \
- (instance.path, pname)
- raise
+ except Exception, e:
+ raise e.__class__, 'Exception while evaluating %s.%s\n%s' % \
+ (instance.path, pname, e)
return instance
@@ -613,7 +550,7 @@ class ConfigNode(object):
cls._anon_subclass_counter += 1
return cls.__metaclass__(name, (cls, ), kwargs)
-class ParamContext(ConfigNode):
+class ParamContext(ConfigNode,ParamType):
pass
class MetaSimObject(MetaConfigNode):
@@ -755,9 +692,9 @@ class Node(object):
param.value = [ self.unproxy(pv, ptype) for pv in pval ]
else:
param.value = self.unproxy(pval, ptype)
- except:
- print 'Error while fixing up %s:%s' % (self.path, param.name)
- raise
+ except Exception, e:
+ raise e.__class__, 'Error while fixing up %s:%s\n%s' % \
+ (self.path, param.name, e)
for child in self.children:
assert(child != self)
@@ -776,9 +713,8 @@ class Node(object):
# before cpu0). Changing ordering can also influence timing
# in the current memory system, as caches get added to a bus
# in different orders which affects their priority in the
- # case of simulataneous requests. We should uncomment the
- # following line once we take care of that issue.
- # self.children.sort(lambda x,y: cmp(x.name, y.name))
+ # case of simulataneous requests.
+ self.children.sort(lambda x,y: cmp(x.name, y.name))
children = [ c.name for c in self.children if not c.paramcontext]
print 'children =', ' '.join(children)
@@ -790,9 +726,9 @@ class Node(object):
value = param.convert(param.value)
string = param.string(value)
- except:
- print 'exception in %s:%s' % (self.path, param.name)
- raise
+ except Exception, e:
+ raise e.__class__, 'exception in %s:%s\n%s' % \
+ (self.path, param.name, e)
print '%s = %s' % (param.name, string)
@@ -825,8 +761,9 @@ class Node(object):
value = param.convert(param.value)
string = param.string(value)
- except:
- print 'exception in %s:%s' % (self.name, param.name)
+ except Exception, e:
+ raise e.__class__, 'exception in %s:%s\n%s' % \
+ (self.name, param.name, e)
raise
if isConfigNode(param.ptype) and string != "Null":
simobjs.append(string)
@@ -835,7 +772,8 @@ class Node(object):
for so in simobjs:
label += "|<%s> %s" % (so, so)
- dot.add_edge(pydot.Edge("%s:%s" % (self.path, so), so, tailport="w"))
+ dot.add_edge(pydot.Edge("%s:%s" % (self.path, so), so,
+ tailport="w"))
label += '}'
dot.add_node(pydot.Node(self.path,shape="Mrecord",label=label))
@@ -875,7 +813,7 @@ class Value(object):
super(Value, self).__setattr__('obj', obj)
def _getattr(self):
- return self.obj._getvalue(self.attr)
+ return self.obj._values.get(self.attr)
def __setattr__(self, attr, value):
setattr(self._getattr(), attr, value)
@@ -895,6 +833,9 @@ class Value(object):
def __str__(self):
return str(self._getattr())
+ def __len__(self):
+ return len(self._getattr())
+
# Regular parameter.
class _Param(object):
def __init__(self, ptype, *args, **kwargs):
diff --git a/python/m5/convert.py b/python/m5/convert.py
index b3f34e4ab..2ebe93889 100644
--- a/python/m5/convert.py
+++ b/python/m5/convert.py
@@ -22,7 +22,7 @@ pebi = tebi * 1024
exbi = pebi * 1024
# memory size configuration stuff
-def to_integer(value):
+def toInteger(value):
if not isinstance(value, str):
result = int(value)
elif value.endswith('Ei'):
@@ -64,7 +64,7 @@ def to_integer(value):
return result
-def to_bool(val):
+def toBool(val):
t = type(val)
if t == bool:
return val
@@ -82,9 +82,9 @@ def to_bool(val):
elif val == "false" or val == "f" or val == "no" or val == "n":
return False
- return to_integer(val) != 0
+ return toInteger(val) != 0
-def to_frequency(value):
+def toFrequency(value):
if not isinstance(value, str):
result = float(value)
elif value.endswith('THz'):
@@ -102,7 +102,7 @@ def to_frequency(value):
return result
-def to_latency(value):
+def toLatency(value):
if not isinstance(value, str):
result = float(value)
elif value.endswith('c'):
@@ -122,7 +122,7 @@ def to_latency(value):
return result;
-def to_network_bandwidth(value):
+def toNetworkBandwidth(value):
if not isinstance(value, str):
result = float(value)
elif value.endswith('Tbps'):
@@ -140,7 +140,7 @@ def to_network_bandwidth(value):
return result
-def to_memory_bandwidth(value):
+def toMemoryBandwidth(value):
if not isinstance(value, str):
result = int(value)
elif value.endswith('PB/s'):
@@ -160,7 +160,7 @@ def to_memory_bandwidth(value):
return result
-def to_memory_size(value):
+def toMemorySize(value):
if not isinstance(value, str):
result = int(value)
elif value.endswith('PB'):
diff --git a/python/m5/multidict.py b/python/m5/multidict.py
new file mode 100644
index 000000000..d0c27fa8e
--- /dev/null
+++ b/python/m5/multidict.py
@@ -0,0 +1,158 @@
+__all__ = [ 'multidict' ]
+
+class multidict(object):
+ __nodefault = object()
+ def __init__(self, parent = {}, **kwargs):
+ self.dict = dict(**kwargs)
+ self.parent = parent
+ self.deleted = {}
+
+ def __str__(self):
+ return str(dict(self.items()))
+
+ def __repr__(self):
+ return `dict(self.items())`
+
+ def __contains__(self, key):
+ return self.dict.has_key(key) or self.parent.has_key(key)
+
+ def __delitem__(self, key):
+ try:
+ del self.dict[key]
+ except KeyError, e:
+ if key in self.parent:
+ self.deleted[key] = True
+ else:
+ raise KeyError, e
+
+ def __setitem__(self, key, value):
+ self.deleted.pop(key, False)
+ self.dict[key] = value
+
+ def __getitem__(self, key):
+ try:
+ return self.dict[key]
+ except KeyError, e:
+ if not self.deleted.get(key, False) and key in self.parent:
+ return self.parent[key]
+ else:
+ raise KeyError, e
+
+ def __len__(self):
+ return len(self.dict) + len(self.parent)
+
+ def next(self):
+ for key,value in self.dict.items():
+ yield key,value
+
+ if self.parent:
+ for key,value in self.parent.next():
+ if key not in self.dict and key not in self.deleted:
+ yield key,value
+
+ def has_key(self, key):
+ return key in self
+
+ def iteritems(self):
+ for item in self.next():
+ yield item
+
+ def items(self):
+ return [ item for item in self.next() ]
+
+ def iterkeys(self):
+ for key,value in self.next():
+ yield key
+
+ def keys(self):
+ return [ key for key,value in self.next() ]
+
+ def itervalues(self):
+ for key,value in self.next():
+ yield value
+
+ def values(self):
+ return [ value for key,value in self.next() ]
+
+ def get(self, key, default=__nodefault):
+ try:
+ return self[key]
+ except KeyError, e:
+ if default != self.__nodefault:
+ return default
+ else:
+ raise KeyError, e
+
+ def setdefault(self, key, default):
+ try:
+ return self[key]
+ except KeyError:
+ self.deleted.pop(key, False)
+ self.dict[key] = default
+ return default
+
+ def _dump(self):
+ print 'multidict dump'
+ node = self
+ while isinstance(node, multidict):
+ print ' ', node.dict
+ node = node.parent
+
+ def _dumpkey(self, key):
+ values = []
+ node = self
+ while isinstance(node, multidict):
+ if key in node.dict:
+ values.append(node.dict[key])
+ node = node.parent
+ print key, values
+
+if __name__ == '__main__':
+ test1 = multidict()
+ test2 = multidict(test1)
+ test3 = multidict(test2)
+ test4 = multidict(test3)
+
+ test1['a'] = 'test1_a'
+ test1['b'] = 'test1_b'
+ test1['c'] = 'test1_c'
+ test1['d'] = 'test1_d'
+ test1['e'] = 'test1_e'
+
+ test2['a'] = 'test2_a'
+ del test2['b']
+ test2['c'] = 'test2_c'
+ del test1['a']
+
+ test2.setdefault('f', multidict)
+
+ print 'test1>', test1.items()
+ print 'test2>', test2.items()
+ #print test1['a']
+ print test1['b']
+ print test1['c']
+ print test1['d']
+ print test1['e']
+
+ print test2['a']
+ #print test2['b']
+ print test2['c']
+ print test2['d']
+ print test2['e']
+
+ for key in test2.iterkeys():
+ print key
+
+ test2.get('g', 'foo')
+ #test2.get('b')
+ test2.get('b', 'bar')
+ test2.setdefault('b', 'blah')
+ print test1
+ print test2
+ print `test2`
+
+ print len(test2)
+
+ test3['a'] = [ 0, 1, 2, 3 ]
+
+ print test4
diff --git a/python/m5/smartdict.py b/python/m5/smartdict.py
index 1ba5d8410..0dbcc50b0 100644
--- a/python/m5/smartdict.py
+++ b/python/m5/smartdict.py
@@ -20,13 +20,13 @@ class SmartDict(dict):
class Proxy(str):
def __int__(self):
- return int(to_integer(str(self)))
+ return int(toInteger(str(self)))
def __long__(self):
- return long(to_integer(str(self)))
+ return long(toInteger(str(self)))
def __float__(self):
- return float(to_integer(str(self)))
+ return float(toInteger(str(self)))
def __nonzero__(self):
- return to_bool(str(self))
+ return toBool(str(self))
def convert(self, other):
t = type(other)
if t == bool:
diff --git a/sim/process.cc b/sim/process.cc
index 7111e8733..c18b31da7 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -89,6 +89,7 @@ Process::Process(const string &nm,
}
mmap_start = mmap_end = 0;
+ nxm_start = nxm_end = 0;
// other parameters will be initialized when the program is loaded
}
diff --git a/sim/process.hh b/sim/process.hh
index 1ab43cd62..51d7639ac 100644
--- a/sim/process.hh
+++ b/sim/process.hh
@@ -97,6 +97,10 @@ class Process : public SimObject
Addr mmap_start;
Addr mmap_end;
+ // Base of region for nxm data
+ Addr nxm_start;
+ Addr nxm_end;
+
std::string prog_fname; // file name
Addr prog_entry; // entry point (initial PC)
@@ -159,9 +163,10 @@ class Process : public SimObject
bool validDataAddr(Addr addr)
{
return ((data_base <= addr && addr < brk_point) ||
- ((stack_base - 16*1024*1024) <= addr && addr < stack_base) ||
+ (next_thread_stack_base <= addr && addr < stack_base) ||
(text_base <= addr && addr < (text_base + text_size)) ||
- (mmap_start <= addr && addr < mmap_end));
+ (mmap_start <= addr && addr < mmap_end) ||
+ (nxm_start <= addr && addr < nxm_end));
}
virtual void syscall(ExecContext *xc) = 0;
diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh
index 51a075a28..69c17c330 100644
--- a/sim/syscall_emul.hh
+++ b/sim/syscall_emul.hh
@@ -412,6 +412,10 @@ mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
// user didn't give an address... pick one from our "mmap region"
start = p->mmap_end;
p->mmap_end += RoundUp<Addr>(length, VMPageSize);
+ if (p->nxm_start != 0) {
+ //If we have an nxm space, make sure we haven't colided
+ assert(p->mmap_end < p->nxm_start);
+ }
}
if (!(flags & OS::TGT_MAP_ANONYMOUS)) {