diff options
Diffstat (limited to 'sim')
36 files changed, 0 insertions, 8442 deletions
diff --git a/sim/async.hh b/sim/async.hh deleted file mode 100644 index e0190a133..000000000 --- a/sim/async.hh +++ /dev/null @@ -1,49 +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. - */ - -#ifndef __ASYNC_HH__ -#define __ASYNC_HH__ - -/// -/// @file sim/async.hh -/// This file defines flags used to handle asynchronous simulator events. -/// - -/// @name Asynchronous event flags. -/// To avoid races, signal handlers simply set these flags, which are -/// then checked in the main event loop. Defined in main.cc. -/// @note See the PollQueue object (in pollevent.hh) for the use of async_io and async_alarm. -//@{ -extern volatile bool async_event; ///< Some asynchronous event has happened. -extern volatile bool async_dump; ///< Async request to dump stats. -extern volatile bool async_exit; ///< Async request to exit simulator. -extern volatile bool async_io; ///< Async I/O request (SIGIO). -extern volatile bool async_alarm; ///< Async alarm event (SIGALRM). -//@} - -#endif // __ASYNC_HH__ diff --git a/sim/builder.cc b/sim/builder.cc deleted file mode 100644 index 7dc118985..000000000 --- a/sim/builder.cc +++ /dev/null @@ -1,177 +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. - */ - -#include <assert.h> - -#include "base/inifile.hh" -#include "base/misc.hh" -#include "sim/builder.hh" -#include "sim/configfile.hh" -#include "sim/config_node.hh" -#include "sim/host.hh" -#include "sim/sim_object.hh" -#include "sim/root.hh" - -using namespace std; - -SimObjectBuilder::SimObjectBuilder(ConfigNode *_configNode) - : ParamContext(_configNode->getPath(), NoAutoInit), - configNode(_configNode) -{ -} - -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' of type '%s':\n", - iniSection, configNode->getType()); -} - - -//////////////////////////////////////////////////////////////////////// -// -// 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, ConfigNode *configNode) -{ - const string &type = configNode->getType(); - - // 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)(configNode); - - 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)(NULL); - - // now get the object builder to describe ite params - objectBuilder->describeParams(os); - - os << endl; - - // done with the object builder now - delete objectBuilder; - } -} diff --git a/sim/builder.hh b/sim/builder.hh deleted file mode 100644 index b32e00e76..000000000 --- a/sim/builder.hh +++ /dev/null @@ -1,189 +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. - */ - -#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 -{ - private: - // The corresponding node in the configuration hierarchy. - // (optional: may be null if the created object is not in the - // hierarchy) - ConfigNode *configNode; - - public: - SimObjectBuilder(ConfigNode *_configNode); - - 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; } - - // return the configuration hierarchy node for this context. - virtual ConfigNode *getConfigNode() { return configNode; } - - // 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)(ConfigNode *configNode); - - 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, ConfigNode *configNode); - - // 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(ConfigNode *configNode); \ - virtual ~OBJ_CLASS##Builder() {} \ - \ - OBJ_CLASS *create(); \ -}; - -#define BEGIN_INIT_SIM_OBJECT_PARAMS(OBJ_CLASS) \ -OBJ_CLASS##Builder::OBJ_CLASS##Builder(ConfigNode *configNode) \ - : SimObjectBuilder(configNode), - - -#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(ConfigNode *configNode) \ -{ \ - return new OBJ_CLASS##Builder(configNode); \ -} \ - \ -SimObjectClass the##OBJ_CLASS##Class(CLASS_NAME, \ - new##OBJ_CLASS##Builder); \ - \ -/* see param.hh */ \ -DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, OBJ_CLASS) - - -#endif // __BUILDER_HH__ diff --git a/sim/byteswap.hh b/sim/byteswap.hh deleted file mode 100644 index a8c5da9d7..000000000 --- a/sim/byteswap.hh +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2004 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -//The purpose of this file is to provide endainness conversion utility -//functions. Depending on the endianness of the guest system, either -//the LittleEndianGuest or BigEndianGuest namespace is used. - -#ifndef __SIM_BYTE_SWAP_HH__ -#define __SIM_BYTE_SWAP_HH__ - -#include "sim/host.hh" - -// This lets us figure out what the byte order of the host system is -#if defined(linux) -#include <endian.h> -// If this is a linux system, lets used the optimized definitions if they exist. -// If one doesn't exist, we pretty much get what is listed below, so it all -// works out -#include <byteswap.h> -#else -#include <machine/endian.h> -#endif - -//These functions actually perform the swapping for parameters -//of various bit lengths -static inline uint64_t -swap_byte64(uint64_t x) -{ -#if defined(linux) - return bswap_64(x); -#else - return (uint64_t)((((uint64_t)(x) & 0xff) << 56) | - ((uint64_t)(x) & 0xff00ULL) << 40 | - ((uint64_t)(x) & 0xff0000ULL) << 24 | - ((uint64_t)(x) & 0xff000000ULL) << 8 | - ((uint64_t)(x) & 0xff00000000ULL) >> 8 | - ((uint64_t)(x) & 0xff0000000000ULL) >> 24 | - ((uint64_t)(x) & 0xff000000000000ULL) >> 40 | - ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ; -#endif -} - -static inline uint32_t -swap_byte32(uint32_t x) -{ -#if defined(linux) - return bswap_32(x); -#else - return (uint32_t)(((uint32_t)(x) & 0xff) << 24 | - ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 | - ((uint32_t)(x) & 0xff000000) >> 24); -#endif -} - -static inline uint16_t -swap_byte16(uint16_t x) -{ -#if defined(linux) - return bswap_16(x); -#else - return (uint16_t)(((uint16_t)(x) & 0xff) << 8 | - ((uint16_t)(x) & 0xff00) >> 8); -#endif -} - -//This lets the compiler figure out how to call the swap_byte functions above -//for different data types. -static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);} -static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);} -static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);} -static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);} -//This is to prevent the following two functions from compiling on -//64bit machines. It won't detect everything, so it should be changed. -#ifndef __x86_64__ -static inline long swap_byte(long x) {return swap_byte32((long)x);} -static inline unsigned long swap_byte(unsigned long x) - { return swap_byte32((unsigned long)x);} -#endif -static inline uint16_t swap_byte(uint16_t x) {return swap_byte32(x);} -static inline int16_t swap_byte(int16_t x) {return swap_byte16((uint16_t)x);} -static inline uint8_t swap_byte(uint8_t x) {return x;} -static inline int8_t swap_byte(int8_t x) {return x;} -static inline double swap_byte(double x) {return swap_byte64((uint64_t)x);} -static inline float swap_byte(float x) {return swap_byte32((uint32_t)x);} - -//The conversion functions with fixed endianness on both ends don't need to -//be in a namespace -template <typename T> static inline T betole(T value) {return swap_byte(value);} -template <typename T> static inline T letobe(T value) {return swap_byte(value);} - -//For conversions not involving the guest system, we can define the functions -//conditionally based on the BYTE_ORDER macro and outside of the namespaces -#if BYTE_ORDER == BIG_ENDIAN -template <typename T> static inline T htole(T value) {return swap_byte(value);} -template <typename T> static inline T letoh(T value) {return swap_byte(value);} -template <typename T> static inline T htobe(T value) {return value;} -template <typename T> static inline T betoh(T value) {return value;} -#elif BYTE_ORDER == LITTLE_ENDIAN -template <typename T> static inline T htole(T value) {return value;} -template <typename T> static inline T letoh(T value) {return value;} -template <typename T> static inline T htobe(T value) {return swap_byte(value);} -template <typename T> static inline T betoh(T value) {return swap_byte(value);} -#else - #error Invalid Endianess -#endif - -namespace BigEndianGuest -{ - template <typename T> - static inline T gtole(T value) {return betole(value);} - template <typename T> - static inline T letog(T value) {return letobe(value);} - template <typename T> - static inline T gtobe(T value) {return value;} - template <typename T> - static inline T betog(T value) {return value;} - template <typename T> - static inline T htog(T value) {return htobe(value);} - template <typename T> - static inline T gtoh(T value) {return betoh(value);} -} - -namespace LittleEndianGuest -{ - template <typename T> - static inline T gtole(T value) {return value;} - template <typename T> - static inline T letog(T value) {return value;} - template <typename T> - static inline T gtobe(T value) {return letobe(value);} - template <typename T> - static inline T betog(T value) {return betole(value);} - template <typename T> - static inline T htog(T value) {return htole(value);} - template <typename T> - static inline T gtoh(T value) {return letoh(value);} -} -#endif // __SIM_BYTE_SWAP_HH__ diff --git a/sim/debug.cc b/sim/debug.cc deleted file mode 100644 index 09e5346a8..000000000 --- a/sim/debug.cc +++ /dev/null @@ -1,136 +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. - */ - -#include <sys/types.h> -#include <signal.h> -#include <unistd.h> - -#include <string> -#include <vector> - -#include "sim/debug.hh" -#include "sim/eventq.hh" -#include "sim/param.hh" -#include "sim/sim_events.hh" - -using namespace std; - -void -debug_break() -{ -#ifndef NDEBUG - kill(getpid(), SIGTRAP); -#else - cprintf("debug_break suppressed, compiled with NDEBUG\n"); -#endif -} - -// -// Debug event: place a breakpoint on the process function and -// schedule the event to break at a particular cycle -// -class DebugBreakEvent : public Event -{ - public: - - DebugBreakEvent(EventQueue *q, Tick _when); - - void process(); // process event - virtual const char *description(); -}; - -// -// constructor: schedule at specified time -// -DebugBreakEvent::DebugBreakEvent(EventQueue *q, Tick _when) - : Event(q, Debug_Break_Pri) -{ - setFlags(AutoDelete); - schedule(_when); -} - -// -// handle debug event: set debugger breakpoint on this function -// -void -DebugBreakEvent::process() -{ - debug_break(); -} - - -const char * -DebugBreakEvent::description() -{ - return "debug break"; -} - -// -// Parameter context for global debug options -// -class DebugContext : public ParamContext -{ - public: - DebugContext(const string &_iniSection) - : ParamContext(_iniSection) {} - void checkParams(); -}; - -DebugContext debugParams("debug"); - -VectorParam<Tick> break_cycles(&debugParams, "break_cycles", - "cycle(s) to create breakpoint events"); - -void -DebugContext::checkParams() -{ - if (break_cycles.isValid()) { - vector<Tick> &cycles = break_cycles; - - vector<Tick>::iterator i = cycles.begin(); - vector<Tick>::iterator end = cycles.end(); - - for (; i < end; ++i) - new DebugBreakEvent(&mainEventQueue, *i); - } -} - -// -// handy function to schedule DebugBreakEvent on main event queue -// (callable from debugger) -// -extern "C" void sched_break_cycle(Tick when) -{ - new DebugBreakEvent(&mainEventQueue, when); -} - -extern "C" void eventq_dump() -{ - mainEventQueue.dump(); -} - diff --git a/sim/debug.hh b/sim/debug.hh deleted file mode 100644 index 75b261d80..000000000 --- a/sim/debug.hh +++ /dev/null @@ -1,34 +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. - */ - -#ifndef __DEBUG_HH__ -#define __DEBUG_HH__ - -void debug_break(); - -#endif // __DEBUG_HH__ diff --git a/sim/eventq.cc b/sim/eventq.cc deleted file mode 100644 index 4bfd6face..000000000 --- a/sim/eventq.cc +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2000-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. - */ - -#include <assert.h> - -#include <iostream> -#include <string> -#include <vector> - -#include "cpu/smt.hh" -#include "base/misc.hh" - -#include "sim/eventq.hh" -#include "base/trace.hh" -#include "sim/root.hh" - -using namespace std; - -// -// Main Event Queue -// -// Events on this queue are processed at the *beginning* of each -// cycle, before the pipeline simulation is performed. -// -EventQueue mainEventQueue("MainEventQueue"); - -void -EventQueue::insert(Event *event) -{ - if (head == NULL || event->when() < head->when() || - (event->when() == head->when() && - event->priority() <= head->priority())) { - event->next = head; - head = event; - } else { - Event *prev = head; - Event *curr = head->next; - - while (curr) { - if (event->when() <= curr->when() && - (event->when() < curr->when() || - event->priority() <= curr->priority())) - break; - - prev = curr; - curr = curr->next; - } - - event->next = curr; - prev->next = event; - } -} - -void -EventQueue::remove(Event *event) -{ - if (head == NULL) - return; - - if (head == event){ - head = event->next; - return; - } - - Event *prev = head; - Event *curr = head->next; - while (curr && curr != event) { - prev = curr; - curr = curr->next; - } - - if (curr == event) - prev->next = curr->next; -} - -void -EventQueue::serviceOne() -{ - Event *event = head; - event->clearFlags(Event::Scheduled); - head = event->next; - - // handle action - if (!event->squashed()) - event->process(); - else - event->clearFlags(Event::Squashed); - - if (event->getFlags(Event::AutoDelete) && !event->scheduled()) - delete event; -} - - -void -Event::serialize(std::ostream &os) -{ - SERIALIZE_SCALAR(_when); - SERIALIZE_SCALAR(_priority); - SERIALIZE_ENUM(_flags); -} - - -void -Event::unserialize(Checkpoint *cp, const string §ion) -{ - if (scheduled()) - deschedule(); - - UNSERIALIZE_SCALAR(_when); - UNSERIALIZE_SCALAR(_priority); - - // need to see if original event was in a scheduled, unsquashed - // state, but don't want to restore those flags in the current - // object itself (since they aren't immediately true) - UNSERIALIZE_ENUM(_flags); - bool wasScheduled = (_flags & Scheduled) && !(_flags & Squashed); - _flags &= ~(Squashed | Scheduled); - - if (wasScheduled) { - DPRINTF(Config, "rescheduling at %d\n", _when); - schedule(_when); - } -} - -void -EventQueue::serialize(ostream &os) -{ - std::list<Event *> eventPtrs; - - int numEvents = 0; - Event *event = head; - while (event) { - if (event->getFlags(Event::AutoSerialize)) { - eventPtrs.push_back(event); - paramOut(os, csprintf("event%d", numEvents++), event->name()); - } - event = event->next; - } - - SERIALIZE_SCALAR(numEvents); - - for (std::list<Event *>::iterator it=eventPtrs.begin(); - it != eventPtrs.end(); ++it) { - (*it)->nameOut(os); - (*it)->serialize(os); - } -} - -void -EventQueue::unserialize(Checkpoint *cp, const std::string §ion) -{ - int numEvents; - UNSERIALIZE_SCALAR(numEvents); - - std::string eventName; - for (int i = 0; i < numEvents; i++) { - // get the pointer value associated with the event - paramIn(cp, section, csprintf("event%d", i), eventName); - - // create the event based on its pointer value - Serializable::create(cp, eventName); - } -} - -void -EventQueue::dump() -{ - cprintf("============================================================\n"); - cprintf("EventQueue Dump (cycle %d)\n", curTick); - cprintf("------------------------------------------------------------\n"); - - if (empty()) - cprintf("<No Events>\n"); - else { - Event *event = head; - while (event) { - event->dump(); - event = event->next; - } - } - - cprintf("============================================================\n"); -} - -extern "C" -void -dumpMainQueue() -{ - mainEventQueue.dump(); -} - - -const char * -Event::description() -{ - return "generic"; -} - -#if TRACING_ON -void -Event::trace(const char *action) -{ - // This DPRINTF is unconditional because calls to this function - // are protected by an 'if (DTRACE(Event))' in the inlined Event - // methods. - // - // This is just a default implementation for derived classes where - // it's not worth doing anything special. If you want to put a - // more informative message in the trace, override this method on - // the particular subclass where you have the information that - // needs to be printed. - DPRINTFN("%s event %s @ %d\n", description(), action, when()); -} -#endif - -void -Event::dump() -{ - cprintf("Event (%s)\n", description()); - cprintf("Flags: %#x\n", _flags); -#if TRACING_ON - cprintf("Created: %d\n", when_created); -#endif - if (scheduled()) { -#if TRACING_ON - cprintf("Scheduled at %d\n", when_scheduled); -#endif - cprintf("Scheduled for %d, priority %d\n", when(), _priority); - } - else { - cprintf("Not Scheduled\n"); - } -} diff --git a/sim/eventq.hh b/sim/eventq.hh deleted file mode 100644 index 5fc73bb53..000000000 --- a/sim/eventq.hh +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2000-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. - */ - -/* @file - * EventQueue interfaces - */ - -#ifndef __SIM_EVENTQ_HH__ -#define __SIM_EVENTQ_HH__ - -#include <assert.h> - -#include <algorithm> -#include <map> -#include <string> -#include <vector> - -#include "sim/host.hh" // for Tick - -#include "base/fast_alloc.hh" -#include "base/trace.hh" -#include "sim/serialize.hh" - -class EventQueue; // forward declaration - -////////////////////// -// -// Main Event Queue -// -// Events on this queue are processed at the *beginning* of each -// cycle, before the pipeline simulation is performed. -// -// defined in eventq.cc -// -////////////////////// -extern EventQueue mainEventQueue; - - -/* - * An item on an event queue. The action caused by a given - * event is specified by deriving a subclass and overriding the - * process() member function. - */ -class Event : public Serializable, public FastAlloc -{ - friend class EventQueue; - - private: - /// queue to which this event belongs (though it may or may not be - /// scheduled on this queue yet) - EventQueue *queue; - - Event *next; - - Tick _when; //!< timestamp when event should be processed - int _priority; //!< event priority - char _flags; - - protected: - enum Flags { - None = 0x0, - Squashed = 0x1, - Scheduled = 0x2, - AutoDelete = 0x4, - AutoSerialize = 0x8 - }; - - bool getFlags(Flags f) const { return (_flags & f) == f; } - void setFlags(Flags f) { _flags |= f; } - void clearFlags(Flags f) { _flags &= ~f; } - - protected: - EventQueue *theQueue() const { return queue; } - -#if TRACING_ON - Tick when_created; //!< Keep track of creation time For debugging - Tick when_scheduled; //!< Keep track of creation time For debugging - - virtual void trace(const char *action); //!< trace event activity -#else - void trace(const char *) {} -#endif - - unsigned annotated_value; - - public: - - /// Event priorities, to provide tie-breakers for events scheduled - /// at the same cycle. Most events are scheduled at the default - /// priority; these values are used to control events that need to - /// be ordered within a cycle. - enum Priority { - /// Breakpoints should happen before anything else, so we - /// don't miss any action when debugging. - Debug_Break_Pri = -100, - - /// For some reason "delayed" inter-cluster writebacks are - /// scheduled before regular writebacks (which have default - /// priority). Steve? - Delayed_Writeback_Pri = -1, - - /// Default is zero for historical reasons. - Default_Pri = 0, - - /// CPU switches schedule the new CPU's tick event for the - /// same cycle (after unscheduling the old CPU's tick event). - /// The switch needs to come before any tick events to make - /// sure we don't tick both CPUs in the same cycle. - CPU_Switch_Pri = 31, - - /// Serailization needs to occur before tick events also, so - /// that a serialize/unserialize is identical to an on-line - /// CPU switch. - Serialize_Pri = 32, - - /// CPU ticks must come after other associated CPU events - /// (such as writebacks). - CPU_Tick_Pri = 50, - - /// Statistics events (dump, reset, etc.) come after - /// everything else, but before exit. - Stat_Event_Pri = 90, - - /// If we want to exit on this cycle, it's the very last thing - /// we do. - Sim_Exit_Pri = 100 - }; - - /* - * Event constructor - * @param queue that the event gets scheduled on - */ - Event(EventQueue *q, Priority p = Default_Pri) - : queue(q), next(NULL), _priority(p), _flags(None), -#if TRACING_ON - when_created(curTick), when_scheduled(0), -#endif - annotated_value(0) - { - } - - ~Event() {} - - virtual const std::string name() const { - return csprintf("Event_%x", (uintptr_t)this); - } - - /// Determine if the current event is scheduled - bool scheduled() const { return getFlags(Scheduled); } - - /// Schedule the event with the current priority or default priority - void schedule(Tick t); - - /// Reschedule the event with the current priority - void reschedule(Tick t); - - /// Remove the event from the current schedule - void deschedule(); - - /// Return a C string describing the event. This string should - /// *not* be dynamically allocated; just a const char array - /// describing the event class. - virtual const char *description(); - - /// Dump the current event data - void dump(); - - /* - * This member function is invoked when the event is processed - * (occurs). There is no default implementation; each subclass - * must provide its own implementation. The event is not - * automatically deleted after it is processed (to allow for - * statically allocated event objects). - * - * If the AutoDestroy flag is set, the object is deleted once it - * is processed. - */ - virtual void process() = 0; - - void annotate(unsigned value) { annotated_value = value; }; - unsigned annotation() { return annotated_value; } - - /// Squash the current event - void squash() { setFlags(Squashed); } - - /// Check whether the event is squashed - bool squashed() { return getFlags(Squashed); } - - /// Get the time that the event is scheduled - Tick when() const { return _when; } - - /// Get the event priority - int priority() const { return _priority; } - - struct priority_compare : - public std::binary_function<Event *, Event *, bool> - { - bool operator()(const Event *l, const Event *r) const { - return l->when() >= r->when() || l->priority() >= r->priority(); - } - }; - - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - -template <class T, void (T::* F)()> -void -DelayFunction(Tick when, T *object) -{ - class DelayEvent : public Event - { - private: - T *object; - - public: - DelayEvent(Tick when, T *o) - : Event(&mainEventQueue), object(o) - { setFlags(this->AutoDestroy); schedule(when); } - void process() { (object->*F)(); } - const char *description() { return "delay"; } - }; - - new DelayEvent(when, object); -} - -template <class T, void (T::* F)()> -class EventWrapper : public Event -{ - private: - T *object; - - public: - EventWrapper(T *obj, bool del = false, EventQueue *q = &mainEventQueue, - Priority p = Default_Pri) - : Event(q, p), object(obj) - { - if (del) - setFlags(AutoDelete); - } - void process() { (object->*F)(); } -}; - -/* - * Queue of events sorted in time order - */ -class EventQueue : public Serializable -{ - protected: - std::string objName; - - private: - Event *head; - - void insert(Event *event); - void remove(Event *event); - - public: - - // constructor - EventQueue(const std::string &n) - : objName(n), head(NULL) - {} - - virtual const std::string name() const { return objName; } - - // schedule the given event on this queue - void schedule(Event *ev); - void deschedule(Event *ev); - void reschedule(Event *ev); - - Tick nextTick() { return head->when(); } - void serviceOne(); - - // process all events up to the given timestamp. we inline a - // quick test to see if there are any events to process; if so, - // call the internal out-of-line version to process them all. - void serviceEvents(Tick when) { - while (!empty()) { - if (nextTick() > when) - break; - - /** - * @todo this assert is a good bug catcher. I need to - * make it true again. - */ - //assert(head->when() >= when && "event scheduled in the past"); - serviceOne(); - } - } - - // default: process all events up to 'now' (curTick) - void serviceEvents() { serviceEvents(curTick); } - - // return true if no events are queued - bool empty() { return head == NULL; } - - void dump(); - - Tick nextEventTime() { return empty() ? curTick : head->when(); } - - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); -}; - - -////////////////////// -// -// inline functions -// -// can't put these inside declaration due to circular dependence -// between Event and EventQueue classes. -// -////////////////////// - -// schedule at specified time (place on event queue specified via -// constructor) -inline void -Event::schedule(Tick t) -{ - assert(!scheduled()); - assert(t >= curTick); - - setFlags(Scheduled); -#if TRACING_ON - when_scheduled = curTick; -#endif - _when = t; - queue->schedule(this); -} - -inline void -Event::deschedule() -{ - assert(scheduled()); - - clearFlags(Squashed); - clearFlags(Scheduled); - queue->deschedule(this); -} - -inline void -Event::reschedule(Tick t) -{ - assert(scheduled()); - clearFlags(Squashed); - -#if TRACING_ON - when_scheduled = curTick; -#endif - _when = t; - queue->reschedule(this); -} - -inline void -EventQueue::schedule(Event *event) -{ - insert(event); - if (DTRACE(Event)) - event->trace("scheduled"); -} - -inline void -EventQueue::deschedule(Event *event) -{ - remove(event); - if (DTRACE(Event)) - event->trace("descheduled"); -} - -inline void -EventQueue::reschedule(Event *event) -{ - remove(event); - insert(event); - if (DTRACE(Event)) - event->trace("rescheduled"); -} - - - -#endif // __SIM_EVENTQ_HH__ diff --git a/sim/faults.cc b/sim/faults.cc deleted file mode 100644 index cb095f852..000000000 --- a/sim/faults.cc +++ /dev/null @@ -1,52 +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. - */ - -#include "base/misc.hh" -#include "sim/faults.hh" -#include "cpu/exec_context.hh" -#include "cpu/base.hh" - -#if !FULL_SYSTEM -void FaultBase::invoke(ExecContext * xc) -{ - fatal("fault (%s) detected @ PC 0x%08p", name(), xc->readPC()); -} -#else -void FaultBase::invoke(ExecContext * xc) -{ - DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->readPC()); - xc->getCpuPtr()->recordEvent(csprintf("Fault %s", name())); - - assert(!xc->misspeculating()); -} -#endif - -void UnimpFault::invoke(ExecContext * xc) -{ - panic("Unimpfault: %s\n", panicStr.c_str()); -} diff --git a/sim/faults.hh b/sim/faults.hh deleted file mode 100644 index 9b3bc9103..000000000 --- a/sim/faults.hh +++ /dev/null @@ -1,80 +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. - */ - -#ifndef __FAULTS_HH__ -#define __FAULTS_HH__ - -#include "base/refcnt.hh" -#include "sim/stats.hh" -#include "config/full_system.hh" - -class ExecContext; -class FaultBase; -typedef RefCountingPtr<FaultBase> Fault; - -typedef const char * FaultName; -typedef Stats::Scalar<> FaultStat; - -// Each class has it's name statically define in _name, -// and has a virtual function to access it's name. -// The function is necessary because otherwise, all objects -// which are being accessed cast as a FaultBase * (namely -// all faults returned using the Fault type) will use the -// generic FaultBase name. - -class FaultBase : public RefCounted -{ - public: - virtual FaultName name() = 0; -#if FULL_SYSTEM - virtual void invoke(ExecContext * xc); -#else - virtual void invoke(ExecContext * xc); -#endif -// template<typename T> -// bool isA() {return dynamic_cast<T *>(this);} - virtual bool isMachineCheckFault() {return false;} - virtual bool isAlignmentFault() {return false;} -}; - -FaultBase * const NoFault = 0; - -class UnimpFault : public FaultBase -{ - private: - std::string panicStr; - public: - UnimpFault(std::string _str) - : panicStr(_str) - { } - - FaultName name() {return "Unimplemented simulator feature";} - void invoke(ExecContext * xc); -}; - -#endif // __FAULTS_HH__ diff --git a/sim/host.hh b/sim/host.hh deleted file mode 100644 index 48c977331..000000000 --- a/sim/host.hh +++ /dev/null @@ -1,67 +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. - */ - -/** - * @file - * Defines host-dependent types: - * Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t. - */ - -#ifndef __HOST_HH__ -#define __HOST_HH__ - -#include <inttypes.h> - -/** uint64_t constant */ -#define ULL(N) ((uint64_t)N##ULL) -/** int64_t constant */ -#define LL(N) (((int64_t)N##LL) - -/** Statistics counter type. Not much excuse for not using a 64-bit - * integer here, but if you're desperate and only run short - * simulations you could make this 32 bits. - */ -typedef int64_t Counter; - -/** - * Clock cycle count type. - * @note using an unsigned breaks the cache. - */ -typedef int64_t Tick; - -/** - * Address type - * This will probably be moved somewhere else in the near future. - * This should be at least as big as the biggest address width in use - * in the system, which will probably be 64 bits. - */ -typedef uint64_t Addr; - -const Addr MaxAddr = (Addr)-1; - -#endif // __HOST_H__ diff --git a/sim/main.cc b/sim/main.cc deleted file mode 100644 index aecc171ed..000000000 --- a/sim/main.cc +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2000-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. - */ - -/// -/// @file sim/main.cc -/// -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> -#include <libgen.h> -#include <stdlib.h> -#include <signal.h> - -#include <list> -#include <string> -#include <vector> - -#include "base/copyright.hh" -#include "base/embedfile.hh" -#include "base/inifile.hh" -#include "base/misc.hh" -#include "base/output.hh" -#include "base/pollevent.hh" -#include "base/statistics.hh" -#include "base/str.hh" -#include "base/time.hh" -#include "cpu/base.hh" -#include "cpu/smt.hh" -#include "python/pyconfig.hh" -#include "sim/async.hh" -#include "sim/builder.hh" -#include "sim/configfile.hh" -#include "sim/host.hh" -#include "sim/sim_events.hh" -#include "sim/sim_exit.hh" -#include "sim/sim_object.hh" -#include "sim/stat_control.hh" -#include "sim/stats.hh" -#include "sim/root.hh" - -using namespace std; - -// See async.h. -volatile bool async_event = false; -volatile bool async_dump = false; -volatile bool async_dumpreset = false; -volatile bool async_exit = false; -volatile bool async_io = false; -volatile bool async_alarm = false; - -/// Stats signal handler. -void -dumpStatsHandler(int sigtype) -{ - async_event = true; - async_dump = true; -} - -void -dumprstStatsHandler(int sigtype) -{ - async_event = true; - async_dumpreset = true; -} - -/// Exit signal handler. -void -exitNowHandler(int sigtype) -{ - async_event = true; - async_exit = true; -} - -/// Abort signal handler. -void -abortHandler(int sigtype) -{ - cerr << "Program aborted at cycle " << curTick << endl; - -#if TRACING_ON - // dump trace buffer, if there is one - Trace::theLog.dump(cerr); -#endif -} - -/// Simulator executable name -char *myProgName = ""; - -/// Show brief help message. -void -showBriefHelp(ostream &out) -{ - char *prog = basename(myProgName); - - ccprintf(out, "Usage:\n"); - ccprintf(out, -"%s [-d <dir>] [-E <var>[=<val>]] [-I <dir>] [-P <python>]\n" -" [--<var>=<val>] <config file>\n" -"\n" -" -d set the output directory to <dir>\n" -" -E set the environment variable <var> to <val> (or 'True')\n" -" -I add the directory <dir> to python's path\n" -" -P execute <python> directly in the configuration\n" -" --var=val set the python variable <var> to '<val>'\n" -" <configfile> config file name (ends in .py)\n\n", - prog); - - ccprintf(out, "%s -X\n -X extract embedded files\n\n", prog); - ccprintf(out, "%s -h\n -h print short help\n\n", prog); -} - -/// Print welcome message. -void -sayHello(ostream &out) -{ - extern const char *compileDate; // from date.cc - - ccprintf(out, "M5 Simulator System\n"); - // display copyright - ccprintf(out, "%s\n", briefCopyright); - ccprintf(out, "M5 compiled on %d\n", compileDate); - - char *host = getenv("HOSTNAME"); - if (!host) - host = getenv("HOST"); - - if (host) - ccprintf(out, "M5 executing on %s\n", host); - - ccprintf(out, "M5 simulation started %s\n", Time::start); -} - -/// -/// Echo the command line for posterity in such a way that it can be -/// used to rerun the same simulation (given the same .ini files). -/// -void -echoCommandLine(int argc, char **argv, ostream &out) -{ - out << "command line: " << argv[0]; - for (int i = 1; i < argc; i++) { - string arg(argv[i]); - - out << ' '; - - // If the arg contains spaces, we need to quote it. - // The rest of this is overkill to make it look purty. - - // print dashes first outside quotes - int non_dash_pos = arg.find_first_not_of("-"); - out << arg.substr(0, non_dash_pos); // print dashes - string body = arg.substr(non_dash_pos); // the rest - - // if it's an assignment, handle the lhs & rhs separately - int eq_pos = body.find("="); - if (eq_pos == string::npos) { - out << quote(body); - } - else { - string lhs(body.substr(0, eq_pos)); - string rhs(body.substr(eq_pos + 1)); - - out << quote(lhs) << "=" << quote(rhs); - } - } - out << endl << endl; -} - -char * -getOptionString(int &index, int argc, char **argv) -{ - char *option = argv[index] + 2; - if (*option != '\0') - return option; - - // We didn't find an argument, it must be in the next variable. - if (++index >= argc) - panic("option string for option '%s' not found", argv[index - 1]); - - return argv[index]; -} - -int -main(int argc, char **argv) -{ - // Save off program name - myProgName = argv[0]; - - signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths - signal(SIGTRAP, SIG_IGN); - signal(SIGUSR1, dumpStatsHandler); // dump intermediate stats - signal(SIGUSR2, dumprstStatsHandler); // dump and reset stats - signal(SIGINT, exitNowHandler); // dump final stats and exit - signal(SIGABRT, abortHandler); - - bool configfile_found = false; - PythonConfig pyconfig; - string outdir; - - if (argc < 2) { - showBriefHelp(cerr); - exit(1); - } - - sayHello(cerr); - - // Parse command-line options. - // Since most of the complex options are handled through the - // config database, we don't mess with getopts, and just parse - // manually. - for (int i = 1; i < argc; ++i) { - char *arg_str = argv[i]; - - // if arg starts with '--', parse as a special python option - // of the format --<python var>=<string value>, if the arg - // starts with '-', it should be a simulator option with a - // format similar to getopt. In any other case, treat the - // option as a configuration file name and load it. - if (arg_str[0] == '-' && arg_str[1] == '-') { - string str = &arg_str[2]; - string var, val; - - if (!split_first(str, var, val, '=')) - panic("Could not parse configuration argument '%s'\n" - "Expecting --<variable>=<value>\n", arg_str); - - pyconfig.setVariable(var, val); - } else if (arg_str[0] == '-') { - char *option; - string var, val; - - // switch on second char - switch (arg_str[1]) { - case 'd': - outdir = getOptionString(i, argc, argv); - break; - - case 'h': - showBriefHelp(cerr); - exit(1); - - case 'E': - option = getOptionString(i, argc, argv); - if (!split_first(option, var, val, '=')) - val = "True"; - - if (setenv(var.c_str(), val.c_str(), true) == -1) - panic("setenv: %s\n", strerror(errno)); - break; - - case 'I': - option = getOptionString(i, argc, argv); - pyconfig.addPath(option); - break; - - case 'P': - option = getOptionString(i, argc, argv); - pyconfig.writeLine(option); - break; - - case 'X': { - list<EmbedFile> lst; - EmbedMap::all(lst); - list<EmbedFile>::iterator i = lst.begin(); - list<EmbedFile>::iterator end = lst.end(); - - while (i != end) { - cprintf("Embedded File: %s\n", i->name); - cout.write(i->data, i->length); - ++i; - } - - return 0; - } - - default: - showBriefHelp(cerr); - panic("invalid argument '%s'\n", arg_str); - } - } else { - string file(arg_str); - string base, ext; - - if (!split_last(file, base, ext, '.') || ext != "py") - panic("Config file '%s' must end in '.py'\n", file); - - pyconfig.load(file); - configfile_found = true; - } - } - - if (outdir.empty()) { - char *env = getenv("OUTPUT_DIR"); - outdir = env ? env : "."; - } - - simout.setDirectory(outdir); - - char *env = getenv("CONFIG_OUTPUT"); - if (!env) - env = "config.out"; - configStream = simout.find(env); - - if (!configfile_found) - panic("no configuration file specified!"); - - // The configuration database is now complete; start processing it. - IniFile inifile; - if (!pyconfig.output(inifile)) - panic("Error processing python code"); - - // Initialize statistics database - Stats::InitSimStats(); - - // Now process the configuration hierarchy and create the SimObjects. - ConfigHierarchy configHierarchy(inifile); - configHierarchy.build(); - configHierarchy.createSimObjects(); - - // Parse and check all non-config-hierarchy parameters. - ParamContext::parseAllContexts(inifile); - ParamContext::checkAllContexts(); - - // Print hello message to stats file if it's actually a file. If - // it's not (i.e. it's cout or cerr) then we already did it above. - if (simout.isFile(*outputStream)) - sayHello(*outputStream); - - // Echo command line and all parameter settings to stats file as well. - echoCommandLine(argc, argv, *outputStream); - ParamContext::showAllContexts(*configStream); - - // Any objects that can't connect themselves until after construction should - // do so now - SimObject::connectAll(); - - // Do a second pass to finish initializing the sim objects - SimObject::initAll(); - - // Restore checkpointed state, if any. - configHierarchy.unserializeSimObjects(); - - // Done processing the configuration database. - // Check for unreferenced entries. - if (inifile.printUnreferenced()) - panic("unreferenced sections/entries in the intermediate ini file"); - - SimObject::regAllStats(); - - // uncomment the following to get PC-based execution-time profile -#ifdef DO_PROFILE - init_profile((char *)&_init, (char *)&_fini); -#endif - - // Check to make sure that the stats package is properly initialized - Stats::check(); - - // Reset to put the stats in a consistent state. - Stats::reset(); - - warn("Entering event queue. Starting simulation...\n"); - SimStartup(); - while (!mainEventQueue.empty()) { - assert(curTick <= mainEventQueue.nextTick() && - "event scheduled in the past"); - - // forward current cycle to the time of the first event on the - // queue - curTick = mainEventQueue.nextTick(); - mainEventQueue.serviceOne(); - - if (async_event) { - async_event = false; - if (async_dump) { - async_dump = false; - - using namespace Stats; - SetupEvent(Dump, curTick); - } - - if (async_dumpreset) { - async_dumpreset = false; - - using namespace Stats; - SetupEvent(Dump | Reset, curTick); - } - - if (async_exit) { - async_exit = false; - new SimExitEvent("User requested STOP"); - } - - if (async_io || async_alarm) { - async_io = false; - async_alarm = false; - pollQueue.service(); - } - } - } - - // This should never happen... every conceivable way for the - // simulation to terminate (hit max cycles/insts, signal, - // simulated system halts/exits) generates an exit event, so we - // should never run out of events on the queue. - exitNow("no events on event loop! All CPUs must be idle.", 1); - - return 0; -} diff --git a/sim/param.cc b/sim/param.cc deleted file mode 100644 index 8998d7d77..000000000 --- a/sim/param.cc +++ /dev/null @@ -1,793 +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. - */ - -#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/config_node.hh" -#include "sim/configfile.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 { - obj = context->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 -// -//////////////////////////////////////////////////////////////////////// - -list<ParamContext *> *ParamContext::ctxList = NULL; - -ParamContext::ParamContext(const string &_iniSection, InitPhase _initPhase) - : iniFilePtr(NULL), // initialized on call to parseParams() - iniSection(_iniSection), paramList(NULL), - initPhase(_initPhase) -{ - // Put this context on global list for initialization - if (initPhase != NoAutoInit) { - if (ctxList == NULL) - ctxList = new list<ParamContext *>(); - - // keep list sorted by ascending initPhase values - list<ParamContext *>::iterator i = ctxList->begin(); - list<ParamContext *>::iterator end = ctxList->end(); - for (; i != end; ++i) { - if (initPhase <= (*i)->initPhase) { - // found where we want to insert - break; - } - } - // (fall through case: insert at end) - ctxList->insert(i, this); - } -} - - -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; -} - -// -// Resolve an object name to a SimObject pointer. The object will be -// created as a side-effect if necessary. If the name contains a -// colon (e.g., "iq:IQ"), then the object is local (invisible to -// outside this context). If there is no colon, the name needs to be -// resolved through the configuration hierarchy (only possible for -// SimObjectBuilder objects, which return non-NULL for configNode()). -// -SimObject * -ParamContext::resolveSimObject(const string &name) -{ - ConfigNode *n = getConfigNode(); - return n ? n->resolveSimObject(name) : NULL; -} - - -// -// static method: call parseParams() on all registered contexts -// -void -ParamContext::parseAllContexts(IniFile &iniFile) -{ - list<ParamContext *>::iterator iter; - - for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) { - ParamContext *pc = *iter; - - pc->parseParams(iniFile); - } -} - - -// -// static method: call checkParams() on all registered contexts -// -void -ParamContext::checkAllContexts() -{ - list<ParamContext *>::iterator iter; - - for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) { - ParamContext *pc = *iter; - - pc->checkParams(); - } -} - - -// -// static method: call showParams() on all registered contexts -// -void -ParamContext::showAllContexts(ostream &os) -{ - list<ParamContext *>::iterator iter; - - for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) { - ParamContext *pc = *iter; - - os << "[" << pc->iniSection << "]" << endl; - pc->showParams(os); - os << endl; - } -} - - -// -// static method: call cleanup() on all registered contexts -// -void -ParamContext::cleanupAllContexts() -{ - list<ParamContext *>::iterator iter; - - for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) { - ParamContext *pc = *iter; - - pc->cleanup(); - } -} - - -// -// static method: call describeParams() on all registered contexts -// -void -ParamContext::describeAllContexts(ostream &os) -{ - list<ParamContext *>::iterator iter; - - for (iter = ctxList->begin(); iter != ctxList->end(); ++iter) { - ParamContext *pc = *iter; - - os << "[" << pc->iniSection << "]\n"; - pc->describeParams(os); - os << endl; - } -} diff --git a/sim/param.hh b/sim/param.hh deleted file mode 100644 index 4a1b8bda1..000000000 --- a/sim/param.hh +++ /dev/null @@ -1,788 +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. - */ - -#ifndef __SIM_PARAM_HH__ -#define __SIM_PARAM_HH__ - -#include <iostream> -#include <list> -#include <string> -#include <vector> - -#include "sim/configfile.hh" -#include "sim/startup.hh" - -// forward decls -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 -{ - private: - - // static list of all ParamContext objects, built as a side effect - // of the ParamContext constructor - static std::list<ParamContext *> *ctxList; - - 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: - - /// Initialization phases for ParamContext objects. - enum InitPhase { - NoAutoInit = -1, ///< Don't initialize at all... params - /// will be parsed later (used by - /// SimObjectBuilder, which parses - /// params in SimObject::create(). - OutputInitPhase = 0, ///< Output stream initialization - TraceInitPhase = 1, ///< Trace context initialization: - /// depends on output streams, but - /// needs to come before others so we - /// can use tracing in other - /// ParamContext init code - StatsInitPhase = 2, ///< Stats output initialization - DefaultInitPhase = 3 ///< Everything else - }; - - /// Records the initialization phase for this ParamContext. - InitPhase initPhase; - - /// Constructor. - /// @param _iniSection Name of .ini section corresponding to this context. - /// @param _initPhase Initialization phase (see InitPhase). - ParamContext(const std::string &_iniSection, - InitPhase _initPhase = DefaultInitPhase); - - 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 &); - - // resolve a SimObject name in this context to an object pointer. - virtual SimObject *resolveSimObject(const std::string &name); - - // 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; } - - // return the configuration hierarchy node for this context. Bare - // ParamContext objects have no corresponding node, so the default - // implementation returns NULL. - virtual ConfigNode *getConfigNode() { return NULL; } - - // Parse all parameters registered with all ParamContext objects. - static void parseAllContexts(IniFile &iniFile); - - // Check all parameters registered with all ParamContext objects. - // (calls checkParams() on each) - static void checkAllContexts(); - - // Print all parameter values on indicated ostream. - static void showAllContexts(std::ostream &os); - - // Clean up all registered ParamContext objects. (calls cleanup() - // on each) - static void cleanupAllContexts(); - - // print descriptions of all parameters registered with all - // ParamContext objects - static void describeAllContexts(std::ostream &os); -}; - - -// -// 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; - } - - // 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); - -#endif // _SIM_PARAM_HH_ diff --git a/sim/process.cc b/sim/process.cc deleted file mode 100644 index 1261b8436..000000000 --- a/sim/process.cc +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (c) 2001-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. - */ - -#include <unistd.h> -#include <fcntl.h> - -#include <string> - -#include "base/intmath.hh" -#include "base/loader/object_file.hh" -#include "base/loader/symtab.hh" -#include "base/statistics.hh" -#include "config/full_system.hh" -#include "cpu/exec_context.hh" -#include "mem/page_table.hh" -#include "mem/physical.hh" -#include "mem/translating_port.hh" -#include "sim/builder.hh" -#include "sim/process.hh" -#include "sim/stats.hh" -#include "sim/syscall_emul.hh" -#include "sim/system.hh" - -using namespace std; -using namespace TheISA; - -// -// The purpose of this code is to fake the loader & syscall mechanism -// when there's no OS: thus there's no resone to use it in FULL_SYSTEM -// mode when we do have an OS -// -#if FULL_SYSTEM -#error "process.cc not compatible with FULL_SYSTEM" -#endif - -// current number of allocated processes -int num_processes = 0; - -Process::Process(const string &nm, - System *_system, - int stdin_fd, // initial I/O descriptors - int stdout_fd, - int stderr_fd) - : SimObject(nm), system(_system) -{ - // initialize first 3 fds (stdin, stdout, stderr) - fd_map[STDIN_FILENO] = stdin_fd; - fd_map[STDOUT_FILENO] = stdout_fd; - fd_map[STDERR_FILENO] = stderr_fd; - - // mark remaining fds as free - for (int i = 3; i <= MAX_FD; ++i) { - fd_map[i] = -1; - } - - mmap_start = mmap_end = 0; - nxm_start = nxm_end = 0; - pTable = new PageTable(system); - // other parameters will be initialized when the program is loaded -} - - -void -Process::regStats() -{ - using namespace Stats; - - num_syscalls - .name(name() + ".PROG:num_syscalls") - .desc("Number of system calls") - ; -} - -// -// static helper functions -// -int -Process::openInputFile(const string &filename) -{ - int fd = open(filename.c_str(), O_RDONLY); - - if (fd == -1) { - perror(NULL); - cerr << "unable to open \"" << filename << "\" for reading\n"; - fatal("can't open input file"); - } - - return fd; -} - - -int -Process::openOutputFile(const string &filename) -{ - int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0774); - - if (fd == -1) { - perror(NULL); - cerr << "unable to open \"" << filename << "\" for writing\n"; - fatal("can't open output file"); - } - - return fd; -} - - -int -Process::registerExecContext(ExecContext *xc) -{ - // add to list - int myIndex = execContexts.size(); - execContexts.push_back(xc); - - // return CPU number to caller - return myIndex; -} - -void -Process::startup() -{ - if (execContexts.empty()) - fatal("Process %s is not associated with any CPUs!\n", name()); - - // first exec context for this process... initialize & enable - ExecContext *xc = execContexts[0]; - - // mark this context as active so it will start ticking. - xc->activate(0); - - Port *mem_port; - mem_port = system->physmem->getPort("functional"); - initVirtMem = new TranslatingPort(pTable, true); - mem_port->setPeer(initVirtMem); - initVirtMem->setPeer(mem_port); -} - -void -Process::replaceExecContext(ExecContext *xc, int xcIndex) -{ - if (xcIndex >= execContexts.size()) { - panic("replaceExecContext: bad xcIndex, %d >= %d\n", - xcIndex, execContexts.size()); - } - - execContexts[xcIndex] = xc; -} - -// map simulator fd sim_fd to target fd tgt_fd -void -Process::dup_fd(int sim_fd, int tgt_fd) -{ - if (tgt_fd < 0 || tgt_fd > MAX_FD) - panic("Process::dup_fd tried to dup past MAX_FD (%d)", tgt_fd); - - fd_map[tgt_fd] = sim_fd; -} - - -// generate new target fd for sim_fd -int -Process::alloc_fd(int sim_fd) -{ - // in case open() returns an error, don't allocate a new fd - if (sim_fd == -1) - return -1; - - // find first free target fd - for (int free_fd = 0; free_fd < MAX_FD; ++free_fd) { - if (fd_map[free_fd] == -1) { - fd_map[free_fd] = sim_fd; - return free_fd; - } - } - - panic("Process::alloc_fd: out of file descriptors!"); -} - - -// free target fd (e.g., after close) -void -Process::free_fd(int tgt_fd) -{ - if (fd_map[tgt_fd] == -1) - warn("Process::free_fd: request to free unused fd %d", tgt_fd); - - fd_map[tgt_fd] = -1; -} - - -// look up simulator fd for given target fd -int -Process::sim_fd(int tgt_fd) -{ - if (tgt_fd > MAX_FD) - return -1; - - return fd_map[tgt_fd]; -} - - - -// -// 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 -// -//////////////////////////////////////////////////////////////////////// - - -void -copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr, - TranslatingPort* memPort) -{ - Addr data_ptr_swap; - for (int i = 0; i < strings.size(); ++i) { - data_ptr_swap = htog(data_ptr); - memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap, sizeof(Addr)); - memPort->writeString(data_ptr, strings[i].c_str()); - array_ptr += sizeof(Addr); - data_ptr += strings[i].size() + 1; - } - // add NULL terminator - data_ptr = 0; - - memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(Addr)); -} - -LiveProcess::LiveProcess(const string &nm, ObjectFile *_objFile, - System *_system, - int stdin_fd, int stdout_fd, int stderr_fd, - vector<string> &_argv, vector<string> &_envp) - : Process(nm, _system, stdin_fd, stdout_fd, stderr_fd), - objFile(_objFile), argv(_argv), envp(_envp) -{ - prog_fname = argv[0]; - - // load up symbols, if any... these may be used for debugging or - // profiling. - if (!debugSymbolTable) { - debugSymbolTable = new SymbolTable(); - if (!objFile->loadGlobalSymbols(debugSymbolTable) || - !objFile->loadLocalSymbols(debugSymbolTable)) { - // didn't load any symbols - delete debugSymbolTable; - debugSymbolTable = NULL; - } - } -} - -void -LiveProcess::argsInit(int intSize, int pageSize) -{ - Process::startup(); - - // load object file into target memory - objFile->loadSections(initVirtMem); - - // Calculate how much space we need for arg & env arrays. - int argv_array_size = intSize * (argv.size() + 1); - int envp_array_size = intSize * (envp.size() + 1); - int arg_data_size = 0; - for (int i = 0; i < argv.size(); ++i) { - arg_data_size += argv[i].size() + 1; - } - int env_data_size = 0; - for (int i = 0; i < envp.size(); ++i) { - env_data_size += envp[i].size() + 1; - } - - int space_needed = - argv_array_size + envp_array_size + arg_data_size + env_data_size; - // for SimpleScalar compatibility - if (space_needed < 16384) - space_needed = 16384; - - // set bottom of stack - stack_min = stack_base - space_needed; - // align it - stack_min &= ~(intSize-1); - stack_size = stack_base - stack_min; - // map memory - pTable->allocate(roundDown(stack_min, pageSize), - roundUp(stack_size, pageSize)); - - // map out initial stack contents - Addr argv_array_base = stack_min + intSize; // room for argc - Addr envp_array_base = argv_array_base + argv_array_size; - Addr arg_data_base = envp_array_base + envp_array_size; - Addr env_data_base = arg_data_base + arg_data_size; - - // write contents to stack - uint64_t argc = argv.size(); - if (intSize == 8) - argc = htog((uint64_t)argc); - else if (intSize == 4) - argc = htog((uint32_t)argc); - else - panic("Unknown int size"); - - initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); - - copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); - copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); - - execContexts[0]->setIntReg(ArgumentReg0, argc); - execContexts[0]->setIntReg(ArgumentReg1, argv_array_base); - execContexts[0]->setIntReg(StackPointerReg, stack_min); - - Addr prog_entry = objFile->entryPoint(); - execContexts[0]->setPC(prog_entry); - execContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); - execContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); - - num_processes++; -} - -void -LiveProcess::syscall(int64_t callnum, ExecContext *xc) -{ - num_syscalls++; - - SyscallDesc *desc = getDesc(callnum); - if (desc == NULL) - fatal("Syscall %d out of range", callnum); - - desc->doSyscall(callnum, this, xc); -} - -DEFINE_SIM_OBJECT_CLASS_NAME("LiveProcess", LiveProcess); diff --git a/sim/process.hh b/sim/process.hh deleted file mode 100644 index 807bf330f..000000000 --- a/sim/process.hh +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2001-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. - */ - -#ifndef __PROCESS_HH__ -#define __PROCESS_HH__ - -// -// The purpose of this code is to fake the loader & syscall mechanism -// when there's no OS: thus there's no reason to use it in FULL_SYSTEM -// mode when we do have an OS. -// -#include "config/full_system.hh" - -#if !FULL_SYSTEM - -#include <vector> - -#include "base/statistics.hh" -#include "sim/sim_object.hh" - -class CPUExecContext; -class ExecContext; -class SyscallDesc; -class PageTable; -class TranslatingPort; -class System; - -void -copyStringArray(std::vector<std::string> &strings, Addr array_ptr, - Addr data_ptr, TranslatingPort* memPort); - -class Process : public SimObject -{ - public: - - /// Pointer to object representing the system this process is - /// running on. - System *system; - - // have we initialized an execution context from this process? If - // yes, subsequent contexts are assumed to be for dynamically - // created threads and are not initialized. - bool initialContextLoaded; - - // execution contexts associated with this process - std::vector<ExecContext *> execContexts; - - // number of CPUs (esxec contexts, really) assigned to this process. - unsigned int numCpus() { return execContexts.size(); } - - // record of blocked context - struct WaitRec - { - Addr waitChan; - ExecContext *waitingContext; - - WaitRec(Addr chan, ExecContext *ctx) - : waitChan(chan), waitingContext(ctx) - { } - }; - - // list of all blocked contexts - std::list<WaitRec> waitList; - - Addr brk_point; // top of the data segment - - Addr stack_base; // stack segment base (highest address) - unsigned stack_size; // initial stack size - Addr stack_min; // lowest address accessed on the stack - - // addr to use for next stack region (for multithreaded apps) - Addr next_thread_stack_base; - - // Base of region for mmaps (when user doesn't specify an address). - Addr mmap_start; - Addr mmap_end; - - // Base of region for nxm data - Addr nxm_start; - Addr nxm_end; - - std::string prog_fname; // file name - - Stats::Scalar<> num_syscalls; // number of syscalls executed - - - protected: - // constructor - Process(const std::string &nm, - System *_system, - int stdin_fd, // initial I/O descriptors - int stdout_fd, - int stderr_fd); - - // post initialization startup - virtual void startup(); - - protected: - /// Memory object for initialization (image loading) - TranslatingPort *initVirtMem; - - public: - PageTable *pTable; - - private: - // file descriptor remapping support - static const int MAX_FD = 256; // max legal fd value - int fd_map[MAX_FD+1]; - - public: - // static helper functions to generate file descriptors for constructor - static int openInputFile(const std::string &filename); - static int openOutputFile(const std::string &filename); - - // override of virtual SimObject method: register statistics - virtual void regStats(); - - // register an execution context for this process. - // returns xc's cpu number (index into execContexts[]) - int registerExecContext(ExecContext *xc); - - - void replaceExecContext(ExecContext *xc, int xcIndex); - - // map simulator fd sim_fd to target fd tgt_fd - void dup_fd(int sim_fd, int tgt_fd); - - // generate new target fd for sim_fd - int alloc_fd(int sim_fd); - - // free target fd (e.g., after close) - void free_fd(int tgt_fd); - - // look up simulator fd for given target fd - int sim_fd(int tgt_fd); - - virtual void syscall(int64_t callnum, ExecContext *xc) = 0; -}; - -// -// "Live" process with system calls redirected to host system -// -class ObjectFile; -class LiveProcess : public Process -{ - protected: - ObjectFile *objFile; - std::vector<std::string> argv; - std::vector<std::string> envp; - - LiveProcess(const std::string &nm, ObjectFile *objFile, - System *_system, int stdin_fd, int stdout_fd, int stderr_fd, - std::vector<std::string> &argv, - std::vector<std::string> &envp); - - virtual void argsInit(int intSize, int pageSize); - - public: - virtual void syscall(int64_t callnum, ExecContext *xc); - - virtual SyscallDesc* getDesc(int callnum) = 0; -}; - - -#endif // !FULL_SYSTEM - -#endif // __PROCESS_HH__ diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc deleted file mode 100644 index 7897b5c8b..000000000 --- a/sim/pseudo_inst.cc +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2003-2006 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> - -#include <string> - -#include "sim/pseudo_inst.hh" -#include "arch/vtophys.hh" -#include "cpu/base.hh" -#include "cpu/sampler/sampler.hh" -#include "cpu/exec_context.hh" -#include "kern/kernel_stats.hh" -#include "sim/param.hh" -#include "sim/serialize.hh" -#include "sim/sim_exit.hh" -#include "sim/stat_control.hh" -#include "sim/stats.hh" -#include "sim/system.hh" -#include "sim/debug.hh" -#include "sim/vptr.hh" - -using namespace std; - -extern Sampler *SampCPU; - -using namespace Stats; -using namespace TheISA; - -namespace AlphaPseudo -{ - bool doStatisticsInsts; - bool doCheckpointInsts; - bool doQuiesce; - - void - arm(ExecContext *xc) - { - xc->getCpuPtr()->kernelStats->arm(); - } - - void - quiesce(ExecContext *xc) - { - if (!doQuiesce) - return; - - xc->suspend(); - xc->getCpuPtr()->kernelStats->quiesce(); - } - - void - quiesceNs(ExecContext *xc, uint64_t ns) - { - if (!doQuiesce || ns == 0) - return; - - Event *quiesceEvent = xc->getQuiesceEvent(); - - if (quiesceEvent->scheduled()) - quiesceEvent->reschedule(curTick + Clock::Int::ns * ns); - else - quiesceEvent->schedule(curTick + Clock::Int::ns * ns); - - xc->suspend(); - xc->getCpuPtr()->kernelStats->quiesce(); - } - - void - quiesceCycles(ExecContext *xc, uint64_t cycles) - { - if (!doQuiesce || cycles == 0) - return; - - Event *quiesceEvent = xc->getQuiesceEvent(); - - if (quiesceEvent->scheduled()) - quiesceEvent->reschedule(curTick + - xc->getCpuPtr()->cycles(cycles)); - else - quiesceEvent->schedule(curTick + - xc->getCpuPtr()->cycles(cycles)); - - xc->suspend(); - xc->getCpuPtr()->kernelStats->quiesce(); - } - - uint64_t - quiesceTime(ExecContext *xc) - { - return (xc->readLastActivate() - xc->readLastSuspend()) / Clock::Int::ns; - } - - void - ivlb(ExecContext *xc) - { - xc->getCpuPtr()->kernelStats->ivlb(); - } - - void - ivle(ExecContext *xc) - { - } - - void - m5exit_old(ExecContext *xc) - { - SimExit(curTick, "m5_exit_old instruction encountered"); - } - - void - m5exit(ExecContext *xc, Tick delay) - { - Tick when = curTick + delay * Clock::Int::ns; - SimExit(when, "m5_exit instruction encountered"); - } - - void - resetstats(ExecContext *xc, Tick delay, Tick period) - { - if (!doStatisticsInsts) - return; - - - Tick when = curTick + delay * Clock::Int::ns; - Tick repeat = period * Clock::Int::ns; - - using namespace Stats; - SetupEvent(Reset, when, repeat); - } - - void - dumpstats(ExecContext *xc, Tick delay, Tick period) - { - if (!doStatisticsInsts) - return; - - - Tick when = curTick + delay * Clock::Int::ns; - Tick repeat = period * Clock::Int::ns; - - using namespace Stats; - SetupEvent(Dump, when, repeat); - } - - void - addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr) - { - char symb[100]; - CopyStringOut(xc, symb, symbolAddr, 100); - std::string symbol(symb); - - DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); - - xc->getSystemPtr()->kernelSymtab->insert(addr,symbol); - } - - void - dumpresetstats(ExecContext *xc, Tick delay, Tick period) - { - if (!doStatisticsInsts) - return; - - - Tick when = curTick + delay * Clock::Int::ns; - Tick repeat = period * Clock::Int::ns; - - using namespace Stats; - SetupEvent(Dump|Reset, when, repeat); - } - - void - m5checkpoint(ExecContext *xc, Tick delay, Tick period) - { - if (!doCheckpointInsts) - return; - - - Tick when = curTick + delay * Clock::Int::ns; - Tick repeat = period * Clock::Int::ns; - - Checkpoint::setup(when, repeat); - } - - uint64_t - readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset) - { - const string &file = xc->getCpuPtr()->system->params()->readfile; - if (file.empty()) { - return ULL(0); - } - - uint64_t result = 0; - - int fd = ::open(file.c_str(), O_RDONLY, 0); - if (fd < 0) - panic("could not open file %s\n", file); - - if (::lseek(fd, offset, SEEK_SET) < 0) - panic("could not seek: %s", strerror(errno)); - - char *buf = new char[len]; - char *p = buf; - while (len > 0) { - int bytes = ::read(fd, p, len); - if (bytes <= 0) - break; - - p += bytes; - result += bytes; - len -= bytes; - } - - close(fd); - CopyIn(xc, vaddr, buf, result); - delete [] buf; - return result; - } - - class Context : public ParamContext - { - public: - Context(const string §ion) : ParamContext(section) {} - void checkParams(); - }; - - Context context("pseudo_inst"); - - Param<bool> __quiesce(&context, "quiesce", - "enable quiesce instructions", - true); - Param<bool> __statistics(&context, "statistics", - "enable statistics pseudo instructions", - true); - Param<bool> __checkpoint(&context, "checkpoint", - "enable checkpoint pseudo instructions", - true); - - void - Context::checkParams() - { - doQuiesce = __quiesce; - doStatisticsInsts = __statistics; - doCheckpointInsts = __checkpoint; - } - - void debugbreak(ExecContext *xc) - { - debug_break(); - } - - void switchcpu(ExecContext *xc) - { - if (SampCPU) - SampCPU->switchCPUs(); - } -} diff --git a/sim/pseudo_inst.hh b/sim/pseudo_inst.hh deleted file mode 100644 index 4dd427c99..000000000 --- a/sim/pseudo_inst.hh +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2003-2006 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -class ExecContext; - -//We need the "Tick" data type from here -#include "sim/host.hh" -//We need the "Addr" data type from here -#include "arch/isa_traits.hh" - -namespace AlphaPseudo -{ - /** - * @todo these externs are only here for a hack in fullCPU::takeOver... - */ - extern bool doStatisticsInsts; - extern bool doCheckpointInsts; - extern bool doQuiesce; - - void arm(ExecContext *xc); - void quiesce(ExecContext *xc); - void quiesceNs(ExecContext *xc, uint64_t ns); - void quiesceCycles(ExecContext *xc, uint64_t cycles); - uint64_t quiesceTime(ExecContext *xc); - void ivlb(ExecContext *xc); - void ivle(ExecContext *xc); - void m5exit(ExecContext *xc, Tick delay); - void m5exit_old(ExecContext *xc); - void resetstats(ExecContext *xc, Tick delay, Tick period); - void dumpstats(ExecContext *xc, Tick delay, Tick period); - void dumpresetstats(ExecContext *xc, Tick delay, Tick period); - void m5checkpoint(ExecContext *xc, Tick delay, Tick period); - uint64_t readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset); - void debugbreak(ExecContext *xc); - void switchcpu(ExecContext *xc); - void addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr); -} diff --git a/sim/root.cc b/sim/root.cc deleted file mode 100644 index 6348ec104..000000000 --- a/sim/root.cc +++ /dev/null @@ -1,156 +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. - */ - -#include <cstring> -#include <fstream> -#include <list> -#include <string> -#include <vector> - -#include "base/misc.hh" -#include "base/output.hh" -#include "sim/builder.hh" -#include "sim/host.hh" -#include "sim/sim_events.hh" -#include "sim/sim_object.hh" -#include "sim/root.hh" - -using namespace std; - -Tick curTick = 0; -ostream *outputStream; -ostream *configStream; - -/// The simulated frequency of curTick. (This is only here for a short time) -Tick ticksPerSecond; - -namespace Clock { -/// The simulated frequency of curTick. (In ticks per second) -Tick Frequency; - -namespace Float { -double s; -double ms; -double us; -double ns; -double ps; - -double Hz; -double kHz; -double MHz; -double GHZ; -/* namespace Float */ } - -namespace Int { -Tick s; -Tick ms; -Tick us; -Tick ns; -Tick ps; -/* namespace Float */ } - -/* namespace Clock */ } - - -// Dummy Object -class Root : public SimObject -{ - private: - Tick max_tick; - Tick progress_interval; - - public: - Root(const std::string &name, Tick maxtick, Tick pi) - : SimObject(name), max_tick(maxtick), progress_interval(pi) - {} - - virtual void startup(); -}; - -void -Root::startup() -{ - if (max_tick != 0) - new SimExitEvent(curTick + max_tick, "reached maximum cycle count"); - - if (progress_interval != 0) - new ProgressEvent(&mainEventQueue, progress_interval); -} - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(Root) - - Param<Tick> clock; - Param<Tick> max_tick; - Param<Tick> progress_interval; - Param<string> output_file; - -END_DECLARE_SIM_OBJECT_PARAMS(Root) - -BEGIN_INIT_SIM_OBJECT_PARAMS(Root) - - INIT_PARAM(clock, "tick frequency"), - INIT_PARAM(max_tick, "maximum simulation time"), - INIT_PARAM(progress_interval, "print a progress message"), - INIT_PARAM(output_file, "file to dump simulator output to") - -END_INIT_SIM_OBJECT_PARAMS(Root) - -CREATE_SIM_OBJECT(Root) -{ - static bool created = false; - if (created) - panic("only one root object allowed!"); - - created = true; - - outputStream = simout.find(output_file); - Root *root = new Root(getInstanceName(), max_tick, progress_interval); - - using namespace Clock; - Frequency = clock; - Float::s = static_cast<double>(Frequency); - Float::ms = Float::s / 1.0e3; - Float::us = Float::s / 1.0e6; - Float::ns = Float::s / 1.0e9; - Float::ps = Float::s / 1.0e12; - - Float::Hz = 1.0 / Float::s; - Float::kHz = 1.0 / Float::ms; - Float::MHz = 1.0 / Float::us; - Float::GHZ = 1.0 / Float::ns; - - Int::s = Frequency; - Int::ms = Int::s / 1000; - Int::us = Int::ms / 1000; - Int::ns = Int::us / 1000; - Int::ps = Int::ns / 1000; - - return root; -} - -REGISTER_SIM_OBJECT("Root", Root) diff --git a/sim/serialize.cc b/sim/serialize.cc deleted file mode 100644 index c4ef124bb..000000000 --- a/sim/serialize.cc +++ /dev/null @@ -1,484 +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. - */ - -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> - -#include <fstream> -#include <list> -#include <string> -#include <vector> - -#include "base/inifile.hh" -#include "base/misc.hh" -#include "base/output.hh" -#include "base/str.hh" -#include "base/trace.hh" -#include "sim/config_node.hh" -#include "sim/eventq.hh" -#include "sim/param.hh" -#include "sim/serialize.hh" -#include "sim/sim_events.hh" -#include "sim/sim_exit.hh" -#include "sim/sim_object.hh" - -using namespace std; - -int Serializable::ckptMaxCount = 0; -int Serializable::ckptCount = 0; -int Serializable::ckptPrevCount = -1; - -void -Serializable::nameOut(ostream &os) -{ - os << "\n[" << name() << "]\n"; -} - -void -Serializable::nameOut(ostream &os, const string &_name) -{ - os << "\n[" << _name << "]\n"; -} - -template <class T> -void -paramOut(ostream &os, const std::string &name, const T ¶m) -{ - os << name << "="; - showParam(os, param); - os << "\n"; -} - - -template <class T> -void -paramIn(Checkpoint *cp, const std::string §ion, - const std::string &name, T ¶m) -{ - std::string str; - if (!cp->find(section, name, str) || !parseParam(str, param)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } -} - - -template <class T> -void -arrayParamOut(ostream &os, const std::string &name, - const T *param, int size) -{ - os << name << "="; - if (size > 0) - showParam(os, param[0]); - for (int i = 1; i < size; ++i) { - os << " "; - showParam(os, param[i]); - } - os << "\n"; -} - - -template <class T> -void -arrayParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, T *param, int size) -{ - std::string str; - if (!cp->find(section, name, str)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } - - // code below stolen from VectorParam<T>::parse(). - // it would be nice to unify these somehow... - - vector<string> tokens; - - tokenize(tokens, str, ' '); - - // Need this if we were doing a vector - // value.resize(tokens.size()); - - if (tokens.size() != size) { - fatal("Array size mismatch on %s:%s'\n", section, name); - } - - 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 += str; - err += "\""; - - fatal(err); - } - - // assign parsed value to vector - param[i] = scalar_value; - } -} - - -void -objParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, Serializable * ¶m) -{ - if (!cp->findObj(section, name, param)) { - fatal("Can't unserialize '%s:%s'\n", section, name); - } -} - - -#define INSTANTIATE_PARAM_TEMPLATES(type) \ -template void \ -paramOut(ostream &os, const std::string &name, type const ¶m); \ -template void \ -paramIn(Checkpoint *cp, const std::string §ion, \ - const std::string &name, type & param); \ -template void \ -arrayParamOut(ostream &os, const std::string &name, \ - type const *param, int size); \ -template void \ -arrayParamIn(Checkpoint *cp, const std::string §ion, \ - const std::string &name, type *param, int size); - -INSTANTIATE_PARAM_TEMPLATES(signed char) -INSTANTIATE_PARAM_TEMPLATES(unsigned char) -INSTANTIATE_PARAM_TEMPLATES(signed short) -INSTANTIATE_PARAM_TEMPLATES(unsigned short) -INSTANTIATE_PARAM_TEMPLATES(signed int) -INSTANTIATE_PARAM_TEMPLATES(unsigned int) -INSTANTIATE_PARAM_TEMPLATES(signed long) -INSTANTIATE_PARAM_TEMPLATES(unsigned long) -INSTANTIATE_PARAM_TEMPLATES(signed long long) -INSTANTIATE_PARAM_TEMPLATES(unsigned long long) -INSTANTIATE_PARAM_TEMPLATES(bool) -INSTANTIATE_PARAM_TEMPLATES(string) - - -///////////////////////////// - -/// Container for serializing global variables (not associated with -/// any serialized object). -class Globals : public Serializable -{ - public: - const string name() const; - void serialize(ostream &os); - void unserialize(Checkpoint *cp); -}; - -/// The one and only instance of the Globals class. -Globals globals; - -const string -Globals::name() const -{ - return "Globals"; -} - -void -Globals::serialize(ostream &os) -{ - nameOut(os); - SERIALIZE_SCALAR(curTick); - - nameOut(os, "MainEventQueue"); - mainEventQueue.serialize(os); -} - -void -Globals::unserialize(Checkpoint *cp) -{ - const string §ion = name(); - UNSERIALIZE_SCALAR(curTick); - - mainEventQueue.unserialize(cp, "MainEventQueue"); -} - -void -Serializable::serializeAll() -{ - string dir = Checkpoint::dir(); - if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) - fatal("couldn't mkdir %s\n", dir); - - string cpt_file = dir + Checkpoint::baseFilename; - ofstream outstream(cpt_file.c_str()); - time_t t = time(NULL); - outstream << "// checkpoint generated: " << ctime(&t); - - globals.serialize(outstream); - SimObject::serializeAll(outstream); - - assert(Serializable::ckptPrevCount + 1 == Serializable::ckptCount); - Serializable::ckptPrevCount++; - if (ckptMaxCount && ++ckptCount >= ckptMaxCount) - SimExit(curTick + 1, "Maximum number of checkpoints dropped"); - -} - - -void -Serializable::unserializeGlobals(Checkpoint *cp) -{ - globals.unserialize(cp); -} - - -class SerializeEvent : public Event -{ - protected: - Tick repeat; - - public: - SerializeEvent(Tick _when, Tick _repeat); - virtual void process(); - virtual void serialize(std::ostream &os) - { - panic("Cannot serialize the SerializeEvent"); - } - -}; - -SerializeEvent::SerializeEvent(Tick _when, Tick _repeat) - : Event(&mainEventQueue, Serialize_Pri), repeat(_repeat) -{ - setFlags(AutoDelete); - schedule(_when); -} - -void -SerializeEvent::process() -{ - Serializable::serializeAll(); - if (repeat) - schedule(curTick + repeat); -} - -const char *Checkpoint::baseFilename = "m5.cpt"; - -static string checkpointDirBase; - -string -Checkpoint::dir() -{ - // use csprintf to insert curTick into directory name if it - // appears to have a format placeholder in it. - return (checkpointDirBase.find("%") != string::npos) ? - csprintf(checkpointDirBase, curTick) : checkpointDirBase; -} - -void -Checkpoint::setup(Tick when, Tick period) -{ - new SerializeEvent(when, period); -} - -class SerializeParamContext : public ParamContext -{ - private: - SerializeEvent *event; - - public: - SerializeParamContext(const string §ion); - ~SerializeParamContext(); - void checkParams(); -}; - -SerializeParamContext serialParams("serialize"); - -Param<string> serialize_dir(&serialParams, "dir", - "dir to stick checkpoint in " - "(sprintf format with cycle #)"); - -Param<Counter> serialize_cycle(&serialParams, - "cycle", - "cycle to serialize", - 0); - -Param<Counter> serialize_period(&serialParams, - "period", - "period to repeat serializations", - 0); - -Param<int> serialize_count(&serialParams, "count", - "maximum number of checkpoints to drop"); - -SerializeParamContext::SerializeParamContext(const string §ion) - : ParamContext(section), event(NULL) -{ } - -SerializeParamContext::~SerializeParamContext() -{ -} - -void -SerializeParamContext::checkParams() -{ - checkpointDirBase = simout.resolve(serialize_dir); - - // guarantee that directory ends with a '/' - if (checkpointDirBase[checkpointDirBase.size() - 1] != '/') - checkpointDirBase += "/"; - - if (serialize_cycle > 0) - Checkpoint::setup(serialize_cycle, serialize_period); - - Serializable::ckptMaxCount = serialize_count; -} - -void -debug_serialize() -{ - Serializable::serializeAll(); -} - -void -debug_serialize(Tick when) -{ - new SerializeEvent(when, 0); -} - -//////////////////////////////////////////////////////////////////////// -// -// SerializableClass member definitions -// -//////////////////////////////////////////////////////////////////////// - -// Map of class names to SerializableBuilder creation functions. -// Need to make this a pointer so we can force initialization on the -// first reference; otherwise, some SerializableClass constructors -// may be invoked before the classMap constructor. -map<string,SerializableClass::CreateFunc> *SerializableClass::classMap = 0; - -// SerializableClass constructor: add mapping to classMap -SerializableClass::SerializableClass(const string &className, - CreateFunc createFunc) -{ - if (classMap == NULL) - classMap = new map<string,SerializableClass::CreateFunc>(); - - if ((*classMap)[className]) - { - cerr << "Error: simulation object class " << className << " redefined" - << endl; - fatal(""); - } - - // add className --> createFunc to class map - (*classMap)[className] = createFunc; -} - - -// -// -Serializable * -SerializableClass::createObject(Checkpoint *cp, - const std::string §ion) -{ - string className; - - if (!cp->find(section, "type", className)) { - fatal("Serializable::create: no 'type' entry in section '%s'.\n", - section); - } - - CreateFunc createFunc = (*classMap)[className]; - - if (createFunc == NULL) { - fatal("Serializable::create: no create function for class '%s'.\n", - className); - } - - Serializable *object = createFunc(cp, section); - - assert(object != NULL); - - return object; -} - - -Serializable * -Serializable::create(Checkpoint *cp, const std::string §ion) -{ - Serializable *object = SerializableClass::createObject(cp, section); - object->unserialize(cp, section); - return object; -} - - -Checkpoint::Checkpoint(const std::string &cpt_dir, const std::string &path, - const ConfigNode *_configNode) - : db(new IniFile), basePath(path), configNode(_configNode), cptDir(cpt_dir) -{ - string filename = cpt_dir + "/" + Checkpoint::baseFilename; - if (!db->load(filename)) { - fatal("Can't load checkpoint file '%s'\n", filename); - } -} - - -bool -Checkpoint::find(const std::string §ion, const std::string &entry, - std::string &value) -{ - return db->find(section, entry, value); -} - - -bool -Checkpoint::findObj(const std::string §ion, const std::string &entry, - Serializable *&value) -{ - string path; - - if (!db->find(section, entry, path)) - return false; - - if ((value = configNode->resolveSimObject(path)) != NULL) - return true; - - if ((value = objMap[path]) != NULL) - return true; - - return false; -} - - -bool -Checkpoint::sectionExists(const std::string §ion) -{ - return db->sectionExists(section); -} diff --git a/sim/serialize.hh b/sim/serialize.hh deleted file mode 100644 index d8f5f8fc5..000000000 --- a/sim/serialize.hh +++ /dev/null @@ -1,243 +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. - */ - -/* @file - * Serialization Interface Declarations - */ - -#ifndef __SERIALIZE_HH__ -#define __SERIALIZE_HH__ - - -#include <list> -#include <iostream> -#include <map> - -#include "sim/host.hh" -#include "sim/configfile.hh" - -class Serializable; -class Checkpoint; - -template <class T> -void paramOut(std::ostream &os, const std::string &name, const T ¶m); - -template <class T> -void paramIn(Checkpoint *cp, const std::string §ion, - const std::string &name, T ¶m); - -template <class T> -void arrayParamOut(std::ostream &os, const std::string &name, - const T *param, int size); - -template <class T> -void arrayParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, T *param, int size); - -void -objParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, Serializable * ¶m); - - -// -// These macros are streamlined to use in serialize/unserialize -// functions. It's assumed that serialize() has a parameter 'os' for -// the ostream, and unserialize() has parameters 'cp' and 'section'. -#define SERIALIZE_SCALAR(scalar) paramOut(os, #scalar, scalar) - -#define UNSERIALIZE_SCALAR(scalar) paramIn(cp, section, #scalar, scalar) - -// ENUMs are like SCALARs, but we cast them to ints on the way out -#define SERIALIZE_ENUM(scalar) paramOut(os, #scalar, (int)scalar) - -#define UNSERIALIZE_ENUM(scalar) \ - do { \ - int tmp; \ - paramIn(cp, section, #scalar, tmp); \ - scalar = (typeof(scalar))tmp; \ - } while (0) - -#define SERIALIZE_ARRAY(member, size) \ - arrayParamOut(os, #member, member, size) - -#define UNSERIALIZE_ARRAY(member, size) \ - arrayParamIn(cp, section, #member, member, size) - -#define SERIALIZE_OBJPTR(objptr) paramOut(os, #objptr, (objptr)->name()) - -#define UNSERIALIZE_OBJPTR(objptr) \ - do { \ - Serializable *sptr; \ - objParamIn(cp, section, #objptr, sptr); \ - objptr = dynamic_cast<typeof(objptr)>(sptr); \ - } while (0) - -/* - * Basic support for object serialization. - */ -class Serializable -{ - protected: - void nameOut(std::ostream &os); - void nameOut(std::ostream &os, const std::string &_name); - - public: - Serializable() {} - virtual ~Serializable() {} - - // manditory virtual function, so objects must provide names - virtual const std::string name() const = 0; - - virtual void serialize(std::ostream &os) {} - virtual void unserialize(Checkpoint *cp, const std::string §ion) {} - - static Serializable *create(Checkpoint *cp, - const std::string §ion); - - static int ckptCount; - static int ckptMaxCount; - static int ckptPrevCount; - static void serializeAll(); - static void unserializeGlobals(Checkpoint *cp); -}; - -// -// A SerializableBuilder serves as an evaluation context for a set of -// parameters that describe a specific instance of a Serializable. 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 -// Serializable references. SerializableBuilder is an abstract superclass; -// derived classes specialize the class for particular subclasses of -// Serializable (e.g., BaseCache). -// -// For typical usage, see the definition of -// SerializableClass::createObject(). -// -class SerializableBuilder -{ - public: - - SerializableBuilder() {} - - virtual ~SerializableBuilder() {} - - // Create the actual Serializable 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 Serializable. - virtual Serializable *create() = 0; -}; - -// -// An instance of SerializableClass corresponds to a class derived from -// Serializable. The SerializableClass 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 SerializableClass -{ - 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 SerializableBuilder is returned. - typedef Serializable *(*CreateFunc)(Checkpoint *cp, - const std::string §ion); - - static std::map<std::string,CreateFunc> *classMap; - - // Constructor. For example: - // - // SerializableClass baseCacheSerializableClass("BaseCacheSerializable", - // newBaseCacheSerializableBuilder); - // - SerializableClass(const std::string &className, CreateFunc createFunc); - - // create Serializable given name of class and pointer to - // configuration hierarchy node - static Serializable *createObject(Checkpoint *cp, - const std::string §ion); -}; - -// -// Macros to encapsulate the magic of declaring & defining -// SerializableBuilder and SerializableClass objects -// - -#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \ -SerializableClass the##OBJ_CLASS##Class(CLASS_NAME, \ - OBJ_CLASS::createForUnserialize); - -class Checkpoint -{ - private: - - IniFile *db; - const std::string basePath; - const ConfigNode *configNode; - std::map<std::string, Serializable*> objMap; - - public: - Checkpoint(const std::string &cpt_dir, const std::string &path, - const ConfigNode *_configNode); - - const std::string cptDir; - - bool find(const std::string §ion, const std::string &entry, - std::string &value); - - bool findObj(const std::string §ion, const std::string &entry, - Serializable *&value); - - bool sectionExists(const std::string §ion); - - // The following static functions have to do with checkpoint - // creation rather than restoration. This class makes a handy - // namespace for them though. - - // Export current checkpoint directory name so other objects can - // derive filenames from it (e.g., memory). The return value is - // guaranteed to end in '/' so filenames can be directly appended. - // This function is only valid while a checkpoint is being created. - static std::string dir(); - - // Filename for base checkpoint file within directory. - static const char *baseFilename; - - // Set up a checkpoint creation event or series of events. - static void setup(Tick when, Tick period = 0); -}; - -#endif // __SERIALIZE_HH__ diff --git a/sim/sim_events.cc b/sim/sim_events.cc deleted file mode 100644 index c2bdca9df..000000000 --- a/sim/sim_events.cc +++ /dev/null @@ -1,148 +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. - */ - -#include <string> - -#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" -#include "sim/stats.hh" - -using namespace std; - -// -// handle termination event -// -void -SimExitEvent::process() -{ - // This event does not autodelete because exitNow may be called, - // and the function will never be allowed to finish. - if (theQueue() == &mainEventQueue) { - string _cause = cause; - int _code = code; - delete this; - exitNow(_cause, _code); - } else { - new SimExitEvent(cause, code); - delete this; - } -} - - -const char * -SimExitEvent::description() -{ - return "simulation termination"; -} - -// -// constructor: automatically schedules at specified time -// -CountedExitEvent::CountedExitEvent(EventQueue *q, const std::string &_cause, - Tick _when, int &_downCounter) - : Event(q, Sim_Exit_Pri), - cause(_cause), - downCounter(_downCounter) -{ - // catch stupid mistakes - assert(downCounter > 0); - - schedule(_when); -} - - -// -// handle termination event -// -void -CountedExitEvent::process() -{ - if (--downCounter == 0) { - new SimExitEvent(cause, 0); - } -} - - -const char * -CountedExitEvent::description() -{ - return "counted exit"; -} - -#ifdef CHECK_SWAP_CYCLES -new CheckSwapEvent(&mainEventQueue, CHECK_SWAP_CYCLES); -#endif - -void -CheckSwapEvent::process() -{ - /* Check the amount of free swap space */ - long swap; - - /* returns free swap in KBytes */ - swap = procInfo("/proc/meminfo", "SwapFree:"); - - if (swap < 1000) - ccprintf(cerr, "\a\a\aWarning! Swap space is low (%d)\n", swap); - - if (swap < 100) { - cerr << "\a\aAborting Simulation! Inadequate swap space!\n\n"; - new SimExitEvent("Lack of swap space"); - } - - schedule(curTick + interval); -} - -const char * -CheckSwapEvent::description() -{ - return "check swap"; -} - -// -// handle progress event: print message and reschedule -// -void -ProgressEvent::process() -{ - DPRINTFN("ProgressEvent\n"); - // reschedule for next interval - schedule(curTick + interval); -} - - -const char * -ProgressEvent::description() -{ - return "progress message"; -} diff --git a/sim/sim_events.hh b/sim/sim_events.hh deleted file mode 100644 index c93914457..000000000 --- a/sim/sim_events.hh +++ /dev/null @@ -1,126 +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. - */ - -#ifndef __SIM_SIM_EVENTS_HH__ -#define __SIM_SIM_EVENTS_HH__ - -#include "sim/eventq.hh" - -// -// Event to terminate simulation at a particular cycle/instruction -// -class SimExitEvent : public Event -{ - private: - // string explaining why we're terminating - std::string cause; - int code; - - public: - SimExitEvent(const std::string &_cause, int c = 0) - : Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause), - code(c) - { schedule(curTick); } - - SimExitEvent(Tick _when, const std::string &_cause, int c = 0) - : Event(&mainEventQueue, Sim_Exit_Pri), cause(_cause), - code(c) - { schedule(_when); } - - SimExitEvent(EventQueue *q, const std::string &_cause, int c = 0) - : Event(q, Sim_Exit_Pri), cause(_cause), code(c) - { schedule(curTick); } - - SimExitEvent(EventQueue *q, Tick _when, const std::string &_cause, - int c = 0) - : Event(q, Sim_Exit_Pri), cause(_cause), code(c) - { schedule(_when); } - - void process(); // process event - - virtual const char *description(); -}; - -// -// Event class to terminate simulation after 'n' related events have -// occurred using a shared counter: used to terminate when *all* -// threads have reached a particular instruction count -// -class CountedExitEvent : public Event -{ - private: - std::string cause; // string explaining why we're terminating - int &downCounter; // decrement & terminate if zero - - public: - CountedExitEvent(EventQueue *q, const std::string &_cause, - Tick _when, int &_downCounter); - - void process(); // process event - - virtual const char *description(); -}; - -// -// Event to check swap usage -// -class CheckSwapEvent : public Event -{ - private: - int interval; - - public: - CheckSwapEvent(EventQueue *q, int ival) - : Event(q), interval(ival) - { schedule(curTick + interval); } - - void process(); // process event - - virtual const char *description(); -}; - -// -// Progress event: print out cycle every so often so we know we're -// making forward progress. -// -class ProgressEvent : public Event -{ - protected: - Tick interval; - - public: - ProgressEvent(EventQueue *q, Tick ival) - : Event(q), interval(ival) - { schedule(curTick + interval); } - - void process(); // process event - - virtual const char *description(); -}; - -#endif // __SIM_SIM_EVENTS_HH__ diff --git a/sim/sim_exit.hh b/sim/sim_exit.hh deleted file mode 100644 index f14256933..000000000 --- a/sim/sim_exit.hh +++ /dev/null @@ -1,44 +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. - */ - -#ifndef __SIM_EXIT_HH__ -#define __SIM_EXIT_HH__ - -#include <string> - -#include "sim/host.hh" - -class Callback; - -void registerExitCallback(Callback *); - -void exitNow(const std::string &cause, int exit_code); -void exitNow(const char *cause, int exit_code); -void SimExit(Tick when, const char *message); - -#endif // __SIM_EXIT_HH__ diff --git a/sim/sim_object.cc b/sim/sim_object.cc deleted file mode 100644 index 17d58ba4f..000000000 --- a/sim/sim_object.cc +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2001-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. - */ - -#include <assert.h> - -#include "base/callback.hh" -#include "base/inifile.hh" -#include "base/match.hh" -#include "base/misc.hh" -#include "base/trace.hh" -#include "base/stats/events.hh" -#include "base/serializer.hh" -#include "sim/configfile.hh" -#include "sim/host.hh" -#include "sim/sim_object.hh" -#include "sim/stats.hh" -#include "sim/param.hh" - -using namespace std; - - -//////////////////////////////////////////////////////////////////////// -// -// SimObject member definitions -// -//////////////////////////////////////////////////////////////////////// - -// -// static list of all SimObjects, used for initialization etc. -// -SimObject::SimObjectList SimObject::simObjectList; - -namespace Stats { - extern ObjectMatch event_ignore; -} - -// -// SimObject constructor: used to maintain static simObjectList -// -SimObject::SimObject(Params *p) - : _params(p) -{ -#ifdef DEBUG - doDebugBreak = false; -#endif - - doRecordEvent = !Stats::event_ignore.match(name()); - simObjectList.push_back(this); -} - -// -// SimObject constructor: used to maintain static simObjectList -// -SimObject::SimObject(const string &_name) - : _params(new Params) -{ - _params->name = _name; -#ifdef DEBUG - doDebugBreak = false; -#endif - - doRecordEvent = !Stats::event_ignore.match(name()); - simObjectList.push_back(this); -} - -void -SimObject::connect() -{ -} - -void -SimObject::init() -{ -} - -// -// no default statistics, so nothing to do in base implementation -// -void -SimObject::regStats() -{ -} - -void -SimObject::regFormulas() -{ -} - -void -SimObject::resetStats() -{ -} - -// -// static function: -// call regStats() on all SimObjects and then regFormulas() on all -// SimObjects. -// -struct SimObjectResetCB : public Callback -{ - virtual void process() { SimObject::resetAllStats(); } -}; - -namespace { - static SimObjectResetCB StatResetCB; -} - -void -SimObject::regAllStats() -{ - SimObjectList::iterator i; - SimObjectList::iterator end = simObjectList.end(); - - /** - * @todo change cprintfs to DPRINTFs - */ - for (i = simObjectList.begin(); i != end; ++i) { -#ifdef STAT_DEBUG - cprintf("registering stats for %s\n", (*i)->name()); -#endif - (*i)->regStats(); - } - - for (i = simObjectList.begin(); i != end; ++i) { -#ifdef STAT_DEBUG - cprintf("registering formulas for %s\n", (*i)->name()); -#endif - (*i)->regFormulas(); - } - - Stats::registerResetCallback(&StatResetCB); -} - -// -// static function: call connect() on all SimObjects. -// -void -SimObject::connectAll() -{ - SimObjectList::iterator i = simObjectList.begin(); - SimObjectList::iterator end = simObjectList.end(); - - for (; i != end; ++i) { - SimObject *obj = *i; - obj->connect(); - } -} - -// -// static function: call init() on all SimObjects. -// -void -SimObject::initAll() -{ - SimObjectList::iterator i = simObjectList.begin(); - SimObjectList::iterator end = simObjectList.end(); - - for (; i != end; ++i) { - SimObject *obj = *i; - obj->init(); - } -} - -// -// static function: call resetStats() on all SimObjects. -// -void -SimObject::resetAllStats() -{ - SimObjectList::iterator i = simObjectList.begin(); - SimObjectList::iterator end = simObjectList.end(); - - for (; i != end; ++i) { - SimObject *obj = *i; - obj->resetStats(); - } -} - -// -// static function: serialize all SimObjects. -// -void -SimObject::serializeAll(ostream &os) -{ - SimObjectList::reverse_iterator ri = simObjectList.rbegin(); - SimObjectList::reverse_iterator rend = simObjectList.rend(); - - for (; ri != rend; ++ri) { - SimObject *obj = *ri; - obj->nameOut(os); - obj->serialize(os); - } -} - -#ifdef DEBUG -// -// static function: flag which objects should have the debugger break -// -void -SimObject::debugObjectBreak(const string &objs) -{ - SimObjectList::const_iterator i = simObjectList.begin(); - SimObjectList::const_iterator end = simObjectList.end(); - - ObjectMatch match(objs); - for (; i != end; ++i) { - SimObject *obj = *i; - obj->doDebugBreak = match.match(obj->name()); - } -} - -extern "C" -void -debugObjectBreak(const char *objs) -{ - SimObject::debugObjectBreak(string(objs)); -} -#endif - -void -SimObject::recordEvent(const std::string &stat) -{ - if (doRecordEvent) - Stats::recordEvent(stat); -} - -void -SimObject::drain(Serializer *serializer) -{ - serializer->signalDrained(); -} - -DEFINE_SIM_OBJECT_CLASS_NAME("SimObject", SimObject) diff --git a/sim/sim_object.hh b/sim/sim_object.hh deleted file mode 100644 index 76aba7ea1..000000000 --- a/sim/sim_object.hh +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2001-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. - */ - -/* @file - * User Console Definitions - */ - -#ifndef __SIM_OBJECT_HH__ -#define __SIM_OBJECT_HH__ - -#include <map> -#include <list> -#include <vector> -#include <iostream> - -#include "sim/serialize.hh" -#include "sim/startup.hh" - -class Serializer; - -/* - * Abstract superclass for simulation objects. Represents things that - * correspond to physical components and can be specified via the - * config file (CPUs, caches, etc.). - */ -class SimObject : public Serializable, protected StartupCallback -{ - public: - struct Params { - std::string name; - }; - - protected: - Params *_params; - - public: - const Params *params() const { return _params; } - - private: - friend class Serializer; - - typedef std::vector<SimObject *> SimObjectList; - - // list of all instantiated simulation objects - static SimObjectList simObjectList; - - public: - SimObject(Params *_params); - SimObject(const std::string &_name); - - virtual ~SimObject() {} - - virtual const std::string name() const { return params()->name; } - - // initialization pass of all objects. - // Gets invoked after construction, before unserialize. - virtual void init(); - virtual void connect(); - static void initAll(); - static void connectAll(); - - // register statistics for this object - virtual void regStats(); - virtual void regFormulas(); - virtual void resetStats(); - - // static: call reg_stats on all SimObjects - static void regAllStats(); - - // static: call resetStats on all SimObjects - static void resetAllStats(); - - // static: call nameOut() & serialize() on all SimObjects - static void serializeAll(std::ostream &); - - // Methods to drain objects in order to take checkpoints - // Or switch from timing -> atomic memory model - virtual void drain(Serializer *serializer); - virtual void resume() { return;} ; - virtual void serializationComplete() - { assert(0 && "Unimplemented"); }; - -#ifdef DEBUG - public: - bool doDebugBreak; - static void debugObjectBreak(const std::string &objs); -#endif - - public: - bool doRecordEvent; - void recordEvent(const std::string &stat); -}; - -#endif // __SIM_OBJECT_HH__ diff --git a/sim/startup.cc b/sim/startup.cc deleted file mode 100644 index 683e6c746..000000000 --- a/sim/startup.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2004-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. - */ - -#include <list> - -#include "base/misc.hh" -#include "sim/debug.hh" -#include "sim/startup.hh" - -typedef std::list<StartupCallback *> startupq_t; - -startupq_t *startupq = NULL; - -StartupCallback::StartupCallback() -{ - if (startupq == NULL) - startupq = new startupq_t; - startupq->push_back(this); -} - -StartupCallback::~StartupCallback() -{ - startupq->remove(this); -} - -void StartupCallback::startup() { } - -void -SimStartup() -{ - startupq_t::iterator i = startupq->begin(); - startupq_t::iterator end = startupq->end(); - - while (i != end) { - (*i)->startup(); - ++i; - } -} diff --git a/sim/startup.hh b/sim/startup.hh deleted file mode 100644 index 3c9b654f1..000000000 --- a/sim/startup.hh +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2004-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. - */ - -#ifndef __SIM_STARTUP_HH__ -#define __SIM_STARTUP_HH__ - -struct StartupCallback -{ - StartupCallback(); - virtual ~StartupCallback(); - virtual void startup(); -}; - -void SimStartup(); - -#endif // __SIM_STARTUP_HH__ diff --git a/sim/stat_control.cc b/sim/stat_control.cc deleted file mode 100644 index 85c405b7f..000000000 --- a/sim/stat_control.cc +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2004-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. - */ - -// This file will contain default statistics for the simulator that -// don't really belong to a specific simulator object - -#include <fstream> -#include <iostream> -#include <list> - -#include "base/callback.hh" -#include "base/hostinfo.hh" -#include "base/statistics.hh" -#include "base/str.hh" -#include "base/time.hh" -#include "base/stats/output.hh" -#include "cpu/base.hh" -#include "sim/eventq.hh" -#include "sim/sim_object.hh" -#include "sim/stat_control.hh" -#include "sim/root.hh" - -using namespace std; - -Stats::Formula hostInstRate; -Stats::Formula hostTickRate; -Stats::Value hostMemory; -Stats::Value hostSeconds; - -Stats::Value simTicks; -Stats::Value simInsts; -Stats::Value simFreq; -Stats::Formula simSeconds; - -namespace Stats { - -Time statTime(true); -Tick startTick; -Tick lastDump(0); - -class SimTicksReset : public Callback -{ - public: - void process() - { - statTime.set(); - startTick = curTick; - } -}; - -double -statElapsedTime() -{ - Time now(true); - Time elapsed = now - statTime; - return elapsed(); -} - -Tick -statElapsedTicks() -{ - return curTick - startTick; -} - -SimTicksReset simTicksReset; - -void -InitSimStats() -{ - simInsts - .functor(BaseCPU::numSimulatedInstructions) - .name("sim_insts") - .desc("Number of instructions simulated") - .precision(0) - .prereq(simInsts) - ; - - simSeconds - .name("sim_seconds") - .desc("Number of seconds simulated") - ; - - simFreq - .scalar(Clock::Frequency) - .name("sim_freq") - .desc("Frequency of simulated ticks") - ; - - simTicks - .functor(statElapsedTicks) - .name("sim_ticks") - .desc("Number of ticks simulated") - ; - - hostInstRate - .name("host_inst_rate") - .desc("Simulator instruction rate (inst/s)") - .precision(0) - .prereq(simInsts) - ; - - hostMemory - .functor(memUsage) - .name("host_mem_usage") - .desc("Number of bytes of host memory used") - .prereq(hostMemory) - ; - - hostSeconds - .functor(statElapsedTime) - .name("host_seconds") - .desc("Real time elapsed on the host") - .precision(2) - ; - - hostTickRate - .name("host_tick_rate") - .desc("Simulator tick rate (ticks/s)") - .precision(0) - ; - - simSeconds = simTicks / simFreq; - hostInstRate = simInsts / hostSeconds; - hostTickRate = simTicks / hostSeconds; - - registerResetCallback(&simTicksReset); -} - -class StatEvent : public Event -{ - protected: - int flags; - Tick repeat; - - public: - StatEvent(int _flags, Tick _when, Tick _repeat); - virtual void process(); - virtual const char *description(); -}; - -StatEvent::StatEvent(int _flags, Tick _when, Tick _repeat) - : Event(&mainEventQueue, Stat_Event_Pri), - flags(_flags), repeat(_repeat) -{ - setFlags(AutoDelete); - schedule(_when); -} - -const char * -StatEvent::description() -{ - return "Statistics dump and/or reset"; -} - -void -StatEvent::process() -{ - if (flags & Stats::Dump) - DumpNow(); - - if (flags & Stats::Reset) - reset(); - - if (repeat) - schedule(curTick + repeat); -} - -list<Output *> OutputList; - -void -DumpNow() -{ - assert(lastDump <= curTick); - if (lastDump == curTick) - return; - lastDump = curTick; - - list<Output *>::iterator i = OutputList.begin(); - list<Output *>::iterator end = OutputList.end(); - for (; i != end; ++i) { - Output *output = *i; - if (!output->valid()) - continue; - - output->output(); - } -} - -void -SetupEvent(int flags, Tick when, Tick repeat) -{ - new StatEvent(flags, when, repeat); -} - -/* namespace Stats */ } - -extern "C" void -debugDumpStats() -{ - Stats::DumpNow(); -} - diff --git a/sim/stat_control.hh b/sim/stat_control.hh deleted file mode 100644 index a22ce76af..000000000 --- a/sim/stat_control.hh +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2004-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. - */ - -#ifndef __SIM_STAT_CONTROL_HH__ -#define __SIM_STAT_CONTROL_HH__ - -#include <fstream> -#include <list> - -namespace Stats { - -enum { - Reset = 0x1, - Dump = 0x2 -}; - -class Output; -extern std::list<Output *> OutputList; - -void DumpNow(); -void SetupEvent(int flags, Tick when, Tick repeat = 0); - -void InitSimStats(); - -/* namespace Stats */ } - -#endif // __SIM_STAT_CONTROL_HH__ diff --git a/sim/stats.hh b/sim/stats.hh deleted file mode 100644 index 8e97d041f..000000000 --- a/sim/stats.hh +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2004-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. - */ - -#ifndef __SIM_STATS_HH__ -#define __SIM_STATS_HH__ - -#include "base/statistics.hh" - -extern Stats::Formula simSeconds; -extern Stats::Value simTicks; - -#endif // __SIM_SIM_STATS_HH__ diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc deleted file mode 100644 index ed0da628e..000000000 --- a/sim/syscall_emul.cc +++ /dev/null @@ -1,454 +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. - */ - -#include <fcntl.h> -#include <unistd.h> - -#include <string> -#include <iostream> - -#include "sim/syscall_emul.hh" -#include "base/chunk_generator.hh" -#include "base/trace.hh" -#include "cpu/exec_context.hh" -#include "cpu/base.hh" -#include "mem/page_table.hh" -#include "sim/process.hh" - -#include "sim/sim_events.hh" - -using namespace std; -using namespace TheISA; - -void -SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) -{ - DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", - curTick,xc->getCpuPtr()->name(), name, - xc->getSyscallArg(0),xc->getSyscallArg(1), - xc->getSyscallArg(2),xc->getSyscallArg(3)); - - SyscallReturn retval = (*funcPtr)(this, callnum, process, xc); - - DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n", - curTick,xc->getCpuPtr()->name(), name, retval.value()); - - if (!(flags & SyscallDesc::SuppressReturnValue)) - xc->setSyscallReturn(retval); -} - - -SyscallReturn -unimplementedFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - fatal("syscall %s (#%d) unimplemented.", desc->name, callnum); - - return 1; -} - - -SyscallReturn -ignoreFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - warn("ignoring syscall %s(%d, %d, ...)", desc->name, - xc->getSyscallArg(0), xc->getSyscallArg(1)); - - return 0; -} - - -SyscallReturn -exitFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - new SimExitEvent("target called exit()", xc->getSyscallArg(0) & 0xff); - - return 1; -} - - -SyscallReturn -getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - return (int)VMPageSize; -} - - -SyscallReturn -obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - Addr junk; - - // change brk addr to first arg - Addr new_brk = xc->getSyscallArg(0); - if (new_brk != 0) { - for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point, - VMPageSize); !gen.done(); gen.next()) { - if (!p->pTable->translate(gen.addr(), junk)) - p->pTable->allocate(roundDown(gen.addr(), VMPageSize), - VMPageSize); - } - p->brk_point = new_brk; - } - DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); - return p->brk_point; -} - - -SyscallReturn -closeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - int target_fd = xc->getSyscallArg(0); - int status = close(p->sim_fd(target_fd)); - if (status >= 0) - p->free_fd(target_fd); - return status; -} - - -SyscallReturn -readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - int fd = p->sim_fd(xc->getSyscallArg(0)); - int nbytes = xc->getSyscallArg(2); - BufferArg bufArg(xc->getSyscallArg(1), nbytes); - - int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); - - if (bytes_read != -1) - bufArg.copyOut(xc->getMemPort()); - - return bytes_read; -} - -SyscallReturn -writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - int fd = p->sim_fd(xc->getSyscallArg(0)); - int nbytes = xc->getSyscallArg(2); - BufferArg bufArg(xc->getSyscallArg(1), nbytes); - - bufArg.copyIn(xc->getMemPort()); - - int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); - - fsync(fd); - - return bytes_written; -} - - -SyscallReturn -lseekFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - int fd = p->sim_fd(xc->getSyscallArg(0)); - uint64_t offs = xc->getSyscallArg(1); - int whence = xc->getSyscallArg(2); - - off_t result = lseek(fd, offs, whence); - - return (result == (off_t)-1) ? -errno : result; -} - - -SyscallReturn -munmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - // given that we don't really implement mmap, munmap is really easy - return 0; -} - - -const char *hostname = "m5.eecs.umich.edu"; - -SyscallReturn -gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - int name_len = xc->getSyscallArg(1); - BufferArg name(xc->getSyscallArg(0), name_len); - - strncpy((char *)name.bufferPtr(), hostname, name_len); - - name.copyOut(xc->getMemPort()); - - return 0; -} - -SyscallReturn -unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return (TheISA::IntReg)-EFAULT; - - int result = unlink(path.c_str()); - return (result == -1) ? -errno : result; -} - -SyscallReturn -renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - string old_name; - - if (!xc->getMemPort()->tryReadString(old_name, xc->getSyscallArg(0))) - return -EFAULT; - - string new_name; - - if (!xc->getMemPort()->tryReadString(new_name, xc->getSyscallArg(1))) - return -EFAULT; - - int64_t result = rename(old_name.c_str(), new_name.c_str()); - return (result == -1) ? -errno : result; -} - -SyscallReturn -truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return -EFAULT; - - off_t length = xc->getSyscallArg(1); - - int result = truncate(path.c_str(), length); - return (result == -1) ? -errno : result; -} - -SyscallReturn -ftruncateFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc) -{ - int fd = process->sim_fd(xc->getSyscallArg(0)); - - if (fd < 0) - return -EBADF; - - off_t length = xc->getSyscallArg(1); - - int result = ftruncate(fd, length); - return (result == -1) ? -errno : result; -} - -SyscallReturn -chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return -EFAULT; - - /* XXX endianess */ - uint32_t owner = xc->getSyscallArg(1); - uid_t hostOwner = owner; - uint32_t group = xc->getSyscallArg(2); - gid_t hostGroup = group; - - int result = chown(path.c_str(), hostOwner, hostGroup); - return (result == -1) ? -errno : result; -} - -SyscallReturn -fchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc) -{ - int fd = process->sim_fd(xc->getSyscallArg(0)); - - if (fd < 0) - return -EBADF; - - /* XXX endianess */ - uint32_t owner = xc->getSyscallArg(1); - uid_t hostOwner = owner; - uint32_t group = xc->getSyscallArg(2); - gid_t hostGroup = group; - - int result = fchown(fd, hostOwner, hostGroup); - return (result == -1) ? -errno : result; -} - - -SyscallReturn -fcntlFunc(SyscallDesc *desc, int num, Process *process, - ExecContext *xc) -{ - int fd = xc->getSyscallArg(0); - - if (fd < 0 || process->sim_fd(fd) < 0) - return -EBADF; - - int cmd = xc->getSyscallArg(1); - switch (cmd) { - case 0: // F_DUPFD - // if we really wanted to support this, we'd need to do it - // in the target fd space. - warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd); - return -EMFILE; - - case 1: // F_GETFD (get close-on-exec flag) - case 2: // F_SETFD (set close-on-exec flag) - return 0; - - case 3: // F_GETFL (get file flags) - case 4: // F_SETFL (set file flags) - // not sure if this is totally valid, but we'll pass it through - // to the underlying OS - warn("fcntl(%d, %d) passed through to host\n", fd, cmd); - return fcntl(process->sim_fd(fd), cmd); - // return 0; - - case 7: // F_GETLK (get lock) - case 8: // F_SETLK (set lock) - case 9: // F_SETLKW (set lock and wait) - // don't mess with file locking... just act like it's OK - warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd); - return 0; - - default: - warn("Unknown fcntl command %d\n", cmd); - return 0; - } -} - -SyscallReturn -pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int fds[2], sim_fds[2]; - int pipe_retval = pipe(fds); - - if (pipe_retval < 0) { - // error - return pipe_retval; - } - - sim_fds[0] = process->alloc_fd(fds[0]); - sim_fds[1] = process->alloc_fd(fds[1]); - - // Alpha Linux convention for pipe() is that fd[0] is returned as - // the return value of the function, and fd[1] is returned in r20. - xc->setIntReg(SyscallPseudoReturnReg, sim_fds[1]); - return sim_fds[0]; -} - - -SyscallReturn -getpidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - // Make up a PID. There's no interprocess communication in - // fake_syscall mode, so there's no way for a process to know it's - // not getting a unique value. - - xc->setIntReg(SyscallPseudoReturnReg, 99); - return 100; -} - - -SyscallReturn -getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - // Make up a UID and EUID... it shouldn't matter, and we want the - // simulation to be deterministic. - - // EUID goes in r20. - xc->setIntReg(SyscallPseudoReturnReg, 100); //EUID - return 100; // UID -} - - -SyscallReturn -getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - // Get current group ID. EGID goes in r20. - xc->setIntReg(SyscallPseudoReturnReg, 100); //EGID - return 100; -} - - -SyscallReturn -setuidFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - // can't fathom why a benchmark would call this. - warn("Ignoring call to setuid(%d)\n", xc->getSyscallArg(0)); - return 0; -} - -SyscallReturn -getpidFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - // Make up a PID. There's no interprocess communication in - // fake_syscall mode, so there's no way for a process to know it's - // not getting a unique value. - - xc->setIntReg(SyscallPseudoReturnReg, 99); //PID - return 100; -} - -SyscallReturn -getppidFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - return 99; -} - -SyscallReturn -getuidFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - return 100; // UID -} - -SyscallReturn -geteuidFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - return 100; // UID -} - -SyscallReturn -getgidFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - return 100; -} - -SyscallReturn -getegidFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - return 100; -} - - diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh deleted file mode 100644 index 00f016410..000000000 --- a/sim/syscall_emul.hh +++ /dev/null @@ -1,849 +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. - */ - -#ifndef __SIM_SYSCALL_EMUL_HH__ -#define __SIM_SYSCALL_EMUL_HH__ - -#define BSD_HOST (defined(__APPLE__) || defined(__OpenBSD__) || \ - defined(__FreeBSD__)) - -/// -/// @file syscall_emul.hh -/// -/// This file defines objects used to emulate syscalls from the target -/// application on the host machine. - -#include <errno.h> -#include <string> -#ifdef __CYGWIN32__ -#include <sys/fcntl.h> // for O_BINARY -#endif -#include <sys/uio.h> - -#include "arch/isa_traits.hh" // for Addr -#include "base/chunk_generator.hh" -#include "base/intmath.hh" // for RoundUp -#include "base/misc.hh" -#include "base/trace.hh" -#include "cpu/base.hh" -#include "cpu/exec_context.hh" -#include "mem/translating_port.hh" -#include "mem/page_table.hh" -#include "sim/process.hh" - -/// -/// System call descriptor. -/// -class SyscallDesc { - - public: - - /// Typedef for target syscall handler functions. - typedef SyscallReturn (*FuncPtr)(SyscallDesc *, int num, - Process *, ExecContext *); - - const char *name; //!< Syscall name (e.g., "open"). - FuncPtr funcPtr; //!< Pointer to emulation function. - int flags; //!< Flags (see Flags enum). - - /// Flag values for controlling syscall behavior. - enum Flags { - /// Don't set return regs according to funcPtr return value. - /// Used for syscalls with non-standard return conventions - /// that explicitly set the ExecContext regs (e.g., - /// sigreturn). - SuppressReturnValue = 1 - }; - - /// Constructor. - SyscallDesc(const char *_name, FuncPtr _funcPtr, int _flags = 0) - : name(_name), funcPtr(_funcPtr), flags(_flags) - { - } - - /// Emulate the syscall. Public interface for calling through funcPtr. - void doSyscall(int callnum, Process *proc, ExecContext *xc); -}; - - -class BaseBufferArg { - - public: - - BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) - { - bufPtr = new uint8_t[size]; - // clear out buffer: in case we only partially populate this, - // and then do a copyOut(), we want to make sure we don't - // introduce any random junk into the simulated address space - memset(bufPtr, 0, size); - } - - virtual ~BaseBufferArg() { delete [] bufPtr; } - - // - // copy data into simulator space (read from target memory) - // - virtual bool copyIn(TranslatingPort *memport) - { - memport->readBlob(addr, bufPtr, size); - return true; // no EFAULT detection for now - } - - // - // copy data out of simulator space (write to target memory) - // - virtual bool copyOut(TranslatingPort *memport) - { - memport->writeBlob(addr, bufPtr, size); - return true; // no EFAULT detection for now - } - - protected: - Addr addr; - int size; - uint8_t *bufPtr; -}; - - -class BufferArg : public BaseBufferArg -{ - public: - BufferArg(Addr _addr, int _size) : BaseBufferArg(_addr, _size) { } - void *bufferPtr() { return bufPtr; } -}; - -template <class T> -class TypedBufferArg : public BaseBufferArg -{ - public: - // user can optionally specify a specific number of bytes to - // allocate to deal with those structs that have variable-size - // arrays at the end - TypedBufferArg(Addr _addr, int _size = sizeof(T)) - : BaseBufferArg(_addr, _size) - { } - - // type case - operator T*() { return (T *)bufPtr; } - - // dereference operators - T &operator*() { return *((T *)bufPtr); } - T* operator->() { return (T *)bufPtr; } - T &operator[](int i) { return ((T *)bufPtr)[i]; } -}; - -////////////////////////////////////////////////////////////////////// -// -// The following emulation functions are generic enough that they -// don't need to be recompiled for different emulated OS's. They are -// defined in sim/syscall_emul.cc. -// -////////////////////////////////////////////////////////////////////// - - -/// Handler for unimplemented syscalls that we haven't thought about. -SyscallReturn unimplementedFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Handler for unimplemented syscalls that we never intend to -/// implement (signal handling, etc.) and should not affect the correct -/// behavior of the program. Print a warning only if the appropriate -/// trace flag is enabled. Return success to the target program. -SyscallReturn ignoreFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target exit() handler: terminate simulation. -SyscallReturn exitFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target getpagesize() handler. -SyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target obreak() handler: set brk address. -SyscallReturn obreakFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target close() handler. -SyscallReturn closeFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target read() handler. -SyscallReturn readFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target write() handler. -SyscallReturn writeFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target lseek() handler. -SyscallReturn lseekFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target munmap() handler. -SyscallReturn munmapFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target gethostname() handler. -SyscallReturn gethostnameFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target unlink() handler. -SyscallReturn unlinkFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target rename() handler. -SyscallReturn renameFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - - -/// Target truncate() handler. -SyscallReturn truncateFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - - -/// Target ftruncate() handler. -SyscallReturn ftruncateFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - - -/// Target chown() handler. -SyscallReturn chownFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - - -/// Target fchown() handler. -SyscallReturn fchownFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target fnctl() handler. -SyscallReturn fcntlFunc(SyscallDesc *desc, int num, - Process *process, ExecContext *xc); - -/// Target setuid() handler. -SyscallReturn setuidFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target getpid() handler. -SyscallReturn getpidFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target getuid() handler. -SyscallReturn getuidFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target getgid() handler. -SyscallReturn getgidFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target getppid() handler. -SyscallReturn getppidFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target geteuid() handler. -SyscallReturn geteuidFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target getegid() handler. -SyscallReturn getegidFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - - - -/// Pseudo Funcs - These functions use a different return convension, -/// returning a second value in a register other than the normal return register -SyscallReturn pipePseudoFunc(SyscallDesc *desc, int num, - Process *process, ExecContext *xc); - -/// Target getpidPseudo() handler. -SyscallReturn getpidPseudoFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target getuidPseudo() handler. -SyscallReturn getuidPseudoFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - -/// Target getgidPseudo() handler. -SyscallReturn getgidPseudoFunc(SyscallDesc *desc, int num, - Process *p, ExecContext *xc); - - -/// This struct is used to build an target-OS-dependent table that -/// maps the target's open() flags to the host open() flags. -struct OpenFlagTransTable { - int tgtFlag; //!< Target system flag value. - int hostFlag; //!< Corresponding host system flag value. -}; - - - -/// A readable name for 1,000,000, for converting microseconds to seconds. -const int one_million = 1000000; - -/// Approximate seconds since the epoch (1/1/1970). About a billion, -/// by my reckoning. We want to keep this a constant (not use the -/// real-world time) to keep simulations repeatable. -const unsigned seconds_since_epoch = 1000000000; - -/// Helper function to convert current elapsed time to seconds and -/// microseconds. -template <class T1, class T2> -void -getElapsedTime(T1 &sec, T2 &usec) -{ - int elapsed_usecs = curTick / Clock::Int::us; - sec = elapsed_usecs / one_million; - usec = elapsed_usecs % one_million; -} - -////////////////////////////////////////////////////////////////////// -// -// The following emulation functions are generic, but need to be -// templated to account for differences in types, constants, etc. -// -////////////////////////////////////////////////////////////////////// - -/// Target ioctl() handler. For the most part, programs call ioctl() -/// only to find out if their stdout is a tty, to determine whether to -/// do line or block buffering. -template <class OS> -SyscallReturn -ioctlFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int fd = xc->getSyscallArg(0); - unsigned req = xc->getSyscallArg(1); - - DPRINTF(SyscallVerbose, "ioctl(%d, 0x%x, ...)\n", fd, req); - - if (fd < 0 || process->sim_fd(fd) < 0) { - // doesn't map to any simulator fd: not a valid target fd - return -EBADF; - } - - switch (req) { - case OS::TIOCISATTY: - case OS::TIOCGETP: - case OS::TIOCSETP: - case OS::TIOCSETN: - case OS::TIOCSETC: - case OS::TIOCGETC: - case OS::TIOCGETS: - case OS::TIOCGETA: - return -ENOTTY; - - default: - fatal("Unsupported ioctl call: ioctl(%d, 0x%x, ...) @ 0x%llx\n", - fd, req, xc->readPC()); - } -} - -/// Target open() handler. -template <class OS> -SyscallReturn -openFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - std::string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return -EFAULT; - - if (path == "/dev/sysdev0") { - // This is a memory-mapped high-resolution timer device on Alpha. - // We don't support it, so just punt. - warn("Ignoring open(%s, ...)\n", path); - return -ENOENT; - } - - int tgtFlags = xc->getSyscallArg(1); - int mode = xc->getSyscallArg(2); - int hostFlags = 0; - - // translate open flags - for (int i = 0; i < OS::NUM_OPEN_FLAGS; i++) { - if (tgtFlags & OS::openFlagTable[i].tgtFlag) { - tgtFlags &= ~OS::openFlagTable[i].tgtFlag; - hostFlags |= OS::openFlagTable[i].hostFlag; - } - } - - // any target flags left? - if (tgtFlags != 0) - warn("Syscall: open: cannot decode flags 0x%x", tgtFlags); - -#ifdef __CYGWIN32__ - hostFlags |= O_BINARY; -#endif - - DPRINTF(SyscallVerbose, "opening file %s\n", path.c_str()); - - // open the file - int fd = open(path.c_str(), hostFlags, mode); - - return (fd == -1) ? -errno : process->alloc_fd(fd); -} - - -/// Target chmod() handler. -template <class OS> -SyscallReturn -chmodFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - std::string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return -EFAULT; - - uint32_t mode = xc->getSyscallArg(1); - mode_t hostMode = 0; - - // XXX translate mode flags via OS::something??? - hostMode = mode; - - // do the chmod - int result = chmod(path.c_str(), hostMode); - if (result < 0) - return -errno; - - return 0; -} - - -/// Target fchmod() handler. -template <class OS> -SyscallReturn -fchmodFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int fd = xc->getSyscallArg(0); - if (fd < 0 || process->sim_fd(fd) < 0) { - // doesn't map to any simulator fd: not a valid target fd - return -EBADF; - } - - uint32_t mode = xc->getSyscallArg(1); - mode_t hostMode = 0; - - // XXX translate mode flags via OS::someting??? - hostMode = mode; - - // do the fchmod - int result = fchmod(process->sim_fd(fd), hostMode); - if (result < 0) - return -errno; - - return 0; -} - - -/// Target stat() handler. -template <class OS> -SyscallReturn -statFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - std::string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return -EFAULT; - - struct stat hostBuf; - int result = stat(path.c_str(), &hostBuf); - - if (result < 0) - return -errno; - - OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); - - return 0; -} - - -/// Target fstat64() handler. -template <class OS> -SyscallReturn -fstat64Func(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int fd = xc->getSyscallArg(0); - if (fd < 0 || process->sim_fd(fd) < 0) { - // doesn't map to any simulator fd: not a valid target fd - return -EBADF; - } - -#if BSD_HOST - struct stat hostBuf; - int result = fstat(process->sim_fd(fd), &hostBuf); -#else - struct stat64 hostBuf; - int result = fstat64(process->sim_fd(fd), &hostBuf); -#endif - - if (result < 0) - return -errno; - - OS::copyOutStat64Buf(xc->getMemPort(), fd, xc->getSyscallArg(1), &hostBuf); - - return 0; -} - - -/// Target lstat() handler. -template <class OS> -SyscallReturn -lstatFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - std::string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return -EFAULT; - - struct stat hostBuf; - int result = lstat(path.c_str(), &hostBuf); - - if (result < 0) - return -errno; - - OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); - - return 0; -} - -/// Target lstat64() handler. -template <class OS> -SyscallReturn -lstat64Func(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - std::string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return -EFAULT; - -#if BSD_HOST - struct stat hostBuf; - int result = lstat(path.c_str(), &hostBuf); -#else - struct stat64 hostBuf; - int result = lstat64(path.c_str(), &hostBuf); -#endif - - if (result < 0) - return -errno; - - OS::copyOutStat64Buf(xc->getMemPort(), -1, xc->getSyscallArg(1), &hostBuf); - - return 0; -} - -/// Target fstat() handler. -template <class OS> -SyscallReturn -fstatFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int fd = process->sim_fd(xc->getSyscallArg(0)); - - DPRINTF(SyscallVerbose, "fstat(%d, ...)\n", fd); - - if (fd < 0) - return -EBADF; - - struct stat hostBuf; - int result = fstat(fd, &hostBuf); - - if (result < 0) - return -errno; - - OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); - - return 0; -} - - -/// Target statfs() handler. -template <class OS> -SyscallReturn -statfsFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - std::string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return -EFAULT; - - struct statfs hostBuf; - int result = statfs(path.c_str(), &hostBuf); - - if (result < 0) - return -errno; - - OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); - - return 0; -} - - -/// Target fstatfs() handler. -template <class OS> -SyscallReturn -fstatfsFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int fd = process->sim_fd(xc->getSyscallArg(0)); - - if (fd < 0) - return -EBADF; - - struct statfs hostBuf; - int result = fstatfs(fd, &hostBuf); - - if (result < 0) - return -errno; - - OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); - - return 0; -} - - -/// Target writev() handler. -template <class OS> -SyscallReturn -writevFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int fd = xc->getSyscallArg(0); - if (fd < 0 || process->sim_fd(fd) < 0) { - // doesn't map to any simulator fd: not a valid target fd - return -EBADF; - } - - TranslatingPort *p = xc->getMemPort(); - uint64_t tiov_base = xc->getSyscallArg(1); - size_t count = xc->getSyscallArg(2); - struct iovec hiov[count]; - for (int i = 0; i < count; ++i) - { - typename OS::tgt_iovec tiov; - - p->readBlob(tiov_base + i*sizeof(typename OS::tgt_iovec), - (uint8_t*)&tiov, sizeof(typename OS::tgt_iovec)); - hiov[i].iov_len = gtoh(tiov.iov_len); - hiov[i].iov_base = new char [hiov[i].iov_len]; - p->readBlob(gtoh(tiov.iov_base), (uint8_t *)hiov[i].iov_base, - hiov[i].iov_len); - } - - int result = writev(process->sim_fd(fd), hiov, count); - - for (int i = 0; i < count; ++i) - { - delete [] (char *)hiov[i].iov_base; - } - - if (result < 0) - return -errno; - - return 0; -} - - -/// Target mmap() handler. -/// -/// We don't really handle mmap(). If the target is mmaping an -/// anonymous region or /dev/zero, we can get away with doing basically -/// nothing (since memory is initialized to zero and the simulator -/// doesn't really check addresses anyway). Always print a warning, -/// since this could be seriously broken if we're not mapping -/// /dev/zero. -// -/// Someday we should explicitly check for /dev/zero in open, flag the -/// file descriptor, and fail (or implement!) a non-anonymous mmap to -/// anything else. -template <class OS> -SyscallReturn -mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) -{ - Addr start = xc->getSyscallArg(0); - uint64_t length = xc->getSyscallArg(1); - // int prot = xc->getSyscallArg(2); - int flags = xc->getSyscallArg(3); - // int fd = p->sim_fd(xc->getSyscallArg(4)); - // int offset = xc->getSyscallArg(5); - - if ((start % TheISA::VMPageSize) != 0 || - (length % TheISA::VMPageSize) != 0) { - warn("mmap failing: arguments not page-aligned: " - "start 0x%x length 0x%x", - start, length); - return -EINVAL; - } - - if (start != 0) { - warn("mmap: ignoring suggested map address 0x%x, using 0x%x", - start, p->mmap_end); - } - - // pick next address from our "mmap region" - start = p->mmap_end; - p->pTable->allocate(start, length); - p->mmap_end += length; - - if (!(flags & OS::TGT_MAP_ANONYMOUS)) { - warn("allowing mmap of file @ fd %d. " - "This will break if not /dev/zero.", xc->getSyscallArg(4)); - } - - return start; -} - -/// Target getrlimit() handler. -template <class OS> -SyscallReturn -getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - unsigned resource = xc->getSyscallArg(0); - TypedBufferArg<typename OS::rlimit> rlp(xc->getSyscallArg(1)); - - switch (resource) { - case OS::TGT_RLIMIT_STACK: - // max stack size in bytes: make up a number (2MB for now) - rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; - rlp->rlim_cur = htog(rlp->rlim_cur); - rlp->rlim_max = htog(rlp->rlim_max); - break; - - default: - std::cerr << "getrlimitFunc: unimplemented resource " << resource - << std::endl; - abort(); - break; - } - - rlp.copyOut(xc->getMemPort()); - return 0; -} - -/// Target gettimeofday() handler. -template <class OS> -SyscallReturn -gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - TypedBufferArg<typename OS::timeval> tp(xc->getSyscallArg(0)); - - getElapsedTime(tp->tv_sec, tp->tv_usec); - tp->tv_sec += seconds_since_epoch; - tp->tv_sec = htog(tp->tv_sec); - tp->tv_usec = htog(tp->tv_usec); - - tp.copyOut(xc->getMemPort()); - - return 0; -} - - -/// Target utimes() handler. -template <class OS> -SyscallReturn -utimesFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - std::string path; - - if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) - return -EFAULT; - - TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); - tp.copyIn(xc->getMemPort()); - - struct timeval hostTimeval[2]; - for (int i = 0; i < 2; ++i) - { - hostTimeval[i].tv_sec = gtoh((*tp)[i].tv_sec); - hostTimeval[i].tv_usec = gtoh((*tp)[i].tv_usec); - } - int result = utimes(path.c_str(), hostTimeval); - - if (result < 0) - return -errno; - - return 0; -} -/// Target getrusage() function. -template <class OS> -SyscallReturn -getrusageFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int who = xc->getSyscallArg(0); // THREAD, SELF, or CHILDREN - TypedBufferArg<typename OS::rusage> rup(xc->getSyscallArg(1)); - - if (who != OS::TGT_RUSAGE_SELF) { - // don't really handle THREAD or CHILDREN, but just warn and - // plow ahead - warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", - who); - } - - getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); - rup->ru_utime.tv_sec = htog(rup->ru_utime.tv_sec); - rup->ru_utime.tv_usec = htog(rup->ru_utime.tv_usec); - - rup->ru_stime.tv_sec = 0; - rup->ru_stime.tv_usec = 0; - rup->ru_maxrss = 0; - rup->ru_ixrss = 0; - rup->ru_idrss = 0; - rup->ru_isrss = 0; - rup->ru_minflt = 0; - rup->ru_majflt = 0; - rup->ru_nswap = 0; - rup->ru_inblock = 0; - rup->ru_oublock = 0; - rup->ru_msgsnd = 0; - rup->ru_msgrcv = 0; - rup->ru_nsignals = 0; - rup->ru_nvcsw = 0; - rup->ru_nivcsw = 0; - - rup.copyOut(xc->getMemPort()); - - return 0; -} - - - - -#endif // __SIM_SYSCALL_EMUL_HH__ diff --git a/sim/system.cc b/sim/system.cc deleted file mode 100644 index ca9d68d77..000000000 --- a/sim/system.cc +++ /dev/null @@ -1,265 +0,0 @@ -#include "arch/isa_traits.hh" -#include "base/loader/object_file.hh" -#include "base/loader/symtab.hh" -#include "base/trace.hh" -#include "cpu/exec_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 "base/remote_gdb.hh" -#include "kern/kernel_stats.hh" -#endif - -using namespace std; -using namespace TheISA; - -vector<System *> System::systemList; - -int System::numSystemsRunning = 0; - -System::System(Params *p) - : SimObject(p->name), physmem(p->physmem), numcpus(0), -#if FULL_SYSTEM - init_param(p->init_param), -#else - page_ptr(0), -#endif - _params(p) -{ - // add self to global system list - systemList.push_back(this); - -#if FULL_SYSTEM - kernelSymtab = new SymbolTable; - debugSymbolTable = new SymbolTable; - - - /** - * Get a functional port to memory - */ - Port *mem_port; - mem_port = physmem->getPort("functional"); - functionalPort.setPeer(mem_port); - mem_port->setPeer(&functionalPort); - - mem_port = physmem->getPort("functional"); - virtPort.setPeer(mem_port); - mem_port->setPeer(&virtPort); - - - /** - * Load the kernel code into memory - */ - // Load kernel code - kernel = createObjectFile(params()->kernel_path); - if (kernel == NULL) - fatal("Could not load kernel file %s", params()->kernel_path); - - // Load program sections into memory - kernel->loadSections(&functionalPort, LoadAddrMask); - - // setup entry points - kernelStart = kernel->textBase(); - kernelEnd = kernel->bssBase() + kernel->bssSize(); - kernelEntry = kernel->entryPoint(); - - // load symbols - if (!kernel->loadGlobalSymbols(kernelSymtab)) - panic("could not load kernel symbols\n"); - - if (!kernel->loadLocalSymbols(kernelSymtab)) - panic("could not load kernel local symbols\n"); - - if (!kernel->loadGlobalSymbols(debugSymbolTable)) - panic("could not load kernel symbols\n"); - - if (!kernel->loadLocalSymbols(debugSymbolTable)) - panic("could not load kernel local symbols\n"); - - DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); - DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); - DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); - DPRINTF(Loader, "Kernel loaded...\n"); - - kernelBinning = new Kernel::Binning(this); -#endif // FULL_SYSTEM - - // increment the number of running systms - numSystemsRunning++; -} - -System::~System() -{ -#if FULL_SYSTEM - delete kernelSymtab; - delete kernel; - - delete kernelBinning; -#else - panic("System::fixFuncEventAddr needs to be rewritten " - "to work with syscall emulation"); -#endif // FULL_SYSTEM} -} - -#if FULL_SYSTEM - - -int rgdb_wait = -1; - -#endif // FULL_SYSTEM - -int -System::registerExecContext(ExecContext *xc, int id) -{ - if (id == -1) { - for (id = 0; id < execContexts.size(); id++) { - if (!execContexts[id]) - break; - } - } - - if (execContexts.size() <= id) - execContexts.resize(id + 1); - - if (execContexts[id]) - panic("Cannot have two CPUs with the same id (%d)\n", id); - - execContexts[id] = xc; - numcpus++; - -#if FULL_SYSTEM - RemoteGDB *rgdb = new RemoteGDB(this, xc); - GDBListener *gdbl = new GDBListener(rgdb, 7000 + id); - gdbl->listen(); - /** - * Uncommenting this line waits for a remote debugger to connect - * to the simulator before continuing. - */ - if (rgdb_wait != -1 && rgdb_wait == id) - gdbl->accept(); - - if (remoteGDB.size() <= id) { - remoteGDB.resize(id + 1); - } - - remoteGDB[id] = rgdb; -#endif // FULL_SYSTEM - - return id; -} - -void -System::startup() -{ - int i; - for (i = 0; i < execContexts.size(); i++) - execContexts[i]->activate(0); -} - -void -System::replaceExecContext(ExecContext *xc, int id) -{ - if (id >= execContexts.size()) { - panic("replaceExecContext: bad id, %d >= %d\n", - id, execContexts.size()); - } - - execContexts[id] = xc; -#if FULL_SYSTEM - remoteGDB[id]->replaceExecContext(xc); -#endif // FULL_SYSTEM -} - -#if !FULL_SYSTEM -Addr -System::new_page() -{ - Addr return_addr = page_ptr << LogVMPageSize; - ++page_ptr; - return return_addr; -} -#endif - -void -System::regStats() -{ -#if FULL_SYSTEM - kernelBinning->regStats(name() + ".kern"); -#endif // FULL_SYSTEM -} - -void -System::serialize(ostream &os) -{ -#if FULL_SYSTEM - kernelBinning->serialize(os); - - kernelSymtab->serialize("kernel_symtab", os); -#endif // FULL_SYSTEM -} - - -void -System::unserialize(Checkpoint *cp, const string §ion) -{ -#if FULL_SYSTEM - kernelBinning->unserialize(cp, section); - - kernelSymtab->unserialize("kernel_symtab", cp, section); -#endif // FULL_SYSTEM -} - -void -System::printSystems() -{ - vector<System *>::iterator i = systemList.begin(); - vector<System *>::iterator end = systemList.end(); - for (; i != end; ++i) { - System *sys = *i; - cerr << "System " << sys->name() << ": " << hex << sys << endl; - } -} - -extern "C" -void -printSystems() -{ - System::printSystems(); -} - -#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; - -END_DECLARE_SIM_OBJECT_PARAMS(System) - -BEGIN_INIT_SIM_OBJECT_PARAMS(System) - - INIT_PARAM(physmem, "physical memory") - -END_INIT_SIM_OBJECT_PARAMS(System) - -CREATE_SIM_OBJECT(System) -{ - System::Params *p = new System::Params; - p->name = getInstanceName(); - p->physmem = physmem; - return new System(p); -} - -REGISTER_SIM_OBJECT("System", System) - -#endif diff --git a/sim/system.hh b/sim/system.hh deleted file mode 100644 index 7e21bd587..000000000 --- a/sim/system.hh +++ /dev/null @@ -1,229 +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. - */ - -#ifndef __SYSTEM_HH__ -#define __SYSTEM_HH__ - -#include <string> -#include <vector> - -#include "base/loader/symtab.hh" -#include "base/misc.hh" -#include "base/statistics.hh" -#include "cpu/pc_event.hh" -#include "mem/port.hh" -#include "sim/sim_object.hh" -#if FULL_SYSTEM -#include "kern/system_events.hh" -#include "mem/vport.hh" -#endif - -class BaseCPU; -class ExecContext; -class ObjectFile; -class PhysicalMemory; - -#if FULL_SYSTEM -class Platform; -class GDBListener; -class RemoteGDB; -namespace Kernel { class Binning; } -#endif - -class System : public SimObject -{ - public: - PhysicalMemory *physmem; - PCEventQueue pcEventQueue; - - std::vector<ExecContext *> execContexts; - int numcpus; - - int getNumCPUs() - { - if (numcpus != execContexts.size()) - panic("cpu array not fully populated!"); - - return numcpus; - } - -#if FULL_SYSTEM - Platform *platform; - uint64_t init_param; - - /** Port to physical memory used for writing object files into ram at - * boot.*/ - FunctionalPort functionalPort; - VirtualPort virtPort; - - /** kernel symbol table */ - SymbolTable *kernelSymtab; - - /** Object pointer for the kernel code */ - ObjectFile *kernel; - - /** Begining of kernel code */ - Addr kernelStart; - - /** End of kernel code */ - Addr kernelEnd; - - /** Entry point in the kernel to start at */ - Addr kernelEntry; - - Kernel::Binning *kernelBinning; - -#else - - int page_ptr; - - -#endif // FULL_SYSTEM - - protected: - -#if FULL_SYSTEM - /** - * Fix up an address used to match PCs for hooking simulator - * events on to target function executions. See comment in - * system.cc for details. - */ - virtual Addr fixFuncEventAddr(Addr addr) = 0; - - /** - * Add a function-based event to the given function, to be looked - * up in the specified symbol table. - */ - template <class T> - T *System::addFuncEvent(SymbolTable *symtab, const char *lbl) - { - Addr addr = 0; // initialize only to avoid compiler warning - - if (symtab->findAddress(lbl, addr)) { - T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr)); - return ev; - } - - return NULL; - } - - /** Add a function-based event to kernel code. */ - template <class T> - T *System::addKernelFuncEvent(const char *lbl) - { - return addFuncEvent<T>(kernelSymtab, lbl); - } - -#endif - public: -#if FULL_SYSTEM - std::vector<RemoteGDB *> remoteGDB; - std::vector<GDBListener *> gdbListen; - virtual bool breakpoint() = 0; -#endif // FULL_SYSTEM - - public: - struct Params - { - std::string name; - PhysicalMemory *physmem; - -#if FULL_SYSTEM - Tick boot_cpu_frequency; - std::string boot_osflags; - uint64_t init_param; - bool bin; - std::vector<std::string> binned_fns; - bool bin_int; - - std::string kernel_path; - std::string readfile; -#endif - }; - - protected: - Params *_params; - - public: - System(Params *p); - ~System(); - - void startup(); - - const Params *params() const { return (const Params *)_params; } - - public: - -#if FULL_SYSTEM - /** - * Returns the addess the kernel starts at. - * @return address the kernel starts at - */ - Addr getKernelStart() const { return kernelStart; } - - /** - * Returns the addess the kernel ends at. - * @return address the kernel ends at - */ - Addr getKernelEnd() const { return kernelEnd; } - - /** - * Returns the addess the entry point to the kernel code. - * @return entry point of the kernel code - */ - Addr getKernelEntry() const { return kernelEntry; } - -#else - - Addr new_page(); - -#endif // FULL_SYSTEM - - int registerExecContext(ExecContext *xc, int xcIndex); - void replaceExecContext(ExecContext *xc, int xcIndex); - - void regStats(); - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); - - public: - //////////////////////////////////////////// - // - // STATIC GLOBAL SYSTEM LIST - // - //////////////////////////////////////////// - - static std::vector<System *> systemList; - static int numSystemsRunning; - - static void printSystems(); - - -}; - -#endif // __SYSTEM_HH__ diff --git a/sim/vptr.hh b/sim/vptr.hh deleted file mode 100644 index cc57e63f0..000000000 --- a/sim/vptr.hh +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2004-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. - */ - -#ifndef __ARCH_ALPHA_VPTR_HH__ -#define __ARCH_ALPHA_VPTR_HH__ - -#include "arch/vtophys.hh" -#include "arch/isa_traits.hh" - -class ExecContext; - -template <class T> -class VPtr -{ - public: - typedef T Type; - - private: - ExecContext *xc; - Addr ptr; - - public: - ExecContext *GetXC() const { return xc; } - Addr GetPointer() const { return ptr; } - - public: - explicit VPtr(ExecContext *_xc, Addr p = 0) : xc(_xc), ptr(p) { } - template <class U> - VPtr(const VPtr<U> &vp) : xc(vp.GetXC()), ptr(vp.GetPointer()) {} - ~VPtr() {} - - bool operator!() const - { - return ptr == 0; - } - - VPtr<T> operator+(int offset) - { - VPtr<T> ptr(*this); - ptr += offset; - - return ptr; - } - - const VPtr<T> &operator+=(int offset) - { - ptr += offset; - assert((ptr & (TheISA::PageBytes - 1)) + sizeof(T) - < TheISA::PageBytes); - - return *this; - } - - const VPtr<T> &operator=(Addr p) - { - assert((p & (TheISA::PageBytes - 1)) + sizeof(T) - < TheISA::PageBytes); - ptr = p; - - return *this; - } - - template <class U> - const VPtr<T> &operator=(const VPtr<U> &vp) - { - xc = vp.GetXC(); - ptr = vp.GetPointer(); - - return *this; - } - - operator T *() - { - panic("Needs to be rewritten\n"); -/* void *addr = vtomem(xc, ptr, sizeof(T)); - return (T *)addr; - */ - } - - T *operator->() - { - panic("Needs to be rewritten\n"); -/* void *addr = vtomem(xc, ptr, sizeof(T)); - return (T *)addr; - */ - } - - T &operator*() - { - panic("Needs to be rewritten\n"); -/* void *addr = vtomem(xc, ptr, sizeof(T)); - return *(T *)addr; - */ - } -}; - -#endif // __ARCH_ALPHA_VPTR_HH__ |