Major changes to how SimObjects are created and initialized. Almost all

creation and initialization now happens in python.  Parameter objects
are generated and initialized by python.  The .ini file is now solely for
debugging purposes and is not used in construction of the objects in any
way.

--HG--
extra : convert_revision : 7e722873e417cb3d696f2e34c35ff488b7bff4ed
This commit is contained in:
Nathan Binkert
2007-07-23 21:51:38 -07:00
parent 552097b92e
commit abc76f20cb
136 changed files with 2044 additions and 6740 deletions

View File

@@ -34,13 +34,11 @@ SimObject('Root.py')
SimObject('System.py')
Source('async.cc')
Source('builder.cc')
Source('core.cc')
Source('debug.cc')
Source('eventq.cc')
Source('faults.cc')
Source('main.cc')
Source('param.cc')
Source('root.cc')
Source('serialize.cc')
Source('sim_events.cc')

View File

@@ -1,179 +0,0 @@
/*
* Copyright (c) 2003-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.
*
* Authors: Nathan Binkert
*/
#include <assert.h>
#include "base/inifile.hh"
#include "base/misc.hh"
#include "sim/builder.hh"
#include "sim/host.hh"
#include "sim/sim_object.hh"
#include "sim/core.hh"
using namespace std;
SimObjectBuilder::SimObjectBuilder(const std::string &_iniSection)
: ParamContext(_iniSection)
{
}
SimObjectBuilder::~SimObjectBuilder()
{
}
///////////////////////////////////////////
//
// SimObjectBuilder member definitions
//
///////////////////////////////////////////
// override ParamContext::parseParams() to check params based on
// instance name first. If not found, then check based on iniSection
// (as in default ParamContext implementation).
void
SimObjectBuilder::parseParams(IniFile &iniFile)
{
iniFilePtr = &iniFile; // set object member
ParamList::iterator i;
for (i = paramList->begin(); i != paramList->end(); ++i) {
string string_value;
if (iniFile.find(iniSection, (*i)->name, string_value))
(*i)->parse(string_value);
}
}
void
SimObjectBuilder::printErrorProlog(ostream &os)
{
ccprintf(os, "Error creating object '%s':\n", iniSection);
}
////////////////////////////////////////////////////////////////////////
//
// SimObjectClass member definitions
//
////////////////////////////////////////////////////////////////////////
// Map of class names to SimObjectBuilder creation functions. Need to
// make this a pointer so we can force initialization on the first
// reference; otherwise, some SimObjectClass constructors may be invoked
// before the classMap constructor.
map<string,SimObjectClass::CreateFunc> *SimObjectClass::classMap = NULL;
// SimObjectClass constructor: add mapping to classMap
SimObjectClass::SimObjectClass(const string &className, CreateFunc createFunc)
{
if (classMap == NULL)
classMap = new map<string,SimObjectClass::CreateFunc>();
if ((*classMap)[className])
panic("Error: simulation object class '%s' redefined\n", className);
// add className --> createFunc to class map
(*classMap)[className] = createFunc;
}
//
//
SimObject *
SimObjectClass::createObject(IniFile &configDB, const std::string &iniSection)
{
string type;
if (!configDB.find(iniSection, "type", type)) {
// no C++ type associated with this object
return NULL;
}
// look up className to get appropriate createFunc
if (classMap->find(type) == classMap->end())
panic("Simulator object type '%s' not found.\n", type);
CreateFunc createFunc = (*classMap)[type];
// call createFunc with config hierarchy node to get object
// builder instance (context with parameters for object creation)
SimObjectBuilder *objectBuilder = (*createFunc)(iniSection);
assert(objectBuilder != NULL);
// parse all parameters in context to generate parameter values
objectBuilder->parseParams(configDB);
// now create the actual simulation object
SimObject *object = objectBuilder->create();
assert(object != NULL);
// echo object parameters to stats file (for documenting the
// config used to generate the associated stats)
ccprintf(*configStream, "[%s]\n", object->name());
ccprintf(*configStream, "type=%s\n", type);
objectBuilder->showParams(*configStream);
ccprintf(*configStream, "\n");
// done with the SimObjectBuilder now
delete objectBuilder;
return object;
}
//
// static method:
//
void
SimObjectClass::describeAllClasses(ostream &os)
{
map<string,CreateFunc>::iterator iter;
for (iter = classMap->begin(); iter != classMap->end(); ++iter) {
const string &className = iter->first;
CreateFunc createFunc = iter->second;
os << "[" << className << "]\n";
// create dummy object builder just to instantiate parameters
SimObjectBuilder *objectBuilder = (*createFunc)("");
// now get the object builder to describe ite params
objectBuilder->describeParams(os);
os << endl;
// done with the object builder now
delete objectBuilder;
}
}

View File

