diff options
author | Nathan Binkert <nate@binkert.org> | 2009-05-11 10:38:43 -0700 |
---|---|---|
committer | Nathan Binkert <nate@binkert.org> | 2009-05-11 10:38:43 -0700 |
commit | 2f30950143cc70bc42a3c8a4111d7cf8198ec881 (patch) | |
tree | 708f6c22edb3c6feb31dd82866c26623a5329580 /src/mem/gems_common/ioutil/initvar.cc | |
parent | c70241810d4e4f523f173c1646b008dc40faad8e (diff) | |
download | gem5-2f30950143cc70bc42a3c8a4111d7cf8198ec881.tar.xz |
ruby: Import ruby and slicc from GEMS
We eventually plan to replace the m5 cache hierarchy with the GEMS
hierarchy, but for now we will make both live alongside eachother.
Diffstat (limited to 'src/mem/gems_common/ioutil/initvar.cc')
-rw-r--r-- | src/mem/gems_common/ioutil/initvar.cc | 626 |
1 files changed, 626 insertions, 0 deletions
diff --git a/src/mem/gems_common/ioutil/initvar.cc b/src/mem/gems_common/ioutil/initvar.cc new file mode 100644 index 000000000..9cccdf64b --- /dev/null +++ b/src/mem/gems_common/ioutil/initvar.cc @@ -0,0 +1,626 @@ +/* + * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood + * 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 has been modified by Kevin Moore and Dan Nussbaum of the + Scalable Systems Research Group at Sun Microsystems Laboratories + (http://research.sun.com/scalable/) to support the Adaptive + Transactional Memory Test Platform (ATMTP). + + Please send email to atmtp-interest@sun.com with feedback, questions, or + to request future announcements about ATMTP. + + ---------------------------------------------------------------------- + + File modification date: 2008-02-23 + + ---------------------------------------------------------------------- +*/ + +/* + * FileName: initvar.C + * Synopsis: implementation of global variable initialization in simics + * Author: cmauer + * Version: $Id$ + */ + +/*------------------------------------------------------------------------*/ +/* Includes */ +/*------------------------------------------------------------------------*/ + +using namespace std; +#include <string> +#include <map> +#include <stdlib.h> + +// Maurice +// extern "C" { +// #include "global.hh" +// #include "simics/api.hh" +// #ifdef SIMICS22X +// #include "configuration_api.hh" +// #endif +// #ifdef SIMICS30 +// #include "configuration.hh" +// #endif +// }; + +#include "FakeSimicsDataTypes.hh" + +#ifdef IS_OPAL +#include "hfatypes.hh" +#include "debugio.hh" +#endif + +#ifdef IS_RUBY +#include "Global.hh" +#endif + +#ifdef IS_TOURMALINE +#include "Tourmaline_Global.hh" +#endif + +#include "confio.hh" +#include "initvar.hh" + +/*------------------------------------------------------------------------*/ +/* Macro declarations */ +/*------------------------------------------------------------------------*/ + +#define CONFIG_VAR_FILENAME "config.include" + +/*------------------------------------------------------------------------*/ +/* Variable declarations */ +/*------------------------------------------------------------------------*/ + +// define global "constants" using centralized file +#define PARAM( NAME ) \ + int32 NAME; +#define PARAM_UINT( NAME ) \ + uint32 NAME; +#define PARAM_ULONG( NAME ) \ + uint64 NAME; +#define PARAM_BOOL( NAME ) \ + bool NAME; +#define PARAM_DOUBLE( NAME ) \ + double NAME; +#define PARAM_STRING( NAME ) \ + char *NAME; +#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \ + PTYPE NAME[ARRAY_SIZE]; +#include CONFIG_VAR_FILENAME +#undef PARAM +#undef PARAM_UINT +#undef PARAM_ULONG +#undef PARAM_BOOL +#undef PARAM_DOUBLE +#undef PARAM_STRING +#undef PARAM_ARRAY + +/** global initvar object */ +initvar_t *initvar_t::m_inst = NULL; + +/*------------------------------------------------------------------------*/ +/* Forward declarations */ +/*------------------------------------------------------------------------*/ + +static attr_value_t initvar_get_attr( void *ptr, void *obj ); +static set_error_t initvar_set_attr( void *ptr, void *obj, + attr_value_t *value ); + +/*------------------------------------------------------------------------*/ +/* Constructor(s) / destructor */ +/*------------------------------------------------------------------------*/ + +//************************************************************************** +initvar_t::initvar_t( const char *name, const char *relativeIncludePath, + const char *initializingString, + void (*allocate_fn)(void), + void (*my_generate_fn)(void), + get_attr_t my_get_attr, set_attr_t my_set_attr ) +{ + m_is_init = false; + m_name = (char *) malloc( sizeof(char)*(strlen( name ) + 2) ); + m_rel_include_path = (char *) malloc( sizeof(char)*(strlen( relativeIncludePath ) + 2) ); + m_config_filename = NULL; + strcpy( m_name, name ); + strcpy( m_rel_include_path, relativeIncludePath ); + m_allocate_f = allocate_fn; + m_generate_values_f = my_generate_fn; + m_my_get_attr = my_get_attr; + m_my_set_attr = my_set_attr; + + initvar_t::m_inst = this; + init_config_reader( initializingString ); +} + +//************************************************************************** +initvar_t::~initvar_t( ) +{ +#define PARAM( NAME ) +#define PARAM_UINT( NAME ) +#define PARAM_ULONG( NAME ) +#define PARAM_BOOL( NAME ) +#define PARAM_DOUBLE( NAME ) +#define PARAM_STRING( NAME ) \ + if (NAME != NULL) { \ + free( NAME ); \ + NAME = NULL; \ + } +#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) +#include CONFIG_VAR_FILENAME +#undef PARAM +#undef PARAM_UINT +#undef PARAM_ULONG +#undef PARAM_BOOL +#undef PARAM_DOUBLE +#undef PARAM_STRING +#undef PARAM_ARRAY + if (m_name) { + free( m_name ); + } + if (m_rel_include_path) { + free( m_rel_include_path ); + } + if (m_config_reader) { + delete m_config_reader; + } + if (m_config_filename) { + delete m_config_filename; + } +} + +//************************************************************************** +void initvar_t::init_config_reader( const char *initString ) +{ + int rc; + const char *name; + + m_config_reader = new confio_t(); + m_config_reader->setVerbosity( false ); + + // Initialize the config reader object to identify each parameter +#define PARAM_UINT PARAM +#define PARAM_ULONG PARAM +#define PARAM_BOOL PARAM +#define PARAM_DOUBLE PARAM +#define PARAM( NAME ) \ + name = #NAME; \ + rc = m_config_reader->register_attribute( name, \ + initvar_get_attr, (void *) name, \ + initvar_set_attr, (void *) name ); +#define PARAM_STRING( NAME ) \ + NAME = NULL; \ + name = #NAME; \ + rc = m_config_reader->register_attribute( name, \ + initvar_get_attr, (void *) name, \ + initvar_set_attr, (void *) name ); +#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \ + name = #NAME; \ + rc = m_config_reader->register_attribute( name, \ + initvar_get_attr, (void *) name, \ + initvar_set_attr, (void *) name ); + +#include CONFIG_VAR_FILENAME +#undef PARAM +#undef PARAM_UINT +#undef PARAM_ULONG +#undef PARAM_BOOL +#undef PARAM_DOUBLE +#undef PARAM_STRING +#undef PARAM_ARRAY + + // read the default configuration from the embedded text file + rc = m_config_reader->readConfigurationString( initString ); + (*m_generate_values_f)(); +} + +/*------------------------------------------------------------------------*/ +/* Public methods */ +/*------------------------------------------------------------------------*/ + +//************************************************************************** +void initvar_t::allocate( void ) +{ + if ( confirm_init() ) { + DEBUG_OUT("error: %s initvar::allocate() called twice\n", m_name); + return; + } + + (*m_generate_values_f)(); + (*m_allocate_f)(); + m_is_init = true; +} + +//************************************************************************** +void initvar_t::checkInitialization( void ) +{ + m_config_reader->checkInitialization(); +} + +//************************************************************************** +attr_value_t initvar_t::dispatch_get( void *id, void *obj, + attr_value_t *idx ) +{ + const char *command = (const char *) id; + if ( !confirm_init() ) { + DEBUG_OUT("error: %s is uninitialized. unable to get \'%s\'\n", m_name, command); + DEBUG_OUT(" : you must initialize %s with a configuration file first.\n", m_name); + DEBUG_OUT(" : use the command \'%s0.init\'\n", m_name); + + attr_value_t ret; + ret.kind = Sim_Val_Invalid; + ret.u.integer = 0; + return ret; + } + + return ((*m_my_get_attr)(id, obj, idx)); +} + + +//************************************************************************** +set_error_t initvar_t::dispatch_set( void *id, void *obj, + attr_value_t *val, attr_value_t *idx ) +{ + const char *command = (const char *) id; + + // DEBUG_OUT("set attribute: %s\n", command); + if (!strcmp(command, "init")) { + if (val->kind == Sim_Val_String) { + if (!strcmp( val->u.string, "" )) { + // update generated values, then allocate + allocate(); + } else { + read_config( val->u.string ); + allocate(); + } + return Sim_Set_Ok; + } else { + return Sim_Set_Need_String; + } + } else if (!strcmp(command, "readparam")) { + if (val->kind == Sim_Val_String) { + read_config( val->u.string ); + return Sim_Set_Ok; + } else { + return Sim_Set_Need_String; + } + } else if (!strcmp(command, "saveparam")) { + if (val->kind == Sim_Val_String) { + FILE *fp = fopen( val->u.string, "w" ); + if (fp == NULL) { + ERROR_OUT("error: unable to open file: %s\n", val->u.string); + return Sim_Set_Illegal_Value; + } + list_param( fp ); + if (fp != NULL) { + fclose( fp ); + } + return Sim_Set_Ok; + } else { + ERROR_OUT("error: saveparam given wrong type.\n"); + return Sim_Set_Illegal_Value; + } + } else if (!strcmp(command, "param")) { + if (val->kind == Sim_Val_Integer) { + list_param( stdout ); + return Sim_Set_Ok; + } else if ( val->kind == Sim_Val_List && + val->u.list.size == 2 && + val->u.list.vector[0].kind == Sim_Val_String ) { + return (set_param( val->u.list.vector[0].u.string, + &val->u.list.vector[1] )); + } else { + DEBUG_OUT("error: set parameter given wrong type.\n"); + return Sim_Set_Illegal_Value; + } + } + + if ( !confirm_init() ) { + DEBUG_OUT("error: %s is uninitialized. unable to set \'%s\'\n", m_name, id); + DEBUG_OUT(" : you must initialize %s with a configuration file first.\n", m_name); + DEBUG_OUT(" : use the command \'%s0.init\'\n", m_name); + return Sim_Set_Illegal_Value; + } + + return (*m_my_set_attr)( id, obj, val, idx ); +} + +/*------------------------------------------------------------------------*/ +/* Accessor(s) / mutator(s) */ +/*------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------*/ +/* Private methods */ +/*------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------*/ +/* Static methods */ +/*------------------------------------------------------------------------*/ + +//************************************************************************** +static attr_value_t initvar_get_attr( void *ptr, void *obj ) +{ + const char *name = (const char *) ptr; + attr_value_t ret; + memset( &ret, 0, sizeof(attr_value_t) ); + +#define PARAM_UINT PARAM +#define PARAM_ULONG PARAM +#define PARAM_BOOL PARAM +#define PARAM( NAME ) \ + if (!strcmp(name, #NAME)) { \ + ret.kind = Sim_Val_Integer; \ + ret.u.integer = NAME; \ + return (ret); \ + } +#define PARAM_DOUBLE( NAME ) \ + if (!strcmp(name, #NAME)) { \ + ret.kind = Sim_Val_Floating; \ + ret.u.floating = NAME; \ + return (ret); \ + } +#define PARAM_STRING( NAME ) \ + if (!strcmp(name, #NAME)) { \ + ret.kind = Sim_Val_String; \ + ret.u.string = NAME; \ + return (ret); \ + } +#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \ + if (!strcmp(name, #NAME)) { \ + ret.kind = Sim_Val_List; \ + ret.u.list.size = ARRAY_SIZE; \ + ret.u.list.vector = mallocAttribute( ARRAY_SIZE ); \ + for (int i = 0; i < ARRAY_SIZE; i++) { \ + ret.u.list.vector[i].u.integer = NAME[i]; \ + } \ + return (ret); \ + } + +#include CONFIG_VAR_FILENAME +#undef PARAM +#undef PARAM_UINT +#undef PARAM_ULONG +#undef PARAM_BOOL +#undef PARAM_DOUBLE +#undef PARAM_STRING +#undef PARAM_ARRAY + + DEBUG_OUT("error: %s not found.\n", name); + ret.kind = Sim_Val_Invalid; + return (ret); +} + +//*************************************************************************** +static set_error_t initvar_set_attr( void *ptr, void *obj, + attr_value_t *value ) +{ + const char *name = (const char *) ptr; + +#define PARAM_UINT PARAM +#define PARAM_ULONG PARAM +#define PARAM( NAME ) \ + if (!strcmp(name, #NAME)) { \ + if ( value->kind != Sim_Val_Integer ) { \ + ERROR_OUT("error: %s is not an integer\n", name );\ + return Sim_Set_Need_Integer; \ + } \ + NAME = value->u.integer; \ + return Sim_Set_Ok; \ + } +#define PARAM_BOOL( NAME ) \ + if (!strcmp(name, #NAME)) { \ + if ( value->kind != Sim_Val_String ) { \ + ERROR_OUT("error: %s is not an bool string\n", name );\ + return Sim_Set_Need_String; \ + } \ + if (!strcmp(value->u.string, "true")) { \ + NAME = true; \ + } else if (!strcmp(value->u.string, "false")) { \ + NAME = false; \ + } else { \ + ERROR_OUT("error: value %s for %s is not an bool string (set to false)\n", value->u.string, name );\ + NAME = false; \ + } \ + return Sim_Set_Ok; \ + } +#define PARAM_DOUBLE( NAME ) \ + if (!strcmp(name, #NAME)) { \ + if ( value->kind != Sim_Val_String ) { \ + ERROR_OUT("error: %s is not a float\n", name );\ + return Sim_Set_Need_Floating; \ + } \ + NAME = atof( value->u.string ); \ + return Sim_Set_Ok; \ + } +#define PARAM_STRING( NAME ) \ + if (!strcmp(name, #NAME)) { \ + if ( value->kind != Sim_Val_String ) { \ + ERROR_OUT("error: %s is not an string\n", name ); \ + return Sim_Set_Need_String; \ + } \ + if (NAME != NULL) { \ + free( NAME ); \ + } \ + NAME = strdup( value->u.string ); \ + return Sim_Set_Ok; \ + } +#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \ + if (!strcmp(name, #NAME)) { \ + if ( value->kind != Sim_Val_List ) { \ + ERROR_OUT("error: %s is not an list\n", name ); \ + return Sim_Set_Need_List; \ + } \ + if ( value->u.list.size != ARRAY_SIZE ) { \ + ERROR_OUT("error: %s has %lld elements (should be %d)\n", name, value->u.list.size, ARRAY_SIZE); \ + return Sim_Set_Illegal_Value; \ + } \ + for (int i = 0; i < ARRAY_SIZE; i++) { \ + NAME[i] = value->u.list.vector[i].u.integer; \ + } \ + return Sim_Set_Ok; \ + } + +#include CONFIG_VAR_FILENAME +#undef PARAM +#undef PARAM_UINT +#undef PARAM_ULONG +#undef PARAM_BOOL +#undef PARAM_DOUBLE +#undef PARAM_STRING +#undef PARAM_ARRAY + + ERROR_OUT("error: %s not a parameter\n", name); + return Sim_Set_Illegal_Value; +} + +//*************************************************************************** +void initvar_t::read_config( const char *parameterFile ) +{ + DEBUG_OUT("read configuration: %s\n", parameterFile ); + m_config_filename = strdup( parameterFile ); + int rc = m_config_reader->readConfiguration( parameterFile, + m_rel_include_path ); + if ( rc < 0 ) { + ERROR_OUT("fatal error in read configuration: unable to continue.\n"); + exit(1); + } + // update generated values + (*m_generate_values_f)(); +} + +/** sets one of the parameters */ +//************************************************************************** +set_error_t initvar_t::set_param( const char *name, attr_value_t *value ) +{ + + // [dann 2007-04-04] ATMTP VV + // + // HACK ALERT: allow setting REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH, + // PROFILE_EXCEPTIONS, PROFILE_XACT, ATMTP_DEBUG_LEVEL and + // ATMTP_ENABLED after initialization. This works is because ruby's + // m_generate_values_f() does nothing -- more particularly, nothing + // that depends on any of these parameters is pre-calculated + // anywhere. + // + if (strcmp(name, "REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH") != 0 && + strcmp(name, "PROFILE_EXCEPTIONS") != 0 && + strcmp(name, "PROFILE_XACT") != 0 && + strcmp(name, "ATMTP_DEBUG_LEVEL") != 0 && + strcmp(name, "ATMTP_ENABLED") != 0) { + // + // [dann 2007-04-04] ATMTP ^^ + if ( confirm_init() ) { + DEBUG_OUT("error: %s is already initialized.\n", m_name); + DEBUG_OUT(" : setting parameters after initialization is unsupported\n"); + return (Sim_Set_Illegal_Value); + } + // [dann 2007-04-04] ATMTP VV + // + } + // + // [dann 2007-04-04] ATMTP ^^ + + set_error_t result = initvar_set_attr( (void *) name, NULL, value ); + (*m_generate_values_f)(); + return (result); +} + +/** print out a list of valid parameters */ +//************************************************************************** +void initvar_t::list_param( FILE *fp ) +{ + if (!fp) + fp = stdout; + +#define PARAM( NAME ) \ + fprintf( fp, "%-44.44s: %26d\n", #NAME, NAME ); +#define PARAM_UINT( NAME ) \ + fprintf( fp, "%-44.44s: %26u\n", #NAME, NAME ); +#define PARAM_ULONG( NAME ) \ + fprintf( fp, "%-44.44s: %26llu\n", #NAME, NAME ); +#define PARAM_BOOL( NAME ) \ + if (NAME == true) { \ + fprintf( fp, "%-44.44s: %26.26s\n", #NAME, "true" ); \ + } else { \ + fprintf( fp, "%-44.44s: %26.26s\n", #NAME, "false" );\ + } +#define PARAM_DOUBLE( NAME ) \ + fprintf( fp, "%-44.44s: %26f\n", #NAME, NAME ); +#define PARAM_STRING( NAME ) \ + if ( NAME != NULL ) { \ + fprintf( fp, "%-44.44s: %26.26s\n", #NAME, NAME ); \ + } +#define PARAM_ARRAY( PTYPE, NAME, ARRAY_SIZE ) \ + fprintf( fp, "%-44.44s: (", #NAME ); \ + for (int i = 0; i < ARRAY_SIZE; i++) { \ + if ( i != 0 ) { \ + fprintf( fp, ", " ); \ + } \ + fprintf( fp, "%d", NAME[i] ); \ + } \ + fprintf( fp, ")\n" ); + +#include CONFIG_VAR_FILENAME +#undef PARAM +#undef PARAM_UINT +#undef PARAM_ULONG +#undef PARAM_BOOL +#undef PARAM_DOUBLE +#undef PARAM_STRING +#undef PARAM_ARRAY +} + +//************************************************************************** +const char *initvar_t::get_config_name( void ) +{ + if (m_config_filename == NULL) { + return "default"; + } + return m_config_filename; +} + +/*------------------------------------------------------------------------*/ +/* Global functions */ +/*------------------------------------------------------------------------*/ + +//************************************************************************** +attr_value_t initvar_dispatch_get( void *id, void *obj, + attr_value_t *idx ) +{ + initvar_t *init_obj = initvar_t::m_inst; + return (init_obj->dispatch_get( id, obj, idx )); +} + +//************************************************************************** +set_error_t initvar_dispatch_set( void *id, void *obj, + attr_value_t *val, attr_value_t *idx ) +{ + initvar_t *init_obj = initvar_t::m_inst; + return (init_obj->dispatch_set( id, obj, val, idx )); +} |