2014-10-16 11:49:37 +02:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2014 ARM Limited
|
|
|
|
* All rights reserved
|
|
|
|
*
|
|
|
|
* The license below extends only to copyright in the software and shall
|
|
|
|
* not be construed as granting a license to any other intellectual
|
|
|
|
* property including but not limited to intellectual property relating
|
|
|
|
* to a hardware implementation of the functionality of the software
|
|
|
|
* licensed hereunder. You may use the software subject to the license
|
|
|
|
* terms below provided that you ensure that this notice is replicated
|
|
|
|
* unmodified and in its entirety in all distributions of the software,
|
|
|
|
* modified or unmodified, in source code or in binary form.
|
|
|
|
*
|
|
|
|
* 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: Andrew Bardsley
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
*
|
|
|
|
* C++-only configuration and instantiation support. This allows a
|
|
|
|
* config to be read back from a config file and instantiated without
|
|
|
|
* Python. Useful if you want to embed gem5 within a larger system
|
|
|
|
* without carrying the integration cost of the fully-featured
|
|
|
|
* configuration system.
|
|
|
|
*
|
|
|
|
* This file contains the config loading/storing manager class
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __SIM_CXX_MANAGER_HH__
|
|
|
|
#define __SIM_CXX_MANAGER_HH__
|
|
|
|
|
|
|
|
#include <list>
|
|
|
|
#include <map>
|
|
|
|
#include <set>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "base/cprintf.hh"
|
|
|
|
#include "sim/cxx_config.hh"
|
|
|
|
|
2015-07-07 10:51:03 +02:00
|
|
|
class CheckpointIn;
|
2014-10-16 11:49:37 +02:00
|
|
|
|
|
|
|
/** This class allows a config file to be read into gem5 (generating the
|
|
|
|
* appropriate SimObjects) from C++ */
|
|
|
|
class CxxConfigManager
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
/** Configuration file being read */
|
|
|
|
CxxConfigFileBase &configFile;
|
|
|
|
|
|
|
|
/** Flags to pass to affect param setting */
|
|
|
|
CxxConfigParams::Flags flags;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/** Exception for instantiate/post-instantiate errors */
|
|
|
|
class Exception : public std::exception
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
std::string name;
|
|
|
|
std::string message;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Exception(const std::string &name_, const std::string &message_) :
|
|
|
|
name(name_), message(message_)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
const char *what() const throw() { return message.c_str(); }
|
|
|
|
|
|
|
|
~Exception() throw() { }
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Name substitution when instantiating any object whose name starts
|
|
|
|
* with fromPrefix. Where both renamed and unrenamed names are used
|
|
|
|
* in the code, `object' as part of a name usually refers to the
|
|
|
|
* unrenamed name (the name as it appears in the config file) and
|
|
|
|
* `instance' is part of the renamed name */
|
|
|
|
struct Renaming
|
|
|
|
{
|
|
|
|
std::string fromPrefix;
|
|
|
|
std::string toPrefix;
|
|
|
|
|
|
|
|
Renaming(const std::string &from_prefix,
|
|
|
|
const std::string &to_prefix) :
|
|
|
|
fromPrefix(from_prefix),
|
|
|
|
toPrefix(to_prefix)
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
/** SimObject indexed by name */
|
|
|
|
std::map<std::string, SimObject *> objectsByName;
|
|
|
|
|
|
|
|
/** ...Params objects created by this manager */
|
|
|
|
std::map<std::string, CxxConfigParams *> objectParamsByName;
|
|
|
|
|
|
|
|
/** SimObjects in order. This is populated by findAllObjects */
|
|
|
|
std::list<SimObject *> objectsInOrder;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/** While configuring, inVisit contains names of SimObjects visited in
|
|
|
|
* this recursive configuration walk */
|
|
|
|
std::set<std::string> inVisit;
|
|
|
|
|
|
|
|
/** All the renamings applicable when instantiating objects */
|
|
|
|
std::list<Renaming> renamings;
|
|
|
|
|
|
|
|
/** Bind a single connection between two objects' ports */
|
|
|
|
void bindPort(SimObject *masterObject, const std::string &masterPort,
|
|
|
|
PortID masterPortIndex, SimObject *slaveObject,
|
|
|
|
const std::string &slavePort, PortID slavePortIndex);
|
|
|
|
|
|
|
|
/** Bind a single (possibly vectored) master port to peers from the
|
|
|
|
* unparsed list peers with elements in the .ini connection format:
|
|
|
|
* path(.path)*.port[index] */
|
|
|
|
void bindMasterPort(SimObject *object,
|
|
|
|
const CxxConfigDirectoryEntry::PortDesc &port,
|
|
|
|
const std::vector<std::string> &peers);
|
|
|
|
|
|
|
|
/** Apply the first matching renaming in renamings to the given name */
|
|
|
|
std::string rename(const std::string &from_name);
|
|
|
|
|
|
|
|
/** Apply the first matching renaming in reverse (toPrefix -> fromPrefix
|
|
|
|
* for the given name */
|
|
|
|
std::string unRename(const std::string &to_name);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/** Bind the ports of all the objects in objectInOrder order.
|
|
|
|
* Also */
|
|
|
|
void bindAllPorts();
|
|
|
|
|
|
|
|
/** Class for resolving SimObject names to SimObjects usable by the
|
|
|
|
* checkpoint restore mechanism */
|
|
|
|
class SimObjectResolver : public ::SimObjectResolver
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
CxxConfigManager &configManager;
|
|
|
|
|
|
|
|
public:
|
|
|
|
SimObjectResolver(CxxConfigManager &configManager_) :
|
|
|
|
configManager(configManager_)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
SimObject *resolveSimObject(const std::string &name)
|
|
|
|
{ return &(configManager.getObject<SimObject>(name)); }
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Singleton instance of SimObjectResolver */
|
|
|
|
SimObjectResolver simObjectResolver;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CxxConfigManager(CxxConfigFileBase &configFile_);
|
|
|
|
|
|
|
|
/** Find the type field for a named object and return both the
|
|
|
|
* name of the type to object_type and the object's directory
|
|
|
|
* entry as the return value */
|
|
|
|
const CxxConfigDirectoryEntry &findObjectType(
|
|
|
|
const std::string &object_name, std::string &object_type);
|
|
|
|
|
|
|
|
/** Add a name prefix renaming to those currently applied. Call this
|
|
|
|
* before trying to instantiate any object as the name mappings are
|
|
|
|
* not applied to the config tree read from the config file but are
|
|
|
|
* applied while processing instantiations */
|
|
|
|
void addRenaming(const Renaming &renaming);
|
|
|
|
|
|
|
|
public:
|
|
|
|
/** Bind the ports of a single SimObject */
|
|
|
|
void bindObjectPorts(SimObject *object);
|
|
|
|
|
|
|
|
/** Walk the configuration starting with object object_name and fill
|
|
|
|
* in all the elements of this object on the way. This involves:
|
|
|
|
* <ul>
|
|
|
|
* <li>Calling findObjectParams to make the ...Params object
|
|
|
|
* If findObjectParams has already been called for this object,
|
|
|
|
* the ...Params object generated by that called (stored in
|
|
|
|
* (objectParamsByName[object_name] will be used)</li>
|
|
|
|
* <li>Populating the ...Params object references to other
|
|
|
|
* SimObjects by recursively descending into the trees formed
|
|
|
|
* by SimObject references</li>
|
|
|
|
* <li>Building the final SimObject and adding it to
|
|
|
|
* objectsByName</li>
|
|
|
|
* <li>If visit_children is true, recursively visit all this
|
|
|
|
* object's children and build/find them too</li>
|
|
|
|
* </ul>
|
|
|
|
* After the first call, this function will return
|
|
|
|
* objectsByName[object_name] */
|
|
|
|
SimObject *findObject(const std::string &object_name,
|
|
|
|
bool visit_children = false);
|
|
|
|
|
|
|
|
/** Find the parameters for the named object. Returns NULL if the
|
|
|
|
* object isn't in the configuration. For the first call with a
|
|
|
|
* particular object name, a new CxxConfigParams descended object
|
|
|
|
* is made with the configuration file contents for this object.
|
|
|
|
* This involves populating that ...Params object with:
|
|
|
|
* <ul>
|
|
|
|
* <li>parameter values from the configuration file</li>
|
|
|
|
* <li>port connection connection counts from the connection counts
|
|
|
|
* indicated by the number of peer ports in the configuration
|
|
|
|
* file</li>
|
|
|
|
* <li>nulled (or vector<>::clear'ed) SimObject references for
|
|
|
|
* SimObject-values parameters</li>
|
|
|
|
* </ul>
|
|
|
|
* The ...Params object is then added to objectParamsByName
|
|
|
|
* After the first call, this function will return
|
|
|
|
* objectParamsByName[object_name] */
|
|
|
|
CxxConfigParams *findObjectParams(const std::string &object_name);
|
|
|
|
|
|
|
|
/** Populate objectsInOrder with a preorder, depth first traversal from
|
|
|
|
* the given object name down through all its children */
|
|
|
|
void findTraversalOrder(const std::string &object_name);
|
|
|
|
|
|
|
|
/** Find an object from objectsByName with a type-checking cast.
|
|
|
|
* This function is provided for manipulating objects after
|
|
|
|
* instantiate as it assumes the named object exists. */
|
|
|
|
template<typename SimObjectType>
|
|
|
|
SimObjectType &
|
|
|
|
getObject(const std::string &object_name)
|
|
|
|
{
|
|
|
|
if (objectsByName.find(object_name) == objectsByName.end()) {
|
|
|
|
throw Exception("", csprintf("No sim object named: %s",
|
|
|
|
object_name));
|
|
|
|
}
|
|
|
|
|
|
|
|
SimObjectType *object = dynamic_cast<SimObjectType *>(
|
|
|
|
objectsByName[object_name]);
|
|
|
|
|
|
|
|
if (!object) {
|
|
|
|
throw Exception("", csprintf("Sim object: %s has the wrong"
|
|
|
|
" type", object_name));
|
|
|
|
}
|
|
|
|
|
|
|
|
return *object;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Perform mem_func on each SimObject */
|
|
|
|
void forEachObject(void (SimObject::*mem_func)());
|
|
|
|
|
|
|
|
/** Find all objects by iterating over the object names in the config
|
|
|
|
* file with findObject. Also populate the traversal order */
|
|
|
|
void findAllObjects();
|
|
|
|
|
|
|
|
/** Parse a port string of the form 'path(.path)*.port[index]' into
|
|
|
|
* path, port and index */
|
|
|
|
static void parsePort(const std::string &inp,
|
|
|
|
std::string &path, std::string &port, unsigned int &index);
|
|
|
|
|
|
|
|
/** Build all objects (if build_all is true, otherwise objects must
|
|
|
|
* have been individually findObject-ed and added to the traversal
|
|
|
|
* order) and perform all the configuration specific actions up to,
|
|
|
|
* but not including initState.
|
|
|
|
*
|
|
|
|
* If you want to set some parameters before completing instantiation,
|
|
|
|
* call findObjectParams on the objects you want to modify, then call
|
|
|
|
* instantiate */
|
|
|
|
void instantiate(bool build_all = true);
|
|
|
|
|
|
|
|
/** Call initState on all objects */
|
|
|
|
void initState();
|
|
|
|
|
|
|
|
/** Call startup on all objects */
|
|
|
|
void startup();
|
|
|
|
|
|
|
|
/** Drain all objects */
|
2015-07-07 10:51:05 +02:00
|
|
|
unsigned int drain();
|
2014-10-16 11:49:37 +02:00
|
|
|
|
|
|
|
/** Resume from drain */
|
|
|
|
void drainResume();
|
|
|
|
|
|
|
|
/** Serialize (checkpoint) all objects to the given stream */
|
|
|
|
void serialize(std::ostream &os);
|
|
|
|
|
|
|
|
/** Load all objects' state from the given Checkpoint */
|
2015-07-07 10:51:03 +02:00
|
|
|
void loadState(CheckpointIn &checkpoint);
|
2014-10-16 11:49:37 +02:00
|
|
|
|
|
|
|
/** Delete all objects and clear objectsByName and objectsByOrder */
|
|
|
|
void deleteObjects();
|
|
|
|
|
|
|
|
/** Get the resolver used to map SimObject names to SimObjects for
|
|
|
|
* checkpoint restore */
|
|
|
|
SimObjectResolver &getSimObjectResolver() { return simObjectResolver; }
|
|
|
|
|
|
|
|
/** Convenience functions for calling set... member functions on a
|
|
|
|
* CxxConfigParams for an object. These functions throw Exception
|
|
|
|
* rather than return a bool on failure */
|
|
|
|
void setParam(const std::string &object_name,
|
|
|
|
const std::string ¶m_name, const std::string ¶m_value);
|
|
|
|
void setParamVector(const std::string &object_name,
|
|
|
|
const std::string ¶m_name,
|
|
|
|
const std::vector<std::string> ¶m_values);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // __SIM_CXX_MANAGER_HH__
|