@@ -1,223 +0,0 @@
/*
* Copyright (c) 2003-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.
*
* Authors: Nathan Binkert
*/
#ifndef __BUILDER_HH__
#define __BUILDER_HH__
#include <iosfwd>
#include <list>
#include <map>
#include <vector>
#include "sim/param.hh"
class SimObject;
//
// A SimObjectBuilder serves as an evaluation context for a set of
// parameters that describe a specific instance of a SimObject. This
// evaluation context corresponds to a section in the .ini file (as
// with the base ParamContext) plus an optional node in the
// configuration hierarchy (the configNode member) for resolving
// SimObject references. SimObjectBuilder is an abstract superclass;
// derived classes specialize the class for particular subclasses of
// SimObject (e.g., BaseCache).
//
// For typical usage, see the definition of
// SimObjectClass::createObject().
//
class SimObjectBuilder : public ParamContext
{
public:
SimObjectBuilder(const std::string &_iniSection);
virtual ~SimObjectBuilder();
// call parse() on all params in this context to convert string
// representations to parameter values
virtual void parseParams(IniFile &iniFile);
// parameter error prolog (override of ParamContext)
virtual void printErrorProlog(std::ostream &);
// generate the name for this SimObject instance (derived from the
// configuration hierarchy node label and position)
virtual const std::string &getInstanceName() { return iniSection; }
// Create the actual SimObject corresponding to the parameter
// values in this context. This function is overridden in derived
// classes to call a specific constructor for a particular
// subclass of SimObject.
virtual SimObject *create() = 0;
};
//
// Handy macros for initializing parameter members of classes derived
// from SimObjectBuilder. Assumes that the name of the parameter
// member object is the same as the textual parameter name seen by the
// user. (Note that '#p' is expanded by the preprocessor to '"p"'.)
//
#define INIT_PARAM(p, desc) p(this, #p, desc)
#define INIT_PARAM_DFLT(p, desc, dflt) p(this, #p, desc, dflt)
//
// Initialize an enumeration variable... assumes that 'map' is the
// name of an array of mappings (char * for SimpleEnumParam, or
// EnumParamMap for MappedEnumParam).
//
#define INIT_ENUM_PARAM(p, desc, map) \
p(this, #p, desc, map, sizeof(map)/sizeof(map[0]))
#define INIT_ENUM_PARAM_DFLT(p, desc, map, dflt) \
p(this, #p, desc, map, sizeof(map)/sizeof(map[0]), dflt)
//
// An instance of SimObjectClass corresponds to a class derived from
// SimObject. The SimObjectClass instance serves to bind the string
// name (found in the config file) to a function that creates an
// instance of the appropriate derived class.
//
// This would be much cleaner in Smalltalk or Objective-C, where types
// are first-class objects themselves.
//
class SimObjectClass
{
public:
// Type CreateFunc is a pointer to a function that creates a new
// simulation object builder based on a .ini-file parameter
// section (specified by the first string argument), a unique name
// for the object (specified by the second string argument), and
// an optional config hierarchy node (specified by the third
// argument). A pointer to the new SimObjectBuilder is returned.
typedef SimObjectBuilder *(*CreateFunc)(const std::string &iniSection);
static std::map<std::string,CreateFunc> *classMap;
// Constructor. For example:
//
// SimObjectClass baseCacheClass("BaseCache", newBaseCacheBuilder);
//
SimObjectClass(const std::string &className, CreateFunc createFunc);
// create SimObject given name of class and pointer to
// configuration hierarchy node
static SimObject *createObject(IniFile &configDB,
const std::string &iniSection);
// print descriptions of all parameters registered with all
// SimObject classes
static void describeAllClasses(std::ostream &os);
};
//
// Macros to encapsulate the magic of declaring & defining
// SimObjectBuilder and SimObjectClass objects
//
#define BEGIN_DECLARE_SIM_OBJECT_PARAMS(OBJ_CLASS) \
class OBJ_CLASS##Builder : public SimObjectBuilder \
{ \
public:
#define END_DECLARE_SIM_OBJECT_PARAMS(OBJ_CLASS) \
\
OBJ_CLASS##Builder(const std::string &iniSection); \
virtual ~OBJ_CLASS##Builder() {} \
\
OBJ_CLASS *create(); \
};
#define BEGIN_INIT_SIM_OBJECT_PARAMS(OBJ_CLASS) \
OBJ_CLASS##Builder::OBJ_CLASS##Builder(const std::string &iSec) \
: SimObjectBuilder(iSec),
#define END_INIT_SIM_OBJECT_PARAMS(OBJ_CLASS) \
{ \
}
#define CREATE_SIM_OBJECT(OBJ_CLASS) \
OBJ_CLASS *OBJ_CLASS##Builder::create()
#define REGISTER_SIM_OBJECT(CLASS_NAME, OBJ_CLASS) \
SimObjectBuilder * \
new##OBJ_CLASS##Builder(const std::string &iniSection) \
{ \
return new OBJ_CLASS##Builder(iniSection); \
} \
\
SimObjectClass the##OBJ_CLASS##Class(CLASS_NAME, \
new##OBJ_CLASS##Builder); \
\
/* see param.hh */ \
DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, OBJ_CLASS)
/* Macros that use the namespace for sinic... yuk. */
#define BEGIN_DECLARE_SIM_OBJECT_PARAMS_WNS(NAME_SPACE, OBJ_CLASS) \
class NAME_SPACE##OBJ_CLASS##Builder : public SimObjectBuilder \
{ \
public:
#define END_DECLARE_SIM_OBJECT_PARAMS_WNS(NAME_SPACE, OBJ_CLASS) \
\
NAME_SPACE##OBJ_CLASS##Builder(const std::string &iniSection); \
virtual ~NAME_SPACE##OBJ_CLASS##Builder() {} \
\
NAME_SPACE::OBJ_CLASS *create(); \
};
#define BEGIN_INIT_SIM_OBJECT_PARAMS_WNS(NAME_SPACE, OBJ_CLASS) \
NAME_SPACE::OBJ_CLASS##Builder::OBJ_CLASS##Builder(const std::string &iSec) \
: SimObjectBuilder(iSec),
#define END_INIT_SIM_OBJECT_PARAMS_WNS(NAME_SPACE, OBJ_CLASS) \
{ \
}
#define CREATE_SIM_OBJECT_WNS(NAME_SPACE, OBJ_CLASS) \
NAME_SPACE::OBJ_CLASS *NAME_SPACE##OBJ_CLASS##Builder::create()
#define REGISTER_SIM_OBJECT_WNS(NAME_SPACE, CLASS_NAME, OBJ_CLASS) \
SimObjectBuilder * \
new##NAME_SPACEi##OBJ_CLASS##Builder(const std::string &iniSection) \
{ \
return new NAME_SPACE##OBJ_CLASS##Builder(iniSection); \
} \
\
SimObjectClass the##NAME_SPACE##OBJ_CLASS##Class(CLASS_NAME, \
new##NAME_SPACE##OBJ_CLASS##Builder); \
\
/* see param.hh */ \
DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, NAME_SPACE##OBJ_CLASS)
#endif // __BUILDER_HH__

View File

@@ -98,7 +98,6 @@ setOutputDir(const string &dir)
}
ostream *outputStream;
ostream *configStream;
void
setOutputFile(const string &file)

View File

@@ -75,9 +75,6 @@ extern std::ostream *outputStream;
void setOutputFile(const std::string &file);
void setOutputDir(const std::string &dir);
/// Output stream for configuration dump.
extern std::ostream *configStream;
struct Callback;
void registerExitCallback(Callback *callback);
void doExitCleanup();

View File

@@ -38,7 +38,6 @@
#include "sim/debug.hh"
#include "sim/eventq.hh"
#include "sim/param.hh"
#include "sim/sim_events.hh"
using namespace std;

View File

