From 456a4570c148759bc229d0295899d4b67b374786 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 1 Aug 2007 17:39:16 -0400 Subject: Configuration: Update the drive systems kernel as well as the testsys kernel with cmd line option. --HG-- extra : convert_revision : 5dfb0db65452c0b7aa3e2dc2a0209e3f8e23811f --- configs/example/fs.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/example/fs.py b/configs/example/fs.py index 76c12bd9e..e772a3ab1 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -134,6 +134,9 @@ if len(bm) == 2: drive_sys = makeSparcSystem(drive_mem_mode, bm[1]) drive_sys.cpu = DriveCPUClass(cpu_id=0) 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) elif len(bm) == 1: root = Root(system=test_sys) -- cgit v1.2.3 From e719a3e4c058920fb5913a38fbe4976d53a0e6e2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Aug 2007 18:19:23 -0700 Subject: Fix how the "cmd" parameter is set in se.py and remove hack in x86 process initialization code. --HG-- extra : convert_revision : 1fc741eea956ebfa4cef488eef4333d1f50617a6 --- configs/example/se.py | 2 +- src/arch/x86/process.cc | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/configs/example/se.py b/configs/example/se.py index b294480f6..20fe75a21 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -64,7 +64,7 @@ if args: process = LiveProcess() process.executable = options.cmd -process.cmd = options.cmd + " " + options.options +process.cmd = [options.cmd] + options.options.split() if options.input != "": process.input = options.input diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 17904cb33..afe41cdeb 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -290,18 +290,19 @@ X86LiveProcess::argsInit(int intSize, int pageSize) //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. - int file_name_size = filename.size(); + int file_name_size = filename.size() + 1; string platform = "x86_64"; int aux_data_size = platform.size() + 1; int env_data_size = 0; 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; for (int i = 0; i < argv.size(); ++i) { - arg_data_size += argv[i].size(); + warn("Argv[%d] size is %d\n", i, argv[i].size() + 1); + arg_data_size += argv[i].size() + 1; } //The auxiliary vector data needs to be padded so it's size is a multiple -- cgit v1.2.3 From 970261f9ceeded02162760365ce08c8d1fd4b506 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 2 Aug 2007 14:32:20 -0400 Subject: debugSymbolTable is a global variable and only needs to be created once, not once per system --HG-- extra : convert_revision : 43cbfd1a58d7d728898cbfae0d7f7d9960eba178 --- src/sim/system.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sim/system.cc b/src/sim/system.cc index 3c4746e93..eb0655aa5 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -72,7 +72,8 @@ System::System(Params *p) #if FULL_SYSTEM kernelSymtab = new SymbolTable; - debugSymbolTable = new SymbolTable; + if (!debugSymbolTable) + debugSymbolTable = new SymbolTable; /** -- cgit v1.2.3 From acb91c2dfa19dadc4549b2e0fced42b2a8bce34f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 2 Aug 2007 14:34:58 -0400 Subject: Linux Support: make sure that when we get the stack page for thread info we're doing a 64bit not --HG-- extra : convert_revision : c581921dd601fc72fd2d45b961c7440755b0331c --- src/arch/alpha/linux/threadinfo.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/alpha/linux/threadinfo.hh b/src/arch/alpha/linux/threadinfo.hh index caeb69f15..b9ffe02ae 100644 --- a/src/arch/alpha/linux/threadinfo.hh +++ b/src/arch/alpha/linux/threadinfo.hh @@ -57,7 +57,7 @@ class ThreadInfo * thread_info struct. So we can get the address by masking off * the lower 14 bits. */ - current = tc->readIntReg(TheISA::StackPointerReg) & ~0x3fff; + current = tc->readIntReg(TheISA::StackPointerReg) & ~ULL(0x3fff); return VPtr(tc, current); } -- cgit v1.2.3 From c4e026daf4f22481d20c6f63d76ad23d5b65af45 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 2 Aug 2007 14:40:56 -0400 Subject: Output: Make OutputDirectory::create() be able to create binary files. --HG-- extra : convert_revision : eae114ee5f27bb8b319df705d9b39bded185b8e8 --- src/base/output.cc | 5 +++-- src/base/output.hh | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/base/output.cc b/src/base/output.cc index afcac03a5..9d02a4a71 100644 --- a/src/base/output.cc +++ b/src/base/output.cc @@ -87,7 +87,7 @@ OutputDirectory::resolve(const string &name) } ostream * -OutputDirectory::create(const string &name) +OutputDirectory::create(const string &name, bool binary) { if (name == "cerr" || name == "stderr") return &cerr; @@ -95,7 +95,8 @@ OutputDirectory::create(const string &name) if (name == "cout" || name == "stdout") 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()) panic("Cannot open file %s", name); diff --git a/src/base/output.hh b/src/base/output.hh index 0aae4ae81..5de0c4005 100644 --- a/src/base/output.hh +++ b/src/base/output.hh @@ -51,7 +51,7 @@ class OutputDirectory const std::string &directory(); 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); static bool isFile(const std::ostream *os); -- cgit v1.2.3 From da5f62af7bdc4a0a6c8da1eee61b0ecb1a7212b4 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 2 Aug 2007 14:43:27 -0400 Subject: Serialization: Provide array serialization methods that work on std::vector --HG-- extra : convert_revision : aecdf1a7e50edbb12921991cc81df1b431ce8b38 --- src/sim/serialize.cc | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/sim/serialize.hh | 9 +++++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index a01e053b9..a7f81d5fb 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -40,6 +40,7 @@ #include #include +#include "base/annotate.hh" #include "base/inifile.hh" #include "base/misc.hh" #include "base/output.hh" @@ -178,6 +179,22 @@ paramOut(ostream &os, const std::string &name, const T ¶m) os << "\n"; } +template +void +arrayParamOut(ostream &os, const std::string &name, + const std::vector ¶m) +{ + 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 void @@ -251,6 +268,49 @@ arrayParamIn(Checkpoint *cp, const std::string §ion, } } +template +void +arrayParamIn(Checkpoint *cp, const std::string §ion, + const std::string &name, std::vector ¶m) +{ + std::string str; + if (!cp->find(section, name, str)) { + fatal("Can't unserialize '%s:%s'\n", section, name); + } + + // code below stolen from VectorParam::parse(). + // it would be nice to unify these somehow... + + vector 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, + // 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 objParamIn(Checkpoint *cp, const std::string §ion, @@ -273,7 +333,13 @@ arrayParamOut(ostream &os, const std::string &name, \ type const *param, int size); \ template void \ arrayParamIn(Checkpoint *cp, const std::string §ion, \ - 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 ¶m); \ +template void \ +arrayParamIn(Checkpoint *cp, const std::string §ion, \ + const std::string &name, std::vector ¶m); INSTANTIATE_PARAM_TEMPLATES(signed char) INSTANTIATE_PARAM_TEMPLATES(unsigned char) @@ -343,6 +409,7 @@ Serializable::serializeAll(const std::string &cpt_dir) outstream << "// checkpoint generated: " << ctime(&t); globals.serialize(outstream); + Annotate::annotations.serialize(outstream); SimObject::serializeAll(outstream); } @@ -358,7 +425,7 @@ Serializable::unserializeAll(const std::string &cpt_dir) dir); Checkpoint *cp = new Checkpoint(dir, section); unserializeGlobals(cp); - + Annotate::annotations.unserialize(cp); SimObject::unserializeAll(cp); } diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index 43cd4ecf4..e72eedb30 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -39,6 +39,7 @@ #include +#include #include #include @@ -60,10 +61,18 @@ template void arrayParamOut(std::ostream &os, const std::string &name, const T *param, int size); +template +void arrayParamOut(std::ostream &os, const std::string &name, + const std::vector ¶m); + template void arrayParamIn(Checkpoint *cp, const std::string §ion, const std::string &name, T *param, int size); +template +void arrayParamIn(Checkpoint *cp, const std::string §ion, + const std::string &name, std::vector ¶m); + void objParamIn(Checkpoint *cp, const std::string §ion, const std::string &name, SimObject * ¶m); -- cgit v1.2.3 From 5682f4f7f98f3ea98ea0b0290f859f55ed0ff45f Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 2 Aug 2007 11:59:02 -0700 Subject: main: expose the build information as a simple command line parameter --HG-- extra : convert_revision : 69189c4a2e9fa9290fe51a2a43a2b08e712c395d --- src/python/m5/main.py | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/python/m5/main.py b/src/python/m5/main.py index 1695ed75f..96f017cb0 100644 --- a/src/python/m5/main.py +++ b/src/python/m5/main.py @@ -26,9 +26,15 @@ # # Authors: Nathan Binkert -import code, optparse, os, socket, sys -from datetime import datetime +import code +import datetime +import optparse +import os +import socket +import sys + from attrdict import attrdict +import defines import traceflags __all__ = [ 'options', 'arguments', 'main' ] @@ -116,6 +122,8 @@ def bool_option(name, default, help): # Help options add_option('-A', "--authors", action="store_true", default=False, 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, help="Show full copyright information") add_option('-R', "--readme", action="store_true", default=False, @@ -195,6 +203,22 @@ def main(): parse_args() 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: done = True print info.LICENSE @@ -242,7 +266,7 @@ def main(): print brief_copyright print 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 "command line:", for argv in sys.argv: -- cgit v1.2.3 From dfa147a70ac87cdc5804993a0b39dfb8bb4cfa1b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 2 Aug 2007 12:03:35 -0700 Subject: python: need to import objects to make some calls work --HG-- extra : convert_revision : b5eec971d76626b2f42448052ab2cb2acb652d1b --- src/python/m5/simulate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py index 1ef78d6cb..ba9fb7899 100644 --- a/src/python/m5/simulate.py +++ b/src/python/m5/simulate.py @@ -36,6 +36,7 @@ import internal from main import options import SimObject import ticks +import objects # The final hook to generate .ini files. Called from the user script # once the config is built. -- cgit v1.2.3 From b3674749168dd4823795644b1bb820ce2876a615 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 2 Aug 2007 14:12:53 -0700 Subject: python: fix m5.build_env variable. As it is now, some objects will get the incorrect value depending where they were defined. --HG-- extra : convert_revision : a11a14842f9524739cbf54a48be6ec051f371200 --- src/python/m5/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/python/m5/__init__.py b/src/python/m5/__init__.py index 36f2eba61..96cb2ca13 100644 --- a/src/python/m5/__init__.py +++ b/src/python/m5/__init__.py @@ -81,11 +81,6 @@ try: except ImportError: running_m5 = False -if running_m5: - from event import * - from simulate import * - from main import options - if running_m5: import defines build_env.update(defines.m5_build_env) @@ -93,6 +88,11 @@ else: import __scons build_env.update(__scons.m5_build_env) +if running_m5: + from event import * + from simulate import * + from main import options + import SimObject import params import objects -- cgit v1.2.3 From 85b661e35d82cea3c5edd27f111cffbd4ee47f4b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 2 Aug 2007 15:09:12 -0700 Subject: X86: Fix special case with SIB index register and REX prefix. --HG-- extra : convert_revision : b305708a722f2a08cb55c4548c5616fcbe6c5d68 --- src/arch/x86/emulenv.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/arch/x86/emulenv.cc b/src/arch/x86/emulenv.cc index 3a54d7365..28282dc7a 100644 --- a/src/arch/x86/emulenv.cc +++ b/src/arch/x86/emulenv.cc @@ -73,7 +73,7 @@ void EmulEnv::doModRM(const ExtMachInst & machInst) if (machInst.sib.base == INTREG_RBP && machInst.modRM.mod == 0) base = NUM_INTREGS; //In -this- special case, we don't use an index. - if (machInst.sib.index == INTREG_RSP) + if (index == INTREG_RSP) index = NUM_INTREGS; } else { if (machInst.addrSize == 2) { @@ -82,11 +82,9 @@ void EmulEnv::doModRM(const ExtMachInst & machInst) scale = 0; base = machInst.modRM.rm | (machInst.rex.b << 3); if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) { - base = NUM_INTREGS; //Since we need to use a different encoding of this //instruction anyway, just ignore the base in those cases -// if (machInst.mode.submode == SixtyFourBitMode) -// base = NUM_INTREGS+7; + base = NUM_INTREGS; } } } -- cgit v1.2.3 From 4af5740afdbd10fc4e8f9370d7b5ad49642c20e4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 2 Aug 2007 15:12:18 -0700 Subject: X86: Finally get the x86 initial stack frame right. After very carefully reading through the Linux source, I'm pretty confident I now know -exactly- how the initial stack frame is constructed, filled, and aligned. --HG-- extra : convert_revision : 3c654ade7e458bdd5445026860f11175f383a65f --- src/arch/x86/process.cc | 68 ++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index afe41cdeb..ce5828a1d 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -167,7 +167,7 @@ X86LiveProcess::argsInit(int intSize, int pageSize) filename = argv[0]; //We want 16 byte alignment - Addr alignmentMask = ~mask(4); + uint64_t align = 16; // load object file into target memory objFile->loadSections(initVirtMem); @@ -285,8 +285,8 @@ X86LiveProcess::argsInit(int intSize, int pageSize) //Figure out how big the initial stack needs to be - // The unaccounted for 0 at the top of the stack - int mysterious_size = intSize; + // A sentry NULL void pointer at the top of the stack. + int sentry_size = intSize; //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. @@ -301,32 +301,19 @@ X86LiveProcess::argsInit(int intSize, int pageSize) } int arg_data_size = 0; for (int i = 0; i < argv.size(); ++i) { - warn("Argv[%d] size is %d\n", i, argv[i].size() + 1); 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 //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 //anyway. - int info_block_size = - (mysterious_size + - file_name_size + - env_data_size + - arg_data_size + - ~alignmentMask) & alignmentMask; - - int info_block_padding = - info_block_size - - mysterious_size - - file_name_size - - env_data_size - - arg_data_size; + int base_info_block_size = + sentry_size + file_name_size + env_data_size + arg_data_size; + + int info_block_size = roundUp(base_info_block_size, align); + + int info_block_padding = info_block_size - base_info_block_size; //Each auxilliary vector is two 8 byte words int aux_array_size = intSize * 2 * (auxv.size() + 1); @@ -336,17 +323,30 @@ X86LiveProcess::argsInit(int intSize, int pageSize) int argc_size = intSize; - int space_needed = - info_block_size + - aux_data_size + - aux_padding + + //Figure out the size of the contents of the actual initial frame + int frame_size = aux_array_size + envp_array_size + argv_array_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; + warn("The partial size is %d.\n", partial_size); + int aligned_partial_size = roundUp(partial_size, align); + warn("The aligned partial size is %d.\n", aligned_partial_size); + int aux_padding = aligned_partial_size - partial_size; + warn("The padding is %d.\n", aux_padding); + + int space_needed = + info_block_size + + aux_data_size + + aux_padding + + frame_size; + stack_min = stack_base - space_needed; - stack_min &= alignmentMask; + stack_min = roundDown(stack_min, align); stack_size = stack_base - stack_min; // map memory @@ -354,11 +354,11 @@ X86LiveProcess::argsInit(int intSize, int pageSize) roundUp(stack_size, pageSize)); // map out initial stack contents - Addr mysterious_base = stack_base - mysterious_size; - Addr file_name_base = mysterious_base - file_name_size; + Addr sentry_base = stack_base - sentry_size; + Addr file_name_base = sentry_base - file_name_size; Addr env_data_base = file_name_base - env_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 envp_array_base = auxv_array_base - envp_array_size; Addr argv_array_base = envp_array_base - argv_array_size; @@ -381,10 +381,10 @@ X86LiveProcess::argsInit(int intSize, int pageSize) uint64_t argc = argv.size(); uint64_t guestArgc = TheISA::htog(argc); - //Write out the mysterious 0 - uint64_t mysterious_zero = 0; - initVirtMem->writeBlob(mysterious_base, - (uint8_t*)&mysterious_zero, mysterious_size); + //Write out the sentry void * + uint64_t sentry_NULL = 0; + initVirtMem->writeBlob(sentry_base, + (uint8_t*)&sentry_NULL, sentry_size); //Write the file name initVirtMem->writeString(file_name_base, filename.c_str()); -- cgit v1.2.3 From f4b89cd897e15b34f1565f55d7c6ce0c056f361a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 2 Aug 2007 16:28:01 -0700 Subject: X86: Get rid of some debug warnings. Get rid of some warnings that were accidentally committed. --HG-- extra : convert_revision : e800dbce253f6ba759932ca47d64bf98129e4177 --- src/arch/x86/process.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index ce5828a1d..3cb027d41 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -333,11 +333,8 @@ X86LiveProcess::argsInit(int intSize, int pageSize) //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; - warn("The partial size is %d.\n", partial_size); int aligned_partial_size = roundUp(partial_size, align); - warn("The aligned partial size is %d.\n", aligned_partial_size); int aux_padding = aligned_partial_size - partial_size; - warn("The padding is %d.\n", aux_padding); int space_needed = info_block_size + -- cgit v1.2.3 From 50bceeae1479117a1ccda62dee370370cf68cac1 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 2 Aug 2007 22:08:33 -0400 Subject: Serialize: This shouldn't have been commited, I got a little bit carried away it seems. --HG-- extra : convert_revision : f8d4d9f3d395d2d3db020cd016c7840876097791 --- src/sim/serialize.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index a7f81d5fb..a0d17f489 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -40,7 +40,6 @@ #include #include -#include "base/annotate.hh" #include "base/inifile.hh" #include "base/misc.hh" #include "base/output.hh" @@ -409,7 +408,6 @@ Serializable::serializeAll(const std::string &cpt_dir) outstream << "// checkpoint generated: " << ctime(&t); globals.serialize(outstream); - Annotate::annotations.serialize(outstream); SimObject::serializeAll(outstream); } @@ -425,7 +423,6 @@ Serializable::unserializeAll(const std::string &cpt_dir) dir); Checkpoint *cp = new Checkpoint(dir, section); unserializeGlobals(cp); - Annotate::annotations.unserialize(cp); SimObject::unserializeAll(cp); } -- cgit v1.2.3 From 0536d0cde931e89d33b10228950d455dd54d8a5f Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 2 Aug 2007 22:50:02 -0700 Subject: python: Improve support for python calling back to C++ member functions. Add support for declaring SimObjects to swig so their members can be wrapped. Make sim_object.i only contain declarations for SimObject. Create system.i to contain declarations for System. Update python code to properly call the C++ given the new changes. --HG-- extra : convert_revision : 82076ee69e8122d56e91b92d6767e356baae420a --- src/python/SConscript | 1 - src/python/generate.py | 24 +++++++++++++++------ src/python/m5/SimObject.py | 42 ++++++++++++++++--------------------- src/python/m5/internal/__init__.py | 1 - src/python/m5/params.py | 6 +++--- src/python/m5/simulate.py | 16 +++++++------- src/python/swig/core.i | 6 ++++++ src/python/swig/pyobject.hh | 20 ------------------ src/python/swig/sim_object.i | 22 ------------------- src/python/swig/system.i | 43 ++++++++++++++++++++++++++++++++++++++ src/sim/System.py | 2 ++ 11 files changed, 98 insertions(+), 85 deletions(-) create mode 100644 src/python/swig/system.i diff --git a/src/python/SConscript b/src/python/SConscript index f1b6a393f..b39c9ea9c 100644 --- a/src/python/SConscript +++ b/src/python/SConscript @@ -53,7 +53,6 @@ SwigSource('m5.internal', 'swig/core.i') SwigSource('m5.internal', 'swig/debug.i') SwigSource('m5.internal', 'swig/event.i') SwigSource('m5.internal', 'swig/random.i') -SwigSource('m5.internal', 'swig/sim_object.i') SwigSource('m5.internal', 'swig/stats.i') SwigSource('m5.internal', 'swig/trace.i') PySource('m5.internal', 'm5/internal/__init__.py') diff --git a/src/python/generate.py b/src/python/generate.py index 6a09b8106..99d0fb68c 100644 --- a/src/python/generate.py +++ b/src/python/generate.py @@ -274,17 +274,29 @@ class Generate(object): print >>out for obj in ordered_objs: - code = 'class %s ' % obj.cxx_class - if str(obj) != 'SimObject': - code += ': public %s ' % obj.__bases__[0] - code += '{};' + if obj.swig_objdecls: + for decl in obj.swig_objdecls: + print >>out, decl + 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; 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) - print >>out, '%%ignore %s;' % klass print >>out, code for obj in ordered_objs: diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 1e7d289e2..22c488f5d 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -128,6 +128,7 @@ class MetaSimObject(type): 'cxx_class' : types.StringType, 'cxx_type' : types.StringType, 'cxx_predecls' : types.ListType, + 'swig_objdecls' : types.ListType, 'swig_predecls' : types.ListType, 'type' : types.StringType } # Attributes that can be set any time @@ -225,6 +226,9 @@ class MetaSimObject(type): cls._value_dict['swig_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 # new (or overriding existing) parameters or ports, setting # class keywords (e.g., 'abstract'), or setting parameter @@ -345,12 +349,13 @@ class MetaSimObject(type): def __str__(cls): return cls.__name__ - def cxx_decl(cls): - if str(cls) != 'SimObject': - base = cls.__bases__[0].type - else: - base = None + def get_base(cls): + if str(cls) == 'SimObject': + return None + + return cls.__bases__[0].type + def cxx_decl(cls): code = "#ifndef __PARAMS__%s\n" % cls code += "#define __PARAMS__%s\n\n" % cls @@ -380,6 +385,7 @@ class MetaSimObject(type): code += "\n".join(predecls2) code += "\n\n"; + base = cls.get_base() if base: code += '#include "params/%s.hh"\n\n' % base @@ -408,11 +414,7 @@ class MetaSimObject(type): return code def cxx_type_decl(cls): - if str(cls) != 'SimObject': - base = cls.__bases__[0] - else: - base = None - + base = cls.get_base() code = '' if base: @@ -427,17 +429,14 @@ class MetaSimObject(type): return code def swig_decl(cls): + base = cls.get_base() + code = '%%module %s\n' % cls code += '%{\n' code += '#include "params/%s.hh"\n' % cls 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 object itself, not including inherited params (which # will also be inherited from the base class's param struct @@ -483,6 +482,7 @@ class SimObject(object): abstract = True name = Param.String("Object name") + swig_objdecls = [ '%include "python/swig/sim_object.i"' ] # Initialize new instance. For objects with SimObject-valued # children, we need to recursively clone the classes represented @@ -792,7 +792,6 @@ class SimObject(object): # necessary to construct it. Does *not* recursively create # children. def getCCObject(self): - import internal params = self.getCCParams() if not self._ccObject: self._ccObject = -1 # flag to catch cycles in recursion @@ -840,24 +839,19 @@ class SimObject(object): if not isinstance(self, m5.objects.System): return None - system_ptr = internal.sim_object.convertToSystemPtr(self._ccObject) - return system_ptr.getMemoryMode() + return self._ccObject.getMemoryMode() def changeTiming(self, mode): - import internal if isinstance(self, m5.objects.System): # 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.sim_object.convertToSystemPtr(self._ccObject) - system_ptr.setMemoryMode(mode) + self._ccObject.setMemoryMode(mode) for child in self._children.itervalues(): child.changeTiming(mode) def takeOverFrom(self, old_cpu): - import internal - cpu_ptr = internal.sim_object.convertToBaseCPUPtr(old_cpu._ccObject) - self._ccObject.takeOverFrom(cpu_ptr) + self._ccObject.takeOverFrom(old_cpu._ccObject) # generate output file for 'dot' to display as a pretty graph. # this code is currently broken. diff --git a/src/python/m5/internal/__init__.py b/src/python/m5/internal/__init__.py index 6b7859cd7..4aa76cca7 100644 --- a/src/python/m5/internal/__init__.py +++ b/src/python/m5/internal/__init__.py @@ -30,6 +30,5 @@ import core import debug import event import random -import sim_object import stats import trace diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 3fca4e97a..df70bf469 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -1025,13 +1025,13 @@ class PortRef(object): # Call C++ to create corresponding port connection between C++ objects def ccConnect(self): - import internal + from m5.objects.params import connectPorts if self.ccConnected: # already done this return peer = self.peer - internal.sim_object.connectPorts(self.simobj.getCCObject(), self.name, - self.index, peer.simobj.getCCObject(), peer.name, peer.index) + 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/simulate.py b/src/python/m5/simulate.py index ba9fb7899..c703664d4 100644 --- a/src/python/m5/simulate.py +++ b/src/python/m5/simulate.py @@ -59,10 +59,10 @@ def instantiate(root): root.connectPorts() # Do a second pass to finish initializing the sim objects - internal.sim_object.initAll() + internal.core.initAll() # 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 internal.stats.check() @@ -136,32 +136,32 @@ def checkpoint(root, dir): raise TypeError, "Checkpoint must be called on a root object." doDrain(root) print "Writing checkpoint" - internal.sim_object.serializeAll(dir) + internal.core.serializeAll(dir) resume(root) def restoreCheckpoint(root, dir): print "Restoring from checkpoint" - internal.sim_object.unserializeAll(dir) + internal.core.unserializeAll(dir) need_resume.append(root) def changeToAtomic(system): if not isinstance(system, (objects.Root, objects.System)): raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \ (type(system), objects.Root, objects.System) - if system.getMemoryMode() != internal.sim_object.SimObject.Atomic: + if system.getMemoryMode() != objects.params.SimObject.Atomic: doDrain(system) print "Changing memory mode to atomic" - system.changeTiming(internal.sim_object.SimObject.Atomic) + system.changeTiming(objects.params.SimObject.Atomic) def changeToTiming(system): if not isinstance(system, (objects.Root, objects.System)): raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \ (type(system), objects.Root, objects.System) - if system.getMemoryMode() != internal.sim_object.SimObject.Timing: + if system.getMemoryMode() != objects.params.SimObject.Timing: doDrain(system) print "Changing memory mode to timing" - system.changeTiming(internal.sim_object.SimObject.Timing) + system.changeTiming(objects.params.SimObject.Timing) def switchCpus(cpuList): print "switching cpus" diff --git a/src/python/swig/core.i b/src/python/swig/core.i index 3edfa4c7e..8960fb228 100644 --- a/src/python/swig/core.i +++ b/src/python/swig/core.i @@ -58,6 +58,12 @@ void setClockFrequency(Tick ticksPerSecond); %immutable curTick; Tick curTick; +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 diff --git a/src/python/swig/pyobject.hh b/src/python/swig/pyobject.hh index da609e07e..8e3a96994 100644 --- a/src/python/swig/pyobject.hh +++ b/src/python/swig/pyobject.hh @@ -47,26 +47,6 @@ void loadIniFile(PyObject *_resolveFunc); 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(obj); - - if (ptr == NULL) - warn("Casting to BaseCPU pointer failed"); - return ptr; -} - -inline System * -convertToSystemPtr(SimObject *obj) -{ - System *ptr = dynamic_cast(obj); - - if (ptr == NULL) - warn("Casting to System pointer failed"); - return ptr; -} - inline void initAll() { diff --git a/src/python/swig/sim_object.i b/src/python/swig/sim_object.i index ebd019ca3..7f71550c6 100644 --- a/src/python/swig/sim_object.i +++ b/src/python/swig/sim_object.i @@ -31,7 +31,6 @@ %module sim_object %{ -#include "enums/MemoryMode.hh" #include "python/swig/pyobject.hh" %} @@ -57,31 +56,10 @@ class SimObject { 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, 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 * diff --git a/src/python/swig/system.i b/src/python/swig/system.i new file mode 100644 index 000000000..a95101bf7 --- /dev/null +++ b/src/python/swig/system.i @@ -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); +}; + diff --git a/src/sim/System.py b/src/sim/System.py index 3f4c57f0c..5712a5c03 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -36,6 +36,8 @@ class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing'] class System(SimObject): type = 'System' + swig_objdecls = [ '%include "python/swig/system.i"' ] + physmem = Param.PhysicalMemory(Parent.any, "phsyical memory") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") if build_env['FULL_SYSTEM']: -- cgit v1.2.3