diff options
Diffstat (limited to 'src/python')
-rw-r--r-- | src/python/SConscript | 3 | ||||
-rw-r--r-- | src/python/m5/SimObject.py | 6 | ||||
-rw-r--r-- | src/python/m5/__init__.py | 95 | ||||
-rw-r--r-- | src/python/m5/main.py | 4 | ||||
-rw-r--r-- | src/python/m5/objects/IntrControl.py | 2 | ||||
-rw-r--r-- | src/python/m5/objects/T1000.py | 20 | ||||
-rw-r--r-- | src/python/m5/params.py | 5 | ||||
-rw-r--r-- | src/python/m5/stats.py | 46 | ||||
-rw-r--r-- | src/python/swig/core.i | 57 | ||||
-rw-r--r-- | src/python/swig/event.i | 45 | ||||
-rw-r--r-- | src/python/swig/pyevent.hh | 26 | ||||
-rw-r--r-- | src/python/swig/pyobject.cc | 137 | ||||
-rw-r--r-- | src/python/swig/pyobject.hh | 94 | ||||
-rw-r--r-- | src/python/swig/sim_object.i | 101 | ||||
-rw-r--r-- | src/python/swig/stats.i | 7 |
15 files changed, 594 insertions, 54 deletions
diff --git a/src/python/SConscript b/src/python/SConscript index 8c7e47909..94db1a747 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -107,10 +107,11 @@ def swig_it(module): '-o ${TARGETS[0]} $SOURCES') swig_modules.append(module) -swig_it('main') +swig_it('core') swig_it('debug') swig_it('event') swig_it('random') +swig_it('sim_object') swig_it('stats') swig_it('trace') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index ba79d3729..42266a80e 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -693,7 +693,7 @@ class SimObject(object): def getCCObject(self): if not self._ccObject: self._ccObject = -1 # flag to catch cycles in recursion - self._ccObject = internal.main.createSimObject(self.path()) + self._ccObject = internal.sim_object.createSimObject(self.path()) elif self._ccObject == -1: raise RuntimeError, "%s: recursive call to getCCObject()" \ % self.path() @@ -727,13 +727,13 @@ class SimObject(object): # i don't know if there's a better way to do this - calling # setMemoryMode directly from self._ccObject results in calling # SimObject::setMemoryMode, not the System::setMemoryMode - system_ptr = internal.main.convertToSystemPtr(self._ccObject) + system_ptr = internal.sim_object.convertToSystemPtr(self._ccObject) system_ptr.setMemoryMode(mode) for child in self._children.itervalues(): child.changeTiming(mode) def takeOverFrom(self, old_cpu): - cpu_ptr = internal.main.convertToBaseCPUPtr(old_cpu._ccObject) + cpu_ptr = internal.sim_object.convertToBaseCPUPtr(old_cpu._ccObject) self._ccObject.takeOverFrom(cpu_ptr) # generate output file for 'dot' to display as a pretty graph. diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index f39cc670a..1c4a79020 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -27,14 +27,16 @@ # Authors: Nathan Binkert # Steve Reinhardt -import atexit, os, sys +import atexit +import os +import sys # import the SWIG-wrapped main C++ functions import internal # import a few SWIG-wrapped items (those that are likely to be used # directly by user scripts) completely into this module for # convenience -from internal.main import simulate, SimLoopExitEvent +from internal.event import SimLoopExitEvent # import the m5 compile options import defines @@ -85,27 +87,60 @@ def instantiate(root): root.print_ini() sys.stdout.close() # close config.ini sys.stdout = sys.__stdout__ # restore to original - internal.main.loadIniFile(resolveSimObject) # load config.ini into C++ + + # load config.ini into C++ + internal.core.loadIniFile(resolveSimObject) + + # Initialize the global statistics + internal.stats.initSimStats() + root.createCCObject() root.connectPorts() - internal.main.finalInit() - noDot = True # temporary until we fix dot - 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") + + # Do a second pass to finish initializing the sim objects + internal.sim_object.initAll() + + # Do a third pass to initialize statistics + internal.sim_object.regAllStats() + + # Check to make sure that the stats package is properly initialized + internal.stats.check() + + # Reset to put the stats in a consistent state. + internal.stats.reset() + +def doDot(root): + 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") + +need_resume = [] +need_startup = True +def simulate(*args, **kwargs): + global need_resume, need_startup + + if need_startup: + internal.core.SimStartup() + need_startup = False + + for root in need_resume: + resume(root) + need_resume = [] + + return internal.event.simulate(*args, **kwargs) # Export curTick to user script. def curTick(): - return internal.main.cvar.curTick + return internal.event.cvar.curTick # register our C++ exit callback function with Python -atexit.register(internal.main.doExitCleanup) +atexit.register(internal.core.doExitCleanup) +atexit.register(internal.stats.dump) # This loops until all objects have been fully drained. def doDrain(root): @@ -119,7 +154,7 @@ def doDrain(root): # be drained. def drain(root): all_drained = False - drain_event = internal.main.createCountedDrain() + drain_event = internal.event.createCountedDrain() unready_objects = root.startDrain(drain_event, True) # If we've got some objects that can't drain immediately, then simulate if unready_objects > 0: @@ -127,7 +162,7 @@ def drain(root): simulate() else: all_drained = True - internal.main.cleanupCountedDrain(drain_event) + internal.event.cleanupCountedDrain(drain_event) return all_drained def resume(root): @@ -135,16 +170,16 @@ def resume(root): def checkpoint(root, dir): if not isinstance(root, objects.Root): - raise TypeError, "Object is not a root object. Checkpoint must be called on a root object." + raise TypeError, "Checkpoint must be called on a root object." doDrain(root) print "Writing checkpoint" - internal.main.serializeAll(dir) + internal.sim_object.serializeAll(dir) resume(root) def restoreCheckpoint(root, dir): print "Restoring from checkpoint" - internal.main.unserializeAll(dir) - resume(root) + internal.sim_object.unserializeAll(dir) + need_resume.append(root) def changeToAtomic(system): if not isinstance(system, objects.Root) and not isinstance(system, objects.System): @@ -152,7 +187,7 @@ def changeToAtomic(system): "called on a root object." doDrain(system) print "Changing memory mode to atomic" - system.changeTiming(internal.main.SimObject.Atomic) + system.changeTiming(internal.sim_object.SimObject.Atomic) def changeToTiming(system): if not isinstance(system, objects.Root) and not isinstance(system, objects.System): @@ -160,7 +195,7 @@ def changeToTiming(system): "called on a root object." doDrain(system) print "Changing memory mode to timing" - system.changeTiming(internal.main.SimObject.Timing) + system.changeTiming(internal.sim_object.SimObject.Timing) def switchCpus(cpuList): print "switching cpus" @@ -180,7 +215,7 @@ def switchCpus(cpuList): raise TypeError, "%s is not of type BaseCPU" % cpu # Drain all of the individual CPUs - drain_event = internal.main.createCountedDrain() + drain_event = internal.event.createCountedDrain() unready_cpus = 0 for old_cpu in old_cpus: unready_cpus += old_cpu.startDrain(drain_event, False) @@ -188,7 +223,7 @@ def switchCpus(cpuList): if unready_cpus > 0: drain_event.setCount(unready_cpus) simulate() - internal.main.cleanupCountedDrain(drain_event) + internal.event.cleanupCountedDrain(drain_event) # Now all of the CPUs are ready to be switched out for old_cpu in old_cpus: old_cpu._ccObject.switchOut() @@ -198,6 +233,14 @@ def switchCpus(cpuList): new_cpu._ccObject.resume() index += 1 +def dumpStats(): + print 'Dumping stats' + internal.stats.dump() + +def resetStats(): + print 'Resetting stats' + internal.stats.reset() + # Since we have so many mutual imports in this package, we should: # 1. Put all intra-package imports at the *bottom* of the file, unless # they're absolutely needed before that (for top-level statements diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 37df884d0..54368b91e 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -240,7 +240,7 @@ def main(): print "M5 Simulator System" print brief_copyright print - print "M5 compiled %s" % internal.main.cvar.compileDate; + print "M5 compiled %s" % internal.core.cvar.compileDate; print "M5 started %s" % datetime.now().ctime() print "M5 executing on %s" % socket.gethostname() print "command line:", @@ -256,7 +256,7 @@ def main(): usage(2) # tell C++ about output directory - internal.main.setOutputDir(options.outdir) + internal.core.setOutputDir(options.outdir) # update the system path with elements from the -p option sys.path[0:0] = options.path diff --git a/src/python/m5/objects/IntrControl.py b/src/python/m5/objects/IntrControl.py index a7cf5cc84..398ba47f9 100644 --- a/src/python/m5/objects/IntrControl.py +++ b/src/python/m5/objects/IntrControl.py @@ -3,4 +3,4 @@ from m5.params import * from m5.proxy import * class IntrControl(SimObject): type = 'IntrControl' - cpu = Param.BaseCPU(Parent.cpu[0], "the cpu") + sys = Param.System(Parent.any, "the system we are part of") diff --git a/src/python/m5/objects/T1000.py b/src/python/m5/objects/T1000.py index aeca491c4..0acfa0920 100644 --- a/src/python/m5/objects/T1000.py +++ b/src/python/m5/objects/T1000.py @@ -1,6 +1,6 @@ from m5.params import * from m5.proxy import * -from Device import BasicPioDevice, IsaFake, BadAddr +from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr from Uart import Uart8250 from Platform import Platform from SimConsole import SimConsole @@ -16,6 +16,10 @@ class DumbTOD(BasicPioDevice): time = Param.Time('01/01/2009', "System time to use ('Now' for real time)") pio_addr = 0xfff0c1fff8 +class Iob(PioDevice): + type = 'Iob' + pio_latency = Param.Latency('1ns', "Programed IO latency in simticks") + class T1000(Platform): type = 'T1000' @@ -28,9 +32,6 @@ class T1000(Platform): ret_data64=0x0000000000000000, update_data=False) #warn_access="Accessing Memory Banks -- Unimplemented!") - fake_iob = IsaFake(pio_addr=0x9800000000, pio_size=0x100000000) - #warn_access="Accessing IOB -- Unimplemented!") - fake_jbi = IsaFake(pio_addr=0x8000000000, pio_size=0x100000000) #warn_access="Accessing JBI -- Unimplemented!") @@ -76,6 +77,13 @@ class T1000(Platform): pconsole = SimConsole() puart0 = Uart8250(pio_addr=0x1f10000000) + iob = Iob() + # Attach I/O devices that are on chip + def attachOnChipIO(self, bus): + self.iob.pio = bus.port + self.htod.pio = bus.port + + # Attach I/O devices to specified bus object. Can't do this # earlier, since the bus object itself is typically defined at the # System level. @@ -84,8 +92,6 @@ class T1000(Platform): self.puart0.sim_console = self.pconsole self.fake_clk.pio = bus.port self.fake_membnks.pio = bus.port - self.fake_iob.pio = bus.port - self.fake_jbi.pio = bus.port self.fake_l2_1.pio = bus.port self.fake_l2_2.pio = bus.port self.fake_l2_3.pio = bus.port @@ -95,6 +101,6 @@ class T1000(Platform): self.fake_l2esr_3.pio = bus.port self.fake_l2esr_4.pio = bus.port self.fake_ssi.pio = bus.port + self.fake_jbi.pio = bus.port self.puart0.pio = bus.port self.hvuart.pio = bus.port - self.htod.pio = bus.port diff --git a/src/python/m5/params.py b/src/python/m5/params.py index f8a9f9ddd..e71e1c3c5 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -894,9 +894,8 @@ class PortRef(object): if self.ccConnected: # already done this return peer = self.peer - internal.main.connectPorts(self.simobj.getCCObject(), self.name, - self.index, peer.simobj.getCCObject(), - peer.name, peer.index) + internal.sim_object.connectPorts(self.simobj.getCCObject(), self.name, + self.index, peer.simobj.getCCObject(), peer.name, peer.index) self.ccConnected = True peer.ccConnected = True diff --git a/src/python/m5/stats.py b/src/python/m5/stats.py new file mode 100644 index 000000000..041a3f58d --- /dev/null +++ b/src/python/m5/stats.py @@ -0,0 +1,46 @@ +# Copyright (c) 2007 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Nathan Binkert + +import internal + +from internal.stats import dump +from internal.stats import initSimStats +from internal.stats import reset +from internal.stats import StatEvent as event + +def initText(filename, desc=True, compat=True): + internal.stats.initText(filename, desc, compat) + +def initMySQL(host, database, user='', passwd='', project='test', name='test', + sample='0'): + if not user: + import getpass + user = getpass.getuser() + + internal.stats.initMySQL(host, database, user, passwd, project, name, + sample) diff --git a/src/python/swig/core.i b/src/python/swig/core.i new file mode 100644 index 000000000..116890763 --- /dev/null +++ b/src/python/swig/core.i @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + */ + +%module core + +%{ +#include "python/swig/pyobject.hh" + +#include "sim/core.hh" +#include "sim/host.hh" +#include "sim/startup.hh" + +extern const char *compileDate; +%} + +%include "std_string.i" + +void setOutputDir(const std::string &dir); +void loadIniFile(PyObject *); +void SimStartup(); +void doExitCleanup(); + +char *compileDate; + +%wrapper %{ +// fix up module name to reflect the fact that it's inside the m5 package +#undef SWIG_name +#define SWIG_name "m5.internal._core" +%} diff --git a/src/python/swig/event.i b/src/python/swig/event.i index 554c9fa0e..51d7d89f0 100644 --- a/src/python/swig/event.i +++ b/src/python/swig/event.i @@ -33,19 +33,48 @@ %{ #include "python/swig/pyevent.hh" -inline void -create(PyObject *object, Tick when) -{ - new PythonEvent(object, when); -} +#include "sim/sim_events.hh" +#include "sim/sim_exit.hh" +#include "sim/simulate.hh" %} %include "stdint.i" +%include "std_string.i" %include "sim/host.hh" -%inline %{ -extern void create(PyObject *object, Tick when); -%} +void create(PyObject *object, Tick when); + +class Event; +class CountedDrainEvent : public Event { + public: + void setCount(int _count); +}; + +CountedDrainEvent *createCountedDrain(); +void cleanupCountedDrain(Event *drain_event); + +%immutable curTick; +Tick curTick; + +// minimal definition of SimExitEvent interface to wrap +class SimLoopExitEvent { + public: + std::string getCause(); + int getCode(); + SimLoopExitEvent(EventQueue *q, Tick _when, Tick _repeat, + const std::string &_cause, int c = 0); +}; + +%exception simulate { + $action + if (!result) { + return NULL; + } +} +SimLoopExitEvent *simulate(Tick num_cycles = MaxTick); +void exitSimLoop(const std::string &message, int exit_code); + +Tick curTick; %wrapper %{ // fix up module name to reflect the fact that it's inside the m5 package diff --git a/src/python/swig/pyevent.hh b/src/python/swig/pyevent.hh index 16af85a84..65e80e9e4 100644 --- a/src/python/swig/pyevent.hh +++ b/src/python/swig/pyevent.hh @@ -32,6 +32,7 @@ #define __PYTHON_SWIG_PYEVENT_HH__ #include "sim/eventq.hh" +#include "sim/sim_events.hh" class PythonEvent : public Event { @@ -45,4 +46,29 @@ class PythonEvent : public Event virtual void process(); }; +inline void +create(PyObject *object, Tick when) +{ + new PythonEvent(object, when); +} + +inline Event * +createCountedDrain() +{ + return new CountedDrainEvent(); +} + +inline void +cleanupCountedDrain(Event *counted_drain) +{ + CountedDrainEvent *event = + dynamic_cast<CountedDrainEvent *>(counted_drain); + if (event == NULL) { + fatal("Called cleanupCountedDrain() on an event that was not " + "a CountedDrainEvent."); + } + assert(event->getCount() == 0); + delete event; +} + #endif // __PYTHON_SWIG_PYEVENT_HH__ diff --git a/src/python/swig/pyobject.cc b/src/python/swig/pyobject.cc new file mode 100644 index 000000000..11141fa84 --- /dev/null +++ b/src/python/swig/pyobject.cc @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#include <Python.h> + +#include <string> + +#include "base/inifile.hh" +#include "base/output.hh" +#include "mem/mem_object.hh" +#include "mem/port.hh" +#include "sim/builder.hh" +#include "sim/sim_object.hh" + +using namespace std; + +/** + * Look up a MemObject port. Helper function for connectPorts(). + */ +Port * +lookupPort(SimObject *so, const std::string &name, int i) +{ + MemObject *mo = dynamic_cast<MemObject *>(so); + if (mo == NULL) { + warn("error casting SimObject %s to MemObject", so->name()); + return NULL; + } + + Port *p = mo->getPort(name, i); + if (p == NULL) + warn("error looking up port %s on object %s", name, so->name()); + return p; +} + + +/** + * Connect the described MemObject ports. Called from Python via SWIG. + */ +int +connectPorts(SimObject *o1, const std::string &name1, int i1, + SimObject *o2, const std::string &name2, int i2) +{ + Port *p1 = lookupPort(o1, name1, i1); + Port *p2 = lookupPort(o2, name2, i2); + + if (p1 == NULL || p2 == NULL) { + warn("connectPorts: port lookup error"); + return 0; + } + + p1->setPeer(p2); + p2->setPeer(p1); + + return 1; +} + +inline IniFile & +inifile() +{ + static IniFile inifile; + return inifile; +} + +SimObject * +createSimObject(const string &name) +{ + return SimObjectClass::createObject(inifile(), name); +} + +/** + * Pointer to the Python function that maps names to SimObjects. + */ +PyObject *resolveFunc = NULL; + +/** + * Convert a pointer to the Python object that SWIG wraps around a C++ + * SimObject pointer back to the actual C++ pointer. See main.i. + */ +extern "C" SimObject *convertSwigSimObjectPtr(PyObject *); + +SimObject * +resolveSimObject(const string &name) +{ + PyObject *pyPtr = PyEval_CallFunction(resolveFunc, "(s)", name.c_str()); + if (pyPtr == NULL) { + PyErr_Print(); + panic("resolveSimObject: failure on call to Python for %s", name); + } + + SimObject *simObj = convertSwigSimObjectPtr(pyPtr); + if (simObj == NULL) + panic("resolveSimObject: failure on pointer conversion for %s", name); + + return simObj; +} + +/** + * Load config.ini into C++ database. Exported to Python via SWIG; + * invoked from m5.instantiate(). + */ +void +loadIniFile(PyObject *_resolveFunc) +{ + resolveFunc = _resolveFunc; + configStream = simout.find("config.out"); + + // The configuration database is now complete; start processing it. + inifile().load(simout.resolve("config.ini")); +} + diff --git a/src/python/swig/pyobject.hh b/src/python/swig/pyobject.hh new file mode 100644 index 000000000..d8efc9149 --- /dev/null +++ b/src/python/swig/pyobject.hh @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#include <Python.h> + +#include "cpu/base.hh" +#include "sim/host.hh" +#include "sim/serialize.hh" +#include "sim/sim_object.hh" +#include "sim/system.hh" + +SimObject *createSimObject(const std::string &name); +extern "C" SimObject *convertSwigSimObjectPtr(PyObject *); +SimObject *resolveSimObject(const std::string &name); +void loadIniFile(PyObject *_resolveFunc); + + +/** + * Connect the described MemObject ports. Called from Python via SWIG. + */ +int connectPorts(SimObject *o1, const std::string &name1, int i1, + SimObject *o2, const std::string &name2, int i2); + +inline BaseCPU * +convertToBaseCPUPtr(SimObject *obj) +{ + BaseCPU *ptr = dynamic_cast<BaseCPU *>(obj); + + if (ptr == NULL) + warn("Casting to BaseCPU pointer failed"); + return ptr; +} + +inline System * +convertToSystemPtr(SimObject *obj) +{ + System *ptr = dynamic_cast<System *>(obj); + + if (ptr == NULL) + warn("Casting to System pointer failed"); + return ptr; +} + +inline void +initAll() +{ + SimObject::initAll(); +} + +inline void +regAllStats() +{ + SimObject::regAllStats(); +} + +inline void +serializeAll(const std::string &cpt_dir) +{ + Serializable::serializeAll(cpt_dir); +} + +inline void +unserializeAll(const std::string &cpt_dir) +{ + Serializable::unserializeAll(cpt_dir); +} + diff --git a/src/python/swig/sim_object.i b/src/python/swig/sim_object.i new file mode 100644 index 000000000..b2af72c61 --- /dev/null +++ b/src/python/swig/sim_object.i @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +%module sim_object + +%{ +#include "python/swig/pyobject.hh" +%} + +// import these files for SWIG to wrap +%include "stdint.i" +%include "std_string.i" +%include "sim/host.hh" + +class BaseCPU; + +class SimObject { + public: + enum State { + Running, + Draining, + Drained + }; + + enum MemoryMode { + Invalid, + Atomic, + Timing + }; + + unsigned int drain(Event *drain_event); + void resume(); + void switchOut(); + void takeOverFrom(BaseCPU *cpu); + SimObject(const std::string &_name); +}; + +class System { + private: + System(); + public: + void setMemoryMode(SimObject::MemoryMode mode); +}; + +SimObject *createSimObject(const std::string &name); + +int connectPorts(SimObject *o1, const std::string &name1, int i1, + SimObject *o2, const std::string &name2, int i2); + +BaseCPU *convertToBaseCPUPtr(SimObject *obj); +System *convertToSystemPtr(SimObject *obj); + +void serializeAll(const std::string &cpt_dir); +void unserializeAll(const std::string &cpt_dir); + +void initAll(); +void regAllStats(); + +%wrapper %{ +// fix up module name to reflect the fact that it's inside the m5 package +#undef SWIG_name +#define SWIG_name "m5.internal._sim_object" + +// Convert a pointer to the Python object that SWIG wraps around a +// C++ SimObject pointer back to the actual C++ pointer. +SimObject * +convertSwigSimObjectPtr(PyObject *pyObj) +{ + SimObject *so; + if (SWIG_ConvertPtr(pyObj, (void **) &so, SWIGTYPE_p_SimObject, 0) == -1) + return NULL; + return so; +} +%} diff --git a/src/python/swig/stats.i b/src/python/swig/stats.i index d6b39c2cb..d36f82dbc 100644 --- a/src/python/swig/stats.i +++ b/src/python/swig/stats.i @@ -42,12 +42,13 @@ namespace Stats { void initSimStats(); void initText(const std::string &filename, bool desc=true, bool compat=true); -void initMySQL(std::string host, std::string database, std::string user = "", - std::string passwd = "", std::string name = "test", - std::string sample = "0", std::string project = "test"); +void initMySQL(std::string host, std::string database, std::string user, + std::string passwd, std::string project, std::string name, + std::string sample); void StatEvent(bool dump, bool reset, Tick when = curTick, Tick repeat = 0); +void check(); void dump(); void reset(); |