@@ -1,700 +0,0 @@
/*
* Copyright (c) 2002-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.
*
* Authors: Steve Reinhardt
*/
#include <algorithm>
#include <cassert>
#include <list>
#include <string>
#include <vector>
#include "base/inifile.hh"
#include "base/misc.hh"
#include "base/range.hh"
#include "base/str.hh"
#include "base/trace.hh"
#include "sim/param.hh"
#include "sim/sim_object.hh"
using namespace std;
////////////////////////////////////////////////////////////////////////
//
// BaseParam member definitions
//
////////////////////////////////////////////////////////////////////////
void
BaseParam::die(const string &err) const
{
context->printErrorProlog(cerr);
cerr << " parameter '" << name << "': "
<< err << endl;
abort();
}
////////////////////////////////////////////////////////////////////////
//
// Param<T> and VectorParam<T> member definitions
//
// We implement parsing & displaying values for various parameter
// types T using a set of overloaded functions:
//
// - parseParam(string s, T &value) parses s into value
// - showParam(ostream &os, T &value) displays value on os
//
// By making these independent functions, we can reuse the same code
// for type T in both Param<T> and VectorParam<T>.
//
// For enum types, the parseParam function requires additional
// arguments, in which case we must specialize the Param<T>::parse and
// VectorParam<T>::parse calls as well.
//
// Type-specific instances come first, followed by more generic
// templated versions and their instantiations.
//
////////////////////////////////////////////////////////////////////////
//
// The base implementations use to_number for parsing and '<<' for
// displaying, suitable for integer types.
//
template <class T>
bool
parseParam(const string &s, T &value)
{
return to_number(s, value);
}
template <class T>
void
showParam(ostream &os, T const &value)
{
os << value;
}
//
// Template specializations:
// - char (8-bit integer)
// - floating-point types
// - bool
// - string
//
// Treat 8-bit ints (chars) as ints on output, not as chars
template <>
void
showParam(ostream &os, const char &value)
{
os << (int)value;
}
template <>
void
showParam(ostream &os, const unsigned char &value)
{
os << (unsigned int)value;
}
// Use sscanf() for FP types as to_number() only handles integers
template <>
bool
parseParam(const string &s, float &value)
{
return (sscanf(s.c_str(), "%f", &value) == 1);
}
template <>
bool
parseParam(const string &s, double &value)
{
return (sscanf(s.c_str(), "%lf", &value) == 1);
}
// Be flexible about what we take for bool
template <>
bool
parseParam(const string &s, bool &value)
{
const string &ls = to_lower(s);
if (ls == "true" || ls == "t" || ls == "yes" || ls == "y" || ls == "1") {
value = true;
return true;
}
if (ls == "false" || ls == "f" || ls == "no" || ls == "n" || ls == "0") {
value = false;
return true;
}
return false;
}
// Display bools as strings
template <>
void
showParam(ostream &os, const bool &value)
{
os << (value ? "true" : "false");
}
// String requires no processing to speak of
template <>
bool
parseParam(const string &s, string &value)
{
value = s;
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
// incorporate them into the Param/VectorParam parse() and showValue()
// methods.
//
// These definitions for Param<T>::parse and VectorParam<T>::parse
// work for any type for which parseParam() takes only two arguments
// (i.e., all the fundamental types like int, bool, etc.), thanks to
// overloading.
template <class T>
void
Param<T>::parse(const string &s)
{
if (parseParam(s, value)) {
wasSet = true;
}
else {
string err("could not parse \"");
err += s;
err += "\"";
die(err);
}
}
template <class T>
void
VectorParam<T>::parse(const string &s)
{
if (s.empty()) {
wasSet = true;
return;
}
vector<string> tokens;
tokenize(tokens, s, ' ');
value.resize(tokens.size());
for (int i = 0; i < tokens.size(); i++) {
// need to parse into local variable to handle vector<bool>,
// for which operator[] returns a special reference class
// that's not the same as 'bool&', (since it's a packed
// vector)
T scalar_value;
if (!parseParam(tokens[i], scalar_value)) {
string err("could not parse \"");
err += s;
err += "\"";
die(err);
}
// assign parsed value to vector
value[i] = scalar_value;
}
wasSet = true;
}
// These definitions for Param<T>::showValue() and
// VectorParam<T>::showValue() work for any type where showParam()
// takes only two arguments (i.e., everything but the SimpleEnum and
// MappedEnum classes).
template <class T>
void
Param<T>::showValue(ostream &os) const
{
showParam(os, value);
}
template <class T>
void
VectorParam<T>::showValue(ostream &os) const
{
for (int i = 0; i < value.size(); i++) {
if (i != 0) {
os << " ";
}
showParam(os, value[i]);
}
}
#ifdef INSURE_BUILD
#define INSTANTIATE_PARAM_TEMPLATES(type, typestr) \
void Param<type>::showType(ostream &os) const { os << typestr; } \
void VectorParam<type>::showType(ostream &os) const { \
os << "vector of " << typestr; \
} \
template Param<type>; \
template VectorParam<type>;
#else
// instantiate all four methods (parse/show, scalar/vector) for basic
// types that can use the above templates
#define INSTANTIATE_PARAM_TEMPLATES(type, typestr) \
template bool parseParam<type>(const string &s, type &value); \
template void showParam<type>(ostream &os, type const &value); \
template void Param<type>::parse(const string &); \
template void VectorParam<type>::parse(const string &); \
template void Param<type>::showValue(ostream &) const; \
template void VectorParam<type>::showValue(ostream &) const; \
template <> void Param<type>::showType(ostream &os) const { os << typestr; } \
template <> void VectorParam<type>::showType(ostream &os) const { \
os << "vector of " << typestr; \
}
#endif
INSTANTIATE_PARAM_TEMPLATES(unsigned long long, "ull")
INSTANTIATE_PARAM_TEMPLATES(signed long long, "sll")
INSTANTIATE_PARAM_TEMPLATES(unsigned long, "uns long")
INSTANTIATE_PARAM_TEMPLATES(signed long, "long")
INSTANTIATE_PARAM_TEMPLATES(unsigned int, "uns")
INSTANTIATE_PARAM_TEMPLATES(signed int, "int")
INSTANTIATE_PARAM_TEMPLATES(unsigned short, "uns short")
INSTANTIATE_PARAM_TEMPLATES(signed short, "short")
INSTANTIATE_PARAM_TEMPLATES(unsigned char, "uns char")
INSTANTIATE_PARAM_TEMPLATES(signed char, "char")
INSTANTIATE_PARAM_TEMPLATES(float, "float")
INSTANTIATE_PARAM_TEMPLATES(double, "double")
INSTANTIATE_PARAM_TEMPLATES(bool, "bool")
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
//
// SimpleEnumParam & MappedEnumParam must specialize their parse(),
// showValue(), and showType() methods.
//
//
// SimpleEnumParam & SimpleEnumVectorParam
//
bool
parseEnumParam(const char *const *map, const int num_values,
const string &s, int &value)
{
for (int i = 0; i < num_values; ++i) {
if (s == map[i]) {
value = i;
return true;
}
}
return false;
}
void
showEnumParam(ostream &os,
const char *const *map, const int num_values,
int value)
{
assert(0 <= value && value < num_values);
os << map[value];
}
void
showEnumType(ostream &os,
const char *const *map, const int num_values)
{
os << "{" << map[0];
for (int i = 1; i < num_values; ++i)
os << "," << map[i];
os << "}";
}
//
// MappedEnumParam & MappedEnumVectorParam
//
bool
parseEnumParam(const EnumParamMap *map, const int num_values,
const string &s, int &value)
{
for (int i = 0; i < num_values; ++i) {
if (s == map[i].name) {
value = map[i].value;
return true;
}
}
return false;
}
void
showEnumParam(ostream &os,
const EnumParamMap *map, const int num_values,
int value)
{
for (int i = 0; i < num_values; ++i) {
if (value == map[i].value) {
os << map[i].name;
return;
}
}
// if we can't find a reverse mapping just print the int value
os << value;
}
void
showEnumType(ostream &os,
const EnumParamMap *map, const int num_values)
{
os << "{" << map[0].name;
for (int i = 1; i < num_values; ++i)
os << "," << map[i].name;
os << "}";
}
template <class Map>
void
EnumParam<Map>::parse(const string &s)
{
if (parseEnumParam(map, num_values, s, value)) {
wasSet = true;
} else {
string err("no match for enum string \"");
err += s;
err += "\"";
die(err);
}
}
template <class Map>
void
EnumVectorParam<Map>::parse(const string &s)
{
vector<string> tokens;
if (s.empty()) {
wasSet = true;
return;
}
tokenize(tokens, s, ' ');
value.resize(tokens.size());
for (int i = 0; i < tokens.size(); i++) {
if (!parseEnumParam(map, num_values, tokens[i], value[i])) {
string err("no match for enum string \"");
err += s;
err += "\"";
die(err);
}
}
wasSet = true;
}
template <class Map>
void
EnumParam<Map>::showValue(ostream &os) const
{
showEnumParam(os, map, num_values, value);
}
template <class Map>
void
EnumVectorParam<Map>::showValue(ostream &os) const
{
for (int i = 0; i < value.size(); i++) {
if (i != 0) {
os << " ";
}
showEnumParam(os, map, num_values, value[i]);
}
}
template <class Map>
void
EnumParam<Map>::showType(ostream &os) const
{
showEnumType(os, map, num_values);
}
template <class Map>
void
EnumVectorParam<Map>::showType(ostream &os) const
{
os << "vector of";
showEnumType(os, map, num_values);
}
template class EnumParam<const char *>;
template class EnumVectorParam<const char *>;
template class EnumParam<EnumParamMap>;
template class EnumVectorParam<EnumParamMap>;
////////////////////////////////////////////////////////////////////////
//
// SimObjectBaseParam methods
//
////////////////////////////////////////////////////////////////////////
bool
parseSimObjectParam(ParamContext *context, const string &s, SimObject *&value)
{
SimObject *obj;
if (to_lower(s) == "null") {
// explicitly set to null by user; assume that's OK
obj = NULL;
}
else {
// defined in main.cc
extern SimObject *resolveSimObject(const string &);
obj = resolveSimObject(s);
if (obj == NULL)
return false;
}
value = obj;
return true;
}
void
SimObjectBaseParam::showValue(ostream &os, SimObject *value) const
{
os << (value ? value->name() : "null");
}
void
SimObjectBaseParam::parse(const string &s, SimObject *&value)
{
if (parseSimObjectParam(context, s, value)) {
wasSet = true;
}
else {
string err("could not resolve object name \"");
err += s;
err += "\"";
die(err);
}
}
void
SimObjectBaseParam::parse(const string &s, vector<SimObject *>&value)
{
vector<string> tokens;
tokenize(tokens, s, ' ');
value.resize(tokens.size());
for (int i = 0; i < tokens.size(); i++) {
if (!parseSimObjectParam(context, tokens[i], value[i])) {
string err("could not resolve object name \"");
err += s;
err += "\"";
die(err);
}
}
wasSet = true;
}
////////////////////////////////////////////////////////////////////////
//
// ParamContext member definitions
//
////////////////////////////////////////////////////////////////////////
ParamContext::ParamContext(const string &_iniSection)
: iniFilePtr(NULL), // initialized on call to parseParams()
iniSection(_iniSection), paramList(NULL)
{
}
void
ParamContext::addParam(BaseParam *param)
{
getParamList()->push_back(param);
}
void
ParamContext::parseParams(IniFile &iniFile)
{
iniFilePtr = &iniFile; // set object member
ParamList::iterator i;
for (i = getParamList()->begin(); i != getParamList()->end(); ++i) {
string string_value;
if (iniFile.find(iniSection, (*i)->name, string_value))
(*i)->parse(string_value);
}
}
// Check parameter values for validity & consistency. Default
// implementation is no-op; derive subclass & override to add
// actual functionality here.
void
ParamContext::checkParams()
{
// nada
}
// Clean up context-related objects at end of execution. Default
// implementation is no-op; derive subclass & override to add actual
// functionality here.
void
ParamContext::cleanup()
{
// nada
}
void
ParamContext::describeParams(ostream &os)
{
ParamList::iterator i;
for (i = getParamList()->begin(); i != getParamList()->end(); ++i) {
BaseParam *p = *i;
os << p->name << " (";
p->showType(os);
os << "): " << p->description << "\n";
}
}
void
ParamContext::showParams(ostream &os)
{
ParamList::iterator i;
for (i = getParamList()->begin(); i != getParamList()->end(); ++i) {
BaseParam *p = *i;
if (p->isValid()) {
os << p->name << "=";
p->showValue(os);
os << endl;
}
else {
os << "// "<< p->name << " not specified" << endl;
}
}
}
void
ParamContext::printErrorProlog(ostream &os)
{
os << "Parameter error in section [" << iniSection << "]: " << endl;
}
void
parseTime(const std::vector<int> &time, struct tm *tm)
{
memset(tm, 0, sizeof(struct tm));
// UNIX is years since 1900
tm->tm_year = time[0] - 1900;
// Python starts at 1, UNIX starts at 0
tm->tm_mon = time[1] - 1;
tm->tm_mday = time[2];
tm->tm_hour = time[3];
tm->tm_min = time[4];
tm->tm_sec = time[5];
// Python has 0 as Monday, UNIX is 0 as sunday
tm->tm_wday = time[6] + 1;
if (tm->tm_wday > 6)
tm->tm_wday -= 7;
// Python starts at 1, Unix starts at 0
tm->tm_yday = time[7] - 1;
}

View File

@@ -1,740 +0,0 @@
/*
* Copyright (c) 2002-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.
*
* Authors: Steve Reinhardt
*/
#ifndef __SIM_PARAM_HH__
#define __SIM_PARAM_HH__
#include <iostream>
#include <list>
#include <string>
#include <vector>
#include "sim/startup.hh"
// forward decls
class IniFile;
class BaseParam;
class SimObject;
//
// The context of a parameter definition... usually a subclass of
// SimObjectBuilder (which derives from ParamContext), but abstracted
// here to support more global simulator control parameters as well.
//
class ParamContext : protected StartupCallback
{
protected:
// .ini file (database) for parameter lookup... initialized on call
// to parseParams()
IniFile *iniFilePtr;
// .ini file section for parameter lookup
const std::string iniSection;
typedef std::vector<BaseParam *> ParamList;
// list of parameters defined in this context
ParamList *paramList;
ParamList *getParamList() {
if (!paramList)
paramList = new ParamList;
return paramList;
}
public:
/// Constructor.
/// @param _iniSection Name of .ini section corresponding to this context.
/// @param _initPhase Initialization phase (see InitPhase).
ParamContext(const std::string &_iniSection);
virtual ~ParamContext() {}
// add a parameter to the context... called from the parameter
// object's constructor (see BaseParam::BaseParam())
void addParam(BaseParam *);
// call parse() on all params in this context to convert string
// representations to parameter values
virtual void parseParams(IniFile &iniFile);
// Check parameter values for validity & consistency. Default
// implementation is no-op; derive subclass & override to add
// actual functionality here
virtual void checkParams();
// Clean up at end of execution: close file descriptors, etc.
// Default implementation is no-op; derive subclass & override to
// add actual functionality here
virtual void cleanup();
// dump parameter descriptions
void describeParams(std::ostream &);
// Display the parameters & values used
void showParams(std::ostream &);
// print context information for parameter error
virtual void printErrorProlog(std::ostream &);
// generate the name for this instance of this context (used as a
// prefix to create unique names in resolveSimObject()
virtual const std::string &getInstanceName() { return iniSection; }
};
//
// Base class for all parameter objects
//
class BaseParam
{
public:
ParamContext *context;
std::string name;
std::string description; // text description for help message
bool wasSet; // true if parameter was set by user
bool hasDefault; // true if parameter has default value
BaseParam(ParamContext *_context, const std::string &_name,
const std::string &_description, bool _hasDefault)
: context(_context), name(_name), description(_description),
wasSet(false), hasDefault(_hasDefault)
{
context->addParam(this);
}
virtual ~BaseParam() {}
// a parameter is valid only if its value was set by the user or
// it has a default value
bool isValid() const
{
return (wasSet || hasDefault);
}
// set value by parsing string
virtual void parse(const std::string &s) = 0;
// display value to stream
virtual void showValue(std::ostream &) const = 0;
// display type to stream
virtual void showType(std::ostream &) const = 0;
// signal parse or usage error
virtual void die(const std::string &err) const;
};
//
// Template classes to specialize parameters to specific types.
//
// Param<T> is for single-valued (scalar) parameters of type T.
// VectorParam<T> is for multi-valued (vector) parameters of type T.
// These are specified in the .ini file as a space-delimited list of
// arguments.
//
template <class T>
class Param : public BaseParam
{
protected:
T value;
public:
// Param with default value: set value to default
Param(ParamContext *context,
const std::string &name, const std::string &description, T dfltValue)
: BaseParam(context, name, description, true),
value(dfltValue)
{
}
// Param with no default value: leave value uninitialized
Param(ParamContext *context,
const std::string &name, const std::string &description)
: BaseParam(context, name, description, false)
{
}
virtual ~Param() {}
operator T&()
{
// if we attempt to reference an invalid parameter (i.e., one
// with no default value that was not set by the user), die.
if (!isValid())
die("not found");
return value;
}
T returnValue() const { return value; }
// display value to stream
virtual void showValue(std::ostream &os) const;
// display type to stream
virtual void showType(std::ostream &) const;
// set value by parsing string
virtual void parse(const std::string &s);
};
//
// Template class for vector-valued parameters (lists)
//
template <class T>
class VectorParam : public BaseParam
{
protected:
std::vector<T> value;
public:
typedef typename std::vector<T>::size_type size_type;
// Param with default value: set value to default
VectorParam(ParamContext *context, const std::string &name,
const std::string &description,
const std::vector<T> &dfltValue)
: BaseParam(context, name, description, true),
value(dfltValue)
{
}
// Param with no default value: leave value uninitialized
VectorParam(ParamContext *context,
const std::string &name, const std::string &description)
: BaseParam(context, name, description, false)
{
}
virtual ~VectorParam() {}
// basic vector access methods
size_type size() const
{
if (!isValid())
die("not found");
return value.size();
}
const T &operator[](size_type n) const
{
if (!isValid())
die("not found");
return value[n];
}
// return reference to value vector
operator std::vector<T>&()
{
if (!isValid())
die("not found");
return value;
}
// display value to stream
virtual void showValue(std::ostream &os) const;
// display type to stream
virtual void showType(std::ostream &) const;
// set value by parsing string
virtual void parse(const std::string &s);
};
//
// Specialization of Param<int> and VectorParam<int> to handle
// enumerated types is done in two ways, using SimpleEnumParam and
// MappedEnumParam (and their vector counterparts,
// SimpleEnumVectorParam and MappedEnumVectorParam). SimpleEnumParam
// takes an array of strings and maps them to integers based on array
// index. MappedEnumParam takes an array of string-to-int mappings,
// allowing for mapping strings to non-contiguous integer values, or
// mapping multiple strings to the same integer value.
//
// Both SimpleEnumParam and MappedEnumParam are implemented using a
// single template class, EnumParam<Map>, which takes the type of the map
// as a parameter (const char * or EnumParamMap). Similarly,
// SimpleEnumVectorParam and MappedEnumVectorParam are both
// implemented using EnumVectorParam<Map>.
//
template <class Map>
class EnumParam : public Param<int>
{
const int num_values;
const Map *map;
public:
// Param with default value: set value to default
EnumParam(ParamContext *context,
const std::string &name, const std::string &description,
const Map *_map, int _num_values,
int dfltValue)
: Param<int>(context, name, description, dfltValue),
num_values(_num_values), map(_map)
{
}
// Param with no default value: leave value uninitialized
EnumParam(ParamContext *context,
const std::string &name, const std::string &description,
const Map *_map, int _num_values)
: Param<int>(context, name, description),
num_values(_num_values), map(_map)
{
}
virtual ~EnumParam() {}
// display value to stream
virtual void showValue(std::ostream &os) const;
// display type to stream
virtual void showType(std::ostream &) const;
// set value by parsing string
virtual void parse(const std::string &s);
};
//
// Vector counterpart to SimpleEnumParam
//
template <class Map>
class EnumVectorParam : public VectorParam<int>
{
const int num_values;
const Map *map;
public:
// Param with default value: set value to default
EnumVectorParam(ParamContext *context,
const std::string &name, const std::string &description,
const Map *_map, int _num_values,
std::vector<int> &dfltValue)
: VectorParam<int>(context, name, description, dfltValue),
num_values(_num_values), map(_map)
{
}
// Param with no default value: leave value uninitialized
EnumVectorParam(ParamContext *context,
const std::string &name, const std::string &description,
const Map *_map, int _num_values)
: VectorParam<int>(context, name, description),
num_values(_num_values), map(_map)
{
}
virtual ~EnumVectorParam() {}
// display value to stream
virtual void showValue(std::ostream &os) const;
// display type to stream
virtual void showType(std::ostream &) const;
// set value by parsing string
virtual void parse(const std::string &s);
};
// Specialize EnumParam for a particular enumeration type ENUM
// (automates casting to get value of enum type)
template <class ENUM>
class SimpleEnumParam : public EnumParam<const char *>
{
public:
SimpleEnumParam(ParamContext *context,
const std::string &name, const std::string &description,
const char **_map, int _num_values,
ENUM dfltValue)
: EnumParam<const char *>(context, name, description,
_map, _num_values, (int)dfltValue)
{
}
SimpleEnumParam(ParamContext *context,
const std::string &name, const std::string &description,
const char **_map, int _num_values)
: EnumParam<const char *>(context, name, description,
_map, _num_values)
{
}
operator ENUM() const
{
if (!isValid())
die("not found");
return (ENUM)value;
}
};
// Specialize EnumParam for a particular enumeration type ENUM
// (automates casting to get value of enum type)
template <class ENUM>
class SimpleEnumVectorParam : public EnumVectorParam<const char *>
{
public:
// skip default value constructor: too much pain to convert
// vector<ENUM> initializer to vector<int>
SimpleEnumVectorParam(ParamContext *context,
const std::string &name,
const std::string &description,
const char **_map, int _num_values)
: EnumVectorParam<const char *>(context, name, description,
_map, _num_values)
{
}
ENUM operator[](size_type n)
{
if (!isValid())
die("not found");
return (ENUM)value[n];
}
};
//
// Handle enums via string-to-int map (see comment above).
//
// An array of string-to-int mappings must be supplied using the
// following type.
typedef struct {
const char *name;
int value;
} EnumParamMap;
// Specialize EnumParam for a particular enumeration type ENUM
// (automates casting to get value of enum type)
template <class ENUM>
class MappedEnumParam : public EnumParam<EnumParamMap>
{
public:
MappedEnumParam(ParamContext *context,
const std::string &name, const std::string &description,
const EnumParamMap *_map, int _num_values,
ENUM dfltValue)
: EnumParam<EnumParamMap>(context, name, description,
_map, _num_values, (int)dfltValue)
{
}
MappedEnumParam(ParamContext *context,
const std::string &name, const std::string &description,
const EnumParamMap *_map, int _num_values)
: EnumParam<EnumParamMap>(context, name, description,
_map, _num_values)
{
}
operator ENUM()
{
if (!isValid())
die("not found");
return (ENUM)value[this->n];
}
};
// Specialize EnumParam for a particular enumeration type ENUM
// (automates casting to get value of enum type)
template <class ENUM>
class MappedEnumVectorParam : public EnumVectorParam<EnumParamMap>
{
public:
// skip default value constructor: too much pain to convert
// vector<ENUM> initializer to vector<int>
MappedEnumVectorParam(ParamContext *context,
const std::string &name,
const std::string &description,
const EnumParamMap *_map, int _num_values)
: EnumVectorParam<EnumParamMap>(context, name, description,
_map, _num_values)
{
}
ENUM operator[](size_type n)
{
if (!isValid())
die("not found");
return (ENUM)value[n];
}
};
//
// Parameters that point to other simulation objects (e.g. caches,
// busses, etc.) are handled by specializing SimObjectBaseParam to the
// specific subtype. The main purpose of SimObjectBaseParam is to
// provide a place to stick several helper functions common to all
// SimObject-derived parameters.
//
class SimObjectBaseParam : public BaseParam
{
public:
SimObjectBaseParam(ParamContext *context, const std::string &name,
const std::string &description, bool hasDefault)
: BaseParam(context, name, description, hasDefault)
{
}
virtual ~SimObjectBaseParam() {}
// helper function for SimObjectParam<T>::showValue()
void showValue(std::ostream &os, SimObject *obj) const;
// helper function for SimObjectParam<T>::parse()
void parse(const std::string &s, SimObject *&value);
// helper function for SimObjectParam<T>::parse()
void parse(const std::string &s, std::vector<SimObject *>&value_vec);
};
//
// Parameter to a specific type of SimObject. Note that T must be a
// pointer to a class derived from SimObject (e.g., <CPU *>).
//
template <class T> class SimObjectParam;
template <class T>
class SimObjectParam<T *> : public SimObjectBaseParam
{
protected:
T *value;
public:
// initialization w/o default
SimObjectParam(ParamContext *context,
const std::string &name, const std::string &description)
: SimObjectBaseParam(context, name, description, false)
{
}
// initialization wit=h default
SimObjectParam(ParamContext *context,
const std::string &name, const std::string &description,
T *dfltValue)
: SimObjectBaseParam(context, name, description, true),
value(dfltValue)
{
}
virtual ~SimObjectParam() {}
// convert to pointer
operator T*()
{
if (!isValid())
die("not found");
return value;
}
T *operator->() const
{
if (!isValid())
die("not found");
return value;
}
// display value to stream
virtual void showValue(std::ostream &os) const
{
SimObjectBaseParam::showValue(os, value);
}
// display type to stream: see REGISTER_SIM_OBJECT macro in
// sim_object.hh for declaration
virtual void showType(std::ostream &os) const;
// set value by parsing string
virtual void parse(const std::string &s)
{
SimObject *so_ptr;
// first parse to generic SimObject *
SimObjectBaseParam::parse(s, so_ptr);
// now dynamic_cast to specific derived type
value = dynamic_cast<T *>(so_ptr);
// check for failure of dynamic_cast
if (value == NULL && so_ptr != NULL)
die("not of appropriate type");
}
};
//
// Vector counterpart to SimObjectParam<T>
//
template <class T> class SimObjectVectorParam;
template <class T>
class SimObjectVectorParam<T *> : public SimObjectBaseParam
{
protected:
std::vector<T *> value;
public:
typedef typename std::vector<T *>::size_type size_type;
SimObjectVectorParam(ParamContext *context,
const std::string &name,
const std::string &description)
: SimObjectBaseParam(context, name, description, false)
{
}
SimObjectVectorParam(ParamContext *context,
const std::string &name,
const std::string &description,
std::vector<T *> dfltValue)
: SimObjectBaseParam(context, name, description, true),
value(dfltValue)
{
}
virtual ~SimObjectVectorParam() {}
// basic vector access methods
size_type size() const
{
if (!isValid())
die("not found");
return value.size();
}
T *&operator[](size_type n)
{
if (!isValid())
die("not found");
return value[n];
}
// return reference to value vector
operator std::vector<T *>&()
{
if (!isValid())
die("not found");
return value;
}
// display value to stream
virtual void showValue(std::ostream &os) const
{
for (int i = 0; i < value.size(); i++) {
if (i != 0)
os << " ";
SimObjectBaseParam::showValue(os, value[i]);
}
}
// display type to stream: see
virtual void showType(std::ostream &os) const;
// set value by parsing string
virtual void parse(const std::string &s)
{
std::vector<SimObject *> so_ptr_vec;
// first parse to generic SimObject * vector (from SimObjectBaseParam)
SimObjectBaseParam::parse(s, so_ptr_vec);
value.resize(so_ptr_vec.size());
for (int i = 0; i < so_ptr_vec.size(); ++i) {
// now dynamic_cast to specific derived type
value[i] = dynamic_cast<T *>(so_ptr_vec[i]);
// check for failure of dynamic_cast
if (value[i] == NULL && so_ptr_vec[i] != NULL)
die("not of appropriate type");
}
}
};
//
// Macro to define showType() methods for SimObjectParam &
// SimObjectVectorParam. Can't do this automatically as it requires a
// string name for the type, which you can't get from a template
// argument. For concrete derived SimObject types, this macro is
// automatically invoked by REGISTER_SIM_OBJECT() (see sim_object.hh).
//
#define DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, OBJ_CLASS) \
template<> \
void \
SimObjectParam<OBJ_CLASS *>::showType(std::ostream &os) const \
{ \
os << CLASS_NAME; \
} \
\
template<> \
void \
SimObjectVectorParam<OBJ_CLASS *>::showType(std::ostream &os) const \
{ \
os << "vector of " << CLASS_NAME; \
}
//
// Declarations for low-level parsing & displaying functions. These
// are used internally, but should not be used directly by clients of
// the parameter mechanism, but are declared here so they can be
// shared with the serialization code (see sim/serialize.cc).
template <class T> bool parseParam(const std::string &str, T &data);
template <class T> void showParam(std::ostream &os, const T &data);
void parseTime(const std::vector<int> &time, struct tm *tm);
#endif // _SIM_PARAM_HH_

View File

@@ -45,7 +45,7 @@
#include "mem/page_table.hh"
#include "mem/physical.hh"
#include "mem/translating_port.hh"
#include "sim/builder.hh"
#include "params/LiveProcess.hh"
#include "sim/process.hh"
#include "sim/process_impl.hh"
#include "sim/stats.hh"
@@ -312,14 +312,6 @@ Process::unserialize(Checkpoint *cp, const std::string &section)
}
//
// need to declare these here since there is no concrete Process type
// that can be constructed (i.e., no REGISTER_SIM_OBJECT() macro call,
// which is where these get declared for concrete types).
//
DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process)
////////////////////////////////////////////////////////////////////////
//
// LiveProcess member definitions
@@ -551,46 +543,8 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd,
return process;
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
VectorParam<string> cmd;
Param<string> executable;
Param<string> input;
Param<string> output;
VectorParam<string> env;
Param<string> cwd;
SimObjectParam<System *> system;
Param<uint64_t> uid;
Param<uint64_t> euid;
Param<uint64_t> gid;
Param<uint64_t> egid;
Param<uint64_t> pid;
Param<uint64_t> ppid;
END_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess)
INIT_PARAM(cmd, "command line (executable plus arguments)"),
INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
INIT_PARAM(env, "environment settings"),
INIT_PARAM(cwd, "current working directory"),
INIT_PARAM(system, "system"),
INIT_PARAM(uid, "user id"),
INIT_PARAM(euid, "effective user id"),
INIT_PARAM(gid, "group id"),
INIT_PARAM(egid, "effective group id"),
INIT_PARAM(pid, "process id"),
INIT_PARAM(ppid, "parent process id")
END_INIT_SIM_OBJECT_PARAMS(LiveProcess)
CREATE_SIM_OBJECT(LiveProcess)
LiveProcess *
LiveProcessParams::create()
{
string in = input;
string out = output;
@@ -612,12 +566,9 @@ CREATE_SIM_OBJECT(LiveProcess)
stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
return LiveProcess::create(getInstanceName(), system,
return LiveProcess::create(name, system,
stdin_fd, stdout_fd, stderr_fd,
(string)executable == "" ? cmd[0] : executable,
cmd, env, cwd,
uid, euid, gid, egid, pid, ppid);
}
REGISTER_SIM_OBJECT("LiveProcess", LiveProcess)

View File

@@ -36,28 +36,17 @@
#include <vector>
#include "base/misc.hh"
#include "sim/builder.hh"
#include "params/Root.hh"
#include "sim/sim_object.hh"
// Dummy Object
struct Root : public SimObject
{
Root(const std::string &name) : SimObject(name) {}
Root(RootParams *params) : SimObject(params) {}
};
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Root)
Param<int> dummy; // needed below
END_DECLARE_SIM_OBJECT_PARAMS(Root)
BEGIN_INIT_SIM_OBJECT_PARAMS(Root)
INIT_PARAM(dummy, "") // All SimObjects must have params
END_INIT_SIM_OBJECT_PARAMS(Root)
CREATE_SIM_OBJECT(Root)
Root *
RootParams::create()
{
static bool created = false;
if (created)
@@ -65,7 +54,5 @@ CREATE_SIM_OBJECT(Root)
created = true;
return new Root(getInstanceName());
return new Root(this);
}
REGISTER_SIM_OBJECT("Root", Root)

