merge from head

--HG--
extra : convert_revision : 21f7afe2719c00744c0981212c1ee6e442238e01
This commit is contained in:
Steve Reinhardt 2007-08-03 03:51:30 -04:00
commit 3afc625975
23 changed files with 252 additions and 140 deletions

View file

@ -134,6 +134,9 @@ if len(bm) == 2:
drive_sys = makeSparcSystem(drive_mem_mode, bm[1]) drive_sys = makeSparcSystem(drive_mem_mode, bm[1])
drive_sys.cpu = DriveCPUClass(cpu_id=0) drive_sys.cpu = DriveCPUClass(cpu_id=0)
drive_sys.cpu.connectMemPorts(drive_sys.membus) drive_sys.cpu.connectMemPorts(drive_sys.membus)
if options.kernel is not None:
drive_sys.kernel = binary(options.kernel)
root = makeDualRoot(test_sys, drive_sys, options.etherdump) root = makeDualRoot(test_sys, drive_sys, options.etherdump)
elif len(bm) == 1: elif len(bm) == 1:
root = Root(system=test_sys) root = Root(system=test_sys)

View file

@ -64,7 +64,7 @@ if args:
process = LiveProcess() process = LiveProcess()
process.executable = options.cmd process.executable = options.cmd
process.cmd = options.cmd + " " + options.options process.cmd = [options.cmd] + options.options.split()
if options.input != "": if options.input != "":
process.input = options.input process.input = options.input

View file

@ -57,7 +57,7 @@ class ThreadInfo
* thread_info struct. So we can get the address by masking off * thread_info struct. So we can get the address by masking off
* the lower 14 bits. * the lower 14 bits.
*/ */
current = tc->readIntReg(TheISA::StackPointerReg) & ~0x3fff; current = tc->readIntReg(TheISA::StackPointerReg) & ~ULL(0x3fff);
return VPtr<thread_info>(tc, current); return VPtr<thread_info>(tc, current);
} }

View file

@ -73,7 +73,7 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
if (machInst.sib.base == INTREG_RBP && machInst.modRM.mod == 0) if (machInst.sib.base == INTREG_RBP && machInst.modRM.mod == 0)
base = NUM_INTREGS; base = NUM_INTREGS;
//In -this- special case, we don't use an index. //In -this- special case, we don't use an index.
if (machInst.sib.index == INTREG_RSP) if (index == INTREG_RSP)
index = NUM_INTREGS; index = NUM_INTREGS;
} else { } else {
if (machInst.addrSize == 2) { if (machInst.addrSize == 2) {
@ -82,11 +82,9 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
scale = 0; scale = 0;
base = machInst.modRM.rm | (machInst.rex.b << 3); base = machInst.modRM.rm | (machInst.rex.b << 3);
if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) { if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) {
base = NUM_INTREGS;
//Since we need to use a different encoding of this //Since we need to use a different encoding of this
//instruction anyway, just ignore the base in those cases //instruction anyway, just ignore the base in those cases
// if (machInst.mode.submode == SixtyFourBitMode) base = NUM_INTREGS;
// base = NUM_INTREGS+7;
} }
} }
} }

View file

