From 51bdb242f98524a76f3124c8381fb1da7e88052c Mon Sep 17 00:00:00 2001 From: Erik Hallnor Date: Fri, 11 Mar 2005 12:29:47 -0500 Subject: [PATCH 01/18] Need to invalidate blocks by calling the invalidateBlk function, not setting status to 0. --HG-- extra : convert_revision : b46ad0b1d665c60bef03cb711a964cb75e4e1e29 From 1eb5e618dee7fbbec73c772fe0b95775394c517f Mon Sep 17 00:00:00 2001 From: Ron Dreslinski Date: Fri, 11 Mar 2005 18:07:07 -0500 Subject: [PATCH 02/18] Added config files for splash2 benchmarks. Parameters: ROOTDIR = root directory of the splash2 code NP = number of proccessors BENCHMARK = name of the splash2 benchmark (Cholesky, FFT, LUContig, LUNoncontig, Radix, Barnes, FMM, OceanContig, OceanNoncontig, Raytrace, WaterNSquared, or WaterSpatial) SYSTEM = Type of system to simulate detailed or simple Note: They use MOESI protocol and do_events is enabled (Multiple L1's and a shared L2) --HG-- extra : convert_revision : c39aa73825ea8108b6c32abd4a4fa4c23391ab09 --- configs/splash2/run.mpy | 50 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 configs/splash2/run.mpy diff --git a/configs/splash2/run.mpy b/configs/splash2/run.mpy new file mode 100644 index 0000000000..a19dcdc939 --- /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") From cf05fa476df711f64d0481117cf075ce68676d57 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 11 Mar 2005 18:28:38 -0500 Subject: [PATCH 03/18] stick all python stuff into a top level python directory. create an m5 package in python/m5 move the objects package into the m5 package move the m5config into the m5 package as config leave both importers outside of the package. SConscript: sim/main.cc: move sim/pyconfig/* -> python python/SConscript: m5config.py -> m5/config.py (now automatically embedded) objects -> python/m5/objects embed all python files in python/m5 python/m5/config.py: importer renamed mpy_importer move code to m5/__init__.py test/genini.py: deal with new python organization keep track of paths we want to add and add them after parameters are parsed. --HG-- rename : sim/pyconfig/SConscript => python/SConscript rename : sim/pyconfig/m5config.py => python/m5/config.py rename : objects/AlphaConsole.mpy => python/m5/objects/AlphaConsole.mpy rename : objects/AlphaTLB.mpy => python/m5/objects/AlphaTLB.mpy rename : objects/BadDevice.mpy => python/m5/objects/BadDevice.mpy rename : objects/BaseCPU.mpy => python/m5/objects/BaseCPU.mpy rename : objects/BaseCache.mpy => python/m5/objects/BaseCache.mpy rename : objects/BaseSystem.mpy => python/m5/objects/BaseSystem.mpy rename : objects/Bus.mpy => python/m5/objects/Bus.mpy rename : objects/CoherenceProtocol.mpy => python/m5/objects/CoherenceProtocol.mpy rename : objects/Device.mpy => python/m5/objects/Device.mpy rename : objects/DiskImage.mpy => python/m5/objects/DiskImage.mpy rename : objects/Ethernet.mpy => python/m5/objects/Ethernet.mpy rename : objects/Ide.mpy => python/m5/objects/Ide.mpy rename : objects/IntrControl.mpy => python/m5/objects/IntrControl.mpy rename : objects/MemTest.mpy => python/m5/objects/MemTest.mpy rename : objects/Pci.mpy => python/m5/objects/Pci.mpy rename : objects/PhysicalMemory.mpy => python/m5/objects/PhysicalMemory.mpy rename : objects/Platform.mpy => python/m5/objects/Platform.mpy rename : objects/Process.mpy => python/m5/objects/Process.mpy rename : objects/Repl.mpy => python/m5/objects/Repl.mpy rename : objects/Root.mpy => python/m5/objects/Root.mpy rename : objects/SimConsole.mpy => python/m5/objects/SimConsole.mpy rename : objects/SimpleDisk.mpy => python/m5/objects/SimpleDisk.mpy rename : objects/Tsunami.mpy => python/m5/objects/Tsunami.mpy rename : objects/Uart.mpy => python/m5/objects/Uart.mpy extra : convert_revision : aebf6ccda33028b1125974ca8b6aeab6f7570f30 --- SConscript | 7 ++++--- {sim/pyconfig => python}/SConscript | 4 ++-- python/m5/__init__.py | 7 +++++++ sim/pyconfig/m5config.py => python/m5/config.py | 5 +---- {objects => python/m5/objects}/AlphaConsole.mpy | 0 {objects => python/m5/objects}/AlphaTLB.mpy | 0 {objects => python/m5/objects}/BadDevice.mpy | 0 {objects => python/m5/objects}/BaseCPU.mpy | 0 {objects => python/m5/objects}/BaseCache.mpy | 0 {objects => python/m5/objects}/BaseSystem.mpy | 0 {objects => python/m5/objects}/Bus.mpy | 0 .../m5/objects}/CoherenceProtocol.mpy | 0 {objects => python/m5/objects}/Device.mpy | 0 {objects => python/m5/objects}/DiskImage.mpy | 0 {objects => python/m5/objects}/Ethernet.mpy | 0 {objects => python/m5/objects}/Ide.mpy | 0 {objects => python/m5/objects}/IntrControl.mpy | 0 {objects => python/m5/objects}/MemTest.mpy | 0 {objects => python/m5/objects}/Pci.mpy | 0 {objects => python/m5/objects}/PhysicalMemory.mpy | 0 {objects => python/m5/objects}/Platform.mpy | 0 {objects => python/m5/objects}/Process.mpy | 0 {objects => python/m5/objects}/Repl.mpy | 0 {objects => python/m5/objects}/Root.mpy | 0 {objects => python/m5/objects}/SimConsole.mpy | 0 {objects => python/m5/objects}/SimpleDisk.mpy | 0 {objects => python/m5/objects}/Tsunami.mpy | 0 {objects => python/m5/objects}/Uart.mpy | 0 sim/main.cc | 2 +- test/genini.py | 13 +++++++------ 30 files changed, 22 insertions(+), 16 deletions(-) rename {sim/pyconfig => python}/SConscript (98%) create mode 100644 python/m5/__init__.py rename sim/pyconfig/m5config.py => python/m5/config.py (99%) rename {objects => python/m5/objects}/AlphaConsole.mpy (100%) rename {objects => python/m5/objects}/AlphaTLB.mpy (100%) rename {objects => python/m5/objects}/BadDevice.mpy (100%) rename {objects => python/m5/objects}/BaseCPU.mpy (100%) rename {objects => python/m5/objects}/BaseCache.mpy (100%) rename {objects => python/m5/objects}/BaseSystem.mpy (100%) rename {objects => python/m5/objects}/Bus.mpy (100%) rename {objects => python/m5/objects}/CoherenceProtocol.mpy (100%) rename {objects => python/m5/objects}/Device.mpy (100%) rename {objects => python/m5/objects}/DiskImage.mpy (100%) rename {objects => python/m5/objects}/Ethernet.mpy (100%) rename {objects => python/m5/objects}/Ide.mpy (100%) rename {objects => python/m5/objects}/IntrControl.mpy (100%) rename {objects => python/m5/objects}/MemTest.mpy (100%) rename {objects => python/m5/objects}/Pci.mpy (100%) rename {objects => python/m5/objects}/PhysicalMemory.mpy (100%) rename {objects => python/m5/objects}/Platform.mpy (100%) rename {objects => python/m5/objects}/Process.mpy (100%) rename {objects => python/m5/objects}/Repl.mpy (100%) rename {objects => python/m5/objects}/Root.mpy (100%) rename {objects => python/m5/objects}/SimConsole.mpy (100%) rename {objects => python/m5/objects}/SimpleDisk.mpy (100%) rename {objects => python/m5/objects}/Tsunami.mpy (100%) rename {objects => python/m5/objects}/Uart.mpy (100%) diff --git a/SConscript b/SConscript index 19f84f9131..cff240a69f 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,7 +377,7 @@ 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) # This function adds the specified sources to the given build diff --git a/sim/pyconfig/SConscript b/python/SConscript similarity index 98% rename from sim/pyconfig/SConscript rename to python/SConscript index 2799ef64f1..81bc52286b 100644 --- a/sim/pyconfig/SConscript +++ b/python/SConscript @@ -193,8 +193,8 @@ EmbedMap %(name)s("%(fname)s", /* namespace */ } ''' -embedded_py_files = ['m5config.py', 'importer.py', '../../util/pbs/jobfile.py'] -objpath = os.path.join(env['SRCDIR'], 'objects') +embedded_py_files = [ 'mpy_importer.py', '../util/pbs/jobfile.py' ] +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 0000000000..7cb3a32c6d --- /dev/null +++ b/python/m5/__init__.py @@ -0,0 +1,7 @@ +from mpy_importer import * +from config import * +from objects import * + +cpp_classes = MetaSimObject.cpp_classes +cpp_classes.sort() + diff --git a/sim/pyconfig/m5config.py b/python/m5/config.py similarity index 99% rename from sim/pyconfig/m5config.py rename to python/m5/config.py index e6201b3ada..b39a8b9a66 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 mpy_importer import AddToPath, LoadMpyFile noDot = False try: @@ -1298,6 +1298,3 @@ class SimObject(ConfigNode): type = 'SimObject' from objects import * - -cpp_classes = MetaSimObject.cpp_classes -cpp_classes.sort() diff --git a/objects/AlphaConsole.mpy b/python/m5/objects/AlphaConsole.mpy similarity index 100% rename from objects/AlphaConsole.mpy rename to python/m5/objects/AlphaConsole.mpy diff --git a/objects/AlphaTLB.mpy b/python/m5/objects/AlphaTLB.mpy similarity index 100% rename from objects/AlphaTLB.mpy rename to python/m5/objects/AlphaTLB.mpy diff --git a/objects/BadDevice.mpy b/python/m5/objects/BadDevice.mpy similarity index 100% rename from objects/BadDevice.mpy rename to python/m5/objects/BadDevice.mpy diff --git a/objects/BaseCPU.mpy b/python/m5/objects/BaseCPU.mpy similarity index 100% rename from objects/BaseCPU.mpy rename to python/m5/objects/BaseCPU.mpy diff --git a/objects/BaseCache.mpy b/python/m5/objects/BaseCache.mpy similarity index 100% rename from objects/BaseCache.mpy rename to python/m5/objects/BaseCache.mpy diff --git a/objects/BaseSystem.mpy b/python/m5/objects/BaseSystem.mpy similarity index 100% rename from objects/BaseSystem.mpy rename to python/m5/objects/BaseSystem.mpy diff --git a/objects/Bus.mpy b/python/m5/objects/Bus.mpy similarity index 100% rename from objects/Bus.mpy rename to python/m5/objects/Bus.mpy diff --git a/objects/CoherenceProtocol.mpy b/python/m5/objects/CoherenceProtocol.mpy similarity index 100% rename from objects/CoherenceProtocol.mpy rename to python/m5/objects/CoherenceProtocol.mpy diff --git a/objects/Device.mpy b/python/m5/objects/Device.mpy similarity index 100% rename from objects/Device.mpy rename to python/m5/objects/Device.mpy diff --git a/objects/DiskImage.mpy b/python/m5/objects/DiskImage.mpy similarity index 100% rename from objects/DiskImage.mpy rename to python/m5/objects/DiskImage.mpy diff --git a/objects/Ethernet.mpy b/python/m5/objects/Ethernet.mpy similarity index 100% rename from objects/Ethernet.mpy rename to python/m5/objects/Ethernet.mpy diff --git a/objects/Ide.mpy b/python/m5/objects/Ide.mpy similarity index 100% rename from objects/Ide.mpy rename to python/m5/objects/Ide.mpy diff --git a/objects/IntrControl.mpy b/python/m5/objects/IntrControl.mpy similarity index 100% rename from objects/IntrControl.mpy rename to python/m5/objects/IntrControl.mpy diff --git a/objects/MemTest.mpy b/python/m5/objects/MemTest.mpy similarity index 100% rename from objects/MemTest.mpy rename to python/m5/objects/MemTest.mpy diff --git a/objects/Pci.mpy b/python/m5/objects/Pci.mpy similarity index 100% rename from objects/Pci.mpy rename to python/m5/objects/Pci.mpy diff --git a/objects/PhysicalMemory.mpy b/python/m5/objects/PhysicalMemory.mpy similarity index 100% rename from objects/PhysicalMemory.mpy rename to python/m5/objects/PhysicalMemory.mpy diff --git a/objects/Platform.mpy b/python/m5/objects/Platform.mpy similarity index 100% rename from objects/Platform.mpy rename to python/m5/objects/Platform.mpy diff --git a/objects/Process.mpy b/python/m5/objects/Process.mpy similarity index 100% rename from objects/Process.mpy rename to python/m5/objects/Process.mpy diff --git a/objects/Repl.mpy b/python/m5/objects/Repl.mpy similarity index 100% rename from objects/Repl.mpy rename to python/m5/objects/Repl.mpy diff --git a/objects/Root.mpy b/python/m5/objects/Root.mpy similarity index 100% rename from objects/Root.mpy rename to python/m5/objects/Root.mpy diff --git a/objects/SimConsole.mpy b/python/m5/objects/SimConsole.mpy similarity index 100% rename from objects/SimConsole.mpy rename to python/m5/objects/SimConsole.mpy diff --git a/objects/SimpleDisk.mpy b/python/m5/objects/SimpleDisk.mpy similarity index 100% rename from objects/SimpleDisk.mpy rename to python/m5/objects/SimpleDisk.mpy diff --git a/objects/Tsunami.mpy b/python/m5/objects/Tsunami.mpy similarity index 100% rename from objects/Tsunami.mpy rename to python/m5/objects/Tsunami.mpy diff --git a/objects/Uart.mpy b/python/m5/objects/Uart.mpy similarity index 100% rename from objects/Uart.mpy rename to python/m5/objects/Uart.mpy diff --git a/sim/main.cc b/sim/main.cc index c15d24453c..ee59cb83bb 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/test/genini.py b/test/genini.py index f4d1575db2..025ba998a3 100755 --- a/test/genini.py +++ b/test/genini.py @@ -30,12 +30,10 @@ 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 - -AddToPath('.') +pathlist = [ '.' ] try: opts, args = getopt.getopt(sys.argv[1:], '-E:I:') @@ -50,11 +48,14 @@ try: value = arg[offset+1:] os.environ[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) From fa1650a08e56b176c2b31cd5c3b8939820e93884 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 11 Mar 2005 18:30:44 -0500 Subject: [PATCH 04/18] Make ConfigNodes as intermediate containers work again. python/m5/config.py: move the type stuff into the Node constructor and only try to grab self.type if the realtype is a SimObject --HG-- extra : convert_revision : 00f6ece47e3812f67f9e1f062fe9c060bd6dd1cf --- python/m5/config.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python/m5/config.py b/python/m5/config.py index b39a8b9a66..33e329f3ff 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -449,7 +449,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() @@ -584,10 +584,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 = {} From c393a51f4a00e88e7a72ad2c7bd56d19194f0b6a Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 11 Mar 2005 18:47:11 -0500 Subject: [PATCH 05/18] move the conversion stuff that was in configs/kernel/Config.py into the m5 package as convert.py add a smartdict class which stores strings and can intelligently interpret those string variables as several other types. make the env dict use the smartdict class python/m5/config.py: move a bunch of conversion functions into convert.py turn the env dict into a smartdict adapt the _CheckedInt stuff to deal with derived types python/m5/objects/BaseCPU.mpy: env is now a smartdict and can properly convert to bool --HG-- extra : convert_revision : 8abcd35a5ab14b82f280aea59020953869e33365 --- python/m5/config.py | 17 ++-- python/m5/convert.py | 181 ++++++++++++++++++++++++++++++++++ python/m5/objects/BaseCPU.mpy | 2 +- python/m5/smartdict.py | 85 ++++++++++++++++ 4 files changed, 276 insertions(+), 9 deletions(-) create mode 100644 python/m5/convert.py create mode 100644 python/m5/smartdict.py diff --git a/python/m5/config.py b/python/m5/config.py index 33e329f3ff..2c5a70b250 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -28,6 +28,8 @@ 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 try: @@ -35,7 +37,7 @@ try: except: noDot = True -env = {} +env = SmartDict() env.update(os.environ) def panic(string): @@ -976,18 +978,17 @@ VectorParam = _VectorParamProxy(None) # Integer parameter type. class _CheckedInt(object): 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' % \ + raise TypeError, 'Integer param out of bounds %d < %d < %d' % \ (cls._min, value, cls._max) return value diff --git a/python/m5/convert.py b/python/m5/convert.py new file mode 100644 index 0000000000..b3f34e4ab6 --- /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/BaseCPU.mpy b/python/m5/objects/BaseCPU.mpy index 484fcccd68..be93e8ad1c 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 Bool._convert(env.get('FULL_SYSTEM', 'False')): + if env.get('FULL_SYSTEM', 'False'): dtb = Param.AlphaDTB("Data TLB") itb = Param.AlphaITB("Instruction TLB") mem = Param.FunctionalMemory("memory") diff --git a/python/m5/smartdict.py b/python/m5/smartdict.py new file mode 100644 index 0000000000..e282bc07b7 --- /dev/null +++ b/python/m5/smartdict.py @@ -0,0 +1,85 @@ +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) + + + def __getitem__(self, key): + return self.Proxy(dict.__getitem__(self, key)) + + 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=''): + return self.Proxy(dict.get(self, key, str(default))) + + def setdefault(self, key, default=''): + return self.Proxy(dict.setdefault(self, key, str(default))) + From 05e07428f103ae97f7929e3a4ed9bb7bea1eab9c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 11 Mar 2005 18:50:04 -0500 Subject: [PATCH 06/18] I don't know why from m5 import * doesn't work. Steve? --HG-- extra : convert_revision : b89dcd4f329973545dc8a5660daeda9bca7050a1 From c977d2a02b1b3071d52fe43779730ed5290babff Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 11 Mar 2005 19:34:35 -0500 Subject: [PATCH 07/18] remove addr from PciConfigDevice since it's not used Random some small config file stuff dev/pcidev.cc: objects/Pci.mpy: remove addr since it's not used --HG-- extra : convert_revision : aeb5993552d65a5e3b57f393bcb7d8aaadf6b5a2 --- dev/pcidev.cc | 10 ---------- objects/Pci.mpy | 4 +--- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/dev/pcidev.cc b/dev/pcidev.cc index c45afadd4c..76b42390ad 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 mmu; - Param addr; - SimObjectParam io_bus; - Param pio_latency; - Param VendorID; Param DeviceID; Param 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/Pci.mpy b/objects/Pci.mpy index caa3c52ff9..9074727279 100644 --- a/objects/Pci.mpy +++ b/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") @@ -49,4 +48,3 @@ simobj PciDevice(DmaDevice): pci_func = Param.Int("PCI function code") configdata = Param.PciConfigData(Super, "PCI Config data") configspace = Param.PciConfigAll(Super, "PCI Configspace") - addr = 0xffffffffffffffffL From 3bbddb43d43b70e6af35a2c4d35607a5a364f463 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 12 Mar 2005 09:42:08 -0500 Subject: [PATCH 08/18] fix syntax error that affected split configurations. --HG-- extra : convert_revision : db462e57736ccd3b6d21a06f2014eb0850a9ae90 From 8dff74b26fbfafad4ea9a12d20ad57b8094b0bc9 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sun, 13 Mar 2005 00:36:06 -0500 Subject: [PATCH 09/18] Clean up import situation... key things are: - global tracking of legitimate param types in separate dict keeps us from having to import objects in config.py, which gets rid of nasty circular dependence - use __all__ in config.py and restrict imports from mpy_importer to reduce m5 namespace pollution python/m5/__init__.py: Try to limit namespace pollution by only importing what's needed from mpy_importer. Explicitly set up legal parameter types rather than relying on eval(). python/m5/config.py: Use empty ParamType base class to distinguish types that are legitimate SimObject params. Explicitly add these to global param_types map. Rework CheckedInt and Range classes a little bit to fit in better with the model. No need to import objects here any longer. Add __all__ list to specify subset of names that get exported on 'from m5.config import *'. --HG-- extra : convert_revision : 01c6e82e0b175fc9b3df25dd0cc80ecd842680bc --- python/m5/__init__.py | 12 ++- python/m5/config.py | 220 +++++++++++++++++++++++++----------------- 2 files changed, 141 insertions(+), 91 deletions(-) diff --git a/python/m5/__init__.py b/python/m5/__init__.py index 7cb3a32c6d..3d54a83da6 100644 --- a/python/m5/__init__.py +++ b/python/m5/__init__.py @@ -1,7 +1,11 @@ -from mpy_importer import * -from config import * -from objects import * +from mpy_importer import AddToPath, LoadMpyFile -cpp_classes = MetaSimObject.cpp_classes +from config import * +config.add_param_types(config.__dict__) + +from objects import * +config.add_param_types(objects.__dict__) + +cpp_classes = config.MetaSimObject.cpp_classes cpp_classes.sort() diff --git a/python/m5/config.py b/python/m5/config.py index 2c5a70b250..a4248192a4 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -27,7 +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 * @@ -210,6 +209,23 @@ class_decorator = 'M5M5_SIMOBJECT_' expr_decorator = 'M5M5_EXPRESSION_' dot_decorator = '_M5M5_DOT_' +param_types = {} + +class ParamType(object): + pass + +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 +263,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 +286,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 +442,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) @@ -562,7 +589,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() @@ -854,13 +881,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 +925,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, '' @@ -975,8 +1004,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 +1041,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) +# 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 -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 +class Int(CheckedInt): cppname = 'int'; size = 32; unsigned = False +class Unsigned(CheckedInt): cppname = 'unsigned'; size = 32; unsigned = True - return super(cls, CheckedIntType).__new__(cls, cppname, min, max) +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 -Int = CheckedIntType('int', 32, False) -Unsigned = CheckedIntType('unsigned', 32, 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 -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) - -Counter = CheckedIntType('Counter', 64, True) -Addr = CheckedIntType('Addr', 64, True) -Tick = CheckedIntType('Tick', 64, 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 +1134,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 +1174,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 +1281,7 @@ class MetaEnum(type): return s # Base class for enum types. -class Enum(object): +class Enum(ParamType): __metaclass__ = MetaEnum vals = [] @@ -1261,8 +1301,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 +1314,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 +1334,17 @@ 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__ = ['env', + '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'] From d94f5bfb04a9e5e99242f960ca20a6e693e6ad56 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sun, 13 Mar 2005 00:54:34 -0500 Subject: [PATCH 10/18] A few fixes after trying one of Nate's job scripts. python/m5/config.py: Add issequence to __all__ export list. Added some more comments too. --HG-- extra : convert_revision : 17cd9205e43fe276f71563fcb96ec3c5069fcc86 --- python/m5/config.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/python/m5/config.py b/python/m5/config.py index a4248192a4..74022059f1 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -209,11 +209,16 @@ 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 @@ -1339,7 +1344,10 @@ class SimObject(ConfigNode, ParamType): type = 'SimObject' -__all__ = ['env', +# __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__ = ['env', 'issequence', 'ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', 'Super', 'Enum', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', From 82964b2705b892f5d36522f7b7c5472975a5d873 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sun, 13 Mar 2005 01:21:23 -0500 Subject: [PATCH 11/18] Minor Python config bug fix. python/m5/config.py: Add 'panic' to __all__ (some of Nate's scripts use it). --HG-- extra : convert_revision : ae3e2398dffe3edd17ee0155f38bc757d3552df2 --- python/m5/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/m5/config.py b/python/m5/config.py index 74022059f1..7dfc4fb041 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -1347,7 +1347,7 @@ class SimObject(ConfigNode, ParamType): # __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__ = ['env', 'issequence', +__all__ = ['env', 'issequence', 'panic', 'ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', 'Super', 'Enum', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', From 1b841a871ecd717dd8705d12ff7311c6fc97fc63 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 14 Mar 2005 07:46:26 -0500 Subject: [PATCH 12/18] - Add capability to auto-generate Param structs from .mpy SimObject descriptions. Structs are defined in simobj/param/ObjectName.hh. - Move compile-time python params (from CPPDEFINES) to separate dict from run-time params (from os.environ). The former are needed to generate proper param structs. This also helps prevent users from messing things up by setting the wrong environment vars (which could have overridden compile-time settings in the old system). - Other misc cleanup of m5 python package. SConscript: Include simobj/SConscript build/SConstruct: Fix type in comment python/SConscript: Move CPPDEFINES dict-generating code to m5scons.flatten_defines python/m5/__init__.py: - Generate a build_env SmartDict here to hold compile-time params (passed in via __main__.m5_build_env). - Move panic and env here from config.py. python/m5/config.py: Move panic, env to top level (m5/__init__.py) python/m5/objects/BaseCPU.mpy: Use build_env instead of env for compile-time params python/m5/smartdict.py: Add some comments. sim/sim_object.hh: Include auto-generated Param struct. Not used yet, just here as proof of concept. test/genini.py: Put -E arguments in build_env as well as os.environ --HG-- extra : convert_revision : cf6f4a2565b230c495b33b18612d6030988adac5 --- SConscript | 2 +- build/SConstruct | 2 +- python/SConscript | 36 +++++++++++++---------------------- python/m5/__init__.py | 32 ++++++++++++++++++++++++++++--- python/m5/config.py | 10 +--------- python/m5/objects/BaseCPU.mpy | 2 +- python/m5/smartdict.py | 23 +++++++++++++++++++--- sim/sim_object.hh | 4 ++++ test/genini.py | 5 ++++- 9 files changed, 74 insertions(+), 42 deletions(-) diff --git a/SConscript b/SConscript index cff240a69f..3b3c871bc2 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/build/SConstruct b/build/SConstruct index 3d7db1db2a..0f688ac3b1 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -289,7 +289,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/python/SConscript b/python/SConscript index 81bc52286b..a50903964c 100644 --- a/python/SConscript +++ b/python/SConscript @@ -26,7 +26,14 @@ # (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') + +# tell python where to find m5 python code +sys.path.append(os.path.join(env['SRCDIR'], 'python')) + +import m5scons def WriteEmbeddedPyFile(target, source, path, name, ext, filename): if isinstance(source, str): @@ -89,7 +96,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 +151,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): diff --git a/python/m5/__init__.py b/python/m5/__init__.py index 3d54a83da6..16f48dba3c 100644 --- a/python/m5/__init__.py +++ b/python/m5/__init__.py @@ -1,10 +1,36 @@ +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 -from config import * -config.add_param_types(config.__dict__) +# 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.__dict__) +config.add_param_types(objects) cpp_classes = config.MetaSimObject.cpp_classes cpp_classes.sort() diff --git a/python/m5/config.py b/python/m5/config.py index 7dfc4fb041..a9d7a2f41c 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -27,7 +27,6 @@ from __future__ import generators import os, re, sys, types, inspect -from smartdict import SmartDict from convert import * noDot = False @@ -36,13 +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) @@ -1347,7 +1339,7 @@ class SimObject(ConfigNode, ParamType): # __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__ = ['env', 'issequence', 'panic', +__all__ = ['issequence', 'ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', 'Super', 'Enum', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', diff --git a/python/m5/objects/BaseCPU.mpy b/python/m5/objects/BaseCPU.mpy index be93e8ad1c..5d8305d888 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/smartdict.py b/python/m5/smartdict.py index e282bc07b7..4ea8210d36 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 f4b316ebb7..b8a3090ad9 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 025ba998a3..b8eda5d46f 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: From de4aa841546daa41da88bb8a427c05ff6cd4df4d Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 14 Mar 2005 07:52:41 -0500 Subject: [PATCH 13/18] Move mpy_importer into m5 package (it logically belongs there since it's so tied in with m5.config). python/SConscript: mpy_importer.py now in m5 package --HG-- extra : convert_revision : 3cd7af4e1cd9338aa6bed5306c824ac5f0965085 --- python/SConscript | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python/SConscript b/python/SConscript index a50903964c..8404bc4bd8 100644 --- a/python/SConscript +++ b/python/SConscript @@ -183,8 +183,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': From e7a106eec1bc5d0546eeed215d73f559f8fb8ddf Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 14 Mar 2005 10:23:43 -0500 Subject: [PATCH 14/18] fix the etherdev2 connection so that nat runs work. --HG-- extra : convert_revision : 8ad4d460836b456b29e5b4ab03081d4af622fb38 From b12f9321ff10468eea568dd1ef431fe47c925e41 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 14 Mar 2005 11:15:41 -0500 Subject: [PATCH 15/18] Ron's fix to some of the No supplier problems, don't deal with badaddrs. --HG-- extra : convert_revision : 442edd3c49333fc59953dd089eaaaee4f7b23deb From 81169916aa2fb37536c8ae841424ac8640e1e0e1 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 14 Mar 2005 11:16:27 -0500 Subject: [PATCH 16/18] print the daddr to pciconfigall DPRINTF. --HG-- extra : convert_revision : d13ce459d5dac026e596f0bb3ba801b1dbed9ed0 --- dev/pciconfigall.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 1a9804f795..2cbd5adc04 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; From bc2923f78d739ad5ff42dee402c5ba27c02004f1 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 14 Mar 2005 14:43:10 -0500 Subject: [PATCH 17/18] Move adding SRCDIR/python to sys.path from multiple SConscript files to SConstruct. build/SConstruct: Add SRCDIR/python to sys.path here. python/SConscript: Move adding SRCDIR/python to sys.path to SConstruct. --HG-- extra : convert_revision : f598d670650f5b4fd501caaf073fe38b44d21855 --- build/SConstruct | 3 +++ python/SConscript | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/SConstruct b/build/SConstruct index 0f688ac3b1..e333732434 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')) + ################################################### # diff --git a/python/SConscript b/python/SConscript index 8404bc4bd8..9c15c6d501 100644 --- a/python/SConscript +++ b/python/SConscript @@ -30,9 +30,6 @@ import os, os.path, re, sys Import('env') -# tell python where to find m5 python code -sys.path.append(os.path.join(env['SRCDIR'], 'python')) - import m5scons def WriteEmbeddedPyFile(target, source, path, name, ext, filename): From c1f5b983f0c8cece7a8387b05b40889c9520fb39 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 14 Mar 2005 15:37:58 -0500 Subject: [PATCH 18/18] put the syscall emulation error stuff to bed, finally remove addr from pciconfig objects and update Monet configuration for ron's changes python/m5/objects/Pci.mpy: I was a little over zelous in my removal of addr, this one should have stayed --HG-- extra : convert_revision : 6c94b11d4c63d50ffe5568b16a131a4105654126 --- python/m5/objects/Pci.mpy | 1 + 1 file changed, 1 insertion(+) diff --git a/python/m5/objects/Pci.mpy b/python/m5/objects/Pci.mpy index 9074727279..4daa902ab6 100644 --- a/python/m5/objects/Pci.mpy +++ b/python/m5/objects/Pci.mpy @@ -43,6 +43,7 @@ simobj PciConfigAll(FooPioDevice): simobj PciDevice(DmaDevice): type = 'PciDevice' abstract = True + addr = 0xffffffff pci_bus = Param.Int("PCI bus") pci_dev = Param.Int("PCI device number") pci_func = Param.Int("PCI function code")