View File

@@ -46,7 +46,6 @@
#include "base/str.hh"
#include "base/trace.hh"
#include "sim/eventq.hh"
#include "sim/param.hh"
#include "sim/serialize.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
@@ -59,6 +58,101 @@ using namespace std;
extern SimObject *resolveSimObject(const string &);
//
// The base implementations use to_number for parsing and '<<' for
// displaying, suitable for integer types.
//
template <class T>
bool
parseParam(const string &s, T &value)
{
return to_number(s, value);
}
template <class T>
void
showParam(ostream &os, const T &value)
{
os << value;
}
//
// Template specializations:
// - char (8-bit integer)
// - floating-point types
// - bool
// - string
//
// Treat 8-bit ints (chars) as ints on output, not as chars
template <>
void
showParam(ostream &os, const char &value)
{
os << (int)value;
}
template <>
void
showParam(ostream &os, const unsigned char &value)
{
os << (unsigned int)value;
}
// Use sscanf() for FP types as to_number() only handles integers
template <>
bool
parseParam(const string &s, float &value)
{
return (sscanf(s.c_str(), "%f", &value) == 1);
}
template <>
bool
parseParam(const string &s, double &value)
{
return (sscanf(s.c_str(), "%lf", &value) == 1);
}
template <>
bool
parseParam(const string &s, bool &value)
{
const string &ls = to_lower(s);
if (ls == "true") {
value = true;
return true;
}
if (ls == "false") {
value = false;
return true;
}
return false;
}
// Display bools as strings
template <>
void
showParam(ostream &os, const bool &value)
{
os << (value ? "true" : "false");
}
// String requires no processing to speak of
template <>
bool
parseParam(const string &s, string &value)
{
value = s;
return true;
}
int Serializable::ckptMaxCount = 0;
int Serializable::ckptCount = 0;
int Serializable::ckptPrevCount = -1;

