summaryrefslogtreecommitdiff
path: root/src/mem/gems_common/ioutil/initvar.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/gems_common/ioutil/initvar.cc')
-rw-r--r--src/mem/gems_common/ioutil/initvar.cc626
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 ));
+}