@ -167,7 +167,7 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
filename = argv[0]; filename = argv[0];
//We want 16 byte alignment //We want 16 byte alignment
Addr alignmentMask = ~mask(4); uint64_t align = 16;
// load object file into target memory // load object file into target memory
objFile->loadSections(initVirtMem); objFile->loadSections(initVirtMem);
@ -285,47 +285,35 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
//Figure out how big the initial stack needs to be //Figure out how big the initial stack needs to be
// The unaccounted for 0 at the top of the stack // A sentry NULL void pointer at the top of the stack.
int mysterious_size = intSize; int sentry_size = intSize;
//This is the name of the file which is present on the initial stack //This is the name of the file which is present on the initial stack
//It's purpose is to let the user space linker examine the original file. //It's purpose is to let the user space linker examine the original file.
int file_name_size = filename.size(); int file_name_size = filename.size() + 1;
string platform = "x86_64"; string platform = "x86_64";
int aux_data_size = platform.size() + 1; int aux_data_size = platform.size() + 1;
int env_data_size = 0; int env_data_size = 0;
for (int i = 0; i < envp.size(); ++i) { for (int i = 0; i < envp.size(); ++i) {
env_data_size += envp[i].size(); env_data_size += envp[i].size() + 1;
} }
int arg_data_size = 0; int arg_data_size = 0;
for (int i = 0; i < argv.size(); ++i) { for (int i = 0; i < argv.size(); ++i) {
arg_data_size += argv[i].size(); arg_data_size += argv[i].size() + 1;
} }
//The auxiliary vector data needs to be padded so it's size is a multiple
//of the alignment mask.
int aux_padding =
((aux_data_size + ~alignmentMask) & alignmentMask) - aux_data_size;
//The info_block needs to be padded so it's size is a multiple of the //The info_block needs to be padded so it's size is a multiple of the
//alignment mask. Also, it appears that there needs to be at least some //alignment mask. Also, it appears that there needs to be at least some
//padding, so if the size is already a multiple, we need to increase it //padding, so if the size is already a multiple, we need to increase it
//anyway. //anyway.
int info_block_size = int base_info_block_size =
(mysterious_size + sentry_size + file_name_size + env_data_size + arg_data_size;
file_name_size +
env_data_size +
arg_data_size +
~alignmentMask) & alignmentMask;
int info_block_padding = int info_block_size = roundUp(base_info_block_size, align);
info_block_size -
mysterious_size - int info_block_padding = info_block_size - base_info_block_size;
file_name_size -
env_data_size -
arg_data_size;
//Each auxilliary vector is two 8 byte words //Each auxilliary vector is two 8 byte words
int aux_array_size = intSize * 2 * (auxv.size() + 1); int aux_array_size = intSize * 2 * (auxv.size() + 1);
@ -335,17 +323,27 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
int argc_size = intSize; int argc_size = intSize;
int space_needed = //Figure out the size of the contents of the actual initial frame
info_block_size + int frame_size =
aux_data_size +
aux_padding +
aux_array_size + aux_array_size +
envp_array_size + envp_array_size +
argv_array_size + argv_array_size +
argc_size; argc_size;
//There needs to be padding after the auxiliary vector data so that the
//very bottom of the stack is aligned properly.
int partial_size = frame_size + aux_data_size;
int aligned_partial_size = roundUp(partial_size, align);
int aux_padding = aligned_partial_size - partial_size;
int space_needed =
info_block_size +
aux_data_size +
aux_padding +
frame_size;
stack_min = stack_base - space_needed; stack_min = stack_base - space_needed;
stack_min &= alignmentMask; stack_min = roundDown(stack_min, align);
stack_size = stack_base - stack_min; stack_size = stack_base - stack_min;
// map memory // map memory
@ -353,11 +351,11 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
roundUp(stack_size, pageSize)); roundUp(stack_size, pageSize));
// map out initial stack contents // map out initial stack contents
Addr mysterious_base = stack_base - mysterious_size; Addr sentry_base = stack_base - sentry_size;
Addr file_name_base = mysterious_base - file_name_size; Addr file_name_base = sentry_base - file_name_size;
Addr env_data_base = file_name_base - env_data_size; Addr env_data_base = file_name_base - env_data_size;
Addr arg_data_base = env_data_base - arg_data_size; Addr arg_data_base = env_data_base - arg_data_size;
Addr aux_data_base = arg_data_base - aux_data_size - info_block_padding; Addr aux_data_base = arg_data_base - info_block_padding - aux_data_size;
Addr auxv_array_base = aux_data_base - aux_array_size - aux_padding; Addr auxv_array_base = aux_data_base - aux_array_size - aux_padding;
Addr envp_array_base = auxv_array_base - envp_array_size; Addr envp_array_base = auxv_array_base - envp_array_size;
Addr argv_array_base = envp_array_base - argv_array_size; Addr argv_array_base = envp_array_base - argv_array_size;
@ -380,10 +378,10 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
uint64_t argc = argv.size(); uint64_t argc = argv.size();
uint64_t guestArgc = TheISA::htog(argc); uint64_t guestArgc = TheISA::htog(argc);
//Write out the mysterious 0 //Write out the sentry void *
uint64_t mysterious_zero = 0; uint64_t sentry_NULL = 0;
initVirtMem->writeBlob(mysterious_base, initVirtMem->writeBlob(sentry_base,
(uint8_t*)&mysterious_zero, mysterious_size); (uint8_t*)&sentry_NULL, sentry_size);
//Write the file name //Write the file name
initVirtMem->writeString(file_name_base, filename.c_str()); initVirtMem->writeString(file_name_base, filename.c_str());

View file