View File

@@ -33,7 +33,6 @@
#include "base/callback.hh"
#include "base/hostinfo.hh"
#include "sim/eventq.hh"
#include "sim/param.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/startup.hh"

View File

@@ -40,7 +40,6 @@
#include "sim/host.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
#include "sim/param.hh"
using namespace std;
@@ -59,7 +58,7 @@ SimObject::SimObjectList SimObject::simObjectList;
//
// SimObject constructor: used to maintain static simObjectList
//
SimObject::SimObject(Params *p)
SimObject::SimObject(const Params *p)
: _params(p)
{
#ifdef DEBUG
@@ -70,13 +69,18 @@ SimObject::SimObject(Params *p)
state = Running;
}
//
// SimObject constructor: used to maintain static simObjectList
//
SimObject::SimObject(const string &_name)
: _params(new Params)
SimObjectParams *
makeParams(const string &name)
{
SimObjectParams *params = new SimObjectParams;
params->name = name;
return params;
}
SimObject::SimObject(const string &_name)
: _params(makeParams(_name))
{
_params->name = _name;
#ifdef DEBUG
doDebugBreak = false;
#endif
@@ -272,5 +276,3 @@ SimObject::takeOverFrom(BaseCPU *cpu)
{
panic("Unimplemented!");
}
DEFINE_SIM_OBJECT_CLASS_NAME("SimObject", SimObject)

View File

@@ -41,6 +41,7 @@
#include <vector>
#include <iostream>
#include "params/SimObject.hh"
#include "sim/serialize.hh"
#include "sim/startup.hh"
@@ -55,33 +56,19 @@ class Event;
class SimObject : public Serializable, protected StartupCallback
{
public:
struct Params {
std::string name;
};
enum State {
Running,
Draining,
Drained
};
enum MemoryMode {
Invalid=0,
Atomic,
Timing
};
private:
State state;
protected:
Params *_params;
void changeState(State new_state) { state = new_state; }
public:
const Params *params() const { return _params; }
State getState() { return state; }
private:
@@ -90,10 +77,14 @@ class SimObject : public Serializable, protected StartupCallback
// list of all instantiated simulation objects
static SimObjectList simObjectList;
public:
SimObject(Params *_params);
SimObject(const std::string &_name);
protected:
const SimObjectParams *_params;
public:
typedef SimObjectParams Params;
const Params *params() const { return _params; }
SimObject(const Params *_params);
SimObject(const std::string &_name);
virtual ~SimObject() {}
virtual const std::string name() const { return params()->name; }

View File

@@ -40,12 +40,13 @@
#include "cpu/thread_context.hh"
#include "mem/mem_object.hh"
#include "mem/physical.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "sim/system.hh"
#if FULL_SYSTEM
#include "arch/vtophys.hh"
#include "kern/kernel_stats.hh"
#else
#include "params/System.hh"
#endif
using namespace std;
@@ -90,14 +91,14 @@ System::System(Params *p)
/**
* Load the kernel code into memory
*/
if (params()->kernel_path == "") {
if (params()->kernel == "") {
warn("No kernel set for full system simulation. Assuming you know what"
" you're doing...\n");
} else {
// Load kernel code
kernel = createObjectFile(params()->kernel_path);
kernel = createObjectFile(params()->kernel);
if (kernel == NULL)
fatal("Could not load kernel file %s", params()->kernel_path);
fatal("Could not load kernel file %s", params()->kernel);
// Load program sections into memory
kernel->loadSections(&functionalPort, LoadAddrMask);
@@ -146,7 +147,7 @@ int rgdb_wait = -1;
int rgdb_enable = true;
void
System::setMemoryMode(MemoryMode mode)
System::setMemoryMode(Enums::MemoryMode mode)
{
assert(getState() == Drained);
memoryMode = mode;
@@ -269,39 +270,16 @@ printSystems()
const char *System::MemoryModeStrings[3] = {"invalid", "atomic",
"timing"};
#if FULL_SYSTEM
#if !FULL_SYSTEM
// In full system mode, only derived classes (e.g. AlphaLinuxSystem)
// can be created directly.
DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
#else
BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
SimObjectParam<PhysicalMemory *> physmem;
SimpleEnumParam<System::MemoryMode> mem_mode;
END_DECLARE_SIM_OBJECT_PARAMS(System)
BEGIN_INIT_SIM_OBJECT_PARAMS(System)
INIT_PARAM(physmem, "physical memory"),
INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
System::MemoryModeStrings)
END_INIT_SIM_OBJECT_PARAMS(System)
CREATE_SIM_OBJECT(System)
System *
SystemParams::create()
{
System::Params *p = new System::Params;
p->name = getInstanceName();
p->name = name;
p->physmem = physmem;
p->mem_mode = mem_mode;
return new System(p);
}
REGISTER_SIM_OBJECT("System", System)
#endif

View File

@@ -41,7 +41,9 @@
#include "base/statistics.hh"
#include "config/full_system.hh"
#include "cpu/pc_event.hh"
#include "enums/MemoryMode.hh"
#include "mem/port.hh"
#include "params/System.hh"
#include "sim/sim_object.hh"
#if FULL_SYSTEM
#include "kern/system_events.hh"
@@ -68,13 +70,18 @@ class System : public SimObject
static const char *MemoryModeStrings[3];
SimObject::MemoryMode getMemoryMode() { assert(memoryMode); return memoryMode; }
Enums::MemoryMode
getMemoryMode()
{
assert(memoryMode);
return memoryMode;
}
/** Change the memory mode of the system. This should only be called by the
* python!!
* @param mode Mode to change to (atomic/timing)
*/
void setMemoryMode(SimObject::MemoryMode mode);
void setMemoryMode(Enums::MemoryMode mode);
PhysicalMemory *physmem;
PCEventQueue pcEventQueue;
@@ -122,8 +129,7 @@ class System : public SimObject
#endif // FULL_SYSTEM
protected:
SimObject::MemoryMode memoryMode;
Enums::MemoryMode memoryMode;
#if FULL_SYSTEM
/**
@@ -164,22 +170,7 @@ class System : public SimObject
bool breakpoint();
public:
struct Params
{
std::string name;
PhysicalMemory *physmem;
SimObject::MemoryMode mem_mode;
#if FULL_SYSTEM
Tick boot_cpu_frequency;
std::string boot_osflags;
uint64_t init_param;
std::string kernel_path;
std::string readfile;
std::string symbolfile;
#endif
};
typedef SystemParams Params;
protected:
Params *_params;