diff options
Diffstat (limited to 'sim')
-rw-r--r-- | sim/eventq.hh | 34 | ||||
-rw-r--r-- | sim/param.cc | 8 | ||||
-rw-r--r-- | sim/param.hh | 9 | ||||
-rw-r--r-- | sim/pyconfig/SConscript | 15 | ||||
-rw-r--r-- | sim/pyconfig/m5config.py | 131 | ||||
-rw-r--r-- | sim/serialize.cc | 1 | ||||
-rw-r--r-- | sim/startup.cc | 24 | ||||
-rw-r--r-- | sim/syscall_emul.hh | 84 | ||||
-rw-r--r-- | sim/universe.cc | 11 |
9 files changed, 203 insertions, 114 deletions
diff --git a/sim/eventq.hh b/sim/eventq.hh index 304e4b16a..d62e7df10 100644 --- a/sim/eventq.hh +++ b/sim/eventq.hh @@ -30,8 +30,8 @@ * EventQueue interfaces */ -#ifndef __EVENTQ_HH__ -#define __EVENTQ_HH__ +#ifndef __SIM_EVENTQ_HH__ +#define __SIM_EVENTQ_HH__ #include <assert.h> @@ -43,11 +43,24 @@ #include "sim/host.hh" // for Tick #include "base/fast_alloc.hh" -#include "sim/serialize.hh" #include "base/trace.hh" +#include "sim/serialize.hh" class EventQueue; // forward declaration +////////////////////// +// +// Main Event Queue +// +// Events on this queue are processed at the *beginning* of each +// cycle, before the pipeline simulation is performed. +// +// defined in eventq.cc +// +////////////////////// +extern EventQueue mainEventQueue; + + /* * An item on an event queue. The action caused by a given * event is specified by deriving a subclass and overriding the @@ -228,7 +241,7 @@ DelayFunction(Tick when, T *object) public: DelayEvent(Tick when, T *o) : Event(&mainEventQueue), object(o) - { setFlags(AutoDestroy); schedule(when); } + { setFlags(this->AutoDestroy); schedule(when); } void process() { (object->*F)(); } const char *description() { return "delay"; } }; @@ -386,16 +399,5 @@ EventQueue::reschedule(Event *event) } -////////////////////// -// -// Main Event Queue -// -// Events on this queue are processed at the *beginning* of each -// cycle, before the pipeline simulation is performed. -// -// defined in eventq.cc -// -////////////////////// -extern EventQueue mainEventQueue; -#endif // __EVENTQ_HH__ +#endif // __SIM_EVENTQ_HH__ diff --git a/sim/param.cc b/sim/param.cc index d666463c9..d16578a2d 100644 --- a/sim/param.cc +++ b/sim/param.cc @@ -493,11 +493,11 @@ EnumVectorParam<Map>::showType(ostream &os) const showEnumType(os, map, num_values); } -template EnumParam<const char *>; -template EnumVectorParam<const char *>; +template class EnumParam<const char *>; +template class EnumVectorParam<const char *>; -template EnumParam<EnumParamMap>; -template EnumVectorParam<EnumParamMap>; +template class EnumParam<EnumParamMap>; +template class EnumVectorParam<EnumParamMap>; //////////////////////////////////////////////////////////////////////// // diff --git a/sim/param.hh b/sim/param.hh index ac57afa31..f4b9d3450 100644 --- a/sim/param.hh +++ b/sim/param.hh @@ -26,9 +26,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __PARAM_HH__ -#define __PARAM_HH__ +#ifndef __SIM_PARAM_HH__ +#define __SIM_PARAM_HH__ +#include <iostream> #include <list> #include <string> #include <vector> @@ -524,7 +525,7 @@ class MappedEnumParam : public EnumParam<EnumParamMap> { if (!isValid()) die("not found"); - return (ENUM)value[n]; + return (ENUM)value[this->n]; } }; @@ -782,4 +783,4 @@ SimObjectVectorParam<OBJ_CLASS *>::showType(std::ostream &os) const \ template <class T> bool parseParam(const std::string &str, T &data); template <class T> void showParam(std::ostream &os, const T &data); -#endif // _PARAM_HH +#endif // _SIM_PARAM_HH_ diff --git a/sim/pyconfig/SConscript b/sim/pyconfig/SConscript index 127b0efae..5708ac9a8 100644 --- a/sim/pyconfig/SConscript +++ b/sim/pyconfig/SConscript @@ -28,14 +28,15 @@ import os, os.path, re -def WriteEmbeddedPyFile(target, source, path, name, ext): +def WriteEmbeddedPyFile(target, source, path, name, ext, filename): if isinstance(source, str): source = file(source, 'r') if isinstance(target, str): target = file(target, 'w') - print >>target, "AddModule(%s, %s, %s, '''\\" % (`path`, `name`, `ext`) + print >>target, "AddModule(%s, %s, %s, %s, '''\\" % \ + (`path`, `name`, `ext`, `filename`) for line in source: line = line @@ -105,7 +106,7 @@ def MakeEmbeddedPyFile(target, source, env): name,ext = pyfile.split('.') if name == '__init__': node['.hasinit'] = True - node[pyfile] = (src,name,ext) + node[pyfile] = (src,name,ext,src) done = False while not done: @@ -136,12 +137,12 @@ def MakeEmbeddedPyFile(target, source, env): raise NameError, 'package directory missing __init__.py' populate(entry, path + [ name ]) else: - pyfile,name,ext = entry - files.append((pyfile, path, name, ext)) + pyfile,name,ext,filename = entry + files.append((pyfile, path, name, ext, filename)) populate(tree) - for pyfile, path, name, ext in files: - WriteEmbeddedPyFile(target, pyfile, path, name, ext) + for pyfile, path, name, ext, filename in files: + WriteEmbeddedPyFile(target, pyfile, path, name, ext, filename) CFileCounter = 0 def MakePythonCFile(target, source, env): diff --git a/sim/pyconfig/m5config.py b/sim/pyconfig/m5config.py index 4e2a377b0..4e3a4103c 100644 --- a/sim/pyconfig/m5config.py +++ b/sim/pyconfig/m5config.py @@ -26,14 +26,14 @@ from __future__ import generators import os, re, sys, types +noDot = False +try: + import pydot +except: + noDot = True env = {} env.update(os.environ) -def defined(key): - return env.has_key(key) - -def define(key, value = True): - env[key] = value def panic(*args, **kwargs): sys.exit(*args, **kwargs) @@ -59,9 +59,6 @@ class Singleton(type): cls._instance = super(Singleton, cls).__call__(*args, **kwargs) return cls._instance -if os.environ.has_key('FULL_SYSTEM'): - FULL_SYSTEM = True - ##################################################################### # # M5 Python Configuration Utility @@ -209,6 +206,17 @@ def isSimObjSequence(value): return True +def isParamContext(value): + try: + return issubclass(value, ParamContext) + except: + return False + + +class_decorator = '_M5M5_SIMOBJECT_' +expr_decorator = '_M5M5_EXPRESSION_' +dot_decorator = '_M5M5_DOT_' + # 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 @@ -218,7 +226,6 @@ def isSimObjSequence(value): class MetaConfigNode(type): keywords = { 'abstract' : types.BooleanType, 'check' : types.FunctionType, - '_init' : types.FunctionType, 'type' : (types.NoneType, types.StringType) } # __new__ is called before __init__, and is where the statements @@ -234,6 +241,11 @@ class MetaConfigNode(type): '_disable' : {} } for key,val in dict.items(): + del dict[key] + + if key.startswith(expr_decorator): + key = key[len(expr_decorator):] + if mcls.keywords.has_key(key): if not isinstance(val, mcls.keywords[key]): raise TypeError, \ @@ -243,11 +255,9 @@ class MetaConfigNode(type): if isinstance(val, types.FunctionType): val = classmethod(val) priv[key] = val - del dict[key] elif key.startswith('_'): priv[key] = val - del dict[key] elif not isNullPointer(val) and isConfigNode(val): dict[key] = val() @@ -255,19 +265,22 @@ class MetaConfigNode(type): elif isSimObjSequence(val): dict[key] = [ v() for v in val ] + else: + dict[key] = val + # If your parent has a value in it that's a config node, clone it. for base in bases: if not isConfigNode(base): continue - for name,value in base._values.iteritems(): - if dict.has_key(name): + for key,value in base._values.iteritems(): + if dict.has_key(key): continue if isConfigNode(value): - priv['_values'][name] = value() + priv['_values'][key] = value() elif isSimObjSequence(value): - priv['_values'][name] = [ val() for val in value ] + priv['_values'][key] = [ val() for val in value ] # entries left in dict will get passed to __init__, where we'll # deal with them as params. @@ -281,12 +294,12 @@ class MetaConfigNode(type): cls._bases = [c for c in cls.__mro__ if isConfigNode(c)] # initialize attributes with values from class definition - for pname,value in dict.iteritems(): - setattr(cls, pname, value) - - if hasattr(cls, '_init'): - cls._init() - del cls._init + for key,value in dict.iteritems(): + key = key.split(dot_decorator) + c = cls + for item in key[:-1]: + c = getattr(c, item) + setattr(c, key[-1], value) def _isvalue(cls, name): for c in cls._bases: @@ -378,7 +391,6 @@ class MetaConfigNode(type): raise AttributeError, \ "object '%s' has no attribute '%s'" % (cls.__name__, cls) - # Set attribute (called on foo.attr = value when foo is an # instance of class cls). def __setattr__(cls, attr, value): @@ -435,7 +447,7 @@ class MetaConfigNode(type): # Print instance info to .ini file. def instantiate(cls, name, parent = None): - instance = Node(name, cls, cls.type, parent) + instance = Node(name, cls, cls.type, parent, isParamContext(cls)) if hasattr(cls, 'check'): cls.check() @@ -456,7 +468,11 @@ class MetaConfigNode(type): if cls._getdisable(pname): continue - value = cls._getvalue(pname) + try: + value = cls._getvalue(pname) + except: + print 'Error getting %s' % pname + raise if isConfigNode(value): value = instance.child_objects[value] @@ -533,6 +549,9 @@ class ConfigNode(object): # v = param.convert(value) # object.__setattr__(self, attr, v) +class ParamContext(ConfigNode): + pass + # SimObject is a minimal extension of ConfigNode, implementing a # hierarchy node that corresponds to an M5 SimObject. It prints out a # "type=" line to indicate its SimObject class, prints out the @@ -569,7 +588,7 @@ class NodeParam(object): class Node(object): all = {} - def __init__(self, name, realtype, type, parent): + def __init__(self, name, realtype, type, parent, paramcontext): self.name = name self.realtype = realtype self.type = type @@ -580,6 +599,7 @@ class Node(object): self.top_child_names = {} self.params = [] self.param_names = {} + self.paramcontext = paramcontext path = [ self.name ] node = self.parent @@ -642,7 +662,7 @@ class Node(object): % (self.name, ptype, value._path) found, done = obj.find(ptype, value._path) if isinstance(found, Proxy): - done = false + done = False obj = obj.parent return found @@ -678,7 +698,8 @@ class Node(object): # instantiate children in same order they were added for # backward compatibility (else we can end up with cpu1 # before cpu0). - print 'children =', ' '.join([ c.name for c in self.children]) + children = [ c.name for c in self.children if not c.paramcontext] + print 'children =', ' '.join(children) for param in self.params: try: @@ -699,6 +720,48 @@ class Node(object): for c in self.children: c.display() + # print type and parameter values to .ini file + def outputDot(self, dot): + + + label = "{%s|" % self.path + if isSimObject(self.realtype): + label += '%s|' % self.type + + if self.children: + # instantiate children in same order they were added for + # backward compatibility (else we can end up with cpu1 + # before cpu0). + for c in self.children: + dot.add_edge(pydot.Edge(self.path,c.path, style="bold")) + + simobjs = [] + for param in self.params: + try: + if param.value is None: + raise AttributeError, 'Parameter with no value' + + value = param.convert(param.value) + string = param.string(value) + except: + print 'exception in %s:%s' % (self.name, param.name) + raise + ptype = eval(param.ptype) + if isConfigNode(ptype) and string != "Null": + simobjs.append(string) + else: + label += '%s = %s\\n' % (param.name, string) + + for so in simobjs: + label += "|<%s> %s" % (so, so) + dot.add_edge(pydot.Edge("%s:%s" % (self.path, so), so, tailport="w")) + label += '}' + dot.add_node(pydot.Node(self.path,shape="Mrecord",label=label)) + + # recursively dump out children + for c in self.children: + c.outputDot(dot) + def _string(cls, value): if not isinstance(value, Node): raise AttributeError, 'expecting %s got %s' % (Node, value) @@ -1196,12 +1259,9 @@ class Enum(type): # "Constants"... handy aliases for various values. # -# For compatibility with C++ bool constants. -false = False -true = True - # Some memory range specifications use this as a default upper bound. MAX_ADDR = Addr._max +MaxTick = Tick._max # For power-of-two sizing, e.g. 64*K gives an integer value 65536. K = 1024 @@ -1234,6 +1294,15 @@ def instantiate(root): instance = root.instantiate('root') instance.fixup() instance.display() + if not noDot: + dot = pydot.Dot() + instance.outputDot(dot) + dot.orientation = "portrait" + dot.size = "8.5,11" + dot.ranksep="equally" + dot.rank="samerank" + dot.write("config.dot") + dot.write_ps("config.ps") from objects import * diff --git a/sim/serialize.cc b/sim/serialize.cc index 2a5e3d398..3a073f68d 100644 --- a/sim/serialize.cc +++ b/sim/serialize.cc @@ -29,6 +29,7 @@ #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> +#include <errno.h> #include <fstream> #include <list> diff --git a/sim/startup.cc b/sim/startup.cc index ebb4c0bc0..7cc0ac8fb 100644 --- a/sim/startup.cc +++ b/sim/startup.cc @@ -29,20 +29,32 @@ #include <list> #include "base/misc.hh" -#include "sim/startup.hh" #include "sim/debug.hh" +#include "sim/startup.hh" typedef std::list<StartupCallback *> startupq_t; -startupq_t &startupq() { static startupq_t queue; return queue; } -StartupCallback::StartupCallback() { startupq().push_back(this); } -StartupCallback::~StartupCallback() { startupq().remove(this); } + +startupq_t *startupq = NULL; + +StartupCallback::StartupCallback() +{ + if (startupq == NULL) + startupq = new startupq_t; + startupq->push_back(this); +} + +StartupCallback::~StartupCallback() +{ + startupq->remove(this); +} + void StartupCallback::startup() { } void SimStartup() { - startupq_t::iterator i = startupq().begin(); - startupq_t::iterator end = startupq().end(); + startupq_t::iterator i = startupq->begin(); + startupq_t::iterator end = startupq->end(); while (i != end) { (*i)->startup(); diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index 77d104449..768bc3700 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __SYSCALL_EMUL_HH__ -#define __SYSCALL_EMUL_HH__ +#ifndef __SIM_SYSCALL_EMUL_HH__ +#define __SIM_SYSCALL_EMUL_HH__ /// /// @file syscall_emul.hh @@ -35,14 +35,16 @@ /// This file defines objects used to emulate syscalls from the target /// application on the host machine. +#include <errno.h> #include <string> #include "base/intmath.hh" // for RoundUp -#include "targetarch/isa_traits.hh" // for Addr #include "mem/functional_mem/functional_memory.hh" +#include "targetarch/isa_traits.hh" // for Addr -class Process; -class ExecContext; +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "sim/process.hh" /// /// System call descriptor. @@ -197,6 +199,36 @@ int unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc); /// Target rename() handler. int renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc); +/// This struct is used to build an target-OS-dependent table that +/// maps the target's open() flags to the host open() flags. +struct OpenFlagTransTable { + int tgtFlag; //!< Target system flag value. + int hostFlag; //!< Corresponding host system flag value. +}; + + + +/// A readable name for 1,000,000, for converting microseconds to seconds. +const int one_million = 1000000; + +/// Approximate seconds since the epoch (1/1/1970). About a billion, +/// by my reckoning. We want to keep this a constant (not use the +/// real-world time) to keep simulations repeatable. +const unsigned seconds_since_epoch = 1000000000; + +/// Helper function to convert current elapsed time to seconds and +/// microseconds. +template <class T1, class T2> +void +getElapsedTime(T1 &sec, T2 &usec) +{ + int cycles_per_usec = ticksPerSecond / one_million; + + int elapsed_usecs = curTick / cycles_per_usec; + sec = elapsed_usecs / one_million; + usec = elapsed_usecs % one_million; +} + ////////////////////////////////////////////////////////////////////// // // The following emulation functions are generic, but need to be @@ -238,14 +270,6 @@ ioctlFunc(SyscallDesc *desc, int callnum, Process *process, } } -/// This struct is used to build an target-OS-dependent table that -/// maps the target's open() flags to the host open() flags. -struct OpenFlagTransTable { - int tgtFlag; //!< Target system flag value. - int hostFlag; //!< Corresponding host system flag value. -}; - - /// Target open() handler. template <class OS> int @@ -260,7 +284,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process, if (path == "/dev/sysdev0") { // This is a memory-mapped high-resolution timer device on Alpha. // We don't support it, so just punt. - DCOUT(SyscallWarnings) << "Ignoring open(" << path << ", ...)" << endl; + DCOUT(SyscallWarnings) << "Ignoring open(" << path << ", ...)" << std::endl; return -ENOENT; } @@ -278,7 +302,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process, // any target flags left? if (tgtFlags != 0) - cerr << "Syscall: open: cannot decode flags: " << tgtFlags << endl; + std::cerr << "Syscall: open: cannot decode flags: " << tgtFlags << std::endl; #ifdef __CYGWIN32__ hostFlags |= O_BINARY; @@ -414,7 +438,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, break; default: - cerr << "getrlimitFunc: unimplemented resource " << resource << endl; + std::cerr << "getrlimitFunc: unimplemented resource " << resource << std::endl; abort(); break; } @@ -423,28 +447,6 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, return 0; } -/// A readable name for 1,000,000, for converting microseconds to seconds. -const int one_million = 1000000; - -/// Approximate seconds since the epoch (1/1/1970). About a billion, -/// by my reckoning. We want to keep this a constant (not use the -/// real-world time) to keep simulations repeatable. -const unsigned seconds_since_epoch = 1000000000; - -/// Helper function to convert current elapsed time to seconds and -/// microseconds. -template <class T1, class T2> -void -getElapsedTime(T1 &sec, T2 &usec) -{ - int cycles_per_usec = ticksPerSecond / one_million; - - int elapsed_usecs = curTick / cycles_per_usec; - sec = elapsed_usecs / one_million; - usec = elapsed_usecs % one_million; -} - - /// Target gettimeofday() handler. template <class OS> int @@ -476,7 +478,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process, // plow ahead DCOUT(SyscallWarnings) << "Warning: getrusage() only supports RUSAGE_SELF." - << " Parameter " << who << " ignored." << endl; + << " Parameter " << who << " ignored." << std::endl; } getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); @@ -502,6 +504,4 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process, return 0; } - - -#endif // __SYSCALL_EMUL_HH__ +#endif // __SIM_SYSCALL_EMUL_HH__ diff --git a/sim/universe.cc b/sim/universe.cc index 69563650d..115f6f790 100644 --- a/sim/universe.cc +++ b/sim/universe.cc @@ -28,6 +28,7 @@ #include <sys/types.h> #include <sys/stat.h> +#include <errno.h> #include <cstring> #include <fstream> @@ -142,7 +143,8 @@ CREATE_SIM_OBJECT(Root) __ticksPerNS = freq / 1.0e9; __ticksPerPS = freq / 1.0e12; - if (output_dir.isValid()) { + outputDirectory = output_dir; + if (!outputDirectory.empty()) { outputDirectory = output_dir; // guarantee that directory ends with a '/' @@ -158,9 +160,10 @@ CREATE_SIM_OBJECT(Root) } outputStream = makeOutputStream(output_file); - configStream = config_output_file.isValid() - ? makeOutputStream(config_output_file) - : outputStream; + configStream = outputStream; + string cof = config_output_file; + if (!cof.empty()) + configStream = makeOutputStream(cof); return root; } |