New and improved configuration mechanism. No more writing of
wierd ini files. The ini files are still used as an intermediate step, but a sophisticated python library exists to help build them more easily. SConscript: add the new embedded file stuff remove all of the old object description junk base/inifile.cc: base/inifile.hh: get rid of findDefault and findAppend since they were the source of much evil. base/trace.cc: For now, if we don't have the dprintf_stream set up, dump to standard out. We probably want a command line option for this. dev/alpha_console.cc: PioDevice now takes a platform parameter. All PioDevices must have a pio_latency parameter. We stick a dummy parameter in here for now until we get rid of the builder stuff. dev/alpha_console.hh: don't need Platform anymore dev/baddev.cc: PioDevice now takes a platform parameter. All PioDevices must have a pio_latency parameter. We stick a dummy parameter in here for now until we get rid of the builder stuff. Same for the platform parameter, though we just pass the PioDevice a null parameter since it isn't used by this device and it's quicker. dev/baddev.hh: fix #include guards dev/etherlink.cc: rename parameters. dev/ethertap.cc: rename parameters dev/ide_ctrl.cc: All devices need an address even if it will get overwritten later. dev/ide_disk.cc: use an enum for the drive ID stuff. rename disk_delay -> delay Actually, I think that we should implement "cable select" and have the controller tell the drive what it is. dev/io_device.cc: dev/io_device.hh: All IO devices take a Platform * dev/ns_gige.cc: all devices need an io_bus. rename header_bus to io_bus We don't need stuff for the interrupt controller since it's all in the platform now. dev/ns_gige.hh: We don't need stuff for the interrupt controller now since it's all in the platform. dev/pciconfigall.cc: Pass a dummy NULL to the PioDevice for the platform since we don't need one. dev/pcidev.cc: Move a bunch of common functionality into the PciDev dev/platform.hh: remove unneeded code dev/tsunami.cc: remove unused param dev/tsunami_cchip.cc: pass platform pointer dev/tsunami_io.cc: dev/tsunami_pchip.cc: dev/uart.cc: pass platform variable dev/uart.hh: don't need to keep a platform pointer. it's in the base class kern/linux/linux_system.cc: kern/tru64/tru64_system.cc: rename some parameters sim/builder.cc: clean up builder code. use more parameters from the config node. all sections with a type= are now created, the old mechanisms no longer work sim/builder.hh: remove some extra variables since they are found in the ConfigNode sim/main.cc: add a quick hack command line argument -X to dump out the embedded files. (probably should be fixed up a little.) accept .mpy files printing to the streams has to happen after the hierarchy is built since we're moving away from param contexts sim/param.cc: add parsing support for ranges sim/process.cc: isValid isn't very useful anymore. interpret the names stdout, stderr, cout, cerr for the file descriptors sim/pyconfig/SConscript: Add Action handlers for creating an embedded python file and for creating an embedded C file. use these action handlers to embed all objects found in the objects tree into the binary along with the importer and the m5config stuff sim/pyconfig/m5config.py: Major changes to the original configuration file generator. These changes largely involve implementing copy-on-write like semantics for all of the SimObjects. Real documentation must be written. sim/universe.cc: Universe becomes a SimObject since we don't really have the notion of param contexts in the python code. --HG-- rename : sim/pyconfig/m5configbase.py => sim/pyconfig/m5config.py extra : convert_revision : c353453e5beb91c37f15755998fc0d8858c6829a
This commit is contained in:
parent
dfecc89150
commit
3ece6ab029
61 changed files with 2128 additions and 1136 deletions
88
SConscript
88
SConscript
|
@ -54,6 +54,7 @@ base_sources = Split('''
|
||||||
base/circlebuf.cc
|
base/circlebuf.cc
|
||||||
base/copyright.cc
|
base/copyright.cc
|
||||||
base/cprintf.cc
|
base/cprintf.cc
|
||||||
|
base/embedfile.cc
|
||||||
base/fast_alloc.cc
|
base/fast_alloc.cc
|
||||||
base/fifo_buffer.cc
|
base/fifo_buffer.cc
|
||||||
base/hostinfo.cc
|
base/hostinfo.cc
|
||||||
|
@ -198,42 +199,9 @@ base_sources = Split('''
|
||||||
sim/trace_context.cc
|
sim/trace_context.cc
|
||||||
sim/universe.cc
|
sim/universe.cc
|
||||||
sim/pyconfig/pyconfig.cc
|
sim/pyconfig/pyconfig.cc
|
||||||
sim/pyconfig/code.cc
|
sim/pyconfig/embedded_py.cc
|
||||||
''')
|
''')
|
||||||
|
|
||||||
base_obj_desc_files = Split('''
|
|
||||||
cpu/full_cpu/iq/segmented/SegmentedIQ.od
|
|
||||||
cpu/full_cpu/iq/seznec/SeznecIQ.od
|
|
||||||
cpu/full_cpu/iq/standard/StandardIQ.od
|
|
||||||
cpu/full_cpu/iq/BaseIQ.od
|
|
||||||
cpu/full_cpu/BranchPred.od
|
|
||||||
cpu/full_cpu/FUDesc.od
|
|
||||||
cpu/full_cpu/FullCPU.od
|
|
||||||
cpu/full_cpu/FuncUnitPool.od
|
|
||||||
cpu/full_cpu/OpDesc.od
|
|
||||||
cpu/full_cpu/PipeTrace.od
|
|
||||||
cpu/sampling_cpu/SamplingCPU.od
|
|
||||||
cpu/simple_cpu/SimpleCPU.od
|
|
||||||
cpu/inorder_cpu/InorderCPU.od
|
|
||||||
cpu/BaseCPU.od
|
|
||||||
cpu/IntrControl.od
|
|
||||||
mem/bus/Bus.od
|
|
||||||
mem/bus/BusBridge.od
|
|
||||||
mem/cache/coherence/CoherenceProtocol.od
|
|
||||||
mem/cache/tags/repl/GenRepl.od
|
|
||||||
mem/cache/tags/repl/Repl.od
|
|
||||||
mem/cache/BaseCache.od
|
|
||||||
mem/functional_mem/FunctionalMemory.od
|
|
||||||
mem/functional_mem/MainMemory.od
|
|
||||||
mem/functional_mem/MemoryController.od
|
|
||||||
mem/functional_mem/PhysicalMemory.od
|
|
||||||
mem/timing_mem/BaseMemory.od
|
|
||||||
mem/BaseHier.od
|
|
||||||
mem/BaseMem.od
|
|
||||||
mem/HierParams.od
|
|
||||||
''')
|
|
||||||
|
|
||||||
|
|
||||||
# MySql sources
|
# MySql sources
|
||||||
mysql_sources = Split('''
|
mysql_sources = Split('''
|
||||||
base/mysql.cc
|
base/mysql.cc
|
||||||
|
@ -316,44 +284,6 @@ full_system_sources = Split('''
|
||||||
sim/system.cc
|
sim/system.cc
|
||||||
''')
|
''')
|
||||||
|
|
||||||
full_system_obj_desc_files = Split('''
|
|
||||||
arch/alpha/AlphaDTB.od
|
|
||||||
arch/alpha/AlphaITB.od
|
|
||||||
arch/alpha/AlphaTLB.od
|
|
||||||
dev/AlphaConsole.od
|
|
||||||
dev/ConsoleListener.od
|
|
||||||
dev/CowDiskImage.od
|
|
||||||
dev/DiskImage.od
|
|
||||||
dev/DmaDevice.od
|
|
||||||
dev/DmaEngine.od
|
|
||||||
dev/EtherBus.od
|
|
||||||
dev/EtherDev.od
|
|
||||||
dev/EtherDevInt.od
|
|
||||||
dev/EtherDump.od
|
|
||||||
dev/EtherInt.od
|
|
||||||
dev/EtherLink.od
|
|
||||||
dev/EtherTap.od
|
|
||||||
dev/PioDevice.od
|
|
||||||
dev/RawDiskImage.od
|
|
||||||
dev/ScsiController.od
|
|
||||||
dev/ScsiDevice.od
|
|
||||||
dev/ScsiDisk.od
|
|
||||||
dev/SimConsole.od
|
|
||||||
dev/SimpleDisk.od
|
|
||||||
dev/TlaserClock.od
|
|
||||||
dev/TlaserIpi.od
|
|
||||||
dev/TlaserMBox.od
|
|
||||||
dev/TlaserMC146818.od
|
|
||||||
dev/TlaserNode.od
|
|
||||||
dev/TlaserPciDev.od
|
|
||||||
dev/TlaserPcia.od
|
|
||||||
dev/TlaserSerial.od
|
|
||||||
dev/TlaserUart.od
|
|
||||||
dev/Turbolaser.od
|
|
||||||
kern/tru64/Tru64System.od
|
|
||||||
sim/System.od
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Syscall emulation (non-full-system) sources
|
# Syscall emulation (non-full-system) sources
|
||||||
syscall_emulation_sources = Split('''
|
syscall_emulation_sources = Split('''
|
||||||
arch/alpha/alpha_common_syscall_emul.cc
|
arch/alpha/alpha_common_syscall_emul.cc
|
||||||
|
@ -369,13 +299,6 @@ syscall_emulation_sources = Split('''
|
||||||
sim/syscall_emul.cc
|
sim/syscall_emul.cc
|
||||||
''')
|
''')
|
||||||
|
|
||||||
syscall_emulation_obj_desc_files = Split('''
|
|
||||||
cpu/memtest/MemTest.od
|
|
||||||
eio/EioProcess.od
|
|
||||||
sim/LiveProcess.od
|
|
||||||
sim/Process.od
|
|
||||||
''')
|
|
||||||
|
|
||||||
targetarch_files = Split('''
|
targetarch_files = Split('''
|
||||||
alpha_common_syscall_emul.hh
|
alpha_common_syscall_emul.hh
|
||||||
alpha_linux_process.hh
|
alpha_linux_process.hh
|
||||||
|
@ -404,14 +327,11 @@ for f in targetarch_files:
|
||||||
|
|
||||||
# Set up complete list of sources based on configuration.
|
# Set up complete list of sources based on configuration.
|
||||||
sources = base_sources
|
sources = base_sources
|
||||||
obj_desc_files = base_obj_desc_files
|
|
||||||
|
|
||||||
if env['FULL_SYSTEM']:
|
if env['FULL_SYSTEM']:
|
||||||
sources += full_system_sources
|
sources += full_system_sources
|
||||||
obj_desc_files += full_system_obj_desc_files
|
|
||||||
else:
|
else:
|
||||||
sources += syscall_emulation_sources
|
sources += syscall_emulation_sources
|
||||||
obj_desc_files += syscall_emulation_obj_desc_files
|
|
||||||
|
|
||||||
extra_libraries = []
|
extra_libraries = []
|
||||||
env.Append(LIBS=['z'])
|
env.Append(LIBS=['z'])
|
||||||
|
@ -455,9 +375,7 @@ env.Command(Split('''arch/alpha/decoder.cc
|
||||||
# SConscript-local is the per-config build, which just copies some
|
# SConscript-local is the per-config build, which just copies some
|
||||||
# header files into a place where they can be found.
|
# header files into a place where they can be found.
|
||||||
SConscript('libelf/SConscript-local', exports = 'env', duplicate=0)
|
SConscript('libelf/SConscript-local', exports = 'env', duplicate=0)
|
||||||
|
SConscript('sim/pyconfig/SConscript', exports = ['env'], duplicate=0)
|
||||||
SConscript('sim/pyconfig/SConscript', exports = ['env', 'obj_desc_files'],
|
|
||||||
duplicate=0)
|
|
||||||
|
|
||||||
|
|
||||||
# This function adds the specified sources to the given build
|
# This function adds the specified sources to the given build
|
||||||
|
|
|
@ -333,47 +333,6 @@ IniFile::find(const string §ionName, const string &entryName,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
IniFile::findDefault(const string &_section, const string &entry,
|
|
||||||
string &value) const
|
|
||||||
{
|
|
||||||
string section = _section;
|
|
||||||
while (!findAppend(section, entry, value)) {
|
|
||||||
if (!find(section, "default", section)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
IniFile::findAppend(const string &_section, const string &entry,
|
|
||||||
string &value) const
|
|
||||||
{
|
|
||||||
string section = _section;
|
|
||||||
bool ret = false;
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
do {
|
|
||||||
string val;
|
|
||||||
if (find(section, entry, val)) {
|
|
||||||
ret = true;
|
|
||||||
if (first) {
|
|
||||||
value = val;
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
value += " ";
|
|
||||||
value += val;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} while (find(section, "append", section));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IniFile::sectionExists(const string §ionName) const
|
IniFile::sectionExists(const string §ionName) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -190,24 +190,6 @@ class IniFile
|
||||||
bool find(const std::string §ion, const std::string &entry,
|
bool find(const std::string §ion, const std::string &entry,
|
||||||
std::string &value) const;
|
std::string &value) const;
|
||||||
|
|
||||||
/// Find value corresponding to given section and entry names,
|
|
||||||
/// following "default" links to other sections where possible.
|
|
||||||
/// Value is returned by reference in 'value' param.
|
|
||||||
/// @return True if found, false if not.
|
|
||||||
bool findDefault(const std::string §ion, const std::string &entry,
|
|
||||||
std::string &value) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a value corresponding to the given section and entry names
|
|
||||||
* following "append" links to other sections where possible.
|
|
||||||
* @param section The section to start with.
|
|
||||||
* @param entry The entry to find.
|
|
||||||
* @param value The value found.
|
|
||||||
* @return True if the entry was found.
|
|
||||||
*/
|
|
||||||
bool findAppend(const std::string §ion, const std::string &entry,
|
|
||||||
std::string &value) const;
|
|
||||||
|
|
||||||
/// Determine whether the named section exists in the .ini file.
|
/// Determine whether the named section exists in the .ini file.
|
||||||
/// Note that the 'Section' class is (intentionally) not public,
|
/// Note that the 'Section' class is (intentionally) not public,
|
||||||
/// so all clients can do is get a bool that says whether there
|
/// so all clients can do is get a bool that says whether there
|
||||||
|
|
|
@ -98,6 +98,8 @@ Log::append(Record *rec)
|
||||||
// dump record to output stream if there's one open
|
// dump record to output stream if there's one open
|
||||||
if (dprintf_stream != NULL) {
|
if (dprintf_stream != NULL) {
|
||||||
rec->dump(*dprintf_stream);
|
rec->dump(*dprintf_stream);
|
||||||
|
} else {
|
||||||
|
rec->dump(cout);
|
||||||
}
|
}
|
||||||
|
|
||||||
// no buffering: justget rid of it now
|
// no buffering: justget rid of it now
|
||||||
|
|
|
@ -56,10 +56,10 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
|
AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
|
||||||
System *system, BaseCPU *cpu, Platform *platform,
|
System *system, BaseCPU *cpu, Platform *p,
|
||||||
int num_cpus, MemoryController *mmu, Addr a,
|
int num_cpus, MemoryController *mmu, Addr a,
|
||||||
HierParams *hier, Bus *bus)
|
HierParams *hier, Bus *bus)
|
||||||
: PioDevice(name), disk(d), console(cons), addr(a)
|
: PioDevice(name, p), disk(d), console(cons), addr(a)
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
mmu->add_child(this, RangeSize(addr, size));
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
|
||||||
alphaAccess->numCPUs = num_cpus;
|
alphaAccess->numCPUs = num_cpus;
|
||||||
alphaAccess->mem_size = system->physmem->size();
|
alphaAccess->mem_size = system->physmem->size();
|
||||||
alphaAccess->cpuClock = cpu->getFreq() / 1000000;
|
alphaAccess->cpuClock = cpu->getFreq() / 1000000;
|
||||||
alphaAccess->intrClockFrequency = platform->intrFrequency();
|
alphaAccess->intrClockFrequency = platform->intrFrequency();
|
||||||
alphaAccess->diskUnit = 1;
|
alphaAccess->diskUnit = 1;
|
||||||
|
|
||||||
alphaAccess->diskCount = 0;
|
alphaAccess->diskCount = 0;
|
||||||
|
@ -329,6 +329,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
SimObjectParam<BaseCPU *> cpu;
|
SimObjectParam<BaseCPU *> cpu;
|
||||||
SimObjectParam<Platform *> platform;
|
SimObjectParam<Platform *> platform;
|
||||||
SimObjectParam<Bus*> io_bus;
|
SimObjectParam<Bus*> io_bus;
|
||||||
|
Param<Tick> pio_latency;
|
||||||
SimObjectParam<HierParams *> hier;
|
SimObjectParam<HierParams *> hier;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
|
END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
|
@ -344,6 +345,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
INIT_PARAM(cpu, "Processor"),
|
INIT_PARAM(cpu, "Processor"),
|
||||||
INIT_PARAM(platform, "platform"),
|
INIT_PARAM(platform, "platform"),
|
||||||
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
|
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
|
||||||
|
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
|
||||||
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
|
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
|
||||||
|
|
||||||
END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
|
END_INIT_SIM_OBJECT_PARAMS(AlphaConsole)
|
||||||
|
|
|
@ -42,7 +42,6 @@
|
||||||
class BaseCPU;
|
class BaseCPU;
|
||||||
class SimConsole;
|
class SimConsole;
|
||||||
class System;
|
class System;
|
||||||
class Platform;
|
|
||||||
class SimpleDisk;
|
class SimpleDisk;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -75,7 +74,7 @@ class AlphaConsole : public PioDevice
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
AlphaAccess *alphaAccess;
|
AlphaAccess *alphaAccess;
|
||||||
uint8_t *consoleData;
|
uint8_t *consoleData;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** the disk must be accessed from the console */
|
/** the disk must be accessed from the console */
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/exec_context.hh"
|
#include "cpu/exec_context.hh"
|
||||||
#include "dev/baddev.hh"
|
#include "dev/baddev.hh"
|
||||||
|
#include "dev/platform.hh"
|
||||||
#include "mem/bus/bus.hh"
|
#include "mem/bus/bus.hh"
|
||||||
#include "mem/bus/pio_interface.hh"
|
#include "mem/bus/pio_interface.hh"
|
||||||
#include "mem/bus/pio_interface_impl.hh"
|
#include "mem/bus/pio_interface_impl.hh"
|
||||||
|
@ -48,7 +49,7 @@ using namespace std;
|
||||||
|
|
||||||
BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu,
|
BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu,
|
||||||
HierParams *hier, Bus *bus, const string &devicename)
|
HierParams *hier, Bus *bus, const string &devicename)
|
||||||
: PioDevice(name), addr(a), devname(devicename)
|
: PioDevice(name, NULL), addr(a), devname(devicename)
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
mmu->add_child(this, RangeSize(addr, size));
|
||||||
|
|
||||||
|
@ -83,20 +84,24 @@ BadDevice::cacheAccess(MemReqPtr &req)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
|
||||||
|
|
||||||
|
SimObjectParam<Platform *> platform;
|
||||||
SimObjectParam<MemoryController *> mmu;
|
SimObjectParam<MemoryController *> mmu;
|
||||||
Param<Addr> addr;
|
Param<Addr> addr;
|
||||||
SimObjectParam<HierParams *> hier;
|
SimObjectParam<HierParams *> hier;
|
||||||
SimObjectParam<Bus*> io_bus;
|
SimObjectParam<Bus*> io_bus;
|
||||||
|
Param<Tick> pio_latency;
|
||||||
Param<string> devicename;
|
Param<string> devicename;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
|
END_DECLARE_SIM_OBJECT_PARAMS(BadDevice)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(BadDevice)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(BadDevice)
|
||||||
|
|
||||||
|
INIT_PARAM(platform, "Platform"),
|
||||||
INIT_PARAM(mmu, "Memory Controller"),
|
INIT_PARAM(mmu, "Memory Controller"),
|
||||||
INIT_PARAM(addr, "Device Address"),
|
INIT_PARAM(addr, "Device Address"),
|
||||||
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
|
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
|
||||||
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
|
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
|
||||||
|
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
|
||||||
INIT_PARAM(devicename, "Name of device to error on")
|
INIT_PARAM(devicename, "Name of device to error on")
|
||||||
|
|
||||||
END_INIT_SIM_OBJECT_PARAMS(BadDevice)
|
END_INIT_SIM_OBJECT_PARAMS(BadDevice)
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
* kernel that touches the frame buffer which isn't allowed.
|
* kernel that touches the frame buffer which isn't allowed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __BADDEV_HH__
|
#ifndef __DEV_BADDEV_HH__
|
||||||
#define __BADDEV_HH__
|
#define __DEV_BADDEV_HH__
|
||||||
|
|
||||||
#include "base/range.hh"
|
#include "base/range.hh"
|
||||||
#include "dev/io_device.hh"
|
#include "dev/io_device.hh"
|
||||||
|
@ -90,4 +90,4 @@ class BadDevice : public PioDevice
|
||||||
Tick cacheAccess(MemReqPtr &req);
|
Tick cacheAccess(MemReqPtr &req);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __BADDEV_HH__
|
#endif // __DEV_BADDEV_HH__
|
||||||
|
|
|
@ -261,28 +261,27 @@ REGISTER_SERIALIZEABLE("LinkDelayEvent", LinkDelayEvent)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
|
||||||
|
|
||||||
SimObjectParam<EtherInt *> interface1;
|
SimObjectParam<EtherInt *> int1;
|
||||||
SimObjectParam<EtherInt *> interface2;
|
SimObjectParam<EtherInt *> int2;
|
||||||
Param<Tick> link_speed;
|
Param<Tick> speed;
|
||||||
Param<Tick> link_delay;
|
Param<Tick> delay;
|
||||||
SimObjectParam<EtherDump *> packet_dump;
|
SimObjectParam<EtherDump *> dump;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
|
END_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink)
|
||||||
|
|
||||||
INIT_PARAM(interface1, "interface 1"),
|
INIT_PARAM(int1, "interface 1"),
|
||||||
INIT_PARAM(interface2, "interface 2"),
|
INIT_PARAM(int2, "interface 2"),
|
||||||
INIT_PARAM_DFLT(link_speed, "link speed in bits per second", 100000000),
|
INIT_PARAM_DFLT(speed, "link speed in bits per second", 100000000),
|
||||||
INIT_PARAM_DFLT(link_delay, "transmit delay of packets in us", 0),
|
INIT_PARAM_DFLT(delay, "transmit delay of packets in us", 0),
|
||||||
INIT_PARAM_DFLT(packet_dump, "object to dump network packets to", NULL)
|
INIT_PARAM_DFLT(dump, "object to dump network packets to", NULL)
|
||||||
|
|
||||||
END_INIT_SIM_OBJECT_PARAMS(EtherLink)
|
END_INIT_SIM_OBJECT_PARAMS(EtherLink)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(EtherLink)
|
CREATE_SIM_OBJECT(EtherLink)
|
||||||
{
|
{
|
||||||
return new EtherLink(getInstanceName(), interface1, interface2, link_speed,
|
return new EtherLink(getInstanceName(), int1, int2, speed, delay, dump);
|
||||||
link_delay, packet_dump);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("EtherLink", EtherLink)
|
REGISTER_SIM_OBJECT("EtherLink", EtherLink)
|
||||||
|
|
|
@ -311,7 +311,7 @@ EtherTap::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherTap)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherTap)
|
||||||
|
|
||||||
SimObjectParam<EtherInt *> peer;
|
SimObjectParam<EtherInt *> peer;
|
||||||
SimObjectParam<EtherDump *> packet_dump;
|
SimObjectParam<EtherDump *> dump;
|
||||||
Param<unsigned> port;
|
Param<unsigned> port;
|
||||||
Param<unsigned> bufsz;
|
Param<unsigned> bufsz;
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(EtherTap)
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(EtherTap)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(EtherTap)
|
||||||
|
|
||||||
INIT_PARAM_DFLT(peer, "peer interface", NULL),
|
INIT_PARAM_DFLT(peer, "peer interface", NULL),
|
||||||
INIT_PARAM_DFLT(packet_dump, "object to dump network packets to", NULL),
|
INIT_PARAM_DFLT(dump, "object to dump network packets to", NULL),
|
||||||
INIT_PARAM_DFLT(port, "tap port", 3500),
|
INIT_PARAM_DFLT(port, "tap port", 3500),
|
||||||
INIT_PARAM_DFLT(bufsz, "tap buffer size", 10000)
|
INIT_PARAM_DFLT(bufsz, "tap buffer size", 10000)
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ END_INIT_SIM_OBJECT_PARAMS(EtherTap)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(EtherTap)
|
CREATE_SIM_OBJECT(EtherTap)
|
||||||
{
|
{
|
||||||
EtherTap *tap = new EtherTap(getInstanceName(), packet_dump, port, bufsz);
|
EtherTap *tap = new EtherTap(getInstanceName(), dump, port, bufsz);
|
||||||
|
|
||||||
if (peer) {
|
if (peer) {
|
||||||
tap->setPeer(peer);
|
tap->setPeer(peer);
|
||||||
|
|
|
@ -664,6 +664,7 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController)
|
||||||
|
|
||||||
|
Param<Addr> addr;
|
||||||
SimObjectVectorParam<IdeDisk *> disks;
|
SimObjectVectorParam<IdeDisk *> disks;
|
||||||
SimObjectParam<MemoryController *> mmu;
|
SimObjectParam<MemoryController *> mmu;
|
||||||
SimObjectParam<PciConfigAll *> configspace;
|
SimObjectParam<PciConfigAll *> configspace;
|
||||||
|
@ -680,6 +681,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(IdeController)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController)
|
||||||
|
|
||||||
|
INIT_PARAM(addr, "Device Address"),
|
||||||
INIT_PARAM(disks, "IDE disks attached to this controller"),
|
INIT_PARAM(disks, "IDE disks attached to this controller"),
|
||||||
INIT_PARAM(mmu, "Memory controller"),
|
INIT_PARAM(mmu, "Memory controller"),
|
||||||
INIT_PARAM(configspace, "PCI Configspace"),
|
INIT_PARAM(configspace, "PCI Configspace"),
|
||||||
|
|
|
@ -1171,12 +1171,14 @@ IdeDisk::unserialize(Checkpoint *cp, const string §ion)
|
||||||
|
|
||||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||||
|
|
||||||
|
enum DriveID { master, slave };
|
||||||
|
static const char *DriveID_strings[] = { "master", "slave" };
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
|
||||||
|
|
||||||
SimObjectParam<DiskImage *> image;
|
SimObjectParam<DiskImage *> image;
|
||||||
SimObjectParam<PhysicalMemory *> physmem;
|
SimObjectParam<PhysicalMemory *> physmem;
|
||||||
Param<int> driveID;
|
SimpleEnumParam<DriveID> driveID;
|
||||||
Param<int> disk_delay;
|
Param<int> delay;
|
||||||
|
|
||||||
END_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
|
END_DECLARE_SIM_OBJECT_PARAMS(IdeDisk)
|
||||||
|
|
||||||
|
@ -1184,16 +1186,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(IdeDisk)
|
||||||
|
|
||||||
INIT_PARAM(image, "Disk image"),
|
INIT_PARAM(image, "Disk image"),
|
||||||
INIT_PARAM(physmem, "Physical memory"),
|
INIT_PARAM(physmem, "Physical memory"),
|
||||||
INIT_PARAM(driveID, "Drive ID (0=master 1=slave)"),
|
INIT_ENUM_PARAM(driveID, "Drive ID (0=master 1=slave)", DriveID_strings),
|
||||||
INIT_PARAM_DFLT(disk_delay, "Fixed disk delay in microseconds", 1)
|
INIT_PARAM_DFLT(delay, "Fixed disk delay in microseconds", 1)
|
||||||
|
|
||||||
END_INIT_SIM_OBJECT_PARAMS(IdeDisk)
|
END_INIT_SIM_OBJECT_PARAMS(IdeDisk)
|
||||||
|
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(IdeDisk)
|
CREATE_SIM_OBJECT(IdeDisk)
|
||||||
{
|
{
|
||||||
return new IdeDisk(getInstanceName(), image, physmem, driveID,
|
return new IdeDisk(getInstanceName(), image, physmem, driveID, delay);
|
||||||
disk_delay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("IdeDisk", IdeDisk)
|
REGISTER_SIM_OBJECT("IdeDisk", IdeDisk)
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
#include "mem/bus/dma_interface.hh"
|
#include "mem/bus/dma_interface.hh"
|
||||||
#include "sim/builder.hh"
|
#include "sim/builder.hh"
|
||||||
|
|
||||||
PioDevice::PioDevice(const std::string &name)
|
PioDevice::PioDevice(const std::string &name, Platform *p)
|
||||||
: FunctionalMemory(name), pioInterface(NULL), pioLatency(0)
|
: FunctionalMemory(name), platform(p), pioInterface(NULL), pioLatency(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PioDevice::~PioDevice()
|
PioDevice::~PioDevice()
|
||||||
|
@ -43,8 +43,8 @@ PioDevice::~PioDevice()
|
||||||
|
|
||||||
DEFINE_SIM_OBJECT_CLASS_NAME("PioDevice", PioDevice)
|
DEFINE_SIM_OBJECT_CLASS_NAME("PioDevice", PioDevice)
|
||||||
|
|
||||||
DmaDevice::DmaDevice(const std::string &name)
|
DmaDevice::DmaDevice(const std::string &name, Platform *p)
|
||||||
: PioDevice(name), dmaInterface(NULL)
|
: PioDevice(name, p), dmaInterface(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
DmaDevice::~DmaDevice()
|
DmaDevice::~DmaDevice()
|
||||||
|
|
|
@ -26,24 +26,26 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __IO_DEVICE_HH__
|
#ifndef __DEV_IO_DEVICE_HH__
|
||||||
#define __IO_DEVICE_HH__
|
#define __DEV_IO_DEVICE_HH__
|
||||||
|
|
||||||
#include "mem/functional_mem/functional_memory.hh"
|
#include "mem/functional_mem/functional_memory.hh"
|
||||||
|
|
||||||
class BaseInterface;
|
class BaseInterface;
|
||||||
class Bus;
|
class Bus;
|
||||||
class HierParams;
|
class HierParams;
|
||||||
|
class Platform;
|
||||||
template <class BusType> class DMAInterface;
|
template <class BusType> class DMAInterface;
|
||||||
|
|
||||||
class PioDevice : public FunctionalMemory
|
class PioDevice : public FunctionalMemory
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
Platform *platform;
|
||||||
BaseInterface *pioInterface;
|
BaseInterface *pioInterface;
|
||||||
Tick pioLatency;
|
Tick pioLatency;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PioDevice(const std::string &name);
|
PioDevice(const std::string &name, Platform *p);
|
||||||
virtual ~PioDevice();
|
virtual ~PioDevice();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,8 +55,8 @@ class DmaDevice : public PioDevice
|
||||||
DMAInterface<Bus> *dmaInterface;
|
DMAInterface<Bus> *dmaInterface;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DmaDevice(const std::string &name);
|
DmaDevice(const std::string &name, Platform *p);
|
||||||
virtual ~DmaDevice();
|
virtual ~DmaDevice();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __IO_DEVICE_HH__
|
#endif // __DEV_IO_DEVICE_HH__
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
|
|
||||||
#include "base/inet.hh"
|
#include "base/inet.hh"
|
||||||
#include "cpu/exec_context.hh"
|
#include "cpu/exec_context.hh"
|
||||||
#include "cpu/intr_control.hh"
|
|
||||||
#include "dev/dma.hh"
|
#include "dev/dma.hh"
|
||||||
#include "dev/etherlink.hh"
|
#include "dev/etherlink.hh"
|
||||||
#include "dev/ns_gige.hh"
|
#include "dev/ns_gige.hh"
|
||||||
|
@ -2637,6 +2636,7 @@ REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
|
||||||
|
|
||||||
|
Param<Addr> addr;
|
||||||
Param<Tick> tx_delay;
|
Param<Tick> tx_delay;
|
||||||
Param<Tick> rx_delay;
|
Param<Tick> rx_delay;
|
||||||
Param<Tick> intr_delay;
|
Param<Tick> intr_delay;
|
||||||
|
@ -2644,7 +2644,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
|
||||||
SimObjectParam<PhysicalMemory *> physmem;
|
SimObjectParam<PhysicalMemory *> physmem;
|
||||||
Param<bool> rx_filter;
|
Param<bool> rx_filter;
|
||||||
Param<string> hardware_address;
|
Param<string> hardware_address;
|
||||||
SimObjectParam<Bus*> header_bus;
|
SimObjectParam<Bus*> io_bus;
|
||||||
SimObjectParam<Bus*> payload_bus;
|
SimObjectParam<Bus*> payload_bus;
|
||||||
SimObjectParam<HierParams *> hier;
|
SimObjectParam<HierParams *> hier;
|
||||||
Param<Tick> pio_latency;
|
Param<Tick> pio_latency;
|
||||||
|
@ -2667,6 +2667,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
|
||||||
|
|
||||||
|
INIT_PARAM(addr, "Device Address"),
|
||||||
INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000),
|
INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000),
|
||||||
INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000),
|
INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000),
|
||||||
INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0),
|
INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0),
|
||||||
|
@ -2675,7 +2676,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
|
||||||
INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true),
|
INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true),
|
||||||
INIT_PARAM_DFLT(hardware_address, "Ethernet Hardware Address",
|
INIT_PARAM_DFLT(hardware_address, "Ethernet Hardware Address",
|
||||||
"00:99:00:00:00:01"),
|
"00:99:00:00:00:01"),
|
||||||
INIT_PARAM_DFLT(header_bus, "The IO Bus to attach to for headers", NULL),
|
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to for headers", NULL),
|
||||||
INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL),
|
INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL),
|
||||||
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
|
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
|
||||||
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
|
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
|
||||||
|
@ -2715,7 +2716,7 @@ CREATE_SIM_OBJECT(NSGigE)
|
||||||
params->tx_delay = tx_delay;
|
params->tx_delay = tx_delay;
|
||||||
params->rx_delay = rx_delay;
|
params->rx_delay = rx_delay;
|
||||||
params->hier = hier;
|
params->hier = hier;
|
||||||
params->header_bus = header_bus;
|
params->header_bus = io_bus;
|
||||||
params->payload_bus = payload_bus;
|
params->payload_bus = payload_bus;
|
||||||
params->pio_latency = pio_latency;
|
params->pio_latency = pio_latency;
|
||||||
params->dma_desc_free = dma_desc_free;
|
params->dma_desc_free = dma_desc_free;
|
||||||
|
|
|
@ -91,7 +91,6 @@ struct dp_rom {
|
||||||
uint8_t perfectMatch[ETH_ADDR_LEN];
|
uint8_t perfectMatch[ETH_ADDR_LEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
class IntrControl;
|
|
||||||
class NSGigEInt;
|
class NSGigEInt;
|
||||||
class PhysicalMemory;
|
class PhysicalMemory;
|
||||||
class BaseInterface;
|
class BaseInterface;
|
||||||
|
@ -302,7 +301,6 @@ class NSGigE : public PciDev
|
||||||
/**
|
/**
|
||||||
* Interrupt management
|
* Interrupt management
|
||||||
*/
|
*/
|
||||||
IntrControl *intctrl;
|
|
||||||
void devIntrPost(uint32_t interrupts);
|
void devIntrPost(uint32_t interrupts);
|
||||||
void devIntrClear(uint32_t interrupts);
|
void devIntrClear(uint32_t interrupts);
|
||||||
void devIntrChangeMask();
|
void devIntrChangeMask();
|
||||||
|
|
|
@ -48,9 +48,10 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
PciConfigAll::PciConfigAll(const string &name, Addr a, MemoryController *mmu,
|
PciConfigAll::PciConfigAll(const string &name,
|
||||||
|
Addr a, MemoryController *mmu,
|
||||||
HierParams *hier, Bus *bus, Tick pio_latency)
|
HierParams *hier, Bus *bus, Tick pio_latency)
|
||||||
: PioDevice(name), addr(a)
|
: PioDevice(name, NULL), addr(a)
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
mmu->add_child(this, RangeSize(addr, size));
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "dev/pciareg.h"
|
#include "dev/pciareg.h"
|
||||||
#include "dev/pcidev.hh"
|
#include "dev/pcidev.hh"
|
||||||
#include "dev/pciconfigall.hh"
|
#include "dev/pciconfigall.hh"
|
||||||
|
#include "mem/bus/bus.hh"
|
||||||
#include "mem/functional_mem/memory_control.hh"
|
#include "mem/functional_mem/memory_control.hh"
|
||||||
#include "sim/builder.hh"
|
#include "sim/builder.hh"
|
||||||
#include "sim/param.hh"
|
#include "sim/param.hh"
|
||||||
|
@ -51,7 +52,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
PciDev::PciDev(Params *p)
|
PciDev::PciDev(Params *p)
|
||||||
: DmaDevice(p->name), _params(p), plat(p->plat), configData(p->configData)
|
: DmaDevice(p->name, p->plat), _params(p), plat(p->plat),
|
||||||
|
configData(p->configData)
|
||||||
{
|
{
|
||||||
// copy the config data from the PciConfigData object
|
// copy the config data from the PciConfigData object
|
||||||
if (configData) {
|
if (configData) {
|
||||||
|
@ -283,6 +285,11 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigData)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigData)
|
||||||
|
|
||||||
|
SimObjectParam<MemoryController *> mmu;
|
||||||
|
Param<Addr> addr;
|
||||||
|
SimObjectParam<Bus*> io_bus;
|
||||||
|
Param<Tick> pio_latency;
|
||||||
|
|
||||||
Param<uint16_t> VendorID;
|
Param<uint16_t> VendorID;
|
||||||
Param<uint16_t> DeviceID;
|
Param<uint16_t> DeviceID;
|
||||||
Param<uint16_t> Command;
|
Param<uint16_t> Command;
|
||||||
|
@ -320,6 +327,11 @@ END_DECLARE_SIM_OBJECT_PARAMS(PciConfigData)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigData)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigData)
|
||||||
|
|
||||||
|
INIT_PARAM(mmu, "Memory Controller"),
|
||||||
|
INIT_PARAM(addr, "Device Address"),
|
||||||
|
INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
|
||||||
|
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
|
||||||
|
|
||||||
INIT_PARAM(VendorID, "Vendor ID"),
|
INIT_PARAM(VendorID, "Vendor ID"),
|
||||||
INIT_PARAM(DeviceID, "Device ID"),
|
INIT_PARAM(DeviceID, "Device ID"),
|
||||||
INIT_PARAM_DFLT(Command, "Command Register", 0x00),
|
INIT_PARAM_DFLT(Command, "Command Register", 0x00),
|
||||||
|
|
|
@ -47,8 +47,6 @@ class Platform : public SimObject
|
||||||
public:
|
public:
|
||||||
/** Pointer to the interrupt controller */
|
/** Pointer to the interrupt controller */
|
||||||
IntrControl *intrctrl;
|
IntrControl *intrctrl;
|
||||||
/** Pointer to the simulation console */
|
|
||||||
SimConsole *cons;
|
|
||||||
/** Pointer to the PCI configuration space */
|
/** Pointer to the PCI configuration space */
|
||||||
PciConfigAll *pciconfig;
|
PciConfigAll *pciconfig;
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,6 @@ Tsunami::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami)
|
||||||
|
|
||||||
SimObjectParam<System *> system;
|
SimObjectParam<System *> system;
|
||||||
SimObjectParam<SimConsole *> cons;
|
|
||||||
SimObjectParam<IntrControl *> intrctrl;
|
SimObjectParam<IntrControl *> intrctrl;
|
||||||
SimObjectParam<PciConfigAll *> pciconfig;
|
SimObjectParam<PciConfigAll *> pciconfig;
|
||||||
Param<int> interrupt_frequency;
|
Param<int> interrupt_frequency;
|
||||||
|
@ -117,7 +116,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(Tsunami)
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami)
|
||||||
|
|
||||||
INIT_PARAM(system, "system"),
|
INIT_PARAM(system, "system"),
|
||||||
INIT_PARAM(cons, "system console"),
|
|
||||||
INIT_PARAM(intrctrl, "interrupt controller"),
|
INIT_PARAM(intrctrl, "interrupt controller"),
|
||||||
INIT_PARAM(pciconfig, "PCI configuration"),
|
INIT_PARAM(pciconfig, "PCI configuration"),
|
||||||
INIT_PARAM_DFLT(interrupt_frequency, "frequency of interrupts", 1024)
|
INIT_PARAM_DFLT(interrupt_frequency, "frequency of interrupts", 1024)
|
||||||
|
|
|
@ -51,7 +51,7 @@ using namespace std;
|
||||||
TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
|
TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
|
||||||
MemoryController *mmu, HierParams *hier, Bus* bus,
|
MemoryController *mmu, HierParams *hier, Bus* bus,
|
||||||
Tick pio_latency)
|
Tick pio_latency)
|
||||||
: PioDevice(name), addr(a), tsunami(t)
|
: PioDevice(name, t), addr(a), tsunami(t)
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
mmu->add_child(this, RangeSize(addr, size));
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ TsunamiIO::ClockEvent::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
|
TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
|
||||||
Addr a, MemoryController *mmu, HierParams *hier, Bus *bus,
|
Addr a, MemoryController *mmu, HierParams *hier, Bus *bus,
|
||||||
Tick pio_latency)
|
Tick pio_latency)
|
||||||
: PioDevice(name), addr(a), tsunami(t), rtc(t)
|
: PioDevice(name, t), addr(a), tsunami(t), rtc(t)
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
mmu->add_child(this, RangeSize(addr, size));
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ using namespace std;
|
||||||
TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
|
TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
|
||||||
MemoryController *mmu, HierParams *hier,
|
MemoryController *mmu, HierParams *hier,
|
||||||
Bus *bus, Tick pio_latency)
|
Bus *bus, Tick pio_latency)
|
||||||
: PioDevice(name), addr(a), tsunami(t)
|
: PioDevice(name, t), addr(a), tsunami(t)
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
mmu->add_child(this, RangeSize(addr, size));
|
||||||
|
|
||||||
|
|
|
@ -88,8 +88,8 @@ Uart::IntrEvent::scheduleIntr()
|
||||||
|
|
||||||
Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a,
|
Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a,
|
||||||
Addr s, HierParams *hier, Bus *bus, Tick pio_latency, Platform *p)
|
Addr s, HierParams *hier, Bus *bus, Tick pio_latency, Platform *p)
|
||||||
: PioDevice(name), addr(a), size(s), cons(c), txIntrEvent(this, TX_INT),
|
: PioDevice(name, p), addr(a), size(s), cons(c),
|
||||||
rxIntrEvent(this, RX_INT), platform(p)
|
txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT)
|
||||||
{
|
{
|
||||||
mmu->add_child(this, RangeSize(addr, size));
|
mmu->add_child(this, RangeSize(addr, size));
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,6 @@ class Uart : public PioDevice
|
||||||
|
|
||||||
IntrEvent txIntrEvent;
|
IntrEvent txIntrEvent;
|
||||||
IntrEvent rxIntrEvent;
|
IntrEvent rxIntrEvent;
|
||||||
Platform *platform;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Uart(const std::string &name, SimConsole *c, MemoryController *mmu,
|
Uart(const std::string &name, SimConsole *c, MemoryController *mmu,
|
||||||
|
|
|
@ -208,12 +208,12 @@ LinuxSystem::setDelayLoop(ExecContext *xc)
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
|
||||||
|
|
||||||
SimObjectParam<MemoryController *> mem_ctl;
|
SimObjectParam<MemoryController *> memctrl;
|
||||||
SimObjectParam<PhysicalMemory *> physmem;
|
SimObjectParam<PhysicalMemory *> physmem;
|
||||||
|
|
||||||
Param<string> kernel_code;
|
Param<string> kernel;
|
||||||
Param<string> console_code;
|
Param<string> console;
|
||||||
Param<string> pal_code;
|
Param<string> pal;
|
||||||
|
|
||||||
Param<string> boot_osflags;
|
Param<string> boot_osflags;
|
||||||
Param<string> readfile;
|
Param<string> readfile;
|
||||||
|
@ -230,11 +230,11 @@ END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
|
||||||
|
|
||||||
INIT_PARAM(mem_ctl, "memory controller"),
|
INIT_PARAM(memctrl, "memory controller"),
|
||||||
INIT_PARAM(physmem, "phsyical memory"),
|
INIT_PARAM(physmem, "phsyical memory"),
|
||||||
INIT_PARAM(kernel_code, "file that contains the kernel code"),
|
INIT_PARAM(kernel, "file that contains the kernel code"),
|
||||||
INIT_PARAM(console_code, "file that contains the console code"),
|
INIT_PARAM(console, "file that contains the console code"),
|
||||||
INIT_PARAM(pal_code, "file that contains palcode"),
|
INIT_PARAM(pal, "file that contains palcode"),
|
||||||
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
||||||
"a"),
|
"a"),
|
||||||
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
|
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
|
||||||
|
@ -251,11 +251,11 @@ CREATE_SIM_OBJECT(LinuxSystem)
|
||||||
{
|
{
|
||||||
System::Params *p = new System::Params;
|
System::Params *p = new System::Params;
|
||||||
p->name = getInstanceName();
|
p->name = getInstanceName();
|
||||||
p->memctrl = mem_ctl;
|
p->memctrl = memctrl;
|
||||||
p->physmem = physmem;
|
p->physmem = physmem;
|
||||||
p->kernel_path = kernel_code;
|
p->kernel_path = kernel;
|
||||||
p->console_path = console_code;
|
p->console_path = console;
|
||||||
p->palcode = pal_code;
|
p->palcode = pal;
|
||||||
p->boot_osflags = boot_osflags;
|
p->boot_osflags = boot_osflags;
|
||||||
p->init_param = init_param;
|
p->init_param = init_param;
|
||||||
p->readfile = readfile;
|
p->readfile = readfile;
|
||||||
|
|
|
@ -116,12 +116,12 @@ Tru64System::~Tru64System()
|
||||||
|
|
||||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
|
||||||
|
|
||||||
SimObjectParam<MemoryController *> mem_ctl;
|
SimObjectParam<MemoryController *> memctrl;
|
||||||
SimObjectParam<PhysicalMemory *> physmem;
|
SimObjectParam<PhysicalMemory *> physmem;
|
||||||
|
|
||||||
Param<string> kernel_code;
|
Param<string> kernel;
|
||||||
Param<string> console_code;
|
Param<string> console;
|
||||||
Param<string> pal_code;
|
Param<string> pal;
|
||||||
|
|
||||||
Param<string> boot_osflags;
|
Param<string> boot_osflags;
|
||||||
Param<string> readfile;
|
Param<string> readfile;
|
||||||
|
@ -137,11 +137,11 @@ END_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
|
||||||
|
|
||||||
BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System)
|
BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System)
|
||||||
|
|
||||||
INIT_PARAM(mem_ctl, "memory controller"),
|
INIT_PARAM(memctrl, "memory controller"),
|
||||||
INIT_PARAM(physmem, "phsyical memory"),
|
INIT_PARAM(physmem, "phsyical memory"),
|
||||||
INIT_PARAM(kernel_code, "file that contains the kernel code"),
|
INIT_PARAM(kernel, "file that contains the kernel code"),
|
||||||
INIT_PARAM(console_code, "file that contains the console code"),
|
INIT_PARAM(console, "file that contains the console code"),
|
||||||
INIT_PARAM(pal_code, "file that contains palcode"),
|
INIT_PARAM(pal, "file that contains palcode"),
|
||||||
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
|
||||||
"a"),
|
"a"),
|
||||||
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
|
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
|
||||||
|
@ -157,11 +157,11 @@ CREATE_SIM_OBJECT(Tru64System)
|
||||||
{
|
{
|
||||||
System::Params *p = new System::Params;
|
System::Params *p = new System::Params;
|
||||||
p->name = getInstanceName();
|
p->name = getInstanceName();
|
||||||
p->memctrl = mem_ctl;
|
p->memctrl = memctrl;
|
||||||
p->physmem = physmem;
|
p->physmem = physmem;
|
||||||
p->kernel_path = kernel_code;
|
p->kernel_path = kernel;
|
||||||
p->console_path = console_code;
|
p->console_path = console;
|
||||||
p->palcode = pal_code;
|
p->palcode = pal;
|
||||||
p->boot_osflags = boot_osflags;
|
p->boot_osflags = boot_osflags;
|
||||||
p->init_param = init_param;
|
p->init_param = init_param;
|
||||||
p->readfile = readfile;
|
p->readfile = readfile;
|
||||||
|
|
8
objects/AlphaConsole.mpy
Normal file
8
objects/AlphaConsole.mpy
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from Device import PioDevice
|
||||||
|
|
||||||
|
simobj AlphaConsole(PioDevice):
|
||||||
|
cpu = Param.BaseCPU(Super, "Processor")
|
||||||
|
disk = Param.SimpleDisk("Simple Disk")
|
||||||
|
num_cpus = Param.Int(1, "Number of CPU's")
|
||||||
|
sim_console = Param.SimConsole(Super, "The Simulator Console")
|
||||||
|
system = Param.BaseSystem(Super, "system object")
|
9
objects/AlphaTLB.mpy
Normal file
9
objects/AlphaTLB.mpy
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
simobj AlphaTLB(SimObject):
|
||||||
|
abstract = True
|
||||||
|
size = Param.Int("TLB size")
|
||||||
|
|
||||||
|
simobj AlphaDTB(AlphaTLB):
|
||||||
|
size = 64
|
||||||
|
|
||||||
|
simobj AlphaITB(AlphaTLB):
|
||||||
|
size = 48
|
4
objects/BadDevice.mpy
Normal file
4
objects/BadDevice.mpy
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
from Device import PioDevice
|
||||||
|
|
||||||
|
simobj BadDevice(PioDevice):
|
||||||
|
devicename = Param.String("Name of device to error on")
|
38
objects/BaseCPU.mpy
Normal file
38
objects/BaseCPU.mpy
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
simobj BaseCPU(SimObject):
|
||||||
|
abstract = True
|
||||||
|
icache = Param.BaseMem(NULL, "L1 instruction cache object")
|
||||||
|
dcache = Param.BaseMem(NULL, "L1 data cache object")
|
||||||
|
|
||||||
|
dtb = Param.AlphaDTB("Data TLB")
|
||||||
|
itb = Param.AlphaITB("Instruction TLB")
|
||||||
|
mem = Param.FunctionalMemory("memory")
|
||||||
|
system = Param.BaseSystem(Super, "system object")
|
||||||
|
workload = VectorParam.Process("processes to run")
|
||||||
|
|
||||||
|
max_insts_all_threads = Param.Counter(0,
|
||||||
|
"terminate when all threads have reached this inst count")
|
||||||
|
max_insts_any_thread = Param.Counter(0,
|
||||||
|
"terminate when any thread reaches this inst count")
|
||||||
|
max_loads_all_threads = Param.Counter(0,
|
||||||
|
"terminate when all threads have reached this load count")
|
||||||
|
max_loads_any_thread = Param.Counter(0,
|
||||||
|
"terminate when any thread reaches this load count")
|
||||||
|
|
||||||
|
defer_registration = Param.Bool(false,
|
||||||
|
"defer registration with system (for sampling)")
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
has_workload = self._hasvalue('workload')
|
||||||
|
has_dtb = self._hasvalue('dtb')
|
||||||
|
has_itb = self._hasvalue('itb')
|
||||||
|
has_mem = self._hasvalue('mem')
|
||||||
|
has_system = self._hasvalue('system')
|
||||||
|
|
||||||
|
if has_workload:
|
||||||
|
self.dtb.disable = True
|
||||||
|
self.itb.disable = True
|
||||||
|
self.mem.disable = True
|
||||||
|
self.system.disable = True
|
||||||
|
|
||||||
|
if has_dtb or has_itb or has_mem or has_system:
|
||||||
|
self.workload.disable = True
|
30
objects/BaseCache.mpy
Normal file
30
objects/BaseCache.mpy
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
from BaseMem import BaseMem
|
||||||
|
|
||||||
|
simobj BaseCache(BaseMem):
|
||||||
|
adaptive_compression = Param.Bool(false,
|
||||||
|
"Use an adaptive compression scheme")
|
||||||
|
assoc = Param.Int("associativity")
|
||||||
|
block_size = Param.Int("block size in bytes")
|
||||||
|
compressed_bus = Param.Bool(false,
|
||||||
|
"This cache connects to a compressed memory")
|
||||||
|
compression_latency = Param.Int(0,
|
||||||
|
"Latency in cycles of compression algorithm")
|
||||||
|
do_copy = Param.Bool(false, "perform fast copies in the cache")
|
||||||
|
hash_delay = Param.Int(1, "time in cycles of hash access")
|
||||||
|
in_bus = Param.Bus(NULL, "incoming bus object")
|
||||||
|
max_miss_count = Param.Counter(0,
|
||||||
|
"number of misses to handle before calling exit")
|
||||||
|
mshrs = Param.Int("number of MSHRs (max outstanding requests)")
|
||||||
|
out_bus = Param.Bus("outgoing bus object")
|
||||||
|
prioritizeRequests = Param.Bool(false,
|
||||||
|
"always service demand misses first")
|
||||||
|
protocol = Param.CoherenceProtocol(NULL, "coherence protocol to use")
|
||||||
|
repl = Param.Repl(NULL, "replacement policy")
|
||||||
|
size = Param.Int("capacity in bytes")
|
||||||
|
store_compressed = Param.Bool(false,
|
||||||
|
"Store compressed data in the cache")
|
||||||
|
subblock_size = Param.Int(0,
|
||||||
|
"Size of subblock in IIC used for compression")
|
||||||
|
tgts_per_mshr = Param.Int("max number of accesses per MSHR")
|
||||||
|
trace_addr = Param.Addr(0, "address to trace")
|
||||||
|
write_buffers = Param.Int(8, "number of write buffers")
|
14
objects/BaseSystem.mpy
Normal file
14
objects/BaseSystem.mpy
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
simobj BaseSystem(SimObject):
|
||||||
|
abstract = True
|
||||||
|
memctrl = Param.MemoryController(Super, "memory controller")
|
||||||
|
physmem = Param.PhysicalMemory(Super, "phsyical memory")
|
||||||
|
kernel = Param.String("file that contains the kernel code")
|
||||||
|
console = Param.String("file that contains the console code")
|
||||||
|
pal = Param.String("file that contains palcode")
|
||||||
|
readfile = Param.String("", "file to read startup script from")
|
||||||
|
init_param = Param.UInt64(0, "numerical value to pass into simulator")
|
||||||
|
boot_osflags = Param.String("a", "boot flags to pass to the kernel")
|
||||||
|
system_type = Param.UInt64("Type of system we are emulating")
|
||||||
|
system_rev = Param.UInt64("Revision of system we are emulating")
|
||||||
|
bin = Param.Bool(false, "is this system binned")
|
||||||
|
binned_fns = VectorParam.String([], "functions broken down and binned")
|
5
objects/Bus.mpy
Normal file
5
objects/Bus.mpy
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from BaseHier import BaseHier
|
||||||
|
|
||||||
|
simobj Bus(BaseHier):
|
||||||
|
clock_ratio = Param.Int("ratio of CPU to bus frequency")
|
||||||
|
width = Param.Int("bus width in bytes")
|
5
objects/CoherenceProtocol.mpy
Normal file
5
objects/CoherenceProtocol.mpy
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
Coherence = Enum('uni', 'msi', 'mesi', 'mosi', 'moesi')
|
||||||
|
|
||||||
|
simobj CoherenceProtocol(SimObject):
|
||||||
|
do_upgrades = Param.Bool(true, "use upgrade transactions?")
|
||||||
|
protocol = Param.Coherence("name of coherence protocol")
|
31
objects/Device.mpy
Normal file
31
objects/Device.mpy
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
from FunctionalMemory import FunctionalMemory
|
||||||
|
|
||||||
|
# This device exists only because there are some devices that I don't
|
||||||
|
# want to have a Platform parameter because it would cause a cycle in
|
||||||
|
# the C++ that cannot be easily solved.
|
||||||
|
#
|
||||||
|
# The real solution to this problem is to pass the ParamXXX structure
|
||||||
|
# to the constructor, but with the express condition that SimObject
|
||||||
|
# parameter values are not to be available at construction time. If
|
||||||
|
# some further configuration must be done, it must be done during the
|
||||||
|
# initialization phase at which point all SimObject pointers will be
|
||||||
|
# valid.
|
||||||
|
simobj FooPioDevice(FunctionalMemory):
|
||||||
|
abstract = True
|
||||||
|
type = 'PioDevice'
|
||||||
|
addr = Param.Addr("Device Address")
|
||||||
|
mmu = Param.MemoryController(Super, "Memory Controller")
|
||||||
|
io_bus = Param.Bus(NULL, "The IO Bus to attach to")
|
||||||
|
pio_latency = Param.Tick(1, "Programmed IO latency in bus cycles")
|
||||||
|
|
||||||
|
simobj FooDmaDevice(FooPioDevice):
|
||||||
|
abstract = True
|
||||||
|
type = 'DmaDevice'
|
||||||
|
|
||||||
|
simobj PioDevice(FooPioDevice):
|
||||||
|
abstract = True
|
||||||
|
platform = Param.Platform(Super, "Platform")
|
||||||
|
|
||||||
|
simobj DmaDevice(PioDevice):
|
||||||
|
abstract = True
|
||||||
|
|
12
objects/DiskImage.mpy
Normal file
12
objects/DiskImage.mpy
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
simobj DiskImage(SimObject):
|
||||||
|
abstract = True
|
||||||
|
image_file = Param.String("disk image file")
|
||||||
|
read_only = Param.Bool(false, "read only image")
|
||||||
|
|
||||||
|
simobj RawDiskImage(DiskImage):
|
||||||
|
pass
|
||||||
|
|
||||||
|
simobj CowDiskImage(DiskImage):
|
||||||
|
child = Param.DiskImage("child image")
|
||||||
|
table_size = Param.Int(65536, "initial table size")
|
||||||
|
image_file = ''
|
77
objects/Ethernet.mpy
Normal file
77
objects/Ethernet.mpy
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
from Device import DmaDevice
|
||||||
|
from Pci import PciDevice
|
||||||
|
|
||||||
|
simobj EtherInt(SimObject):
|
||||||
|
abstract = True
|
||||||
|
peer = Param.EtherInt(NULL, "peer interface")
|
||||||
|
|
||||||
|
simobj EtherLink(SimObject):
|
||||||
|
int1 = Param.EtherInt("interface 1")
|
||||||
|
int2 = Param.EtherInt("interface 2")
|
||||||
|
delay = Param.Tick(0, "transmit delay of packets in us")
|
||||||
|
speed = Param.Tick(100000000, "link speed in bits per second")
|
||||||
|
dump = Param.EtherDump(NULL, "dump object")
|
||||||
|
|
||||||
|
simobj EtherBus(SimObject):
|
||||||
|
loopback = Param.Bool(true,
|
||||||
|
"send packet back to the interface from which it came")
|
||||||
|
dump = Param.EtherDump(NULL, "dump object")
|
||||||
|
speed = Param.UInt64(100000000, "bus speed in bits per second")
|
||||||
|
|
||||||
|
simobj EtherTap(EtherInt):
|
||||||
|
bufsz = Param.Int(10000, "tap buffer size")
|
||||||
|
dump = Param.EtherDump(NULL, "dump object")
|
||||||
|
port = Param.UInt16(3500, "tap port")
|
||||||
|
|
||||||
|
simobj EtherDump(SimObject):
|
||||||
|
file = Param.String("dump file")
|
||||||
|
|
||||||
|
simobj EtherDev(DmaDevice):
|
||||||
|
hardware_address = Param.EthernetAddr(NextEthernetAddr,
|
||||||
|
"Ethernet Hardware Address")
|
||||||
|
|
||||||
|
dma_data_free = Param.Bool(false, "DMA of Data is free")
|
||||||
|
dma_desc_free = Param.Bool(false, "DMA of Descriptors is free")
|
||||||
|
dma_read_delay = Param.Tick(0, "fixed delay for dma reads")
|
||||||
|
dma_read_factor = Param.Tick(0, "multiplier for dma reads")
|
||||||
|
dma_write_delay = Param.Tick(0, "fixed delay for dma writes")
|
||||||
|
dma_write_factor = Param.Tick(0, "multiplier for dma writes")
|
||||||
|
|
||||||
|
rx_filter = Param.Bool(true, "Enable Receive Filter")
|
||||||
|
rx_delay = Param.Tick(1000, "Receive Delay")
|
||||||
|
tx_delay = Param.Tick(1000, "Transmit Delay")
|
||||||
|
|
||||||
|
intr_delay = Param.Tick(0, "Interrupt Delay in microseconds")
|
||||||
|
payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
|
||||||
|
physmem = Param.PhysicalMemory(Super, "Physical Memory")
|
||||||
|
tlaser = Param.Turbolaser(Super, "Turbolaser")
|
||||||
|
|
||||||
|
simobj NSGigE(PciDevice):
|
||||||
|
hardware_address = Param.EthernetAddr(NextEthernetAddr,
|
||||||
|
"Ethernet Hardware Address")
|
||||||
|
|
||||||
|
dma_data_free = Param.Bool(false, "DMA of Data is free")
|
||||||
|
dma_desc_free = Param.Bool(false, "DMA of Descriptors is free")
|
||||||
|
dma_read_delay = Param.Tick(0, "fixed delay for dma reads")
|
||||||
|
dma_read_factor = Param.Tick(0, "multiplier for dma reads")
|
||||||
|
dma_write_delay = Param.Tick(0, "fixed delay for dma writes")
|
||||||
|
dma_write_factor = Param.Tick(0, "multiplier for dma writes")
|
||||||
|
|
||||||
|
rx_filter = Param.Bool(true, "Enable Receive Filter")
|
||||||
|
rx_delay = Param.Tick(1000, "Receive Delay")
|
||||||
|
tx_delay = Param.Tick(1000, "Transmit Delay")
|
||||||
|
|
||||||
|
rx_fifo_size = Param.Int(131072, "max size in bytes of rxFifo")
|
||||||
|
tx_fifo_size = Param.Int(131072, "max size in bytes of txFifo")
|
||||||
|
|
||||||
|
intr_delay = Param.Tick(0, "Interrupt Delay in microseconds")
|
||||||
|
payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
|
||||||
|
physmem = Param.PhysicalMemory(Super, "Physical Memory")
|
||||||
|
|
||||||
|
simobj EtherDevInt(EtherInt):
|
||||||
|
device = Param.EtherDev("Ethernet device of this interface")
|
||||||
|
|
||||||
|
simobj NSGigEInt(EtherInt):
|
||||||
|
device = Param.NSGigE("Ethernet device of this interface")
|
||||||
|
|
||||||
|
|
12
objects/Ide.mpy
Normal file
12
objects/Ide.mpy
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from Pci import PciDevice
|
||||||
|
|
||||||
|
IdeID = Enum('master', 'slave')
|
||||||
|
|
||||||
|
simobj IdeDisk(SimObject):
|
||||||
|
delay = Param.Tick(1, "Fixed disk delay in microseconds")
|
||||||
|
driveID = Param.IdeID('master', "Drive ID")
|
||||||
|
image = Param.DiskImage("Disk image")
|
||||||
|
physmem = Param.PhysicalMemory(Super, "Physical memory")
|
||||||
|
|
||||||
|
simobj IdeController(PciDevice):
|
||||||
|
disks = VectorParam.IdeDisk("IDE disks attached to this controller")
|
2
objects/IntrControl.mpy
Normal file
2
objects/IntrControl.mpy
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
simobj IntrControl(SimObject):
|
||||||
|
cpu = Param.BaseCPU(Super, "the cpu")
|
20
objects/MemTest.mpy
Normal file
20
objects/MemTest.mpy
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
simobj MemTest(SimObject):
|
||||||
|
cache = Param.BaseCache("L1 cache")
|
||||||
|
check_mem = Param.FunctionalMemory("check memory")
|
||||||
|
main_mem = Param.FunctionalMemory("hierarchical memory")
|
||||||
|
max_loads_all_threads = Param.Counter(0,
|
||||||
|
"terminate when all threads have reached this load count")
|
||||||
|
max_loads_any_thread = Param.Counter(0,
|
||||||
|
"terminate when any thread reaches this load count")
|
||||||
|
memory_size = Param.Int(65536, "memory size")
|
||||||
|
percent_copies = Param.Percent(0, "target copy percentage")
|
||||||
|
percent_dest_unaligned = Param.Percent(50,
|
||||||
|
"percent of copy dest address that are unaligned")
|
||||||
|
percent_reads = Param.Percent(65, "target read percentage")
|
||||||
|
percent_source_unaligned = Param.Percent(50,
|
||||||
|
"percent of copy source address that are unaligned")
|
||||||
|
percent_uncacheable = Param.Percent(10,
|
||||||
|
"target uncacheable percentage")
|
||||||
|
progress_interval = Param.Counter(1000000,
|
||||||
|
"progress report interval (in accesses)")
|
||||||
|
trace_addr = Param.Addr(0, "address to trace")
|
50
objects/Pci.mpy
Normal file
50
objects/Pci.mpy
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
from Device import FooPioDevice, DmaDevice
|
||||||
|
|
||||||
|
simobj PciConfigData(FooPioDevice):
|
||||||
|
addr = 0xffffffffffffffff
|
||||||
|
VendorID = Param.UInt16("Vendor ID")
|
||||||
|
DeviceID = Param.UInt16("Device ID")
|
||||||
|
Command = Param.UInt16(0, "Command")
|
||||||
|
Status = Param.UInt16(0, "Status")
|
||||||
|
Revision = Param.UInt8(0, "Device")
|
||||||
|
ProgIF = Param.UInt8(0, "Programming Interface")
|
||||||
|
SubClassCode = Param.UInt8(0, "Sub-Class Code")
|
||||||
|
ClassCode = Param.UInt8(0, "Class Code")
|
||||||
|
CacheLineSize = Param.UInt8(0, "System Cacheline Size")
|
||||||
|
LatencyTimer = Param.UInt8(0, "PCI Latency Timer")
|
||||||
|
HeaderType = Param.UInt8(0, "PCI Header Type")
|
||||||
|
BIST = Param.UInt8(0, "Built In Self Test")
|
||||||
|
|
||||||
|
BAR0 = Param.UInt32(0x00, "Base Address Register 0")
|
||||||
|
BAR1 = Param.UInt32(0x00, "Base Address Register 1")
|
||||||
|
BAR2 = Param.UInt32(0x00, "Base Address Register 2")
|
||||||
|
BAR3 = Param.UInt32(0x00, "Base Address Register 3")
|
||||||
|
BAR4 = Param.UInt32(0x00, "Base Address Register 4")
|
||||||
|
BAR5 = Param.UInt32(0x00, "Base Address Register 5")
|
||||||
|
BAR0Size = Param.UInt32(0, "Base Address Register 0 Size")
|
||||||
|
BAR1Size = Param.UInt32(0, "Base Address Register 1 Size")
|
||||||
|
BAR2Size = Param.UInt32(0, "Base Address Register 2 Size")
|
||||||
|
BAR3Size = Param.UInt32(0, "Base Address Register 3 Size")
|
||||||
|
BAR4Size = Param.UInt32(0, "Base Address Register 4 Size")
|
||||||
|
BAR5Size = Param.UInt32(0, "Base Address Register 5 Size")
|
||||||
|
|
||||||
|
CardbusCIS = Param.UInt32(0x00, "Cardbus Card Information Structure")
|
||||||
|
SubsystemID = Param.UInt16(0x00, "Subsystem ID")
|
||||||
|
SubsystemVendorID = Param.UInt16(0x00, "Subsystem Vendor ID")
|
||||||
|
ExpansionROM = Param.UInt32(0x00, "Expansion ROM Base Address")
|
||||||
|
InterruptLine = Param.UInt8(0x00, "Interrupt Line")
|
||||||
|
InterruptPin = Param.UInt8(0x00, "Interrupt Pin")
|
||||||
|
MaximumLatency = Param.UInt8(0x00, "Maximum Latency")
|
||||||
|
MinimumGrant = Param.UInt8(0x00, "Minimum Grant")
|
||||||
|
|
||||||
|
simobj PciConfigAll(FooPioDevice):
|
||||||
|
pass
|
||||||
|
|
||||||
|
simobj PciDevice(DmaDevice):
|
||||||
|
abstract = True
|
||||||
|
pci_bus = Param.Int("PCI bus")
|
||||||
|
pci_dev = Param.Int("PCI device number")
|
||||||
|
pci_func = Param.Int("PCI function code")
|
||||||
|
configdata = Param.PciConfigData(Super, "PCI Config data")
|
||||||
|
configspace = Param.PciConfigAll(Super, "PCI Configspace")
|
||||||
|
addr = 0xffffffffffffffff
|
6
objects/PhysicalMemory.mpy
Normal file
6
objects/PhysicalMemory.mpy
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from FunctionalMemory import FunctionalMemory
|
||||||
|
|
||||||
|
simobj PhysicalMemory(FunctionalMemory):
|
||||||
|
range = Param.AddrRange("Device Address")
|
||||||
|
file = Param.String('', "memory mapped file")
|
||||||
|
mmu = Param.MemoryController(Super, "Memory Controller")
|
4
objects/Platform.mpy
Normal file
4
objects/Platform.mpy
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
simobj Platform(SimObject):
|
||||||
|
abstract = True
|
||||||
|
interrupt_frequency = Param.Tick(1200, "frequency of interrupts")
|
||||||
|
intrctrl = Param.IntrControl(Super, "interrupt controller")
|
12
objects/Process.mpy
Normal file
12
objects/Process.mpy
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
simobj Process(SimObject):
|
||||||
|
abstract = True
|
||||||
|
output = Param.String('cout', 'filename for stdout/stderr')
|
||||||
|
|
||||||
|
simobj LiveProcess(Process):
|
||||||
|
cmd = VectorParam.String("command line (executable plus arguments)")
|
||||||
|
env = VectorParam.String('', "environment settings")
|
||||||
|
input = Param.String('cin', "filename for stdin")
|
||||||
|
|
||||||
|
simobj EioProcess(Process):
|
||||||
|
chkpt = Param.String('', "EIO checkpoint file name (optional)")
|
||||||
|
file = Param.String("EIO trace file name")
|
7
objects/Repl.mpy
Normal file
7
objects/Repl.mpy
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
simobj Repl(SimObject):
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
simobj GenRepl(Repl):
|
||||||
|
fresh_res = Param.Int("associativity")
|
||||||
|
num_pools = Param.Int("capacity in bytes")
|
||||||
|
pool_res = Param.Int("block size in bytes")
|
9
objects/Root.mpy
Normal file
9
objects/Root.mpy
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from HierParams import HierParams
|
||||||
|
simobj Root(SimObject):
|
||||||
|
frequency = Param.Tick(200000000, "tick frequency")
|
||||||
|
output_dir = Param.String('.', "directory to output data to")
|
||||||
|
output_file = Param.String('cout', "file to dump simulator output to")
|
||||||
|
config_output_file = Param.String('m5config.out',
|
||||||
|
"file to dump simulator config to")
|
||||||
|
full_system = Param.Bool("Full system simulation?")
|
||||||
|
hier = HierParams(do_data = false, do_events = true)
|
9
objects/SimConsole.mpy
Normal file
9
objects/SimConsole.mpy
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
simobj ConsoleListener(SimObject):
|
||||||
|
port = Param.UInt16(3456, "listen port")
|
||||||
|
|
||||||
|
simobj SimConsole(SimObject):
|
||||||
|
append_name = Param.Bool(true, "append name() to filename")
|
||||||
|
intr_control = Param.IntrControl(Super, "interrupt controller")
|
||||||
|
listener = Param.ConsoleListener("console listener")
|
||||||
|
number = Param.Int(0, "console number")
|
||||||
|
output = Param.String("", "file to dump output to")
|
3
objects/SimpleDisk.mpy
Normal file
3
objects/SimpleDisk.mpy
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
simobj SimpleDisk(SimObject):
|
||||||
|
disk = Param.DiskImage("Disk Image")
|
||||||
|
physmem = Param.PhysicalMemory(Super, "Physical Memory")
|
21
objects/Tsunami.mpy
Normal file
21
objects/Tsunami.mpy
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from Device import FooPioDevice
|
||||||
|
from Platform import Platform
|
||||||
|
|
||||||
|
simobj Tsunami(Platform):
|
||||||
|
pciconfig = Param.PciConfigAll("PCI configuration")
|
||||||
|
system = Param.BaseSystem(Super, "system")
|
||||||
|
interrupt_frequency = Param.Int(1024, "frequency of interrupts")
|
||||||
|
|
||||||
|
simobj TsunamiCChip(FooPioDevice):
|
||||||
|
tsunami = Param.Tsunami(Super, "Tsunami")
|
||||||
|
|
||||||
|
simobj TsunamiFake(FooPioDevice):
|
||||||
|
pass
|
||||||
|
|
||||||
|
simobj TsunamiIO(FooPioDevice):
|
||||||
|
time = Param.UInt64(1136073600,
|
||||||
|
"System time to use (0 for actual time, default is 1/1/06)")
|
||||||
|
tsunami = Param.Tsunami(Super, "Tsunami")
|
||||||
|
|
||||||
|
simobj TsunamiPChip(FooPioDevice):
|
||||||
|
tsunami = Param.Tsunami(Super, "Tsunami")
|
5
objects/Uart.mpy
Normal file
5
objects/Uart.mpy
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from Device import PioDevice
|
||||||
|
|
||||||
|
simobj Uart(PioDevice):
|
||||||
|
console = Param.SimConsole(Super, "The console")
|
||||||
|
size = Param.Addr(0x8, "Device size")
|
|
@ -39,14 +39,9 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
SimObjectBuilder::SimObjectBuilder(const string &_configClass,
|
SimObjectBuilder::SimObjectBuilder(ConfigNode *_configNode)
|
||||||
const string &_instanceName,
|
: ParamContext(_configNode->getPath(), NoAutoInit),
|
||||||
ConfigNode *_configNode,
|
configNode(_configNode)
|
||||||
const string &_simObjClassName)
|
|
||||||
: ParamContext(_configClass, NoAutoInit),
|
|
||||||
instanceName(_instanceName),
|
|
||||||
configNode(_configNode),
|
|
||||||
simObjClassName(_simObjClassName)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,13 +67,8 @@ SimObjectBuilder::parseParams(IniFile &iniFile)
|
||||||
|
|
||||||
for (i = paramList->begin(); i != paramList->end(); ++i) {
|
for (i = paramList->begin(); i != paramList->end(); ++i) {
|
||||||
string string_value;
|
string string_value;
|
||||||
|
if (iniFile.find(iniSection, (*i)->name, string_value))
|
||||||
if (iniFile.findDefault(instanceName, (*i)->name, string_value)) {
|
|
||||||
(*i)->parse(string_value);
|
(*i)->parse(string_value);
|
||||||
}
|
|
||||||
else if (iniFile.findDefault(iniSection, (*i)->name, string_value)) {
|
|
||||||
(*i)->parse(string_value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +76,8 @@ SimObjectBuilder::parseParams(IniFile &iniFile)
|
||||||
void
|
void
|
||||||
SimObjectBuilder::printErrorProlog(ostream &os)
|
SimObjectBuilder::printErrorProlog(ostream &os)
|
||||||
{
|
{
|
||||||
os << "Error creating object '" << getInstanceName()
|
ccprintf(os, "Error creating object '%s' of type '%s':\n",
|
||||||
<< "' of type '" << simObjClassName
|
iniSection, configNode->getType());
|
||||||
<< "', section '" << iniSection << "':" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,11 +100,7 @@ SimObjectClass::SimObjectClass(const string &className, CreateFunc createFunc)
|
||||||
classMap = new map<string,SimObjectClass::CreateFunc>();
|
classMap = new map<string,SimObjectClass::CreateFunc>();
|
||||||
|
|
||||||
if ((*classMap)[className])
|
if ((*classMap)[className])
|
||||||
{
|
panic("Error: simulation object class '%s' redefined\n", className);
|
||||||
cerr << "Error: simulation object class " << className << " redefined"
|
|
||||||
<< endl;
|
|
||||||
fatal("");
|
|
||||||
}
|
|
||||||
|
|
||||||
// add className --> createFunc to class map
|
// add className --> createFunc to class map
|
||||||
(*classMap)[className] = createFunc;
|
(*classMap)[className] = createFunc;
|
||||||
|
@ -125,35 +110,20 @@ SimObjectClass::SimObjectClass(const string &className, CreateFunc createFunc)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
SimObject *
|
SimObject *
|
||||||
SimObjectClass::createObject(IniFile &configDB,
|
SimObjectClass::createObject(IniFile &configDB, ConfigNode *configNode)
|
||||||
const string &configClassName,
|
|
||||||
const string &objName,
|
|
||||||
ConfigNode *configNode)
|
|
||||||
{
|
{
|
||||||
// find simulation object class name from configuration class
|
const string &type = configNode->getType();
|
||||||
// (specified by 'type=' parameter)
|
|
||||||
string simObjClassName;
|
|
||||||
|
|
||||||
if (!configNode->find("type", simObjClassName)) {
|
|
||||||
cerr << "Configuration class '" << configClassName << "' not found."
|
|
||||||
<< endl;
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
// look up className to get appropriate createFunc
|
// look up className to get appropriate createFunc
|
||||||
if (classMap->find(simObjClassName) == classMap->end()) {
|
if (classMap->find(type) == classMap->end())
|
||||||
cerr << "Simulator object class '" << simObjClassName << "' not found."
|
panic("Simulator object type '%s' not found.\n", type);
|
||||||
<< endl;
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateFunc createFunc = (*classMap)[simObjClassName];
|
|
||||||
|
CreateFunc createFunc = (*classMap)[type];
|
||||||
|
|
||||||
// call createFunc with config hierarchy node to get object
|
// call createFunc with config hierarchy node to get object
|
||||||
// builder instance (context with parameters for object creation)
|
// builder instance (context with parameters for object creation)
|
||||||
SimObjectBuilder *objectBuilder = (*createFunc)(configClassName,
|
SimObjectBuilder *objectBuilder = (*createFunc)(configNode);
|
||||||
objName, configNode,
|
|
||||||
simObjClassName);
|
|
||||||
|
|
||||||
assert(objectBuilder != NULL);
|
assert(objectBuilder != NULL);
|
||||||
|
|
||||||
|
@ -167,10 +137,10 @@ SimObjectClass::createObject(IniFile &configDB,
|
||||||
|
|
||||||
// echo object parameters to stats file (for documenting the
|
// echo object parameters to stats file (for documenting the
|
||||||
// config used to generate the associated stats)
|
// config used to generate the associated stats)
|
||||||
*configStream << "[" << object->name() << "]" << endl;
|
ccprintf(*configStream, "[%s]\n", object->name());
|
||||||
*configStream << "type=" << simObjClassName << endl;
|
ccprintf(*configStream, "type=%s\n", type);
|
||||||
objectBuilder->showParams(*configStream);
|
objectBuilder->showParams(*configStream);
|
||||||
*configStream << endl;
|
ccprintf(*configStream, "\n");
|
||||||
|
|
||||||
// done with the SimObjectBuilder now
|
// done with the SimObjectBuilder now
|
||||||
delete objectBuilder;
|
delete objectBuilder;
|
||||||
|
@ -194,7 +164,7 @@ SimObjectClass::describeAllClasses(ostream &os)
|
||||||
os << "[" << className << "]\n";
|
os << "[" << className << "]\n";
|
||||||
|
|
||||||
// create dummy object builder just to instantiate parameters
|
// create dummy object builder just to instantiate parameters
|
||||||
SimObjectBuilder *objectBuilder = (*createFunc)("", "", NULL, "");
|
SimObjectBuilder *objectBuilder = (*createFunc)(NULL);
|
||||||
|
|
||||||
// now get the object builder to describe ite params
|
// now get the object builder to describe ite params
|
||||||
objectBuilder->describeParams(os);
|
objectBuilder->describeParams(os);
|
||||||
|
|
|
@ -54,22 +54,13 @@ class SimObject;
|
||||||
class SimObjectBuilder : public ParamContext
|
class SimObjectBuilder : public ParamContext
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// name of the instance we are creating
|
|
||||||
std::string instanceName;
|
|
||||||
|
|
||||||
// The corresponding node in the configuration hierarchy.
|
// The corresponding node in the configuration hierarchy.
|
||||||
// (optional: may be null if the created object is not in the
|
// (optional: may be null if the created object is not in the
|
||||||
// hierarchy)
|
// hierarchy)
|
||||||
ConfigNode *configNode;
|
ConfigNode *configNode;
|
||||||
|
|
||||||
// The external SimObject class name (for error messages)
|
|
||||||
std::string simObjClassName;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SimObjectBuilder(const std::string &_configClass,
|
SimObjectBuilder(ConfigNode *_configNode);
|
||||||
const std::string &_instanceName,
|
|
||||||
ConfigNode *_configNode,
|
|
||||||
const std::string &_simObjClassName);
|
|
||||||
|
|
||||||
virtual ~SimObjectBuilder();
|
virtual ~SimObjectBuilder();
|
||||||
|
|
||||||
|
@ -82,7 +73,7 @@ class SimObjectBuilder : public ParamContext
|
||||||
|
|
||||||
// generate the name for this SimObject instance (derived from the
|
// generate the name for this SimObject instance (derived from the
|
||||||
// configuration hierarchy node label and position)
|
// configuration hierarchy node label and position)
|
||||||
virtual const std::string &getInstanceName() { return instanceName; }
|
virtual const std::string &getInstanceName() { return iniSection; }
|
||||||
|
|
||||||
// return the configuration hierarchy node for this context.
|
// return the configuration hierarchy node for this context.
|
||||||
virtual ConfigNode *getConfigNode() { return configNode; }
|
virtual ConfigNode *getConfigNode() { return configNode; }
|
||||||
|
@ -132,10 +123,7 @@ class SimObjectClass
|
||||||
// for the object (specified by the second string argument), and
|
// for the object (specified by the second string argument), and
|
||||||
// an optional config hierarchy node (specified by the third
|
// an optional config hierarchy node (specified by the third
|
||||||
// argument). A pointer to the new SimObjectBuilder is returned.
|
// argument). A pointer to the new SimObjectBuilder is returned.
|
||||||
typedef SimObjectBuilder *(*CreateFunc)(const std::string &configClassName,
|
typedef SimObjectBuilder *(*CreateFunc)(ConfigNode *configNode);
|
||||||
const std::string &objName,
|
|
||||||
ConfigNode *configNode,
|
|
||||||
const std::string &simObjClassName);
|
|
||||||
|
|
||||||
static std::map<std::string,CreateFunc> *classMap;
|
static std::map<std::string,CreateFunc> *classMap;
|
||||||
|
|
||||||
|
@ -147,10 +135,7 @@ class SimObjectClass
|
||||||
|
|
||||||
// create SimObject given name of class and pointer to
|
// create SimObject given name of class and pointer to
|
||||||
// configuration hierarchy node
|
// configuration hierarchy node
|
||||||
static SimObject *createObject(IniFile &configDB,
|
static SimObject *createObject(IniFile &configDB, ConfigNode *configNode);
|
||||||
const std::string &configClassName,
|
|
||||||
const std::string &objName,
|
|
||||||
ConfigNode *configNode);
|
|
||||||
|
|
||||||
// print descriptions of all parameters registered with all
|
// print descriptions of all parameters registered with all
|
||||||
// SimObject classes
|
// SimObject classes
|
||||||
|
@ -169,22 +154,15 @@ class OBJ_CLASS##Builder : public SimObjectBuilder \
|
||||||
|
|
||||||
#define END_DECLARE_SIM_OBJECT_PARAMS(OBJ_CLASS) \
|
#define END_DECLARE_SIM_OBJECT_PARAMS(OBJ_CLASS) \
|
||||||
\
|
\
|
||||||
OBJ_CLASS##Builder(const std::string &configClass, \
|
OBJ_CLASS##Builder(ConfigNode *configNode); \
|
||||||
const std::string &instanceName, \
|
|
||||||
ConfigNode *configNode, \
|
|
||||||
const std::string &simObjClassName); \
|
|
||||||
virtual ~OBJ_CLASS##Builder() {} \
|
virtual ~OBJ_CLASS##Builder() {} \
|
||||||
\
|
\
|
||||||
OBJ_CLASS *create(); \
|
OBJ_CLASS *create(); \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BEGIN_INIT_SIM_OBJECT_PARAMS(OBJ_CLASS) \
|
#define BEGIN_INIT_SIM_OBJECT_PARAMS(OBJ_CLASS) \
|
||||||
OBJ_CLASS##Builder::OBJ_CLASS##Builder(const std::string &configClass, \
|
OBJ_CLASS##Builder::OBJ_CLASS##Builder(ConfigNode *configNode) \
|
||||||
const std::string &instanceName, \
|
: SimObjectBuilder(configNode),
|
||||||
ConfigNode *configNode, \
|
|
||||||
const std::string &simObjClassName) \
|
|
||||||
: SimObjectBuilder(configClass, instanceName, \
|
|
||||||
configNode, simObjClassName),
|
|
||||||
|
|
||||||
|
|
||||||
#define END_INIT_SIM_OBJECT_PARAMS(OBJ_CLASS) \
|
#define END_INIT_SIM_OBJECT_PARAMS(OBJ_CLASS) \
|
||||||
|
@ -196,13 +174,9 @@ OBJ_CLASS *OBJ_CLASS##Builder::create()
|
||||||
|
|
||||||
#define REGISTER_SIM_OBJECT(CLASS_NAME, OBJ_CLASS) \
|
#define REGISTER_SIM_OBJECT(CLASS_NAME, OBJ_CLASS) \
|
||||||
SimObjectBuilder * \
|
SimObjectBuilder * \
|
||||||
new##OBJ_CLASS##Builder(const std::string &configClass, \
|
new##OBJ_CLASS##Builder(ConfigNode *configNode) \
|
||||||
const std::string &instanceName, \
|
|
||||||
ConfigNode *configNode, \
|
|
||||||
const std::string &simObjClassName) \
|
|
||||||
{ \
|
{ \
|
||||||
return new OBJ_CLASS##Builder(configClass, instanceName, \
|
return new OBJ_CLASS##Builder(configNode); \
|
||||||
configNode, simObjClassName); \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
SimObjectClass the##OBJ_CLASS##Class(CLASS_NAME, \
|
SimObjectClass the##OBJ_CLASS##Class(CLASS_NAME, \
|
||||||
|
|
29
sim/main.cc
29
sim/main.cc
|
@ -34,10 +34,12 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/copyright.hh"
|
#include "base/copyright.hh"
|
||||||
|
#include "base/embedfile.hh"
|
||||||
#include "base/inifile.hh"
|
#include "base/inifile.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "base/pollevent.hh"
|
#include "base/pollevent.hh"
|
||||||
|
@ -254,6 +256,21 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
// switch on second char
|
// switch on second char
|
||||||
switch (arg_str[1]) {
|
switch (arg_str[1]) {
|
||||||
|
case 'X': {
|
||||||
|
list<EmbedFile> lst;
|
||||||
|
EmbedMap::all(lst);
|
||||||
|
list<EmbedFile>::iterator i = lst.begin();
|
||||||
|
list<EmbedFile>::iterator end = lst.end();
|
||||||
|
|
||||||
|
while (i != end) {
|
||||||
|
cprintf("Embedded File: %s\n", i->name);
|
||||||
|
cout.write(i->data, i->length);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
// -h: show help
|
// -h: show help
|
||||||
showLongHelp(cerr);
|
showLongHelp(cerr);
|
||||||
|
@ -311,7 +328,7 @@ main(int argc, char **argv)
|
||||||
cprintf("Error processing file %s\n", filename);
|
cprintf("Error processing file %s\n", filename);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} else if (ext == ".py") {
|
} else if (ext == ".py" || ext == ".mpy") {
|
||||||
if (!loadPythonConfig(filename, &simConfigDB)) {
|
if (!loadPythonConfig(filename, &simConfigDB)) {
|
||||||
cprintf("Error processing file %s\n", filename);
|
cprintf("Error processing file %s\n", filename);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -335,6 +352,11 @@ main(int argc, char **argv)
|
||||||
// the stat file name is set via a .ini param... thus it just got
|
// the stat file name is set via a .ini param... thus it just got
|
||||||
// opened above during ParamContext::checkAllContexts().
|
// opened above during ParamContext::checkAllContexts().
|
||||||
|
|
||||||
|
// Now process the configuration hierarchy and create the SimObjects.
|
||||||
|
ConfigHierarchy configHierarchy(simConfigDB);
|
||||||
|
configHierarchy.build();
|
||||||
|
configHierarchy.createSimObjects();
|
||||||
|
|
||||||
// Print hello message to stats file if it's actually a file. If
|
// Print hello message to stats file if it's actually a file. If
|
||||||
// it's not (i.e. it's cout or cerr) then we already did it above.
|
// it's not (i.e. it's cout or cerr) then we already did it above.
|
||||||
if (outputStream != &cout && outputStream != &cerr)
|
if (outputStream != &cout && outputStream != &cerr)
|
||||||
|
@ -344,11 +366,6 @@ main(int argc, char **argv)
|
||||||
echoCommandLine(argc, argv, *outputStream);
|
echoCommandLine(argc, argv, *outputStream);
|
||||||
ParamContext::showAllContexts(*configStream);
|
ParamContext::showAllContexts(*configStream);
|
||||||
|
|
||||||
// Now process the configuration hierarchy and create the SimObjects.
|
|
||||||
ConfigHierarchy configHierarchy(simConfigDB);
|
|
||||||
configHierarchy.build();
|
|
||||||
configHierarchy.createSimObjects();
|
|
||||||
|
|
||||||
// Do a second pass to finish initializing the sim objects
|
// Do a second pass to finish initializing the sim objects
|
||||||
SimObject::initAll();
|
SimObject::initAll();
|
||||||
|
|
||||||
|
|
48
sim/param.cc
48
sim/param.cc
|
@ -27,21 +27,21 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stdio.h> // for sscanf()
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "sim/param.hh"
|
|
||||||
#include "sim/sim_object.hh"
|
|
||||||
#include "base/inifile.hh"
|
#include "base/inifile.hh"
|
||||||
#include "sim/configfile.hh"
|
|
||||||
#include "sim/config_node.hh"
|
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
|
#include "base/range.hh"
|
||||||
#include "base/str.hh"
|
#include "base/str.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
|
#include "sim/config_node.hh"
|
||||||
|
#include "sim/configfile.hh"
|
||||||
|
#include "sim/param.hh"
|
||||||
|
#include "sim/sim_object.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -180,6 +180,22 @@ parseParam(const string &s, string &value)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool
|
||||||
|
parseParam(const string &s, Range<uint32_t> &value)
|
||||||
|
{
|
||||||
|
value = s;
|
||||||
|
return value.valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool
|
||||||
|
parseParam(const string &s, Range<uint64_t> &value)
|
||||||
|
{
|
||||||
|
value = s;
|
||||||
|
return value.valid();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// End of parseParam/showParam definitions. Now we move on to
|
// End of parseParam/showParam definitions. Now we move on to
|
||||||
// incorporate them into the Param/VectorParam parse() and showValue()
|
// incorporate them into the Param/VectorParam parse() and showValue()
|
||||||
|
@ -310,6 +326,9 @@ INSTANTIATE_PARAM_TEMPLATES(double, "double")
|
||||||
INSTANTIATE_PARAM_TEMPLATES(bool, "bool")
|
INSTANTIATE_PARAM_TEMPLATES(bool, "bool")
|
||||||
INSTANTIATE_PARAM_TEMPLATES(string, "string")
|
INSTANTIATE_PARAM_TEMPLATES(string, "string")
|
||||||
|
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(Range<uint64_t>, "uint64 range")
|
||||||
|
INSTANTIATE_PARAM_TEMPLATES(Range<uint32_t>, "uint32 range")
|
||||||
|
|
||||||
#undef INSTANTIATE_PARAM_TEMPLATES
|
#undef INSTANTIATE_PARAM_TEMPLATES
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -602,9 +621,8 @@ ParamContext::parseParams(IniFile &iniFile)
|
||||||
for (i = getParamList()->begin(); i != getParamList()->end(); ++i) {
|
for (i = getParamList()->begin(); i != getParamList()->end(); ++i) {
|
||||||
string string_value;
|
string string_value;
|
||||||
|
|
||||||
if (iniFile.findDefault(iniSection, (*i)->name, string_value)) {
|
if (iniFile.find(iniSection, (*i)->name, string_value))
|
||||||
(*i)->parse(string_value);
|
(*i)->parse(string_value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,18 +698,8 @@ ParamContext::printErrorProlog(ostream &os)
|
||||||
// SimObjectBuilder objects, which return non-NULL for configNode()).
|
// SimObjectBuilder objects, which return non-NULL for configNode()).
|
||||||
//
|
//
|
||||||
SimObject *
|
SimObject *
|
||||||
ParamContext::resolveSimObject(const string &_name)
|
ParamContext::resolveSimObject(const string &name)
|
||||||
{
|
{
|
||||||
// look for a colon
|
|
||||||
string::size_type i = _name.find(':');
|
|
||||||
string name = _name;
|
|
||||||
if (i != string::npos) {
|
|
||||||
// colon found: local object
|
|
||||||
// add as child to current node and create it
|
|
||||||
name = _name.substr(0, i);
|
|
||||||
string objConfigClassName = _name.substr(i + 1);
|
|
||||||
getConfigNode()->addChild(name, objConfigClassName);
|
|
||||||
}
|
|
||||||
ConfigNode *n = getConfigNode();
|
ConfigNode *n = getConfigNode();
|
||||||
return n ? n->resolveSimObject(name) : NULL;
|
return n ? n->resolveSimObject(name) : NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -397,19 +397,29 @@ END_INIT_SIM_OBJECT_PARAMS(LiveProcess)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(LiveProcess)
|
CREATE_SIM_OBJECT(LiveProcess)
|
||||||
{
|
{
|
||||||
// initialize file descriptors to default: same as simulator
|
string in = input;
|
||||||
int stdin_fd = input.isValid() ? Process::openInputFile(input) : 0;
|
string out = output;
|
||||||
int stdout_fd = output.isValid() ? Process::openOutputFile(output) : 1;
|
|
||||||
int stderr_fd = output.isValid() ? stdout_fd : 2;
|
|
||||||
|
|
||||||
// dummy for default env
|
// initialize file descriptors to default: same as simulator
|
||||||
vector<string> null_vec;
|
int stdin_fd, stdout_fd, stderr_fd;
|
||||||
|
|
||||||
|
if (in == "stdin" || in == "cin")
|
||||||
|
stdin_fd = STDIN_FILENO;
|
||||||
|
else
|
||||||
|
stdin_fd = Process::openInputFile(input);
|
||||||
|
|
||||||
|
if (out == "stdout" || out == "cout")
|
||||||
|
stdout_fd = STDOUT_FILENO;
|
||||||
|
else if (out == "stderr" || out == "cerr")
|
||||||
|
stdout_fd = STDERR_FILENO;
|
||||||
|
else
|
||||||
|
stdout_fd = Process::openOutputFile(out);
|
||||||
|
|
||||||
|
stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
|
||||||
|
|
||||||
return LiveProcess::create(getInstanceName(),
|
return LiveProcess::create(getInstanceName(),
|
||||||
stdin_fd, stdout_fd, stderr_fd,
|
stdin_fd, stdout_fd, stderr_fd,
|
||||||
cmd,
|
cmd, env);
|
||||||
env.isValid() ? env : null_vec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("LiveProcess", LiveProcess)
|
REGISTER_SIM_OBJECT("LiveProcess", LiveProcess)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# -*- mode:python -*-
|
# -*- mode:python -*-
|
||||||
|
|
||||||
# Copyright (c) 2004 The Regents of The University of Michigan
|
# Copyright (c) 2005 The Regents of The University of Michigan
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -26,25 +26,164 @@
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import os
|
import os, os.path, re
|
||||||
|
|
||||||
Import('env', 'obj_desc_files')
|
def WriteEmbeddedPyFile(target, source, path, name, ext):
|
||||||
|
if isinstance(source, str):
|
||||||
|
source = file(source, 'r')
|
||||||
|
|
||||||
my_obj_desc_files = map(lambda x: '../../' + x, obj_desc_files)
|
if isinstance(target, str):
|
||||||
|
target = file(target, 'w')
|
||||||
|
|
||||||
env.Command('m5odescs.py', my_obj_desc_files,
|
print >>target, "AddModule(%s, %s, %s, '''\\" % (`path`, `name`, `ext`)
|
||||||
'$TARGET.srcdir/load_odescs.py $_CPPDEFFLAGS $SOURCES $TARGET')
|
|
||||||
|
|
||||||
# Python modules to encapsulate
|
for line in source:
|
||||||
string_module_bases = Split('m5config m5configbase m5odescs')
|
line = line
|
||||||
string_modules = map(lambda x: x + '_as_string.py', string_module_bases)
|
# escape existing backslashes
|
||||||
|
line = line.replace('\\', '\\\\')
|
||||||
|
# escape existing triple quotes
|
||||||
|
line = line.replace("'''", r"\'\'\'")
|
||||||
|
|
||||||
for m in string_module_bases:
|
print >>target, line,
|
||||||
env.Command(m + '_as_string.py', m + '.py',
|
|
||||||
'$TARGET.srcdir/make_string_module.py $SOURCE $TARGET')
|
|
||||||
|
|
||||||
embedded_py_files = Split('string_importer.py') + string_modules
|
print >>target, "''')"
|
||||||
|
print >>target
|
||||||
|
|
||||||
env.Command('code.cc', embedded_py_files,
|
def WriteCFile(target, source, name):
|
||||||
'$TARGET.srcdir/make_c_file.py pyconfig_code $SOURCES $TARGET')
|
if isinstance(source, str):
|
||||||
|
source = file(source, 'r')
|
||||||
|
|
||||||
|
if isinstance(target, str):
|
||||||
|
target = file(target, 'w')
|
||||||
|
|
||||||
|
print >>target, 'const char %s_string[] = {' % name
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
from array import array
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
foo = array('B')
|
||||||
|
foo.fromfile(source, 10000)
|
||||||
|
l = [ str(i) for i in foo.tolist() ]
|
||||||
|
count += len(l)
|
||||||
|
for i in xrange(0,9999,20):
|
||||||
|
print >>target, ','.join(l[i:i+20]) + ','
|
||||||
|
except EOFError:
|
||||||
|
l = [ str(i) for i in foo.tolist() ]
|
||||||
|
count += len(l)
|
||||||
|
for i in xrange(0,len(l),20):
|
||||||
|
print >>target, ','.join(l[i:i+20]) + ','
|
||||||
|
print >>target, ','.join(l[i:]) + ','
|
||||||
|
|
||||||
|
print >>target, '};'
|
||||||
|
print >>target, 'const int %s_length = %d;' % (name, count)
|
||||||
|
print >>target
|
||||||
|
|
||||||
|
def splitpath(path):
|
||||||
|
dir,file = os.path.split(path)
|
||||||
|
path = []
|
||||||
|
assert(file)
|
||||||
|
while dir:
|
||||||
|
dir,base = os.path.split(dir)
|
||||||
|
path.insert(0, base)
|
||||||
|
return path, file
|
||||||
|
|
||||||
|
Import('env')
|
||||||
|
def MakeEmbeddedPyFile(target, source, env):
|
||||||
|
target = file(str(target[0]), 'w')
|
||||||
|
|
||||||
|
tree = {}
|
||||||
|
for src in source:
|
||||||
|
src = str(src)
|
||||||
|
path,pyfile = splitpath(src)
|
||||||
|
node = tree
|
||||||
|
for dir in path:
|
||||||
|
if not node.has_key(dir):
|
||||||
|
node[dir] = { }
|
||||||
|
node = node[dir]
|
||||||
|
|
||||||
|
name,ext = pyfile.split('.')
|
||||||
|
if name == '__init__':
|
||||||
|
node['.hasinit'] = True
|
||||||
|
node[pyfile] = (src,name,ext)
|
||||||
|
|
||||||
|
done = False
|
||||||
|
while not done:
|
||||||
|
done = True
|
||||||
|
for name,entry in tree.items():
|
||||||
|
if not isinstance(entry, dict): continue
|
||||||
|
if entry.has_key('.hasinit'): continue
|
||||||
|
|
||||||
|
done = False
|
||||||
|
del tree[name]
|
||||||
|
for key,val in entry.iteritems():
|
||||||
|
if tree.has_key(key):
|
||||||
|
raise NameError, \
|
||||||
|
"dir already has %s can't add it again" % key
|
||||||
|
tree[key] = val
|
||||||
|
|
||||||
|
files = []
|
||||||
|
def populate(node, path = []):
|
||||||
|
names = node.keys()
|
||||||
|
names.sort()
|
||||||
|
for name in names:
|
||||||
|
if name == '.hasinit':
|
||||||
|
continue
|
||||||
|
|
||||||
|
entry = node[name]
|
||||||
|
if isinstance(entry, dict):
|
||||||
|
if not entry.has_key('.hasinit'):
|
||||||
|
raise NameError, 'package directory missing __init__.py'
|
||||||
|
populate(entry, path + [ name ])
|
||||||
|
else:
|
||||||
|
pyfile,name,ext = entry
|
||||||
|
files.append((pyfile, path, name, ext))
|
||||||
|
populate(tree)
|
||||||
|
|
||||||
|
for pyfile, path, name, ext in files:
|
||||||
|
WriteEmbeddedPyFile(target, pyfile, path, name, ext)
|
||||||
|
|
||||||
|
CFileCounter = 0
|
||||||
|
def MakePythonCFile(target, source, env):
|
||||||
|
global CFileCounter
|
||||||
|
target = file(str(target[0]), 'w')
|
||||||
|
|
||||||
|
print >>target, '''\
|
||||||
|
#include "base/embedfile.hh"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
'''
|
||||||
|
for src in source:
|
||||||
|
src = str(src)
|
||||||
|
fname = os.path.basename(src)
|
||||||
|
name = 'embedded_file%d' % CFileCounter
|
||||||
|
CFileCounter += 1
|
||||||
|
WriteCFile(target, src, name)
|
||||||
|
print >>target, '''\
|
||||||
|
EmbedMap %(name)s("%(fname)s",
|
||||||
|
%(name)s_string, %(name)s_length);
|
||||||
|
|
||||||
|
''' % locals()
|
||||||
|
print >>target, '''\
|
||||||
|
|
||||||
|
/* namespace */ }
|
||||||
|
'''
|
||||||
|
|
||||||
|
embedded_py_files = ['m5config.py']
|
||||||
|
objpath = os.path.join(env['SRCDIR'], 'objects')
|
||||||
|
for root, dirs, files in os.walk(objpath, topdown=True):
|
||||||
|
for i,dir in enumerate(dirs):
|
||||||
|
if dir == 'SCCS':
|
||||||
|
del dirs[i]
|
||||||
|
break
|
||||||
|
|
||||||
|
assert(root.startswith(objpath))
|
||||||
|
for f in files:
|
||||||
|
if f.endswith('.mpy') or f.endswith('.py'):
|
||||||
|
embedded_py_files.append(os.path.join(root, f))
|
||||||
|
|
||||||
|
embedfile_hh = os.path.join(env['SRCDIR'], 'base/embedfile.hh')
|
||||||
|
env.Depends('embedded_py.cc', embedfile_hh)
|
||||||
|
env.Command('embedded_py.py', embedded_py_files, MakeEmbeddedPyFile)
|
||||||
|
env.Command('embedded_py.cc', ['importer.py', 'embedded_py.py'],
|
||||||
|
MakePythonCFile)
|
||||||
|
|
1250
sim/pyconfig/m5config.py
Normal file
1250
sim/pyconfig/m5config.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,723 +0,0 @@
|
||||||
# Copyright (c) 2004 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.
|
|
||||||
|
|
||||||
from __future__ import generators
|
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
#
|
|
||||||
# M5 Python Configuration Utility
|
|
||||||
#
|
|
||||||
# The basic idea is to write simple Python programs that build Python
|
|
||||||
# objects corresponding to M5 SimObjects for the deisred simulation
|
|
||||||
# configuration. For now, the Python emits a .ini file that can be
|
|
||||||
# parsed by M5. In the future, some tighter integration between M5
|
|
||||||
# and the Python interpreter may allow bypassing the .ini file.
|
|
||||||
#
|
|
||||||
# Each SimObject class in M5 is represented by a Python class with the
|
|
||||||
# same name. The Python inheritance tree mirrors the M5 C++ tree
|
|
||||||
# (e.g., SimpleCPU derives from BaseCPU in both cases, and all
|
|
||||||
# SimObjects inherit from a single SimObject base class). To specify
|
|
||||||
# an instance of an M5 SimObject in a configuration, the user simply
|
|
||||||
# instantiates the corresponding Python object. The parameters for
|
|
||||||
# that SimObject are given by assigning to attributes of the Python
|
|
||||||
# object, either using keyword assignment in the constructor or in
|
|
||||||
# separate assignment statements. For example:
|
|
||||||
#
|
|
||||||
# cache = BaseCache('my_cache', root, size=64*K)
|
|
||||||
# cache.hit_latency = 3
|
|
||||||
# cache.assoc = 8
|
|
||||||
#
|
|
||||||
# (The first two constructor arguments specify the name of the created
|
|
||||||
# cache and its parent node in the hierarchy.)
|
|
||||||
#
|
|
||||||
# The magic lies in the mapping of the Python attributes for SimObject
|
|
||||||
# classes to the actual SimObject parameter specifications. This
|
|
||||||
# allows parameter validity checking in the Python code. Continuing
|
|
||||||
# the example above, the statements "cache.blurfl=3" or
|
|
||||||
# "cache.assoc='hello'" would both result in runtime errors in Python,
|
|
||||||
# since the BaseCache object has no 'blurfl' parameter and the 'assoc'
|
|
||||||
# parameter requires an integer, respectively. This magic is done
|
|
||||||
# primarily by overriding the special __setattr__ method that controls
|
|
||||||
# assignment to object attributes.
|
|
||||||
#
|
|
||||||
# The Python module provides another class, ConfigNode, which is a
|
|
||||||
# superclass of SimObject. ConfigNode implements the parent/child
|
|
||||||
# relationship for building the configuration hierarchy tree.
|
|
||||||
# Concrete instances of ConfigNode can be used to group objects in the
|
|
||||||
# hierarchy, but do not correspond to SimObjects themselves (like a
|
|
||||||
# .ini section with "children=" but no "type=".
|
|
||||||
#
|
|
||||||
# Once a set of Python objects have been instantiated in a hierarchy,
|
|
||||||
# calling 'instantiate(obj)' (where obj is the root of the hierarchy)
|
|
||||||
# will generate a .ini file. See simple-4cpu.py for an example
|
|
||||||
# (corresponding to m5-test/simple-4cpu.ini).
|
|
||||||
#
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
#
|
|
||||||
# ConfigNode/SimObject classes
|
|
||||||
#
|
|
||||||
# The Python class hierarchy rooted by ConfigNode (which is the base
|
|
||||||
# class of SimObject, which in turn is the base class of all other M5
|
|
||||||
# SimObject classes) has special attribute behavior. In general, an
|
|
||||||
# object in this hierarchy has three categories of attribute-like
|
|
||||||
# things:
|
|
||||||
#
|
|
||||||
# 1. Regular Python methods and variables. These must start with an
|
|
||||||
# underscore to be treated normally.
|
|
||||||
#
|
|
||||||
# 2. SimObject parameters. These values are stored as normal Python
|
|
||||||
# attributes, but all assignments to these attributes are checked
|
|
||||||
# against the pre-defined set of parameters stored in the class's
|
|
||||||
# _param_dict dictionary. Assignments to attributes that do not
|
|
||||||
# correspond to predefined parameters, or that are not of the correct
|
|
||||||
# type, incur runtime errors.
|
|
||||||
#
|
|
||||||
# 3. Hierarchy children. The child nodes of a ConfigNode are stored
|
|
||||||
# in the node's _children dictionary, but can be accessed using the
|
|
||||||
# Python attribute dot-notation (just as they are printed out by the
|
|
||||||
# simulator). Children cannot be created using attribute assigment;
|
|
||||||
# they must be added by specifying the parent node in the child's
|
|
||||||
# constructor or using the '+=' operator.
|
|
||||||
|
|
||||||
# The SimObject parameters are the most complex, for a few reasons.
|
|
||||||
# First, both parameter descriptions and parameter values are
|
|
||||||
# inherited. Thus parameter description lookup must go up the
|
|
||||||
# inheritance chain like normal attribute lookup, but this behavior
|
|
||||||
# must be explicitly coded since the lookup occurs in each class's
|
|
||||||
# _param_dict attribute. Second, because parameter values can be set
|
|
||||||
# on SimObject classes (to implement default values), the parameter
|
|
||||||
# checking behavior must be enforced on class attribute assignments as
|
|
||||||
# well as instance attribute assignments. Finally, because we allow
|
|
||||||
# class specialization via inheritance (e.g., see the L1Cache class in
|
|
||||||
# the simple-4cpu.py example), we must do parameter checking even on
|
|
||||||
# class instantiation. To provide all these features, we use a
|
|
||||||
# metaclass to define most of the SimObject parameter behavior for
|
|
||||||
# this class hierarchy.
|
|
||||||
#
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
# The metaclass for ConfigNode (and thus for everything that derives
|
|
||||||
# from ConfigNode, including SimObject). This class controls how new
|
|
||||||
# classes that derive from ConfigNode are instantiated, and provides
|
|
||||||
# inherited class behavior (just like a class controls how instances
|
|
||||||
# of that class are instantiated, and provides inherited instance
|
|
||||||
# behavior).
|
|
||||||
class MetaConfigNode(type):
|
|
||||||
|
|
||||||
# __new__ is called before __init__, and is where the statements
|
|
||||||
# in the body of the class definition get loaded into the class's
|
|
||||||
# __dict__. We intercept this to filter out parameter assignments
|
|
||||||
# and only allow "private" attributes to be passed to the base
|
|
||||||
# __new__ (starting with underscore).
|
|
||||||
def __new__(cls, name, bases, dict):
|
|
||||||
priv_keys = [k for k in dict.iterkeys() if k.startswith('_')]
|
|
||||||
priv_dict = {}
|
|
||||||
for k in priv_keys: priv_dict[k] = dict[k]; del dict[k]
|
|
||||||
# entries left in dict will get passed to __init__, where we'll
|
|
||||||
# deal with them as params.
|
|
||||||
return super(MetaConfigNode, cls).__new__(cls, name, bases, priv_dict)
|
|
||||||
|
|
||||||
# initialization: start out with an empty param dict (makes life
|
|
||||||
# simpler if we can assume _param_dict is always valid). Also
|
|
||||||
# build inheritance list to simplify searching for inherited
|
|
||||||
# params. Finally set parameters specified in class definition
|
|
||||||
# (if any).
|
|
||||||
def __init__(cls, name, bases, dict):
|
|
||||||
super(MetaConfigNode, cls).__init__(cls, name, bases, {})
|
|
||||||
# initialize _param_dict to empty
|
|
||||||
cls._param_dict = {}
|
|
||||||
# __mro__ is the ordered list of classes Python uses for
|
|
||||||
# method resolution. We want to pick out the ones that have a
|
|
||||||
# _param_dict attribute for doing parameter lookups.
|
|
||||||
cls._param_bases = \
|
|
||||||
[c for c in cls.__mro__ if hasattr(c, '_param_dict')]
|
|
||||||
# initialize attributes with values from class definition
|
|
||||||
for (pname, value) in dict.items():
|
|
||||||
try:
|
|
||||||
setattr(cls, pname, value)
|
|
||||||
except Exception, exc:
|
|
||||||
print "Error setting '%s' to '%s' on class '%s'\n" \
|
|
||||||
% (pname, value, cls.__name__), exc
|
|
||||||
|
|
||||||
# set the class's parameter dictionary (called when loading
|
|
||||||
# class descriptions)
|
|
||||||
def set_param_dict(cls, param_dict):
|
|
||||||
# should only be called once (current one should be empty one
|
|
||||||
# from __init__)
|
|
||||||
assert not cls._param_dict
|
|
||||||
cls._param_dict = param_dict
|
|
||||||
# initialize attributes with default values
|
|
||||||
for (pname, param) in param_dict.items():
|
|
||||||
try:
|
|
||||||
setattr(cls, pname, param.default)
|
|
||||||
except Exception, exc:
|
|
||||||
print "Error setting '%s' default on class '%s'\n" \
|
|
||||||
% (pname, cls.__name__), exc
|
|
||||||
|
|
||||||
# Set the class's parameter dictionary given a code string of
|
|
||||||
# parameter initializers (as from an object description file).
|
|
||||||
# Note that the caller must pass in the namespace in which to
|
|
||||||
# execute the code (usually the caller's globals()), since if we
|
|
||||||
# call globals() from inside this function all we get is this
|
|
||||||
# module's internal scope.
|
|
||||||
def init_params(cls, init_code, ctx):
|
|
||||||
dict = {}
|
|
||||||
try:
|
|
||||||
exec fixPythonIndentation(init_code) in ctx, dict
|
|
||||||
except Exception, exc:
|
|
||||||
print "Error in %s.init_params:" % cls.__name__, exc
|
|
||||||
raise
|
|
||||||
cls.set_param_dict(dict)
|
|
||||||
|
|
||||||
# Lookup a parameter description by name in the given class. Use
|
|
||||||
# the _param_bases list defined in __init__ to go up the
|
|
||||||
# inheritance hierarchy if necessary.
|
|
||||||
def lookup_param(cls, param_name):
|
|
||||||
for c in cls._param_bases:
|
|
||||||
param = c._param_dict.get(param_name)
|
|
||||||
if param: return param
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Set attribute (called on foo.attr_name = value when foo is an
|
|
||||||
# instance of class cls).
|
|
||||||
def __setattr__(cls, attr_name, value):
|
|
||||||
# normal processing for private attributes
|
|
||||||
if attr_name.startswith('_'):
|
|
||||||
type.__setattr__(cls, attr_name, value)
|
|
||||||
return
|
|
||||||
# no '_': must be SimObject param
|
|
||||||
param = cls.lookup_param(attr_name)
|
|
||||||
if not param:
|
|
||||||
raise AttributeError, \
|
|
||||||
"Class %s has no parameter %s" % (cls.__name__, attr_name)
|
|
||||||
# It's ok: set attribute by delegating to 'object' class.
|
|
||||||
# Note the use of param.make_value() to verify/canonicalize
|
|
||||||
# the assigned value
|
|
||||||
type.__setattr__(cls, attr_name, param.make_value(value))
|
|
||||||
|
|
||||||
# generator that iterates across all parameters for this class and
|
|
||||||
# all classes it inherits from
|
|
||||||
def all_param_names(cls):
|
|
||||||
for c in cls._param_bases:
|
|
||||||
for p in c._param_dict.iterkeys():
|
|
||||||
yield p
|
|
||||||
|
|
||||||
# The ConfigNode class is the root of the special hierarchy. Most of
|
|
||||||
# the code in this class deals with the configuration hierarchy itself
|
|
||||||
# (parent/child node relationships).
|
|
||||||
class ConfigNode(object):
|
|
||||||
# Specify metaclass. Any class inheriting from ConfigNode will
|
|
||||||
# get this metaclass.
|
|
||||||
__metaclass__ = MetaConfigNode
|
|
||||||
|
|
||||||
# Constructor. Since bare ConfigNodes don't have parameters, just
|
|
||||||
# worry about the name and the parent/child stuff.
|
|
||||||
def __init__(self, _name, _parent=None):
|
|
||||||
# Type-check _name
|
|
||||||
if type(_name) != str:
|
|
||||||
if isinstance(_name, ConfigNode):
|
|
||||||
# special case message for common error of trying to
|
|
||||||
# coerce a SimObject to the wrong type
|
|
||||||
raise TypeError, \
|
|
||||||
"Attempt to coerce %s to %s" \
|
|
||||||
% (_name.__class__.__name__, self.__class__.__name__)
|
|
||||||
else:
|
|
||||||
raise TypeError, \
|
|
||||||
"%s name must be string (was %s, %s)" \
|
|
||||||
% (self.__class__.__name__, _name, type(_name))
|
|
||||||
# if specified, parent must be a subclass of ConfigNode
|
|
||||||
if _parent != None and not isinstance(_parent, ConfigNode):
|
|
||||||
raise TypeError, \
|
|
||||||
"%s parent must be ConfigNode subclass (was %s, %s)" \
|
|
||||||
% (self.__class__.__name__, _name, type(_name))
|
|
||||||
self._name = _name
|
|
||||||
self._parent = _parent
|
|
||||||
if (_parent):
|
|
||||||
_parent._add_child(self)
|
|
||||||
self._children = {}
|
|
||||||
# keep a list of children in addition to the dictionary keys
|
|
||||||
# so we can remember the order they were added and print them
|
|
||||||
# out in that order.
|
|
||||||
self._child_list = []
|
|
||||||
|
|
||||||
# When printing (e.g. to .ini file), just give the name.
|
|
||||||
def __str__(self):
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
# Catch attribute accesses that could be requesting children, and
|
|
||||||
# satisfy them. Note that __getattr__ is called only if the
|
|
||||||
# regular attribute lookup fails, so private and parameter lookups
|
|
||||||
# will already be satisfied before we ever get here.
|
|
||||||
def __getattr__(self, name):
|
|
||||||
try:
|
|
||||||
return self._children[name]
|
|
||||||
except KeyError:
|
|
||||||
raise AttributeError, \
|
|
||||||
"Node '%s' has no attribute or child '%s'" \
|
|
||||||
% (self._name, name)
|
|
||||||
|
|
||||||
# Set attribute. All attribute assignments go through here. Must
|
|
||||||
# be private attribute (starts with '_') or valid parameter entry.
|
|
||||||
# Basically identical to MetaConfigClass.__setattr__(), except
|
|
||||||
# this sets attributes on specific instances rather than on classes.
|
|
||||||
def __setattr__(self, attr_name, value):
|
|
||||||
if attr_name.startswith('_'):
|
|
||||||
object.__setattr__(self, attr_name, value)
|
|
||||||
return
|
|
||||||
# not private; look up as param
|
|
||||||
param = self.__class__.lookup_param(attr_name)
|
|
||||||
if not param:
|
|
||||||
raise AttributeError, \
|
|
||||||
"Class %s has no parameter %s" \
|
|
||||||
% (self.__class__.__name__, attr_name)
|
|
||||||
# It's ok: set attribute by delegating to 'object' class.
|
|
||||||
# Note the use of param.make_value() to verify/canonicalize
|
|
||||||
# the assigned value.
|
|
||||||
v = param.make_value(value)
|
|
||||||
object.__setattr__(self, attr_name, v)
|
|
||||||
|
|
||||||
# A little convenient magic: if the parameter is a ConfigNode
|
|
||||||
# (or vector of ConfigNodes, or anything else with a
|
|
||||||
# '_set_parent_if_none' function attribute) that does not have
|
|
||||||
# a parent (and so is not part of the configuration
|
|
||||||
# hierarchy), then make this node its parent.
|
|
||||||
if hasattr(v, '_set_parent_if_none'):
|
|
||||||
v._set_parent_if_none(self)
|
|
||||||
|
|
||||||
def _path(self):
|
|
||||||
# Return absolute path from root.
|
|
||||||
if not self._parent and self._name != 'Universe':
|
|
||||||
print >> sys.stderr, "Warning:", self._name, "has no parent"
|
|
||||||
parent_path = self._parent and self._parent._path()
|
|
||||||
if parent_path and parent_path != 'Universe':
|
|
||||||
return parent_path + '.' + self._name
|
|
||||||
else:
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
# Add a child to this node.
|
|
||||||
def _add_child(self, new_child):
|
|
||||||
# set child's parent before calling this function
|
|
||||||
assert new_child._parent == self
|
|
||||||
if not isinstance(new_child, ConfigNode):
|
|
||||||
raise TypeError, \
|
|
||||||
"ConfigNode child must also be of class ConfigNode"
|
|
||||||
if new_child._name in self._children:
|
|
||||||
raise AttributeError, \
|
|
||||||
"Node '%s' already has a child '%s'" \
|
|
||||||
% (self._name, new_child._name)
|
|
||||||
self._children[new_child._name] = new_child
|
|
||||||
self._child_list += [new_child]
|
|
||||||
|
|
||||||
# operator overload for '+='. You can say "node += child" to add
|
|
||||||
# a child that was created with parent=None. An early attempt
|
|
||||||
# at playing with syntax; turns out not to be that useful.
|
|
||||||
def __iadd__(self, new_child):
|
|
||||||
if new_child._parent != None:
|
|
||||||
raise AttributeError, \
|
|
||||||
"Node '%s' already has a parent" % new_child._name
|
|
||||||
new_child._parent = self
|
|
||||||
self._add_child(new_child)
|
|
||||||
return self
|
|
||||||
|
|
||||||
# Set this instance's parent to 'parent' if it doesn't already
|
|
||||||
# have one. See ConfigNode.__setattr__().
|
|
||||||
def _set_parent_if_none(self, parent):
|
|
||||||
if self._parent == None:
|
|
||||||
parent += self
|
|
||||||
|
|
||||||
# Print instance info to .ini file.
|
|
||||||
def _instantiate(self):
|
|
||||||
print '[' + self._path() + ']' # .ini section header
|
|
||||||
if self._child_list:
|
|
||||||
# instantiate children in same order they were added for
|
|
||||||
# backward compatibility (else we can end up with cpu1
|
|
||||||
# before cpu0).
|
|
||||||
print 'children =', ' '.join([c._name for c in self._child_list])
|
|
||||||
self._instantiateParams()
|
|
||||||
print
|
|
||||||
# recursively dump out children
|
|
||||||
for c in self._child_list:
|
|
||||||
c._instantiate()
|
|
||||||
|
|
||||||
# ConfigNodes have no parameters. Overridden by SimObject.
|
|
||||||
def _instantiateParams(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# SimObject is a minimal extension of ConfigNode, implementing a
|
|
||||||
# hierarchy node that corresponds to an M5 SimObject. It prints out a
|
|
||||||
# "type=" line to indicate its SimObject class, prints out the
|
|
||||||
# assigned parameters corresponding to its class, and allows
|
|
||||||
# parameters to be set by keyword in the constructor. Note that most
|
|
||||||
# of the heavy lifting for the SimObject param handling is done in the
|
|
||||||
# MetaConfigNode metaclass.
|
|
||||||
|
|
||||||
class SimObject(ConfigNode):
|
|
||||||
# initialization: like ConfigNode, but handle keyword-based
|
|
||||||
# parameter initializers.
|
|
||||||
def __init__(self, _name, _parent=None, **params):
|
|
||||||
ConfigNode.__init__(self, _name, _parent)
|
|
||||||
for param, value in params.items():
|
|
||||||
setattr(self, param, value)
|
|
||||||
|
|
||||||
# print type and parameter values to .ini file
|
|
||||||
def _instantiateParams(self):
|
|
||||||
print "type =", self.__class__._name
|
|
||||||
for pname in self.__class__.all_param_names():
|
|
||||||
value = getattr(self, pname)
|
|
||||||
if value != None:
|
|
||||||
print pname, '=', value
|
|
||||||
|
|
||||||
def _sim_code(cls):
|
|
||||||
name = cls.__name__
|
|
||||||
param_names = cls._param_dict.keys()
|
|
||||||
param_names.sort()
|
|
||||||
code = "BEGIN_DECLARE_SIM_OBJECT_PARAMS(%s)\n" % name
|
|
||||||
decls = [" " + cls._param_dict[pname].sim_decl(pname) \
|
|
||||||
for pname in param_names]
|
|
||||||
code += "\n".join(decls) + "\n"
|
|
||||||
code += "END_DECLARE_SIM_OBJECT_PARAMS(%s)\n\n" % name
|
|
||||||
code += "BEGIN_INIT_SIM_OBJECT_PARAMS(%s)\n" % name
|
|
||||||
inits = [" " + cls._param_dict[pname].sim_init(pname) \
|
|
||||||
for pname in param_names]
|
|
||||||
code += ",\n".join(inits) + "\n"
|
|
||||||
code += "END_INIT_SIM_OBJECT_PARAMS(%s)\n\n" % name
|
|
||||||
return code
|
|
||||||
_sim_code = classmethod(_sim_code)
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
#
|
|
||||||
# Parameter description classes
|
|
||||||
#
|
|
||||||
# The _param_dict dictionary in each class maps parameter names to
|
|
||||||
# either a Param or a VectorParam object. These objects contain the
|
|
||||||
# parameter description string, the parameter type, and the default
|
|
||||||
# value (loaded from the PARAM section of the .odesc files). The
|
|
||||||
# make_value() method on these objects is used to force whatever value
|
|
||||||
# is assigned to the parameter to the appropriate type.
|
|
||||||
#
|
|
||||||
# Note that the default values are loaded into the class's attribute
|
|
||||||
# space when the parameter dictionary is initialized (in
|
|
||||||
# MetaConfigNode.set_param_dict()); after that point they aren't
|
|
||||||
# used.
|
|
||||||
#
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
def isNullPointer(value):
|
|
||||||
return isinstance(value, NullSimObject)
|
|
||||||
|
|
||||||
# Regular parameter.
|
|
||||||
class Param(object):
|
|
||||||
# Constructor. E.g., Param(Int, "number of widgets", 5)
|
|
||||||
def __init__(self, ptype, desc, default=None):
|
|
||||||
self.ptype = ptype
|
|
||||||
self.ptype_name = self.ptype.__name__
|
|
||||||
self.desc = desc
|
|
||||||
self.default = default
|
|
||||||
|
|
||||||
# Convert assigned value to appropriate type. Force parameter
|
|
||||||
# value (rhs of '=') to ptype (or None, which means not set).
|
|
||||||
def make_value(self, value):
|
|
||||||
# nothing to do if None or already correct type. Also allow NULL
|
|
||||||
# pointer to be assigned where a SimObject is expected.
|
|
||||||
if value == None or isinstance(value, self.ptype) or \
|
|
||||||
isNullPointer(value) and issubclass(self.ptype, ConfigNode):
|
|
||||||
return value
|
|
||||||
# this type conversion will raise an exception if it's illegal
|
|
||||||
return self.ptype(value)
|
|
||||||
|
|
||||||
def sim_decl(self, name):
|
|
||||||
return 'Param<%s> %s;' % (self.ptype_name, name)
|
|
||||||
|
|
||||||
def sim_init(self, name):
|
|
||||||
if self.default == None:
|
|
||||||
return 'INIT_PARAM(%s, "%s")' % (name, self.desc)
|
|
||||||
else:
|
|
||||||
return 'INIT_PARAM_DFLT(%s, "%s", %s)' % \
|
|
||||||
(name, self.desc, str(self.default))
|
|
||||||
|
|
||||||
# The _VectorParamValue class is a wrapper for vector-valued
|
|
||||||
# parameters. The leading underscore indicates that users shouldn't
|
|
||||||
# see this class; it's magically generated by VectorParam. The
|
|
||||||
# parameter values are stored in the 'value' field as a Python list of
|
|
||||||
# whatever type the parameter is supposed to be. The only purpose of
|
|
||||||
# storing these instead of a raw Python list is that we can override
|
|
||||||
# the __str__() method to not print out '[' and ']' in the .ini file.
|
|
||||||
class _VectorParamValue(object):
|
|
||||||
def __init__(self, value):
|
|
||||||
assert isinstance(value, list) or value == None
|
|
||||||
self.value = value
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return ' '.join(map(str, self.value))
|
|
||||||
|
|
||||||
# Set member instance's parents to 'parent' if they don't already
|
|
||||||
# have one. Extends "magic" parenting of ConfigNodes to vectors
|
|
||||||
# of ConfigNodes as well. See ConfigNode.__setattr__().
|
|
||||||
def _set_parent_if_none(self, parent):
|
|
||||||
if self.value and hasattr(self.value[0], '_set_parent_if_none'):
|
|
||||||
for v in self.value:
|
|
||||||
v._set_parent_if_none(parent)
|
|
||||||
|
|
||||||
# Vector-valued parameter description. Just like Param, except that
|
|
||||||
# the value is a vector (list) of the specified type instead of a
|
|
||||||
# single value.
|
|
||||||
class VectorParam(Param):
|
|
||||||
|
|
||||||
# Inherit Param constructor. However, the resulting parameter
|
|
||||||
# will be a list of ptype rather than a single element of ptype.
|
|
||||||
def __init__(self, ptype, desc, default=None):
|
|
||||||
Param.__init__(self, ptype, desc, default)
|
|
||||||
|
|
||||||
# Convert assigned value to appropriate type. If the RHS is not a
|
|
||||||
# list or tuple, it generates a single-element list.
|
|
||||||
def make_value(self, value):
|
|
||||||
if value == None: return value
|
|
||||||
if isinstance(value, list) or isinstance(value, tuple):
|
|
||||||
# list: coerce each element into new list
|
|
||||||
val_list = [Param.make_value(self, v) for v in iter(value)]
|
|
||||||
else:
|
|
||||||
# singleton: coerce & wrap in a list
|
|
||||||
val_list = [Param.make_value(self, value)]
|
|
||||||
# wrap list in _VectorParamValue (see above)
|
|
||||||
return _VectorParamValue(val_list)
|
|
||||||
|
|
||||||
def sim_decl(self, name):
|
|
||||||
return 'VectorParam<%s> %s;' % (self.ptype_name, name)
|
|
||||||
|
|
||||||
# sim_init inherited from Param
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
#
|
|
||||||
# Parameter Types
|
|
||||||
#
|
|
||||||
# Though native Python types could be used to specify parameter types
|
|
||||||
# (the 'ptype' field of the Param and VectorParam classes), it's more
|
|
||||||
# flexible to define our own set of types. This gives us more control
|
|
||||||
# over how Python expressions are converted to values (via the
|
|
||||||
# __init__() constructor) and how these values are printed out (via
|
|
||||||
# the __str__() conversion method). Eventually we'll need these types
|
|
||||||
# to correspond to distinct C++ types as well.
|
|
||||||
#
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
# Integer parameter type.
|
|
||||||
class Int(object):
|
|
||||||
# Constructor. Value must be Python int or long (long integer).
|
|
||||||
def __init__(self, value):
|
|
||||||
t = type(value)
|
|
||||||
if t == int or t == long:
|
|
||||||
self.value = value
|
|
||||||
else:
|
|
||||||
raise TypeError, "Int param got value %s %s" % (repr(value), t)
|
|
||||||
|
|
||||||
# Use Python string conversion. Note that this puts an 'L' on the
|
|
||||||
# end of long integers; we can strip that off here if it gives us
|
|
||||||
# trouble.
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.value)
|
|
||||||
|
|
||||||
# Counter, Addr, and Tick are just aliases for Int for now.
|
|
||||||
class Counter(Int):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Addr(Int):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Tick(Int):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Boolean parameter type.
|
|
||||||
class Bool(object):
|
|
||||||
|
|
||||||
# Constructor. Typically the value will be one of the Python bool
|
|
||||||
# constants True or False (or the aliases true and false below).
|
|
||||||
# Also need to take integer 0 or 1 values since bool was not a
|
|
||||||
# distinct type in Python 2.2. Parse a bunch of boolean-sounding
|
|
||||||
# strings too just for kicks.
|
|
||||||
def __init__(self, value):
|
|
||||||
t = type(value)
|
|
||||||
if t == bool:
|
|
||||||
self.value = value
|
|
||||||
elif t == int or t == long:
|
|
||||||
if value == 1:
|
|
||||||
self.value = True
|
|
||||||
elif value == 0:
|
|
||||||
self.value = False
|
|
||||||
elif t == str:
|
|
||||||
v = value.lower()
|
|
||||||
if v == "true" or v == "t" or v == "yes" or v == "y":
|
|
||||||
self.value = True
|
|
||||||
elif v == "false" or v == "f" or v == "no" or v == "n":
|
|
||||||
self.value = False
|
|
||||||
# if we didn't set it yet, it must not be something we understand
|
|
||||||
if not hasattr(self, 'value'):
|
|
||||||
raise TypeError, "Bool param got value %s %s" % (repr(value), t)
|
|
||||||
|
|
||||||
# Generate printable string version.
|
|
||||||
def __str__(self):
|
|
||||||
if self.value: return "true"
|
|
||||||
else: return "false"
|
|
||||||
|
|
||||||
# String-valued parameter.
|
|
||||||
class String(object):
|
|
||||||
# Constructor. Value must be Python string.
|
|
||||||
def __init__(self, value):
|
|
||||||
t = type(value)
|
|
||||||
if t == str:
|
|
||||||
self.value = value
|
|
||||||
else:
|
|
||||||
raise TypeError, "String param got value %s %s" % (repr(value), t)
|
|
||||||
|
|
||||||
# Generate printable string version. Not too tricky.
|
|
||||||
def __str__(self):
|
|
||||||
return self.value
|
|
||||||
|
|
||||||
# Special class for NULL pointers. Note the special check in
|
|
||||||
# make_param_value() above that lets these be assigned where a
|
|
||||||
# SimObject is required.
|
|
||||||
class NullSimObject(object):
|
|
||||||
# Constructor. No parameters, nothing to do.
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "NULL"
|
|
||||||
|
|
||||||
# The only instance you'll ever need...
|
|
||||||
NULL = NullSimObject()
|
|
||||||
|
|
||||||
# Enumerated types are a little more complex. The user specifies the
|
|
||||||
# type as Enum(foo) where foo is either a list or dictionary of
|
|
||||||
# alternatives (typically strings, but not necessarily so). (In the
|
|
||||||
# long run, the integer value of the parameter will be the list index
|
|
||||||
# or the corresponding dictionary value. For now, since we only check
|
|
||||||
# that the alternative is valid and then spit it into a .ini file,
|
|
||||||
# there's not much point in using the dictionary.)
|
|
||||||
|
|
||||||
# What Enum() must do is generate a new type encapsulating the
|
|
||||||
# provided list/dictionary so that specific values of the parameter
|
|
||||||
# can be instances of that type. We define two hidden internal
|
|
||||||
# classes (_ListEnum and _DictEnum) to serve as base classes, then
|
|
||||||
# derive the new type from the appropriate base class on the fly.
|
|
||||||
|
|
||||||
|
|
||||||
# Base class for list-based Enum types.
|
|
||||||
class _ListEnum(object):
|
|
||||||
# Constructor. Value must be a member of the type's map list.
|
|
||||||
def __init__(self, value):
|
|
||||||
if value in self.map:
|
|
||||||
self.value = value
|
|
||||||
self.index = self.map.index(value)
|
|
||||||
else:
|
|
||||||
raise TypeError, "Enum param got bad value '%s' (not in %s)" \
|
|
||||||
% (value, self.map)
|
|
||||||
|
|
||||||
# Generate printable string version of value.
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.value)
|
|
||||||
|
|
||||||
class _DictEnum(object):
|
|
||||||
# Constructor. Value must be a key in the type's map dictionary.
|
|
||||||
def __init__(self, value):
|
|
||||||
if value in self.map:
|
|
||||||
self.value = value
|
|
||||||
self.index = self.map[value]
|
|
||||||
else:
|
|
||||||
raise TypeError, "Enum param got bad value '%s' (not in %s)" \
|
|
||||||
% (value, self.map.keys())
|
|
||||||
|
|
||||||
# Generate printable string version of value.
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.value)
|
|
||||||
|
|
||||||
# Enum metaclass... calling Enum(foo) generates a new type (class)
|
|
||||||
# that derives from _ListEnum or _DictEnum as appropriate.
|
|
||||||
class Enum(type):
|
|
||||||
# counter to generate unique names for generated classes
|
|
||||||
counter = 1
|
|
||||||
|
|
||||||
def __new__(cls, map):
|
|
||||||
if isinstance(map, dict):
|
|
||||||
base = _DictEnum
|
|
||||||
keys = map.keys()
|
|
||||||
elif isinstance(map, list):
|
|
||||||
base = _ListEnum
|
|
||||||
keys = map
|
|
||||||
else:
|
|
||||||
raise TypeError, "Enum map must be list or dict (got %s)" % map
|
|
||||||
classname = "Enum%04d" % Enum.counter
|
|
||||||
Enum.counter += 1
|
|
||||||
# New class derives from selected base, and gets a 'map'
|
|
||||||
# attribute containing the specified list or dict.
|
|
||||||
return type.__new__(cls, classname, (base,), { 'map': map })
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# "Constants"... handy aliases for various values.
|
|
||||||
#
|
|
||||||
|
|
||||||
# For compatibility with C++ bool constants.
|
|
||||||
false = False
|
|
||||||
true = True
|
|
||||||
|
|
||||||
# Some memory range specifications use this as a default upper bound.
|
|
||||||
MAX_ADDR = 2**64 - 1
|
|
||||||
|
|
||||||
# For power-of-two sizing, e.g. 64*K gives an integer value 65536.
|
|
||||||
K = 1024
|
|
||||||
M = K*K
|
|
||||||
G = K*M
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
|
|
||||||
# Munge an arbitrary Python code string to get it to execute (mostly
|
|
||||||
# dealing with indentation). Stolen from isa_parser.py... see
|
|
||||||
# comments there for a more detailed description.
|
|
||||||
def fixPythonIndentation(s):
|
|
||||||
# get rid of blank lines first
|
|
||||||
s = re.sub(r'(?m)^\s*\n', '', s);
|
|
||||||
if (s != '' and re.match(r'[ \t]', s[0])):
|
|
||||||
s = 'if 1:\n' + s
|
|
||||||
return s
|
|
||||||
|
|
||||||
# Hook to generate C++ parameter code.
|
|
||||||
def gen_sim_code(file):
|
|
||||||
for objname in sim_object_list:
|
|
||||||
print >> file, eval("%s._sim_code()" % objname)
|
|
||||||
|
|
||||||
# The final hook to generate .ini files. Called from configuration
|
|
||||||
# script once config is built.
|
|
||||||
def instantiate(*objs):
|
|
||||||
for obj in objs:
|
|
||||||
obj._instantiate()
|
|
||||||
|
|
||||||
|
|
126
sim/universe.cc
126
sim/universe.cc
|
@ -36,9 +36,10 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "sim/universe.hh"
|
#include "sim/builder.hh"
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "sim/param.hh"
|
#include "sim/sim_object.hh"
|
||||||
|
#include "sim/universe.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -53,60 +54,13 @@ string outputDirectory;
|
||||||
ostream *outputStream;
|
ostream *outputStream;
|
||||||
ostream *configStream;
|
ostream *configStream;
|
||||||
|
|
||||||
class UniverseParamContext : public ParamContext
|
// Dummy Object
|
||||||
|
class Root : public SimObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UniverseParamContext(const string &is)
|
Root(const std::string &name) : SimObject(name) {}
|
||||||
: ParamContext(is, OutputInitPhase) {}
|
|
||||||
void checkParams();
|
|
||||||
};
|
};
|
||||||
|
Root *root = NULL;
|
||||||
UniverseParamContext universe("Universe");
|
|
||||||
|
|
||||||
Param<Tick> universe_freq(&universe, "frequency", "tick frequency",
|
|
||||||
200000000);
|
|
||||||
|
|
||||||
Param<string> universe_output_dir(&universe, "output_dir",
|
|
||||||
"directory to output data to",
|
|
||||||
".");
|
|
||||||
Param<string> universe_output_file(&universe, "output_file",
|
|
||||||
"file to dump simulator output to",
|
|
||||||
"cout");
|
|
||||||
Param<string> universe_config_output_file(&universe, "config_output_file",
|
|
||||||
"file to dump simulator config to",
|
|
||||||
"m5config.out");
|
|
||||||
|
|
||||||
void
|
|
||||||
UniverseParamContext::checkParams()
|
|
||||||
{
|
|
||||||
ticksPerSecond = universe_freq;
|
|
||||||
double freq = double(ticksPerSecond);
|
|
||||||
__ticksPerMS = freq / 1.0e3;
|
|
||||||
__ticksPerUS = freq / 1.0e6;
|
|
||||||
__ticksPerNS = freq / 1.0e9;
|
|
||||||
__ticksPerPS = freq / 1.0e12;
|
|
||||||
|
|
||||||
if (universe_output_dir.isValid()) {
|
|
||||||
outputDirectory = universe_output_dir;
|
|
||||||
|
|
||||||
// guarantee that directory ends with a '/'
|
|
||||||
if (outputDirectory[outputDirectory.size() - 1] != '/')
|
|
||||||
outputDirectory += "/";
|
|
||||||
|
|
||||||
if (mkdir(outputDirectory.c_str(), 0777) < 0) {
|
|
||||||
if (errno != EEXIST) {
|
|
||||||
panic("%s\ncould not make output directory: %s\n",
|
|
||||||
strerror(errno), outputDirectory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outputStream = makeOutputStream(universe_output_file);
|
|
||||||
configStream = universe_config_output_file.isValid()
|
|
||||||
? makeOutputStream(universe_config_output_file)
|
|
||||||
: outputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::ostream *
|
std::ostream *
|
||||||
makeOutputStream(std::string &name)
|
makeOutputStream(std::string &name)
|
||||||
|
@ -146,4 +100,70 @@ closeOutputStream(std::ostream *os)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Root)
|
||||||
|
|
||||||
|
Param<bool> full_system;
|
||||||
|
Param<Tick> frequency;
|
||||||
|
Param<string> output_dir;
|
||||||
|
Param<string> output_file;
|
||||||
|
Param<string> config_output_file;
|
||||||
|
|
||||||
|
END_DECLARE_SIM_OBJECT_PARAMS(Root)
|
||||||
|
|
||||||
|
BEGIN_INIT_SIM_OBJECT_PARAMS(Root)
|
||||||
|
|
||||||
|
INIT_PARAM_DFLT(full_system, "full system simulation", true),
|
||||||
|
INIT_PARAM_DFLT(frequency, "tick frequency", 200000000),
|
||||||
|
INIT_PARAM_DFLT(output_dir, "directory to output data to", "."),
|
||||||
|
INIT_PARAM_DFLT(output_file, "file to dump simulator output to", "cout"),
|
||||||
|
INIT_PARAM_DFLT(config_output_file, "file to dump simulator config to",
|
||||||
|
"m5config.out")
|
||||||
|
|
||||||
|
END_INIT_SIM_OBJECT_PARAMS(Root)
|
||||||
|
|
||||||
|
CREATE_SIM_OBJECT(Root)
|
||||||
|
{
|
||||||
|
#ifdef FULL_SYSTEM
|
||||||
|
if (!bool(full_system))
|
||||||
|
panic("FULL_SYSTEM compiled and configuration not full_system");
|
||||||
|
#else
|
||||||
|
if (bool(full_system))
|
||||||
|
panic("FULL_SYSTEM not compiled but configuration is full_system");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (root)
|
||||||
|
panic("only one root object allowed!");
|
||||||
|
root = new Root(getInstanceName());
|
||||||
|
|
||||||
|
ticksPerSecond = frequency;
|
||||||
|
double freq = double(ticksPerSecond);
|
||||||
|
__ticksPerMS = freq / 1.0e3;
|
||||||
|
__ticksPerUS = freq / 1.0e6;
|
||||||
|
__ticksPerNS = freq / 1.0e9;
|
||||||
|
__ticksPerPS = freq / 1.0e12;
|
||||||
|
|
||||||
|
if (output_dir.isValid()) {
|
||||||
|
outputDirectory = output_dir;
|
||||||
|
|
||||||
|
// guarantee that directory ends with a '/'
|
||||||
|
if (outputDirectory[outputDirectory.size() - 1] != '/')
|
||||||
|
outputDirectory += "/";
|
||||||
|
|
||||||
|
if (mkdir(outputDirectory.c_str(), 0777) < 0) {
|
||||||
|
if (errno != EEXIST) {
|
||||||
|
panic("%s\ncould not make output directory: %s\n",
|
||||||
|
strerror(errno), outputDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStream = makeOutputStream(output_file);
|
||||||
|
configStream = config_output_file.isValid()
|
||||||
|
? makeOutputStream(config_output_file)
|
||||||
|
: outputStream;
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_SIM_OBJECT("Root", Root)
|
||||||
|
|
||||||
|
|
56
test/genini.py
Normal file
56
test/genini.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
# Copyright (c) 2005 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.
|
||||||
|
|
||||||
|
import getopt, os, sys
|
||||||
|
|
||||||
|
sys.path.append('..')
|
||||||
|
sys.path.append('../configs/kernel')
|
||||||
|
sys.path.append('../sim/pyconfig')
|
||||||
|
|
||||||
|
from importer import mpy_exec
|
||||||
|
from m5config import *
|
||||||
|
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(sys.argv[1:], '-E:')
|
||||||
|
for o,a in opts:
|
||||||
|
if o == '-E':
|
||||||
|
offset = a.find('=')
|
||||||
|
if offset == -1:
|
||||||
|
name = a
|
||||||
|
value = True
|
||||||
|
else:
|
||||||
|
name = a[:offset]
|
||||||
|
value = a[offset+1:]
|
||||||
|
env[name] = value
|
||||||
|
except getopt.GetoptError:
|
||||||
|
sys.exit('Improper Usage')
|
||||||
|
|
||||||
|
for arg in args:
|
||||||
|
mpy_exec(file(arg, 'r'), globals())
|
||||||
|
|
||||||
|
if globals().has_key('root') and isinstance(root, type) \
|
||||||
|
and issubclass(root, Root):
|
||||||
|
instantiate(root)
|
Loading…
Reference in a new issue