@ -87,7 +87,7 @@ OutputDirectory::resolve(const string &name)
} }
ostream * ostream *
OutputDirectory::create(const string &name) OutputDirectory::create(const string &name, bool binary)
{ {
if (name == "cerr" || name == "stderr") if (name == "cerr" || name == "stderr")
return &cerr; return &cerr;
@ -95,7 +95,8 @@ OutputDirectory::create(const string &name)
if (name == "cout" || name == "stdout") if (name == "cout" || name == "stdout")
return &cout; return &cout;
ofstream *file = new ofstream(resolve(name).c_str(), ios::trunc); ofstream *file = new ofstream(resolve(name).c_str(),
ios::trunc | binary ? ios::binary : (ios::openmode)0);
if (!file->is_open()) if (!file->is_open())
panic("Cannot open file %s", name); panic("Cannot open file %s", name);

View file

@ -51,7 +51,7 @@ class OutputDirectory
const std::string &directory(); const std::string &directory();
std::string resolve(const std::string &name); std::string resolve(const std::string &name);
std::ostream *create(const std::string &name); std::ostream *create(const std::string &name, bool binary = false);
std::ostream *find(const std::string &name); std::ostream *find(const std::string &name);
static bool isFile(const std::ostream *os); static bool isFile(const std::ostream *os);

View file

@ -53,7 +53,6 @@ SwigSource('m5.internal', 'swig/core.i')
SwigSource('m5.internal', 'swig/debug.i') SwigSource('m5.internal', 'swig/debug.i')
SwigSource('m5.internal', 'swig/event.i') SwigSource('m5.internal', 'swig/event.i')
SwigSource('m5.internal', 'swig/random.i') SwigSource('m5.internal', 'swig/random.i')
SwigSource('m5.internal', 'swig/sim_object.i')
SwigSource('m5.internal', 'swig/stats.i') SwigSource('m5.internal', 'swig/stats.i')
SwigSource('m5.internal', 'swig/trace.i') SwigSource('m5.internal', 'swig/trace.i')
PySource('m5.internal', 'm5/internal/__init__.py') PySource('m5.internal', 'm5/internal/__init__.py')

View file

@ -274,17 +274,29 @@ class Generate(object):
print >>out print >>out
for obj in ordered_objs: for obj in ordered_objs:
code = 'class %s ' % obj.cxx_class if obj.swig_objdecls:
if str(obj) != 'SimObject': for decl in obj.swig_objdecls:
code += ': public %s ' % obj.__bases__[0] print >>out, decl
code += '{};' continue
code = ''
base = obj.get_base()
code += '// stop swig from creating/wrapping default ctor/dtor\n'
code += '%%nodefault %s;\n' % obj.cxx_class
code += 'class %s ' % obj.cxx_class
if base:
code += ': public %s' % base
code += ' {};\n'
klass = obj.cxx_class; klass = obj.cxx_class;
if hasattr(obj, 'cxx_namespace'): if hasattr(obj, 'cxx_namespace'):
code = 'namespace %s { %s }' % (obj.cxx_namespace, code) new_code = 'namespace %s {\n' % obj.cxx_namespace
new_code += code
new_code += '}\n'
code = new_code
klass = '%s::%s' % (obj.cxx_namespace, klass) klass = '%s::%s' % (obj.cxx_namespace, klass)
print >>out, '%%ignore %s;' % klass
print >>out, code print >>out, code
for obj in ordered_objs: for obj in ordered_objs:

View file

@ -128,6 +128,7 @@ class MetaSimObject(type):
'cxx_class' : types.StringType, 'cxx_class' : types.StringType,
'cxx_type' : types.StringType, 'cxx_type' : types.StringType,
'cxx_predecls' : types.ListType, 'cxx_predecls' : types.ListType,
'swig_objdecls' : types.ListType,
'swig_predecls' : types.ListType, 'swig_predecls' : types.ListType,
'type' : types.StringType } 'type' : types.StringType }
# Attributes that can be set any time # Attributes that can be set any time
@ -225,6 +226,9 @@ class MetaSimObject(type):
cls._value_dict['swig_predecls'] = \ cls._value_dict['swig_predecls'] = \
cls._value_dict['cxx_predecls'] cls._value_dict['cxx_predecls']
if 'swig_objdecls' not in cls._value_dict:
cls._value_dict['swig_objdecls'] = []
# Now process the _value_dict items. They could be defining # Now process the _value_dict items. They could be defining
# new (or overriding existing) parameters or ports, setting # new (or overriding existing) parameters or ports, setting
# class keywords (e.g., 'abstract'), or setting parameter # class keywords (e.g., 'abstract'), or setting parameter
@ -345,12 +349,13 @@ class MetaSimObject(type):
def __str__(cls): def __str__(cls):
return cls.__name__ return cls.__name__
def cxx_decl(cls): def get_base(cls):
if str(cls) != 'SimObject': if str(cls) == 'SimObject':
base = cls.__bases__[0].type return None
else:
base = None
return cls.__bases__[0].type
def cxx_decl(cls):
code = "#ifndef __PARAMS__%s\n" % cls code = "#ifndef __PARAMS__%s\n" % cls
code += "#define __PARAMS__%s\n\n" % cls code += "#define __PARAMS__%s\n\n" % cls
@ -380,6 +385,7 @@ class MetaSimObject(type):
code += "\n".join(predecls2) code += "\n".join(predecls2)
code += "\n\n"; code += "\n\n";
base = cls.get_base()
if base: if base:
code += '#include "params/%s.hh"\n\n' % base code += '#include "params/%s.hh"\n\n' % base
@ -408,11 +414,7 @@ class MetaSimObject(type):
return code return code
def cxx_type_decl(cls): def cxx_type_decl(cls):
if str(cls) != 'SimObject': base = cls.get_base()
base = cls.__bases__[0]
else:
base = None
code = '' code = ''
if base: if base:
@ -427,17 +429,14 @@ class MetaSimObject(type):
return code return code
def swig_decl(cls): def swig_decl(cls):
base = cls.get_base()
code = '%%module %s\n' % cls code = '%%module %s\n' % cls
code += '%{\n' code += '%{\n'
code += '#include "params/%s.hh"\n' % cls code += '#include "params/%s.hh"\n' % cls
code += '%}\n\n' code += '%}\n\n'
if str(cls) != 'SimObject':
base = cls.__bases__[0]
else:
base = None
# The 'dict' attribute restricts us to the params declared in # The 'dict' attribute restricts us to the params declared in
# the object itself, not including inherited params (which # the object itself, not including inherited params (which
# will also be inherited from the base class's param struct # will also be inherited from the base class's param struct
@ -483,6 +482,7 @@ class SimObject(object):
abstract = True abstract = True
name = Param.String("Object name") name = Param.String("Object name")
swig_objdecls = [ '%include "python/swig/sim_object.i"' ]
# Initialize new instance. For objects with SimObject-valued # Initialize new instance. For objects with SimObject-valued
# children, we need to recursively clone the classes represented # children, we need to recursively clone the classes represented
@ -792,7 +792,6 @@ class SimObject(object):
# necessary to construct it. Does *not* recursively create # necessary to construct it. Does *not* recursively create
# children. # children.
def getCCObject(self): def getCCObject(self):
import internal
params = self.getCCParams() params = self.getCCParams()
if not self._ccObject: if not self._ccObject:
self._ccObject = -1 # flag to catch cycles in recursion self._ccObject = -1 # flag to catch cycles in recursion
@ -840,24 +839,19 @@ class SimObject(object):
if not isinstance(self, m5.objects.System): if not isinstance(self, m5.objects.System):
return None return None
system_ptr = internal.sim_object.convertToSystemPtr(self._ccObject) return self._ccObject.getMemoryMode()
return system_ptr.getMemoryMode()
def changeTiming(self, mode): def changeTiming(self, mode):
import internal
if isinstance(self, m5.objects.System): if isinstance(self, m5.objects.System):
# i don't know if there's a better way to do this - calling # i don't know if there's a better way to do this - calling
# setMemoryMode directly from self._ccObject results in calling # setMemoryMode directly from self._ccObject results in calling
# SimObject::setMemoryMode, not the System::setMemoryMode # SimObject::setMemoryMode, not the System::setMemoryMode
system_ptr = internal.sim_object.convertToSystemPtr(self._ccObject) self._ccObject.setMemoryMode(mode)
system_ptr.setMemoryMode(mode)
for child in self._children.itervalues(): for child in self._children.itervalues():
child.changeTiming(mode) child.changeTiming(mode)
def takeOverFrom(self, old_cpu): def takeOverFrom(self, old_cpu):
import internal self._ccObject.takeOverFrom(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. # generate output file for 'dot' to display as a pretty graph.
# this code is currently broken. # this code is currently broken.

View file

@ -81,11 +81,6 @@ try:
except ImportError: except ImportError:
running_m5 = False running_m5 = False
if running_m5:
from event import *
from simulate import *
from main import options
if running_m5: if running_m5:
import defines import defines
build_env.update(defines.m5_build_env) build_env.update(defines.m5_build_env)
@ -93,6 +88,11 @@ else:
import __scons import __scons
build_env.update(__scons.m5_build_env) build_env.update(__scons.m5_build_env)
if running_m5:
from event import *
from simulate import *
from main import options
import SimObject import SimObject
import params import params
import objects import objects

View file

@ -30,6 +30,5 @@ import core
import debug import debug
import event import event
import random import random
import sim_object
import stats import stats
import trace import trace

View file

@ -26,9 +26,15 @@
# #
# Authors: Nathan Binkert # Authors: Nathan Binkert
import code, optparse, os, socket, sys import code
from datetime import datetime import datetime
import optparse
import os
import socket
import sys
from attrdict import attrdict from attrdict import attrdict
import defines
import traceflags import traceflags
__all__ = [ 'options', 'arguments', 'main' ] __all__ = [ 'options', 'arguments', 'main' ]
@ -116,6 +122,8 @@ def bool_option(name, default, help):
# Help options # Help options
add_option('-A', "--authors", action="store_true", default=False, add_option('-A', "--authors", action="store_true", default=False,
help="Show author information") help="Show author information")
add_option('-B', "--build-info", action="store_true", default=False,
help="Show build information")
add_option('-C', "--copyright", action="store_true", default=False, add_option('-C', "--copyright", action="store_true", default=False,
help="Show full copyright information") help="Show full copyright information")
add_option('-R', "--readme", action="store_true", default=False, add_option('-R', "--readme", action="store_true", default=False,
@ -195,6 +203,22 @@ def main():
parse_args() parse_args()
done = False done = False
if options.build_info:
done = True
print 'Build information:'
print
print 'compiled %s' % internal.core.cvar.compileDate;
print 'started %s' % datetime.datetime.now().ctime()
print 'executing on %s' % socket.gethostname()
print 'build options:'
keys = defines.m5_build_env.keys()
keys.sort()
for key in keys:
val = defines.m5_build_env[key]
print ' %s = %s' % (key, val)
print
if options.copyright: if options.copyright:
done = True done = True
print info.LICENSE print info.LICENSE
@ -242,7 +266,7 @@ def main():
print brief_copyright print brief_copyright
print print
print "M5 compiled %s" % internal.core.cvar.compileDate; print "M5 compiled %s" % internal.core.cvar.compileDate;
print "M5 started %s" % datetime.now().ctime() print "M5 started %s" % datetime.datetime.now().ctime()
print "M5 executing on %s" % socket.gethostname() print "M5 executing on %s" % socket.gethostname()
print "command line:", print "command line:",
for argv in sys.argv: for argv in sys.argv:

View file

@ -1025,13 +1025,13 @@ class PortRef(object):
# Call C++ to create corresponding port connection between C++ objects # Call C++ to create corresponding port connection between C++ objects
def ccConnect(self): def ccConnect(self):
import internal from m5.objects.params import connectPorts
if self.ccConnected: # already done this if self.ccConnected: # already done this
return return
peer = self.peer peer = self.peer
internal.sim_object.connectPorts(self.simobj.getCCObject(), self.name, connectPorts(self.simobj.getCCObject(), self.name, self.index,
self.index, peer.simobj.getCCObject(), peer.name, peer.index) peer.simobj.getCCObject(), peer.name, peer.index)
self.ccConnected = True self.ccConnected = True
peer.ccConnected = True peer.ccConnected = True

View file

@ -36,6 +36,7 @@ import internal
from main import options from main import options
import SimObject import SimObject
import ticks import ticks
import objects
# The final hook to generate .ini files. Called from the user script # The final hook to generate .ini files. Called from the user script
# once the config is built. # once the config is built.
@ -58,10 +59,10 @@ def instantiate(root):
root.connectPorts() root.connectPorts()
# Do a second pass to finish initializing the sim objects # Do a second pass to finish initializing the sim objects
internal.sim_object.initAll() internal.core.initAll()
# Do a third pass to initialize statistics # Do a third pass to initialize statistics
internal.sim_object.regAllStats() internal.core.regAllStats()
# Check to make sure that the stats package is properly initialized # Check to make sure that the stats package is properly initialized
internal.stats.check() internal.stats.check()
@ -135,32 +136,32 @@ def checkpoint(root, dir):
raise TypeError, "Checkpoint must be called on a root object." raise TypeError, "Checkpoint must be called on a root object."
doDrain(root) doDrain(root)
print "Writing checkpoint" print "Writing checkpoint"
internal.sim_object.serializeAll(dir) internal.core.serializeAll(dir)
resume(root) resume(root)
def restoreCheckpoint(root, dir): def restoreCheckpoint(root, dir):
print "Restoring from checkpoint" print "Restoring from checkpoint"
internal.sim_object.unserializeAll(dir) internal.core.unserializeAll(dir)
need_resume.append(root) need_resume.append(root)
def changeToAtomic(system): def changeToAtomic(system):
if not isinstance(system, (objects.Root, objects.System)): if not isinstance(system, (objects.Root, objects.System)):
raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \ raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \
(type(system), objects.Root, objects.System) (type(system), objects.Root, objects.System)
if system.getMemoryMode() != internal.sim_object.SimObject.Atomic: if system.getMemoryMode() != objects.params.SimObject.Atomic:
doDrain(system) doDrain(system)
print "Changing memory mode to atomic" print "Changing memory mode to atomic"
system.changeTiming(internal.sim_object.SimObject.Atomic) system.changeTiming(objects.params.SimObject.Atomic)
def changeToTiming(system): def changeToTiming(system):
if not isinstance(system, (objects.Root, objects.System)): if not isinstance(system, (objects.Root, objects.System)):
raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \ raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \
(type(system), objects.Root, objects.System) (type(system), objects.Root, objects.System)
if system.getMemoryMode() != internal.sim_object.SimObject.Timing: if system.getMemoryMode() != objects.params.SimObject.Timing:
doDrain(system) doDrain(system)
print "Changing memory mode to timing" print "Changing memory mode to timing"
system.changeTiming(internal.sim_object.SimObject.Timing) system.changeTiming(objects.params.SimObject.Timing)
def switchCpus(cpuList): def switchCpus(cpuList):
print "switching cpus" print "switching cpus"

View file

@ -58,6 +58,12 @@ void setClockFrequency(Tick ticksPerSecond);
%immutable curTick; %immutable curTick;
Tick curTick; Tick curTick;
void serializeAll(const std::string &cpt_dir);
void unserializeAll(const std::string &cpt_dir);
void initAll();
void regAllStats();
%wrapper %{ %wrapper %{
// fix up module name to reflect the fact that it's inside the m5 package // fix up module name to reflect the fact that it's inside the m5 package
#undef SWIG_name #undef SWIG_name

View file

@ -47,26 +47,6 @@ void loadIniFile(PyObject *_resolveFunc);
int connectPorts(SimObject *o1, const std::string &name1, int i1, int connectPorts(SimObject *o1, const std::string &name1, int i1,
SimObject *o2, const std::string &name2, int i2); 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 inline void
initAll() initAll()
{ {

View file

@ -31,7 +31,6 @@
%module sim_object %module sim_object
%{ %{
#include "enums/MemoryMode.hh"
#include "python/swig/pyobject.hh" #include "python/swig/pyobject.hh"
%} %}
@ -57,31 +56,10 @@ class SimObject {
SimObject(const std::string &_name); SimObject(const std::string &_name);
}; };
class System {
private:
System();
public:
Enums::MemoryMode getMemoryMode();
void setMemoryMode(Enums::MemoryMode mode);
};
int connectPorts(SimObject *o1, const std::string &name1, int i1, int connectPorts(SimObject *o1, const std::string &name1, int i1,
SimObject *o2, const std::string &name2, int i2); 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 %{ %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 // Convert a pointer to the Python object that SWIG wraps around a
// C++ SimObject pointer back to the actual C++ pointer. // C++ SimObject pointer back to the actual C++ pointer.
SimObject * SimObject *

43
src/python/swig/system.i Normal file
View file

@ -0,0 +1,43 @@
/*
* 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 "enums/MemoryMode.hh"
class System : public SimObject
{
private:
System();
public:
Enums::MemoryMode getMemoryMode();
void setMemoryMode(Enums::MemoryMode mode);
};

View file

@ -36,6 +36,8 @@ class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing']
class System(SimObject): class System(SimObject):
type = 'System' type = 'System'
swig_objdecls = [ '%include "python/swig/system.i"' ]
physmem = Param.PhysicalMemory(Parent.any, "phsyical memory") physmem = Param.PhysicalMemory(Parent.any, "phsyical memory")
mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in")
if build_env['FULL_SYSTEM']: if build_env['FULL_SYSTEM']:

View file

@ -178,6 +178,22 @@ paramOut(ostream &os, const std::string &name, const T &param)
os << "\n"; os << "\n";
} }
template <class T>
void
arrayParamOut(ostream &os, const std::string &name,
const std::vector<T> &param)
{
int size = param.size();
os << name << "=";
if (size > 0)
showParam(os, param[0]);
for (int i = 1; i < size; ++i) {
os << " ";
showParam(os, param[i]);
}
os << "\n";
}
template <class T> template <class T>
void void
@ -251,6 +267,49 @@ arrayParamIn(Checkpoint *cp, const std::string &section,
} }
} }
template <class T>
void
arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, std::vector<T> &param)
{
std::string str;
if (!cp->find(section, name, str)) {
fatal("Can't unserialize '%s:%s'\n", section, name);
}
// code below stolen from VectorParam<T>::parse().
// it would be nice to unify these somehow...
vector<string> tokens;
tokenize(tokens, str, ' ');
// Need this if we were doing a vector
// value.resize(tokens.size());
param.resize(tokens.size());
for (int i = 0; i < tokens.size(); i++) {
// need to parse into local variable to handle vector<bool>,
// for which operator[] returns a special reference class
// that's not the same as 'bool&', (since it's a packed
// vector)
T scalar_value;
if (!parseParam(tokens[i], scalar_value)) {
string err("could not parse \"");
err += str;
err += "\"";
fatal(err);
}
// assign parsed value to vector
param[i] = scalar_value;
}
}
void void
objParamIn(Checkpoint *cp, const std::string &section, objParamIn(Checkpoint *cp, const std::string &section,
@ -273,7 +332,13 @@ arrayParamOut(ostream &os, const std::string &name, \
type const *param, int size); \ type const *param, int size); \
template void \ template void \
arrayParamIn(Checkpoint *cp, const std::string &section, \ arrayParamIn(Checkpoint *cp, const std::string &section, \
const std::string &name, type *param, int size); const std::string &name, type *param, int size); \
template void \
arrayParamOut(ostream &os, const std::string &name, \
const std::vector<type> &param); \
template void \
arrayParamIn(Checkpoint *cp, const std::string &section, \
const std::string &name, std::vector<type> &param);
INSTANTIATE_PARAM_TEMPLATES(signed char) INSTANTIATE_PARAM_TEMPLATES(signed char)
INSTANTIATE_PARAM_TEMPLATES(unsigned char) INSTANTIATE_PARAM_TEMPLATES(unsigned char)
@ -358,7 +423,6 @@ Serializable::unserializeAll(const std::string &cpt_dir)
dir); dir);
Checkpoint *cp = new Checkpoint(dir, section); Checkpoint *cp = new Checkpoint(dir, section);
unserializeGlobals(cp); unserializeGlobals(cp);
SimObject::unserializeAll(cp); SimObject::unserializeAll(cp);
} }

View file

@ -39,6 +39,7 @@
#include <list> #include <list>
#include <vector>
#include <iostream> #include <iostream>
#include <map> #include <map>
@ -60,10 +61,18 @@ template <class T>
void arrayParamOut(std::ostream &os, const std::string &name, void arrayParamOut(std::ostream &os, const std::string &name,
const T *param, int size); const T *param, int size);
template <class T>
void arrayParamOut(std::ostream &os, const std::string &name,
const std::vector<T> &param);
template <class T> template <class T>
void arrayParamIn(Checkpoint *cp, const std::string &section, void arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, T *param, int size); const std::string &name, T *param, int size);
template <class T>
void arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, std::vector<T> &param);
void void
objParamIn(Checkpoint *cp, const std::string &section, objParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, SimObject * &param); const std::string &name, SimObject * &param);

View file

@ -72,7 +72,8 @@ System::System(Params *p)
#if FULL_SYSTEM #if FULL_SYSTEM
kernelSymtab = new SymbolTable; kernelSymtab = new SymbolTable;
debugSymbolTable = new SymbolTable; if (!debugSymbolTable)
debugSymbolTable = new SymbolTable;
/** /**