110458Sandreas.hansson@arm.com/* 210458Sandreas.hansson@arm.com * Copyright (c) 2014 ARM Limited 310458Sandreas.hansson@arm.com * All rights reserved 410458Sandreas.hansson@arm.com * 510458Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 610458Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 710458Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 810458Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 910458Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 1010458Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 1110458Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 1210458Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 1310458Sandreas.hansson@arm.com * 1410458Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 1510458Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 1610458Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 1710458Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 1810458Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1910458Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 2010458Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 2110458Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 2210458Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 2310458Sandreas.hansson@arm.com * this software without specific prior written permission. 2410458Sandreas.hansson@arm.com * 2510458Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610458Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710458Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810458Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910458Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010458Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110458Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210458Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310458Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410458Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510458Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610458Sandreas.hansson@arm.com * 3710458Sandreas.hansson@arm.com * Authors: Andrew Bardsley 3810458Sandreas.hansson@arm.com */ 3910458Sandreas.hansson@arm.com 4010458Sandreas.hansson@arm.com/** 4110458Sandreas.hansson@arm.com * @file 4210458Sandreas.hansson@arm.com * 4310458Sandreas.hansson@arm.com * C++-only configuration and instantiation support. This allows a 4410458Sandreas.hansson@arm.com * config to be read back from a config file and instantiated without 4510458Sandreas.hansson@arm.com * Python. Useful if you want to embed gem5 within a larger system 4610458Sandreas.hansson@arm.com * without carrying the integration cost of the fully-featured 4710458Sandreas.hansson@arm.com * configuration system. 4810458Sandreas.hansson@arm.com * 4910458Sandreas.hansson@arm.com * This file contains the config loading/storing manager class 5010458Sandreas.hansson@arm.com */ 5110458Sandreas.hansson@arm.com 5210458Sandreas.hansson@arm.com#ifndef __SIM_CXX_MANAGER_HH__ 5310458Sandreas.hansson@arm.com#define __SIM_CXX_MANAGER_HH__ 5410458Sandreas.hansson@arm.com 5510458Sandreas.hansson@arm.com#include <list> 5610458Sandreas.hansson@arm.com#include <map> 5710458Sandreas.hansson@arm.com#include <set> 5810458Sandreas.hansson@arm.com#include <string> 5910458Sandreas.hansson@arm.com#include <vector> 6010458Sandreas.hansson@arm.com 6110458Sandreas.hansson@arm.com#include "base/cprintf.hh" 6210458Sandreas.hansson@arm.com#include "sim/cxx_config.hh" 6310458Sandreas.hansson@arm.com 6410905Sandreas.sandberg@arm.comclass CheckpointIn; 6510458Sandreas.hansson@arm.com 6610458Sandreas.hansson@arm.com/** This class allows a config file to be read into gem5 (generating the 6710458Sandreas.hansson@arm.com * appropriate SimObjects) from C++ */ 6810458Sandreas.hansson@arm.comclass CxxConfigManager 6910458Sandreas.hansson@arm.com{ 7010458Sandreas.hansson@arm.com protected: 7110458Sandreas.hansson@arm.com /** Configuration file being read */ 7210458Sandreas.hansson@arm.com CxxConfigFileBase &configFile; 7310458Sandreas.hansson@arm.com 7410458Sandreas.hansson@arm.com /** Flags to pass to affect param setting */ 7510458Sandreas.hansson@arm.com CxxConfigParams::Flags flags; 7610458Sandreas.hansson@arm.com 7710458Sandreas.hansson@arm.com public: 7810458Sandreas.hansson@arm.com /** Exception for instantiate/post-instantiate errors */ 7910458Sandreas.hansson@arm.com class Exception : public std::exception 8010458Sandreas.hansson@arm.com { 8110458Sandreas.hansson@arm.com public: 8210458Sandreas.hansson@arm.com std::string name; 8310458Sandreas.hansson@arm.com std::string message; 8410458Sandreas.hansson@arm.com 8510458Sandreas.hansson@arm.com public: 8610458Sandreas.hansson@arm.com Exception(const std::string &name_, const std::string &message_) : 8710458Sandreas.hansson@arm.com name(name_), message(message_) 8810458Sandreas.hansson@arm.com { } 8910458Sandreas.hansson@arm.com 9010458Sandreas.hansson@arm.com const char *what() const throw() { return message.c_str(); } 9110458Sandreas.hansson@arm.com 9210458Sandreas.hansson@arm.com ~Exception() throw() { } 9310458Sandreas.hansson@arm.com }; 9410458Sandreas.hansson@arm.com 9510458Sandreas.hansson@arm.com /** Name substitution when instantiating any object whose name starts 9610458Sandreas.hansson@arm.com * with fromPrefix. Where both renamed and unrenamed names are used 9710458Sandreas.hansson@arm.com * in the code, `object' as part of a name usually refers to the 9810458Sandreas.hansson@arm.com * unrenamed name (the name as it appears in the config file) and 9910458Sandreas.hansson@arm.com * `instance' is part of the renamed name */ 10010458Sandreas.hansson@arm.com struct Renaming 10110458Sandreas.hansson@arm.com { 10210458Sandreas.hansson@arm.com std::string fromPrefix; 10310458Sandreas.hansson@arm.com std::string toPrefix; 10410458Sandreas.hansson@arm.com 10510458Sandreas.hansson@arm.com Renaming(const std::string &from_prefix, 10610458Sandreas.hansson@arm.com const std::string &to_prefix) : 10710458Sandreas.hansson@arm.com fromPrefix(from_prefix), 10810458Sandreas.hansson@arm.com toPrefix(to_prefix) 10910458Sandreas.hansson@arm.com { } 11010458Sandreas.hansson@arm.com }; 11110458Sandreas.hansson@arm.com 11210458Sandreas.hansson@arm.com public: 11310458Sandreas.hansson@arm.com /** SimObject indexed by name */ 11410458Sandreas.hansson@arm.com std::map<std::string, SimObject *> objectsByName; 11510458Sandreas.hansson@arm.com 11610458Sandreas.hansson@arm.com /** ...Params objects created by this manager */ 11710458Sandreas.hansson@arm.com std::map<std::string, CxxConfigParams *> objectParamsByName; 11810458Sandreas.hansson@arm.com 11910458Sandreas.hansson@arm.com /** SimObjects in order. This is populated by findAllObjects */ 12010458Sandreas.hansson@arm.com std::list<SimObject *> objectsInOrder; 12110458Sandreas.hansson@arm.com 12210458Sandreas.hansson@arm.com protected: 12310458Sandreas.hansson@arm.com /** While configuring, inVisit contains names of SimObjects visited in 12410458Sandreas.hansson@arm.com * this recursive configuration walk */ 12510458Sandreas.hansson@arm.com std::set<std::string> inVisit; 12610458Sandreas.hansson@arm.com 12710458Sandreas.hansson@arm.com /** All the renamings applicable when instantiating objects */ 12810458Sandreas.hansson@arm.com std::list<Renaming> renamings; 12910458Sandreas.hansson@arm.com 13010458Sandreas.hansson@arm.com /** Bind a single connection between two objects' ports */ 13110458Sandreas.hansson@arm.com void bindPort(SimObject *masterObject, const std::string &masterPort, 13210458Sandreas.hansson@arm.com PortID masterPortIndex, SimObject *slaveObject, 13310458Sandreas.hansson@arm.com const std::string &slavePort, PortID slavePortIndex); 13410458Sandreas.hansson@arm.com 13510458Sandreas.hansson@arm.com /** Bind a single (possibly vectored) master port to peers from the 13610458Sandreas.hansson@arm.com * unparsed list peers with elements in the .ini connection format: 13710458Sandreas.hansson@arm.com * path(.path)*.port[index] */ 13810458Sandreas.hansson@arm.com void bindMasterPort(SimObject *object, 13910458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry::PortDesc &port, 14010458Sandreas.hansson@arm.com const std::vector<std::string> &peers); 14110458Sandreas.hansson@arm.com 14210458Sandreas.hansson@arm.com /** Apply the first matching renaming in renamings to the given name */ 14310458Sandreas.hansson@arm.com std::string rename(const std::string &from_name); 14410458Sandreas.hansson@arm.com 14510458Sandreas.hansson@arm.com /** Apply the first matching renaming in reverse (toPrefix -> fromPrefix 14610458Sandreas.hansson@arm.com * for the given name */ 14710458Sandreas.hansson@arm.com std::string unRename(const std::string &to_name); 14810458Sandreas.hansson@arm.com 14910458Sandreas.hansson@arm.com protected: 15010458Sandreas.hansson@arm.com /** Bind the ports of all the objects in objectInOrder order. 15110458Sandreas.hansson@arm.com * Also */ 15210458Sandreas.hansson@arm.com void bindAllPorts(); 15310458Sandreas.hansson@arm.com 15410458Sandreas.hansson@arm.com /** Class for resolving SimObject names to SimObjects usable by the 15510458Sandreas.hansson@arm.com * checkpoint restore mechanism */ 15610458Sandreas.hansson@arm.com class SimObjectResolver : public ::SimObjectResolver 15710458Sandreas.hansson@arm.com { 15810458Sandreas.hansson@arm.com protected: 15910458Sandreas.hansson@arm.com CxxConfigManager &configManager; 16010458Sandreas.hansson@arm.com 16110458Sandreas.hansson@arm.com public: 16210458Sandreas.hansson@arm.com SimObjectResolver(CxxConfigManager &configManager_) : 16310458Sandreas.hansson@arm.com configManager(configManager_) 16410458Sandreas.hansson@arm.com { } 16510458Sandreas.hansson@arm.com 16610458Sandreas.hansson@arm.com SimObject *resolveSimObject(const std::string &name) 16710458Sandreas.hansson@arm.com { return &(configManager.getObject<SimObject>(name)); } 16810458Sandreas.hansson@arm.com }; 16910458Sandreas.hansson@arm.com 17010458Sandreas.hansson@arm.com /** Singleton instance of SimObjectResolver */ 17110458Sandreas.hansson@arm.com SimObjectResolver simObjectResolver; 17210458Sandreas.hansson@arm.com 17310458Sandreas.hansson@arm.com public: 17410458Sandreas.hansson@arm.com CxxConfigManager(CxxConfigFileBase &configFile_); 17510458Sandreas.hansson@arm.com 17610458Sandreas.hansson@arm.com /** Find the type field for a named object and return both the 17710458Sandreas.hansson@arm.com * name of the type to object_type and the object's directory 17810458Sandreas.hansson@arm.com * entry as the return value */ 17910458Sandreas.hansson@arm.com const CxxConfigDirectoryEntry &findObjectType( 18010458Sandreas.hansson@arm.com const std::string &object_name, std::string &object_type); 18110458Sandreas.hansson@arm.com 18210458Sandreas.hansson@arm.com /** Add a name prefix renaming to those currently applied. Call this 18310458Sandreas.hansson@arm.com * before trying to instantiate any object as the name mappings are 18410458Sandreas.hansson@arm.com * not applied to the config tree read from the config file but are 18510458Sandreas.hansson@arm.com * applied while processing instantiations */ 18610458Sandreas.hansson@arm.com void addRenaming(const Renaming &renaming); 18710458Sandreas.hansson@arm.com 18810458Sandreas.hansson@arm.com public: 18910458Sandreas.hansson@arm.com /** Bind the ports of a single SimObject */ 19010458Sandreas.hansson@arm.com void bindObjectPorts(SimObject *object); 19110458Sandreas.hansson@arm.com 19210458Sandreas.hansson@arm.com /** Walk the configuration starting with object object_name and fill 19310458Sandreas.hansson@arm.com * in all the elements of this object on the way. This involves: 19410458Sandreas.hansson@arm.com * <ul> 19510458Sandreas.hansson@arm.com * <li>Calling findObjectParams to make the ...Params object 19610458Sandreas.hansson@arm.com * If findObjectParams has already been called for this object, 19710458Sandreas.hansson@arm.com * the ...Params object generated by that called (stored in 19810458Sandreas.hansson@arm.com * (objectParamsByName[object_name] will be used)</li> 19910458Sandreas.hansson@arm.com * <li>Populating the ...Params object references to other 20010458Sandreas.hansson@arm.com * SimObjects by recursively descending into the trees formed 20110458Sandreas.hansson@arm.com * by SimObject references</li> 20210458Sandreas.hansson@arm.com * <li>Building the final SimObject and adding it to 20310458Sandreas.hansson@arm.com * objectsByName</li> 20410458Sandreas.hansson@arm.com * <li>If visit_children is true, recursively visit all this 20510458Sandreas.hansson@arm.com * object's children and build/find them too</li> 20610458Sandreas.hansson@arm.com * </ul> 20710458Sandreas.hansson@arm.com * After the first call, this function will return 20810458Sandreas.hansson@arm.com * objectsByName[object_name] */ 20910458Sandreas.hansson@arm.com SimObject *findObject(const std::string &object_name, 21010458Sandreas.hansson@arm.com bool visit_children = false); 21110458Sandreas.hansson@arm.com 21210458Sandreas.hansson@arm.com /** Find the parameters for the named object. Returns NULL if the 21310458Sandreas.hansson@arm.com * object isn't in the configuration. For the first call with a 21410458Sandreas.hansson@arm.com * particular object name, a new CxxConfigParams descended object 21510458Sandreas.hansson@arm.com * is made with the configuration file contents for this object. 21610458Sandreas.hansson@arm.com * This involves populating that ...Params object with: 21710458Sandreas.hansson@arm.com * <ul> 21810458Sandreas.hansson@arm.com * <li>parameter values from the configuration file</li> 21910458Sandreas.hansson@arm.com * <li>port connection connection counts from the connection counts 22010458Sandreas.hansson@arm.com * indicated by the number of peer ports in the configuration 22110458Sandreas.hansson@arm.com * file</li> 22210458Sandreas.hansson@arm.com * <li>nulled (or vector<>::clear'ed) SimObject references for 22310458Sandreas.hansson@arm.com * SimObject-values parameters</li> 22410458Sandreas.hansson@arm.com * </ul> 22510458Sandreas.hansson@arm.com * The ...Params object is then added to objectParamsByName 22610458Sandreas.hansson@arm.com * After the first call, this function will return 22710458Sandreas.hansson@arm.com * objectParamsByName[object_name] */ 22810458Sandreas.hansson@arm.com CxxConfigParams *findObjectParams(const std::string &object_name); 22910458Sandreas.hansson@arm.com 23010458Sandreas.hansson@arm.com /** Populate objectsInOrder with a preorder, depth first traversal from 23110458Sandreas.hansson@arm.com * the given object name down through all its children */ 23210458Sandreas.hansson@arm.com void findTraversalOrder(const std::string &object_name); 23310458Sandreas.hansson@arm.com 23410458Sandreas.hansson@arm.com /** Find an object from objectsByName with a type-checking cast. 23510458Sandreas.hansson@arm.com * This function is provided for manipulating objects after 23610458Sandreas.hansson@arm.com * instantiate as it assumes the named object exists. */ 23710458Sandreas.hansson@arm.com template<typename SimObjectType> 23810458Sandreas.hansson@arm.com SimObjectType & 23910458Sandreas.hansson@arm.com getObject(const std::string &object_name) 24010458Sandreas.hansson@arm.com { 24110458Sandreas.hansson@arm.com if (objectsByName.find(object_name) == objectsByName.end()) { 24210458Sandreas.hansson@arm.com throw Exception("", csprintf("No sim object named: %s", 24310458Sandreas.hansson@arm.com object_name)); 24410458Sandreas.hansson@arm.com } 24510458Sandreas.hansson@arm.com 24610458Sandreas.hansson@arm.com SimObjectType *object = dynamic_cast<SimObjectType *>( 24710458Sandreas.hansson@arm.com objectsByName[object_name]); 24810458Sandreas.hansson@arm.com 24910458Sandreas.hansson@arm.com if (!object) { 25010458Sandreas.hansson@arm.com throw Exception("", csprintf("Sim object: %s has the wrong" 25110458Sandreas.hansson@arm.com " type", object_name)); 25210458Sandreas.hansson@arm.com } 25310458Sandreas.hansson@arm.com 25410458Sandreas.hansson@arm.com return *object; 25510458Sandreas.hansson@arm.com } 25610458Sandreas.hansson@arm.com 25710458Sandreas.hansson@arm.com /** Perform mem_func on each SimObject */ 25810458Sandreas.hansson@arm.com void forEachObject(void (SimObject::*mem_func)()); 25910458Sandreas.hansson@arm.com 26010458Sandreas.hansson@arm.com /** Find all objects by iterating over the object names in the config 26110458Sandreas.hansson@arm.com * file with findObject. Also populate the traversal order */ 26210458Sandreas.hansson@arm.com void findAllObjects(); 26310458Sandreas.hansson@arm.com 26410458Sandreas.hansson@arm.com /** Parse a port string of the form 'path(.path)*.port[index]' into 26510458Sandreas.hansson@arm.com * path, port and index */ 26610458Sandreas.hansson@arm.com static void parsePort(const std::string &inp, 26710458Sandreas.hansson@arm.com std::string &path, std::string &port, unsigned int &index); 26810458Sandreas.hansson@arm.com 26910458Sandreas.hansson@arm.com /** Build all objects (if build_all is true, otherwise objects must 27010458Sandreas.hansson@arm.com * have been individually findObject-ed and added to the traversal 27110458Sandreas.hansson@arm.com * order) and perform all the configuration specific actions up to, 27210458Sandreas.hansson@arm.com * but not including initState. 27310458Sandreas.hansson@arm.com * 27410458Sandreas.hansson@arm.com * If you want to set some parameters before completing instantiation, 27510458Sandreas.hansson@arm.com * call findObjectParams on the objects you want to modify, then call 27610458Sandreas.hansson@arm.com * instantiate */ 27710458Sandreas.hansson@arm.com void instantiate(bool build_all = true); 27810458Sandreas.hansson@arm.com 27910458Sandreas.hansson@arm.com /** Call initState on all objects */ 28010458Sandreas.hansson@arm.com void initState(); 28110458Sandreas.hansson@arm.com 28210458Sandreas.hansson@arm.com /** Call startup on all objects */ 28310458Sandreas.hansson@arm.com void startup(); 28410458Sandreas.hansson@arm.com 28510458Sandreas.hansson@arm.com /** Drain all objects */ 28610912Sandreas.sandberg@arm.com unsigned int drain(); 28710458Sandreas.hansson@arm.com 28810458Sandreas.hansson@arm.com /** Resume from drain */ 28910458Sandreas.hansson@arm.com void drainResume(); 29010458Sandreas.hansson@arm.com 29110458Sandreas.hansson@arm.com /** Serialize (checkpoint) all objects to the given stream */ 29210458Sandreas.hansson@arm.com void serialize(std::ostream &os); 29310458Sandreas.hansson@arm.com 29410458Sandreas.hansson@arm.com /** Load all objects' state from the given Checkpoint */ 29510905Sandreas.sandberg@arm.com void loadState(CheckpointIn &checkpoint); 29610458Sandreas.hansson@arm.com 29710458Sandreas.hansson@arm.com /** Delete all objects and clear objectsByName and objectsByOrder */ 29810458Sandreas.hansson@arm.com void deleteObjects(); 29910458Sandreas.hansson@arm.com 30010458Sandreas.hansson@arm.com /** Get the resolver used to map SimObject names to SimObjects for 30110458Sandreas.hansson@arm.com * checkpoint restore */ 30210458Sandreas.hansson@arm.com SimObjectResolver &getSimObjectResolver() { return simObjectResolver; } 30310458Sandreas.hansson@arm.com 30410458Sandreas.hansson@arm.com /** Convenience functions for calling set... member functions on a 30510458Sandreas.hansson@arm.com * CxxConfigParams for an object. These functions throw Exception 30610458Sandreas.hansson@arm.com * rather than return a bool on failure */ 30710458Sandreas.hansson@arm.com void setParam(const std::string &object_name, 30810458Sandreas.hansson@arm.com const std::string ¶m_name, const std::string ¶m_value); 30910458Sandreas.hansson@arm.com void setParamVector(const std::string &object_name, 31010458Sandreas.hansson@arm.com const std::string ¶m_name, 31110458Sandreas.hansson@arm.com const std::vector<std::string> ¶m_values); 31210458Sandreas.hansson@arm.com}; 31310458Sandreas.hansson@arm.com 31410458Sandreas.hansson@arm.com#endif // __SIM_CXX_MANAGER_HH__ 315