summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript9
-rw-r--r--arch/alpha/alpha_tru64_process.cc2
-rw-r--r--build/SConstruct5
-rw-r--r--configs/splash2/run.mpy50
-rw-r--r--cpu/base_cpu.cc3
-rw-r--r--cpu/simple_cpu/simple_cpu.cc29
-rw-r--r--dev/pciconfigall.cc5
-rw-r--r--dev/pcidev.cc10
-rw-r--r--objects/AlphaConsole.mpy9
-rw-r--r--python/SConscript (renamed from sim/pyconfig/SConscript)39
-rw-r--r--python/m5/__init__.py37
-rw-r--r--python/m5/config.py (renamed from sim/pyconfig/m5config.py)412
-rw-r--r--python/m5/convert.py181
-rw-r--r--python/m5/objects/AlphaConsole.mpy9
-rw-r--r--python/m5/objects/AlphaTLB.mpy (renamed from objects/AlphaTLB.mpy)0
-rw-r--r--python/m5/objects/BadDevice.mpy (renamed from objects/BadDevice.mpy)0
-rw-r--r--python/m5/objects/BaseCPU.mpy (renamed from objects/BaseCPU.mpy)4
-rw-r--r--python/m5/objects/BaseCache.mpy (renamed from objects/BaseCache.mpy)0
-rw-r--r--python/m5/objects/BaseSystem.mpy (renamed from objects/BaseSystem.mpy)4
-rw-r--r--python/m5/objects/Bus.mpy (renamed from objects/Bus.mpy)0
-rw-r--r--python/m5/objects/CoherenceProtocol.mpy (renamed from objects/CoherenceProtocol.mpy)0
-rw-r--r--python/m5/objects/Device.mpy (renamed from objects/Device.mpy)4
-rw-r--r--python/m5/objects/DiskImage.mpy (renamed from objects/DiskImage.mpy)0
-rw-r--r--python/m5/objects/Ethernet.mpy (renamed from objects/Ethernet.mpy)6
-rw-r--r--python/m5/objects/Ide.mpy (renamed from objects/Ide.mpy)2
-rw-r--r--python/m5/objects/IntrControl.mpy (renamed from objects/IntrControl.mpy)2
-rw-r--r--python/m5/objects/MemTest.mpy (renamed from objects/MemTest.mpy)0
-rw-r--r--python/m5/objects/Pci.mpy (renamed from objects/Pci.mpy)9
-rw-r--r--python/m5/objects/PhysicalMemory.mpy (renamed from objects/PhysicalMemory.mpy)2
-rw-r--r--python/m5/objects/Platform.mpy (renamed from objects/Platform.mpy)2
-rw-r--r--python/m5/objects/Process.mpy (renamed from objects/Process.mpy)0
-rw-r--r--python/m5/objects/Repl.mpy (renamed from objects/Repl.mpy)0
-rw-r--r--python/m5/objects/Root.mpy (renamed from objects/Root.mpy)0
-rw-r--r--python/m5/objects/SimConsole.mpy (renamed from objects/SimConsole.mpy)2
-rw-r--r--python/m5/objects/SimpleDisk.mpy (renamed from objects/SimpleDisk.mpy)2
-rw-r--r--python/m5/objects/Tsunami.mpy (renamed from objects/Tsunami.mpy)8
-rw-r--r--python/m5/objects/Uart.mpy (renamed from objects/Uart.mpy)2
-rw-r--r--python/m5/smartdict.py108
-rw-r--r--sim/main.cc2
-rw-r--r--sim/sim_object.cc19
-rw-r--r--sim/sim_object.hh13
-rwxr-xr-xtest/genini.py16
-rw-r--r--util/stats/display.py2
-rw-r--r--util/stats/info.py36
-rw-r--r--util/stats/print.py2
45 files changed, 761 insertions, 286 deletions
diff --git a/SConscript b/SConscript
index 19f84f913..3b3c871bc 100644
--- a/SConscript
+++ b/SConscript
@@ -183,6 +183,9 @@ base_sources = Split('''
mem/trace/mem_trace_writer.cc
mem/trace/m5_writer.cc
+ python/pyconfig.cc
+ python/embedded_py.cc
+
sim/builder.cc
sim/configfile.cc
sim/debug.cc
@@ -199,8 +202,6 @@ base_sources = Split('''
sim/stat_control.cc
sim/trace_context.cc
sim/universe.cc
- sim/pyconfig/pyconfig.cc
- sim/pyconfig/embedded_py.cc
''')
# MySql sources
@@ -376,8 +377,8 @@ env.Command(Split('''arch/alpha/decoder.cc
# SConscript-local is the per-config build, which just copies some
# header files into a place where they can be found.
SConscript('libelf/SConscript-local', exports = 'env', duplicate=0)
-SConscript('sim/pyconfig/SConscript', 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 8660cc5c5..a211e0ae8 100644
--- a/arch/alpha/alpha_tru64_process.cc
+++ b/arch/alpha/alpha_tru64_process.cc
@@ -957,7 +957,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/configs/splash2/run.mpy b/configs/splash2/run.mpy
new file mode 100644
index 000000000..a19dcdc93
--- /dev/null
+++ b/configs/splash2/run.mpy
@@ -0,0 +1,50 @@
+import Splash2
+
+if 'SYSTEM' not in env:
+ panic("The SYSTEM environment variable must be set!\ne.g -ESYSTEM=Detailed\n")
+
+if env['SYSTEM'] == 'Simple':
+ from SimpleConfig import *
+ BaseCPU.workload = Super.workload
+ SimpleStandAlone.cpu = [ CPU() for i in xrange(int(env['NP'])) ]
+ root = SimpleStandAlone
+elif env['SYSTEM'] == 'Detailed':
+ from DetailedConfig import *
+ BaseCPU.workload = Super.workload
+ DetailedStandAlone.cpu = [ DetailedCPU() for i in xrange(int(env['NP'])) ]
+ root = DetailedStandAlone
+else:
+ panic("The SYSTEM environment variable was set to something improper.\n Use Simple or Detailed\n")
+
+if 'BENCHMARK' not in env:
+ panic("The BENCHMARK environment variable must be set!\ne.g. -EBENCHMARK=Cholesky\n")
+
+if env['BENCHMARK'] == 'Cholesky':
+ root.workload = Splash2.Cholesky()
+elif env['BENCHMARK'] == 'FFT':
+ root.workload = Splash2.FFT()
+elif env['BENCHMARK'] == 'LUContig':
+ root.workload = Splash2.LU_contig()
+elif env['BENCHMARK'] == 'LUNoncontig':
+ root.workload = Splash2.LU_noncontig()
+elif env['BENCHMARK'] == 'Radix':
+ root.workload = Splash2.Radix()
+elif env['BENCHMARK'] == 'Barnes':
+ root.workload = Splash2.Barnes()
+elif env['BENCHMARK'] == 'FMM':
+ root.workload = Splash2.FMM()
+elif env['BENCHMARK'] == 'OceanContig':
+ root.workload = Splash2.Ocean_contig()
+elif env['BENCHMARK'] == 'OceanNoncontig':
+ root.workload = Splash2.Ocean_noncontig()
+elif env['BENCHMARK'] == 'Raytrace':
+ root.workload = Splash2.Raytrace()
+elif env['BENCHMARK'] == 'WaterNSquared':
+ root.workload = Splash2.Water_nsquared()
+elif env['BENCHMARK'] == 'WaterSpatial':
+ root.workload = Splash2.Water_spatial()
+else:
+ panic("The BENCHMARK environment variable was set to something" \
+ +" improper.\nUse Cholesky, FFT, LUContig, LUNoncontig, Radix" \
+ +", Barnes, FMM, OceanContig,\nOceanNoncontig, Raytrace," \
+ +" WaterNSquared, or WaterSpatial\n")
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/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index 86aeab7d7..6a95a52c2 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -393,13 +393,11 @@ template <class T>
Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags)
{
- if (status() == DcacheMissStall) {
+ if (status() == DcacheMissStall || status() == DcacheMissSwitch) {
Fault fault = xc->read(memReq,data);
if (traceData) {
traceData->setAddr(addr);
- if (fault == No_Fault)
- traceData->setData(data);
}
return fault;
}
@@ -428,21 +426,11 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
// do functional access
fault = xc->read(memReq, data);
- if (traceData) {
- traceData->setAddr(addr);
- if (fault == No_Fault)
- traceData->setData(data);
- }
}
} else if(fault == No_Fault) {
// do functional access
fault = xc->read(memReq, data);
- if (traceData) {
- traceData->setAddr(addr);
- if (fault == No_Fault)
- traceData->setData(data);
- }
}
if (!dcacheInterface && (memReq->flags & UNCACHEABLE))
@@ -498,11 +486,6 @@ template <class T>
Fault
SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
- if (traceData) {
- traceData->setAddr(addr);
- traceData->setData(data);
- }
-
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
@@ -605,6 +588,8 @@ SimpleCPU::processCacheCompletion()
case DcacheMissStall:
if (memReq->cmd.isRead()) {
curStaticInst->execute(this,traceData);
+ if (traceData)
+ traceData->finalize();
}
dcacheStallCycles += curTick - lastDcacheStall;
_status = Running;
@@ -613,6 +598,8 @@ SimpleCPU::processCacheCompletion()
case DcacheMissSwitch:
if (memReq->cmd.isRead()) {
curStaticInst->execute(this,traceData);
+ if (traceData)
+ traceData->finalize();
}
_status = SwitchedOut;
sampler->signalSwitched();
@@ -785,8 +772,12 @@ SimpleCPU::tick()
comLoadEventQueue[0]->serviceEvents(numLoad);
}
- if (traceData)
+ // If we have a dcache miss, then we can't finialize the instruction
+ // trace yet because we want to populate it with the data later
+ if (traceData &&
+ !(status() == DcacheMissStall && memReq->cmd.isRead())) {
traceData->finalize();
+ }
traceFunctions(xc->regs.pc);
diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc
index 1a9804f79..2cbd5adc0 100644
--- a/dev/pciconfigall.cc
+++ b/dev/pciconfigall.cc
@@ -98,11 +98,12 @@ PciConfigAll::startup()
Fault
PciConfigAll::read(MemReqPtr &req, uint8_t *data)
{
- DPRINTF(PciConfigAll, "read va=%#x size=%d\n",
- req->vaddr, req->size);
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
+ DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n",
+ req->vaddr, daddr, req->size);
+
int device = (daddr >> 11) & 0x1F;
int func = (daddr >> 8) & 0x7;
int reg = daddr & 0xFF;
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 &section)
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/objects/AlphaConsole.mpy b/objects/AlphaConsole.mpy
deleted file mode 100644
index 79918a01e..000000000
--- a/objects/AlphaConsole.mpy
+++ /dev/null
@@ -1,9 +0,0 @@
-from Device import PioDevice
-
-simobj AlphaConsole(PioDevice):
- type = 'AlphaConsole'
- cpu = Param.BaseCPU(Super, "Processor")
- disk = Param.SimpleDisk("Simple Disk")
- num_cpus = Param.Int(1, "Number of CPUs")
- sim_console = Param.SimConsole(Super, "The Simulator Console")
- system = Param.BaseSystem(Super, "system object")
diff --git a/sim/pyconfig/SConscript b/python/SConscript
index 2799ef64f..9c15c6d50 100644
--- a/sim/pyconfig/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 = ['m5config.py', 'importer.py', '../../util/pbs/jobfile.py']
-objpath = os.path.join(env['SRCDIR'], 'objects')
+# 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
new file mode 100644
index 000000000..16f48dba3
--- /dev/null
+++ b/python/m5/__init__.py
@@ -0,0 +1,37 @@
+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 = config.MetaSimObject.cpp_classes
+cpp_classes.sort()
+
diff --git a/sim/pyconfig/m5config.py b/python/m5/config.py
index e6201b3ad..e6ad5a0ba 100644
--- a/sim/pyconfig/m5config.py
+++ b/python/m5/config.py
@@ -27,7 +27,7 @@
from __future__ import generators
import os, re, sys, types, inspect
-from importer import AddToPath, LoadMpyFile
+from convert import *
noDot = False
try:
@@ -35,16 +35,6 @@ try:
except:
noDot = True
-env = {}
-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'):
@@ -149,25 +139,90 @@ class Singleton(type):
#####################################################################
class Proxy(object):
- def __init__(self, path = ()):
+ def __init__(self, path):
self._object = None
- self._path = path
+ if path == 'any':
+ self._path = None
+ else:
+ # path is a list of (attr,index) tuples
+ self._path = [(path,None)]
+ self._index = None
+ self._multiplier = None
def __getattr__(self, attr):
- return Proxy(self._path + (attr, ))
+ if attr == '__bases__':
+ return super(Proxy, self).__getattr__(self, attr)
+ self._path.append((attr,None))
+ return self
def __setattr__(self, attr, value):
if not attr.startswith('_'):
raise AttributeError, 'cannot set attribute %s' % attr
super(Proxy, self).__setattr__(attr, value)
- def _convert(self):
- obj = self._object
- for attr in self._path:
- obj = obj.__getattribute__(attr)
+ # support indexing on proxies (e.g., parent.cpu[0])
+ def __getitem__(self, key):
+ if not isinstance(key, int):
+ raise TypeError, "Proxy object requires integer index"
+ if self._path == None:
+ raise IndexError, "Index applied to 'any' proxy"
+ # replace index portion of last path element with new index
+ self._path[-1] = (self._path[-1][0], key)
+ return self
+
+ # support multiplying proxies by constants
+ def __mul__(self, other):
+ if not isinstance(other, int):
+ raise TypeError, "Proxy multiplier must be integer"
+ if self._multiplier == None:
+ self._multiplier = other
+ else:
+ # support chained multipliers
+ self._multiplier *= other
+ return self
+
+ def _mulcheck(self, result):
+ if self._multiplier == None:
+ return result
+ if not isinstance(result, int):
+ raise TypeError, "Proxy with multiplier resolves to " \
+ "non-integer value"
+ return result * self._multiplier
+
+ def unproxy(self, base, ptype):
+ obj = base
+ done = False
+ while not done:
+ if obj is None:
+ 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
+ obj = obj.parent
+
+ return self._mulcheck(found)
+
+ def getindex(obj, index):
+ if index == None:
+ return obj
+ try:
+ obj = obj[index]
+ except TypeError:
+ if index != 0:
+ raise
+ # if index is 0 and item is not subscriptable, just
+ # use item itself (so cpu[0] works on uniprocessors)
return obj
+ getindex = staticmethod(getindex)
-Super = Proxy()
+class ProxyFactory(object):
+ def __getattr__(self, attr):
+ return Proxy(attr)
+
+# global object for handling parent.foo proxies
+parent = ProxyFactory()
def isSubClass(value, cls):
try:
@@ -188,7 +243,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:
@@ -208,6 +263,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
@@ -245,7 +322,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
@@ -268,19 +345,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.
@@ -417,7 +501,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)
@@ -429,7 +517,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)
@@ -449,7 +537,7 @@ class MetaConfigNode(type):
# Print instance info to .ini file.
def instantiate(cls, name, parent = None):
- instance = Node(name, cls, cls.type, parent, isParamContext(cls))
+ instance = Node(name, cls, parent, isParamContext(cls))
if hasattr(cls, 'check'):
cls.check()
@@ -457,10 +545,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:
@@ -471,7 +559,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):
@@ -560,7 +648,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()
@@ -584,10 +672,13 @@ class NodeParam(object):
class Node(object):
all = {}
- def __init__(self, name, realtype, type, parent, paramcontext):
+ def __init__(self, name, realtype, parent, paramcontext):
self.name = name
self.realtype = realtype
- self.type = type
+ if isSimObject(realtype):
+ self.type = realtype.type
+ else:
+ self.type = None
self.parent = parent
self.children = []
self.child_names = {}
@@ -617,50 +708,40 @@ class Node(object):
if issubclass(child.realtype, realtype):
if obj is not None:
raise AttributeError, \
- 'Super matched more than one: %s %s' % \
+ 'parent.any matched more than one: %s %s' % \
(obj.path, child.path)
obj = child
return obj, obj is not None
try:
obj = self
- for node in path[:-1]:
- obj = obj.child_names[node]
+ for (node,index) in path[:-1]:
+ if obj.child_names.has_key(node):
+ obj = obj.child_names[node]
+ else:
+ obj = obj.top_child_names[node]
+ obj = Proxy.getindex(obj, index)
- last = path[-1]
+ (last,index) = path[-1]
if obj.child_names.has_key(last):
value = obj.child_names[last]
- if issubclass(value.realtype, realtype):
- return value, True
+ return Proxy.getindex(value, index), True
+ elif obj.top_child_names.has_key(last):
+ value = obj.top_child_names[last]
+ return Proxy.getindex(value, index), True
elif obj.param_names.has_key(last):
value = obj.param_names[last]
realtype._convert(value.value)
- return value.value, True
+ return Proxy.getindex(value.value, index), True
except KeyError:
pass
return None, False
- def unproxy(self, ptype, value):
- if not isinstance(value, Proxy):
- return value
-
- if value is None:
- raise AttributeError, 'Error while fixing up %s' % self.path
-
- obj = self
- done = False
- while not done:
- if obj is None:
- raise AttributeError, \
- 'Parent of %s type %s not found at path %s' \
- % (self.name, ptype, value._path)
- found, done = obj.find(ptype, value._path)
- if isinstance(found, Proxy):
- done = False
- obj = obj.parent
-
- return found
+ def unproxy(self, param, ptype):
+ if not isinstance(param, Proxy):
+ return param
+ return param.unproxy(self, ptype)
def fixup(self):
self.all[self.path] = self
@@ -670,10 +751,10 @@ class Node(object):
pval = param.value
try:
- if issequence(pval):
- param.value = [ self.unproxy(ptype, pv) for pv in pval ]
+ if isinstance(pval, (list, tuple)):
+ param.value = [ self.unproxy(pv, ptype) for pv in pval ]
else:
- param.value = self.unproxy(ptype, pval)
+ param.value = self.unproxy(pval, ptype)
except:
print 'Error while fixing up %s:%s' % (self.path, param.name)
raise
@@ -849,13 +930,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)
@@ -882,19 +974,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, ''
@@ -921,7 +1004,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)
@@ -934,7 +1017,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:
@@ -942,7 +1025,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)
@@ -970,99 +1053,109 @@ 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):
- t = type(value)
- if t == bool:
+ if isinstance(value, bool):
return int(value)
- if t != int and t != long and t != float and t != str:
- raise TypeError, 'Integer parameter of invalid type %s' % t
+ if not isinstance(value, (int, long, float, str)):
+ raise TypeError, 'Integer param of invalid type %s' % type(value)
- if t == str or t == float:
- value = long(value)
+ if isinstance(value, (str, float)):
+ value = long(float(value))
- if not cls._min <= value <= cls._max:
- raise TypeError, 'Integer parameter out of bounds %d < %d < %d' % \
- (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)
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)
@@ -1090,7 +1183,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.
@@ -1130,7 +1223,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):
@@ -1237,7 +1330,7 @@ class MetaEnum(type):
return s
# Base class for enum types.
-class Enum(object):
+class Enum(ParamType):
__metaclass__ = MetaEnum
vals = []
@@ -1257,8 +1350,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
@@ -1270,9 +1363,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()
@@ -1293,11 +1383,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 *
-cpp_classes = MetaSimObject.cpp_classes
-cpp_classes.sort()
+# __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',
+ 'parent', '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/convert.py b/python/m5/convert.py
new file mode 100644
index 000000000..b3f34e4ab
--- /dev/null
+++ b/python/m5/convert.py
@@ -0,0 +1,181 @@
+# metric prefixes
+exa = 1.0e18
+peta = 1.0e15
+tera = 1.0e12
+giga = 1.0e9
+mega = 1.0e6
+kilo = 1.0e3
+
+milli = 1.0e-3
+micro = 1.0e-6
+nano = 1.0e-9
+pico = 1.0e-12
+femto = 1.0e-15
+atto = 1.0e-18
+
+# power of 2 prefixes
+kibi = 1024
+mebi = kibi * 1024
+gibi = mebi * 1024
+tebi = gibi * 1024
+pebi = tebi * 1024
+exbi = pebi * 1024
+
+# memory size configuration stuff
+def to_integer(value):
+ if not isinstance(value, str):
+ result = int(value)
+ elif value.endswith('Ei'):
+ result = int(value[:-2]) * exbi
+ elif value.endswith('Pi'):
+ result = int(value[:-2]) * pebi
+ elif value.endswith('Ti'):
+ result = int(value[:-2]) * tebi
+ elif value.endswith('Gi'):
+ result = int(value[:-2]) * gibi
+ elif value.endswith('Mi'):
+ result = int(value[:-2]) * mebi
+ elif value.endswith('ki'):
+ result = int(value[:-2]) * kibi
+ elif value.endswith('E'):
+ result = int(value[:-1]) * exa
+ elif value.endswith('P'):
+ result = int(value[:-1]) * peta
+ elif value.endswith('T'):
+ result = int(value[:-1]) * tera
+ elif value.endswith('G'):
+ result = int(value[:-1]) * giga
+ elif value.endswith('M'):
+ result = int(value[:-1]) * mega
+ elif value.endswith('k'):
+ result = int(value[:-1]) * kilo
+ elif value.endswith('m'):
+ result = int(value[:-1]) * milli
+ elif value.endswith('u'):
+ result = int(value[:-1]) * micro
+ elif value.endswith('n'):
+ result = int(value[:-1]) * nano
+ elif value.endswith('p'):
+ result = int(value[:-1]) * pico
+ elif value.endswith('f'):
+ result = int(value[:-1]) * femto
+ else:
+ result = int(value)
+
+ return result
+
+def to_bool(val):
+ t = type(val)
+ if t == bool:
+ return val
+
+ if t == None:
+ return False
+
+ if t == int or t == long:
+ return bool(val)
+
+ if t == str:
+ val = val.lower()
+ if val == "true" or val == "t" or val == "yes" or val == "y":
+ return True
+ elif val == "false" or val == "f" or val == "no" or val == "n":
+ return False
+
+ return to_integer(val) != 0
+
+def to_frequency(value):
+ if not isinstance(value, str):
+ result = float(value)
+ elif value.endswith('THz'):
+ result = float(value[:-3]) * tera
+ elif value.endswith('GHz'):
+ result = float(value[:-3]) * giga
+ elif value.endswith('MHz'):
+ result = float(value[:-3]) * mega
+ elif value.endswith('kHz'):
+ result = float(value[:-3]) * kilo
+ elif value.endswith('Hz'):
+ result = float(value[:-2])
+ else:
+ result = float(value)
+
+ return result
+
+def to_latency(value):
+ if not isinstance(value, str):
+ result = float(value)
+ elif value.endswith('c'):
+ result = float(value[:-1])
+ elif value.endswith('ps'):
+ result = float(value[:-2]) * pico
+ elif value.endswith('ns'):
+ result = float(value[:-2]) * nano
+ elif value.endswith('us'):
+ result = float(value[:-2]) * micro
+ elif value.endswith('ms'):
+ result = float(value[:-2]) * milli
+ elif value.endswith('s'):
+ result = float(value[:-1])
+ else:
+ result = float(value)
+
+ return result;
+
+def to_network_bandwidth(value):
+ if not isinstance(value, str):
+ result = float(value)
+ elif value.endswith('Tbps'):
+ result = float(value[:-3]) * tera
+ elif value.endswith('Gbps'):
+ result = float(value[:-3]) * giga
+ elif value.endswith('Mbps'):
+ result = float(value[:-3]) * mega
+ elif value.endswith('kbps'):
+ result = float(value[:-3]) * kilo
+ elif value.endswith('bps'):
+ result = float(value[:-2])
+ else:
+ result = float(value)
+
+ return result
+
+def to_memory_bandwidth(value):
+ if not isinstance(value, str):
+ result = int(value)
+ elif value.endswith('PB/s'):
+ result = int(value[:-4]) * pebi
+ elif value.endswith('TB/s'):
+ result = int(value[:-4]) * tebi
+ elif value.endswith('GB/s'):
+ result = int(value[:-4]) * gibi
+ elif value.endswith('MB/s'):
+ result = int(value[:-4]) * mebi
+ elif value.endswith('kB/s'):
+ result = int(value[:-4]) * kibi
+ elif value.endswith('B/s'):
+ result = int(value[:-3])
+ else:
+ result = int(value)
+
+ return result
+
+def to_memory_size(value):
+ if not isinstance(value, str):
+ result = int(value)
+ elif value.endswith('PB'):
+ result = int(value[:-2]) * pebi
+ elif value.endswith('TB'):
+ result = int(value[:-2]) * tebi
+ elif value.endswith('GB'):
+ result = int(value[:-2]) * gibi
+ elif value.endswith('MB'):
+ result = int(value[:-2]) * mebi
+ elif value.endswith('kB'):
+ result = int(value[:-2]) * kibi
+ elif value.endswith('B'):
+ result = int(value[:-1])
+ else:
+ result = int(value)
+
+ return result
diff --git a/python/m5/objects/AlphaConsole.mpy b/python/m5/objects/AlphaConsole.mpy
new file mode 100644
index 000000000..63aea5b7d
--- /dev/null
+++ b/python/m5/objects/AlphaConsole.mpy
@@ -0,0 +1,9 @@
+from Device import PioDevice
+
+simobj AlphaConsole(PioDevice):
+ type = 'AlphaConsole'
+ cpu = Param.BaseCPU(parent.any, "Processor")
+ disk = Param.SimpleDisk("Simple Disk")
+ num_cpus = Param.Int(1, "Number of CPUs")
+ sim_console = Param.SimConsole(parent.any, "The Simulator Console")
+ system = Param.BaseSystem(parent.any, "system object")
diff --git a/objects/AlphaTLB.mpy b/python/m5/objects/AlphaTLB.mpy
index 8e7cd62cc..8e7cd62cc 100644
--- a/objects/AlphaTLB.mpy
+++ b/python/m5/objects/AlphaTLB.mpy
diff --git a/objects/BadDevice.mpy b/python/m5/objects/BadDevice.mpy
index 35a12e0bf..35a12e0bf 100644
--- a/objects/BadDevice.mpy
+++ b/python/m5/objects/BadDevice.mpy
diff --git a/objects/BaseCPU.mpy b/python/m5/objects/BaseCPU.mpy
index 484fcccd6..d84e30e53 100644
--- a/objects/BaseCPU.mpy
+++ b/python/m5/objects/BaseCPU.mpy
@@ -4,11 +4,11 @@ simobj BaseCPU(SimObject):
icache = Param.BaseMem(NULL, "L1 instruction cache object")
dcache = Param.BaseMem(NULL, "L1 data cache object")
- if Bool._convert(env.get('FULL_SYSTEM', 'False')):
+ if build_env['FULL_SYSTEM']:
dtb = Param.AlphaDTB("Data TLB")
itb = Param.AlphaITB("Instruction TLB")
mem = Param.FunctionalMemory("memory")
- system = Param.BaseSystem(Super, "system object")
+ system = Param.BaseSystem(parent.any, "system object")
else:
workload = VectorParam.Process("processes to run")
diff --git a/objects/BaseCache.mpy b/python/m5/objects/BaseCache.mpy
index 98a422e30..98a422e30 100644
--- a/objects/BaseCache.mpy
+++ b/python/m5/objects/BaseCache.mpy
diff --git a/objects/BaseSystem.mpy b/python/m5/objects/BaseSystem.mpy
index 1cbdf4e99..450b6a58e 100644
--- a/objects/BaseSystem.mpy
+++ b/python/m5/objects/BaseSystem.mpy
@@ -1,8 +1,8 @@
simobj BaseSystem(SimObject):
type = 'BaseSystem'
abstract = True
- memctrl = Param.MemoryController(Super, "memory controller")
- physmem = Param.PhysicalMemory(Super, "phsyical memory")
+ memctrl = Param.MemoryController(parent.any, "memory controller")
+ physmem = Param.PhysicalMemory(parent.any, "phsyical memory")
kernel = Param.String("file that contains the kernel code")
console = Param.String("file that contains the console code")
pal = Param.String("file that contains palcode")
diff --git a/objects/Bus.mpy b/python/m5/objects/Bus.mpy
index 025d69785..025d69785 100644
--- a/objects/Bus.mpy
+++ b/python/m5/objects/Bus.mpy
diff --git a/objects/CoherenceProtocol.mpy b/python/m5/objects/CoherenceProtocol.mpy
index f3b0026b7..f3b0026b7 100644
--- a/objects/CoherenceProtocol.mpy
+++ b/python/m5/objects/CoherenceProtocol.mpy
diff --git a/objects/Device.mpy b/python/m5/objects/Device.mpy
index 47f8db1cb..a0d02a647 100644
--- a/objects/Device.mpy
+++ b/python/m5/objects/Device.mpy
@@ -14,7 +14,7 @@ simobj FooPioDevice(FunctionalMemory):
type = 'PioDevice'
abstract = True
addr = Param.Addr("Device Address")
- mmu = Param.MemoryController(Super, "Memory Controller")
+ mmu = Param.MemoryController(parent.any, "Memory Controller")
io_bus = Param.Bus(NULL, "The IO Bus to attach to")
pio_latency = Param.Tick(1, "Programmed IO latency in bus cycles")
@@ -25,7 +25,7 @@ simobj FooDmaDevice(FooPioDevice):
simobj PioDevice(FooPioDevice):
type = 'PioDevice'
abstract = True
- platform = Param.Platform(Super, "Platform")
+ platform = Param.Platform(parent.any, "Platform")
simobj DmaDevice(PioDevice):
type = 'DmaDevice'
diff --git a/objects/DiskImage.mpy b/python/m5/objects/DiskImage.mpy
index 80ef7b072..80ef7b072 100644
--- a/objects/DiskImage.mpy
+++ b/python/m5/objects/DiskImage.mpy
diff --git a/objects/Ethernet.mpy b/python/m5/objects/Ethernet.mpy
index 088df4b93..cd251f36d 100644
--- a/objects/Ethernet.mpy
+++ b/python/m5/objects/Ethernet.mpy
@@ -49,8 +49,8 @@ simobj EtherDev(DmaDevice):
intr_delay = Param.Tick(0, "Interrupt Delay in microseconds")
payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
- physmem = Param.PhysicalMemory(Super, "Physical Memory")
- tlaser = Param.Turbolaser(Super, "Turbolaser")
+ physmem = Param.PhysicalMemory(parent.any, "Physical Memory")
+ tlaser = Param.Turbolaser(parent.any, "Turbolaser")
simobj NSGigE(PciDevice):
type = 'NSGigE'
@@ -73,7 +73,7 @@ simobj NSGigE(PciDevice):
intr_delay = Param.Tick(0, "Interrupt Delay in microseconds")
payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
- physmem = Param.PhysicalMemory(Super, "Physical Memory")
+ physmem = Param.PhysicalMemory(parent.any, "Physical Memory")
simobj EtherDevInt(EtherInt):
type = 'EtherDevInt'
diff --git a/objects/Ide.mpy b/python/m5/objects/Ide.mpy
index ce760ad96..786109efa 100644
--- a/objects/Ide.mpy
+++ b/python/m5/objects/Ide.mpy
@@ -7,7 +7,7 @@ simobj IdeDisk(SimObject):
delay = Param.Tick(1, "Fixed disk delay in microseconds")
driveID = Param.IdeID('master', "Drive ID")
image = Param.DiskImage("Disk image")
- physmem = Param.PhysicalMemory(Super, "Physical memory")
+ physmem = Param.PhysicalMemory(parent.any, "Physical memory")
simobj IdeController(PciDevice):
type = 'IdeController'
diff --git a/objects/IntrControl.mpy b/python/m5/objects/IntrControl.mpy
index 1ef5a17ee..144be0fd4 100644
--- a/objects/IntrControl.mpy
+++ b/python/m5/objects/IntrControl.mpy
@@ -1,3 +1,3 @@
simobj IntrControl(SimObject):
type = 'IntrControl'
- cpu = Param.BaseCPU(Super, "the cpu")
+ cpu = Param.BaseCPU(parent.any, "the cpu")
diff --git a/objects/MemTest.mpy b/python/m5/objects/MemTest.mpy
index af14ed9c3..af14ed9c3 100644
--- a/objects/MemTest.mpy
+++ b/python/m5/objects/MemTest.mpy
diff --git a/objects/Pci.mpy b/python/m5/objects/Pci.mpy
index caa3c52ff..b9b3e5a95 100644
--- a/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
+ configdata = Param.PciConfigData(parent.any, "PCI Config data")
+ configspace = Param.PciConfigAll(parent.any, "PCI Configspace")
diff --git a/objects/PhysicalMemory.mpy b/python/m5/objects/PhysicalMemory.mpy
index d1e4ad4b4..e6df2a161 100644
--- a/objects/PhysicalMemory.mpy
+++ b/python/m5/objects/PhysicalMemory.mpy
@@ -4,4 +4,4 @@ simobj PhysicalMemory(FunctionalMemory):
type = 'PhysicalMemory'
range = Param.AddrRange("Device Address")
file = Param.String('', "memory mapped file")
- mmu = Param.MemoryController(Super, "Memory Controller")
+ mmu = Param.MemoryController(parent.any, "Memory Controller")
diff --git a/objects/Platform.mpy b/python/m5/objects/Platform.mpy
index d0510eaf8..a71ab3b77 100644
--- a/objects/Platform.mpy
+++ b/python/m5/objects/Platform.mpy
@@ -2,4 +2,4 @@ simobj Platform(SimObject):
type = 'Platform'
abstract = True
interrupt_frequency = Param.Tick(1200, "frequency of interrupts")
- intrctrl = Param.IntrControl(Super, "interrupt controller")
+ intrctrl = Param.IntrControl(parent.any, "interrupt controller")
diff --git a/objects/Process.mpy b/python/m5/objects/Process.mpy
index 6a91c09c2..6a91c09c2 100644
--- a/objects/Process.mpy
+++ b/python/m5/objects/Process.mpy
diff --git a/objects/Repl.mpy b/python/m5/objects/Repl.mpy
index fff5a2a02..fff5a2a02 100644
--- a/objects/Repl.mpy
+++ b/python/m5/objects/Repl.mpy
diff --git a/objects/Root.mpy b/python/m5/objects/Root.mpy
index 0e531054b..0e531054b 100644
--- a/objects/Root.mpy
+++ b/python/m5/objects/Root.mpy
diff --git a/objects/SimConsole.mpy b/python/m5/objects/SimConsole.mpy
index fb74f1775..3588a949d 100644
--- a/objects/SimConsole.mpy
+++ b/python/m5/objects/SimConsole.mpy
@@ -5,7 +5,7 @@ simobj ConsoleListener(SimObject):
simobj SimConsole(SimObject):
type = 'SimConsole'
append_name = Param.Bool(True, "append name() to filename")
- intr_control = Param.IntrControl(Super, "interrupt controller")
+ intr_control = Param.IntrControl(parent.any, "interrupt controller")
listener = Param.ConsoleListener("console listener")
number = Param.Int(0, "console number")
output = Param.String('console', "file to dump output to")
diff --git a/objects/SimpleDisk.mpy b/python/m5/objects/SimpleDisk.mpy
index c4dd5435b..b616fb3d1 100644
--- a/objects/SimpleDisk.mpy
+++ b/python/m5/objects/SimpleDisk.mpy
@@ -1,4 +1,4 @@
simobj SimpleDisk(SimObject):
type = 'SimpleDisk'
disk = Param.DiskImage("Disk Image")
- physmem = Param.PhysicalMemory(Super, "Physical Memory")
+ physmem = Param.PhysicalMemory(parent.any, "Physical Memory")
diff --git a/objects/Tsunami.mpy b/python/m5/objects/Tsunami.mpy
index cfe23977e..a8471cee2 100644
--- a/objects/Tsunami.mpy
+++ b/python/m5/objects/Tsunami.mpy
@@ -4,12 +4,12 @@ from Platform import Platform
simobj Tsunami(Platform):
type = 'Tsunami'
pciconfig = Param.PciConfigAll("PCI configuration")
- system = Param.BaseSystem(Super, "system")
+ system = Param.BaseSystem(parent.any, "system")
interrupt_frequency = Param.Int(1024, "frequency of interrupts")
simobj TsunamiCChip(FooPioDevice):
type = 'TsunamiCChip'
- tsunami = Param.Tsunami(Super, "Tsunami")
+ tsunami = Param.Tsunami(parent.any, "Tsunami")
simobj TsunamiFake(FooPioDevice):
type = 'TsunamiFake'
@@ -18,8 +18,8 @@ simobj TsunamiIO(FooPioDevice):
type = 'TsunamiIO'
time = Param.UInt64(1136073600,
"System time to use (0 for actual time, default is 1/1/06)")
- tsunami = Param.Tsunami(Super, "Tsunami")
+ tsunami = Param.Tsunami(parent.any, "Tsunami")
simobj TsunamiPChip(FooPioDevice):
type = 'TsunamiPChip'
- tsunami = Param.Tsunami(Super, "Tsunami")
+ tsunami = Param.Tsunami(parent.any, "Tsunami")
diff --git a/objects/Uart.mpy b/python/m5/objects/Uart.mpy
index 76ee8805f..5a6c25f8e 100644
--- a/objects/Uart.mpy
+++ b/python/m5/objects/Uart.mpy
@@ -2,5 +2,5 @@ from Device import PioDevice
simobj Uart(PioDevice):
type = 'Uart'
- console = Param.SimConsole(Super, "The console")
+ console = Param.SimConsole(parent.any, "The console")
size = Param.Addr(0x8, "Device size")
diff --git a/python/m5/smartdict.py b/python/m5/smartdict.py
new file mode 100644
index 000000000..1ba5d8410
--- /dev/null
+++ b/python/m5/smartdict.py
@@ -0,0 +1,108 @@
+# 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)))
+ def __long__(self):
+ return long(to_integer(str(self)))
+ def __float__(self):
+ return float(to_integer(str(self)))
+ def __nonzero__(self):
+ return to_bool(str(self))
+ def convert(self, other):
+ t = type(other)
+ if t == bool:
+ return bool(self)
+ if t == int:
+ return int(self)
+ if t == long:
+ return long(self)
+ if t == float:
+ return float(self)
+ return str(self)
+ def __lt__(self, other):
+ return self.convert(other) < other
+ def __le__(self, other):
+ return self.convert(other) <= other
+ def __eq__(self, other):
+ return self.convert(other) == other
+ def __ne__(self, other):
+ return self.convert(other) != other
+ def __gt__(self, other):
+ return self.convert(other) > other
+ def __ge__(self, other):
+ return self.convert(other) >= other
+
+ def __add__(self, other):
+ return self.convert(other) + other
+ def __sub__(self, other):
+ return self.convert(other) - other
+ def __mul__(self, other):
+ return self.convert(other) * other
+ def __div__(self, other):
+ return self.convert(other) / other
+ def __truediv__(self, other):
+ return self.convert(other) / other
+
+ def __radd__(self, other):
+ return other + self.convert(other)
+ def __rsub__(self, other):
+ return other - self.convert(other)
+ def __rmul__(self, other):
+ return other * self.convert(other)
+ def __rdiv__(self, other):
+ return other / self.convert(other)
+ def __rtruediv__(self, other):
+ return other / self.convert(other)
+
+
+ # __getitem__ uses dict.get() to return 'False' if the key is not
+ # found (rather than raising KeyError). Note that this does *not*
+ # set the key's value to 'False' in the dict, so that even after
+ # we call env['foo'] we still get a meaningful answer from "'foo'
+ # in env" (which calls dict.__contains__, which we do not
+ # override).
+ def __getitem__(self, key):
+ return self.Proxy(dict.get(self, key, 'False'))
+
+ def __setitem__(self, key, item):
+ dict.__setitem__(self, key, str(item))
+
+ def values(self):
+ return [ self.Proxy(v) for v in dict.values(self) ]
+
+ def itervalues(self):
+ for value in dict.itervalues(self):
+ yield self.Proxy(value)
+
+ def items(self):
+ return [ (k, self.Proxy(v)) for k,v in dict.items(self) ]
+
+ def iteritems(self):
+ for key,value in dict.iteritems(self):
+ yield key, self.Proxy(value)
+
+ def get(self, key, default='False'):
+ return self.Proxy(dict.get(self, key, str(default)))
+
+ def setdefault(self, key, default='False'):
+ return self.Proxy(dict.setdefault(self, key, str(default)))
+
diff --git a/sim/main.cc b/sim/main.cc
index c15d24453..ee59cb83b 100644
--- a/sim/main.cc
+++ b/sim/main.cc
@@ -51,6 +51,7 @@
#include "base/time.hh"
#include "cpu/base_cpu.hh"
#include "cpu/full_cpu/smt.hh"
+#include "python/pyconfig.hh"
#include "sim/async.hh"
#include "sim/builder.hh"
#include "sim/configfile.hh"
@@ -61,7 +62,6 @@
#include "sim/stat_control.hh"
#include "sim/stats.hh"
#include "sim/universe.hh"
-#include "sim/pyconfig/pyconfig.hh"
using namespace std;
diff --git a/sim/sim_object.cc b/sim/sim_object.cc
index 818648b98..559415102 100644
--- a/sim/sim_object.cc
+++ b/sim/sim_object.cc
@@ -61,14 +61,29 @@ namespace Stats {
//
// SimObject constructor: used to maintain static simObjectList
//
+SimObject::SimObject(Params *p)
+ : _params(p)
+{
+#ifdef DEBUG
+ doDebugBreak = false;
+#endif
+
+ doRecordEvent = !Stats::event_ignore.match(name());
+ simObjectList.push_back(this);
+}
+
+//
+// SimObject constructor: used to maintain static simObjectList
+//
SimObject::SimObject(const string &_name)
- : objName(_name)
+ : _params(new Params)
{
+ _params->name = _name;
#ifdef DEBUG
doDebugBreak = false;
#endif
- doRecordEvent = !Stats::event_ignore.match(_name);
+ doRecordEvent = !Stats::event_ignore.match(name());
simObjectList.push_back(this);
}
diff --git a/sim/sim_object.hh b/sim/sim_object.hh
index f4b316ebb..db8d4f4d3 100644
--- a/sim/sim_object.hh
+++ b/sim/sim_object.hh
@@ -48,8 +48,16 @@
*/
class SimObject : public Serializable, protected StartupCallback
{
+ public:
+ struct Params {
+ std::string name;
+ };
+
protected:
- std::string objName;
+ Params *_params;
+
+ public:
+ const Params *params() const { return _params; }
private:
friend class Serializer;
@@ -60,11 +68,12 @@ class SimObject : public Serializable, protected StartupCallback
static SimObjectList simObjectList;
public:
+ SimObject(Params *_params);
SimObject(const std::string &_name);
virtual ~SimObject() {}
- virtual const std::string name() const { return objName; }
+ virtual const std::string name() const { return params()->name; }
// initialization pass of all objects.
// Gets invoked after construction, before unserialize.
diff --git a/test/genini.py b/test/genini.py
index f4d1575db..b8eda5d46 100755
--- a/test/genini.py
+++ b/test/genini.py
@@ -30,12 +30,12 @@ from os.path import join as joinpath, realpath
mypath = sys.path[0]
sys.path.append(joinpath(mypath, '..'))
+sys.path.append(joinpath(mypath, '../python'))
sys.path.append(joinpath(mypath, '../util/pbs'))
-sys.path.append(joinpath(mypath, '../sim/pyconfig'))
-from importer import AddToPath, LoadMpyFile
+pathlist = [ '.' ]
-AddToPath('.')
+m5_build_env = {}
try:
opts, args = getopt.getopt(sys.argv[1:], '-E:I:')
@@ -44,17 +44,21 @@ 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':
- AddToPath(arg)
+ pathlist.append(arg)
except getopt.GetoptError:
sys.exit('Improper Usage')
-from m5config import *
+from m5 import *
+
+for path in pathlist:
+ AddToPath(path)
for arg in args:
LoadMpyFile(arg)
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