summaryrefslogtreecommitdiff
path: root/src/mem/gems_common/ioutil/confio.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/gems_common/ioutil/confio.cc')
-rw-r--r--src/mem/gems_common/ioutil/confio.cc456
1 files changed, 456 insertions, 0 deletions
diff --git a/src/mem/gems_common/ioutil/confio.cc b/src/mem/gems_common/ioutil/confio.cc
new file mode 100644
index 000000000..68d44197a
--- /dev/null
+++ b/src/mem/gems_common/ioutil/confio.cc
@@ -0,0 +1,456 @@
+/*
+ * 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.
+ */
+
+/*
+ * saves configuration information for later runs
+ */
+
+/*------------------------------------------------------------------------*/
+/* Includes */
+/*------------------------------------------------------------------------*/
+
+#ifdef IS_OPAL
+#include "hfa.hh"
+#endif
+
+#ifdef IS_RUBY
+#include "Global.hh"
+#define SIM_HALT ASSERT(0)
+#endif
+
+#ifdef IS_TOURMALINE
+#include "Tourmaline_Global.hh"
+#endif
+
+using namespace std;
+#include <string>
+#include <map>
+#include <stdlib.h>
+
+// Maurice
+// extern "C" {
+// #include "global.hh"
+// #include "simics/api.hh"
+//
+// #ifdef SIMICS22X
+// #include "sparc_api.hh"
+// #endif
+// #ifdef SIMICS30
+// #ifdef SPARC
+// #include "sparc.hh"
+// #else
+// #include "x86.hh"
+// #endif
+// #endif
+// };
+
+#include "FakeSimicsDataTypes.hh"
+
+#include "confio.hh"
+
+/*------------------------------------------------------------------------*/
+/* Macro declarations */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Variable declarations */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Forward declarations */
+/*------------------------------------------------------------------------*/
+
+// C++ Template: explicit instantiation
+template class map<string, confnode_t *>;
+
+// These functions are defined in parser/attrlex.l
+extern "C" int parseAttrFile( FILE *inputFile, const char *relative_include_path, attr_value_t *myTable );
+extern "C" int parseAttrString( const char *str, attr_value_t *myTable );
+
+/*------------------------------------------------------------------------*/
+/* Constructor(s) / destructor */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+confio_t::confio_t( )
+{
+ m_verbose = false;
+}
+
+//**************************************************************************
+confio_t::~confio_t( )
+{
+ ConfTable::iterator iter;
+
+ for ( iter = m_table.begin(); iter != m_table.end(); iter++ ) {
+ confnode_t *cfnode = (*iter).second;
+ free( cfnode );
+ }
+}
+
+/*------------------------------------------------------------------------*/
+/* Public methods */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Accessor(s) / mutator(s) */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+int confio_t::register_attribute( const char *name,
+ get_confio_t get_attr, void *get_attr_data,
+ set_confio_t set_attr, void *set_attr_data )
+{
+ confnode_t *newnode;
+ if ( m_table.find(name) == m_table.end() ) {
+ if (m_verbose)
+ DEBUG_OUT(" registering checkpoint attribute: \"%s\"\n", name);
+
+ // add a new entry to the table
+ newnode = (confnode_t *) malloc( sizeof( confnode_t ) );
+ newnode->get_attr = get_attr;
+ newnode->set_attr = set_attr;
+ newnode->set_attr_data = set_attr_data;
+ newnode->get_attr_data = get_attr_data;
+ newnode->attr_is_set = false;
+ string key(name);
+ m_table[key] = newnode;
+ } else {
+ ERROR_OUT(" warning: confio: adding existing conf node: %s\n", name);
+ }
+ return 0;
+}
+
+//**************************************************************************
+void fprintAttr( FILE *fp, attr_value_t attr )
+{
+ switch (attr.kind) {
+ case Sim_Val_Invalid:
+ fprintf(fp, "invalid");
+ break;
+
+ case Sim_Val_String:
+ fprintf(fp, "%s", attr.u.string);
+ break;
+
+ case Sim_Val_Integer:
+ fprintf(fp, "0x%llx", attr.u.integer);
+ break;
+
+ case Sim_Val_Floating:
+ fprintf(fp, "0x%llx", attr.u.integer);
+ break;
+
+ case Sim_Val_List:
+ fprintf(fp, "(");
+ for (uint32 i = 0; i < attr.u.list.size; i++) {
+ fprintAttr(fp, attr.u.list.vector[i]);
+ if (i != attr.u.list.size -1) {
+ fprintf(fp, ", ");
+ }
+ }
+ fprintf(fp, ")");
+ break;
+
+ default:
+ ERROR_OUT("fprintAttr: unknown/unimplemented attribute %d\n", attr.kind);
+ }
+}
+
+//**************************************************************************
+void freeAttribute( attr_value_t *attr )
+{
+ switch (attr->kind) {
+ case Sim_Val_Invalid:
+ break;
+
+ case Sim_Val_String:
+ free( (char *) attr->u.string );
+ break;
+
+ case Sim_Val_Integer:
+ break;
+
+ case Sim_Val_Floating:
+ break;
+
+ case Sim_Val_List:
+ for (uint32 i = 0; i < attr->u.list.size; i++) {
+ freeAttribute( &(attr->u.list.vector[i]) );
+ }
+ free( attr->u.list.vector );
+ break;
+
+ default:
+ ERROR_OUT("freeAttr: unknown/unimplemented attribute %d\n", attr->kind);
+ }
+}
+
+/**
+ * Allocates, and initializes a attribute value.
+ * @param number The number of values to allocate.
+ * @return A pointer to the newly allocated structure.
+ */
+//**************************************************************************
+attr_value_t *mallocAttribute( uint32 number )
+{
+ attr_value_t *newattr = (attr_value_t *) malloc( number *
+ sizeof(attr_value_t) );
+ if ( newattr == NULL ) {
+ ERROR_OUT( "confio: mallocAttribute: out of memory\n" );
+ exit(1);
+ }
+ memset( newattr, 0, number*sizeof(attr_value_t) );
+ return (newattr);
+}
+
+
+//**************************************************************************
+void fprintMap( FILE *fp, attr_value_t attr )
+{
+ attr_value_t name;
+ attr_value_t value;
+
+ if (attr.kind != Sim_Val_List)
+ return;
+
+ for (int i = 0; i < attr.u.list.size; i++) {
+
+ if (attr.u.list.vector[i].kind != Sim_Val_List ||
+ attr.u.list.vector[i].u.list.size != 2)
+ return;
+
+ name = attr.u.list.vector[i].u.list.vector[0];
+ value = attr.u.list.vector[i].u.list.vector[1];
+ fprintf( fp, " %s: ", name.u.string);
+ fprintAttr( fp, value );
+ fprintf( fp, "\n");
+ }
+}
+
+/**
+ * write a configuration file: e.g. save state
+ */
+//**************************************************************************
+int confio_t::writeConfiguration( const char *outputFilename )
+{
+ FILE *fp;
+ ConfTable::iterator iter;
+ confnode_t *cfnode;
+ attr_value_t attr;
+
+ memset( &attr, 0, sizeof(attr_value_t) );
+ if ( outputFilename == NULL ) {
+ fp = stdout;
+ } else {
+ fp = fopen( outputFilename, "w" );
+ if ( fp == NULL ) {
+ ERROR_OUT("error: writeConfiguration: unable to open file %s\n",
+ outputFilename );
+ return (-1);
+ }
+ }
+
+ for (iter = m_table.begin(); iter != m_table.end(); iter++) {
+ fprintf( fp, " %s: ", (*iter).first.c_str() );
+ cfnode = (*iter).second;
+ attr = (*(cfnode->get_attr))( cfnode->get_attr_data, NULL );
+ fprintAttr( fp, attr );
+ fprintf(fp, "\n");
+ }
+
+ if ( outputFilename != NULL ) {
+ // wrote to a file: now close it!
+ fclose( fp );
+ }
+ return 0;
+}
+
+/**
+ * read state from an existing configuration file
+ */
+//**************************************************************************
+int confio_t::readConfiguration( const char *inputFilename,
+ const char *relativeIncludePath )
+{
+ // parse the input stream
+ FILE *fp;
+ char relativeFilename[256];
+
+ fp = fopen( inputFilename, "r" );
+ if ( fp == NULL ) {
+ sprintf( relativeFilename, "%s%s", relativeIncludePath, inputFilename );
+ fp = fopen( relativeFilename, "r" );
+ }
+ if ( fp == NULL ) {
+ sprintf( relativeFilename, "%s%s%s", relativeIncludePath, "config/",
+ inputFilename );
+ fp = fopen( relativeFilename, "r" );
+ }
+ if ( fp == NULL ) {
+ ERROR_OUT("error: readConfiguration: unable to open file %s or %s\n",
+ inputFilename, relativeFilename);
+ return (-1);
+ }
+
+ attr_value_t *myattr = mallocAttribute(1);
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() parsing conf file\n");
+#endif
+ int rc = parseAttrFile( fp, relativeIncludePath, myattr );
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() parse completed\n");
+#endif
+ if ( rc == 0 ) {
+ applyConfiguration( myattr );
+ freeAttribute( myattr );
+ free(myattr);
+ }
+
+ fclose( fp );
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() completed\n");
+#endif
+ return (rc);
+}
+
+/**
+ * read state from a configuration string
+ */
+//**************************************************************************
+int confio_t::readConfigurationString( const char *inputBuffer )
+{
+ if ( inputBuffer == NULL ) {
+ ERROR_OUT( "error: readConfiguration: NULL inputBuffer\n" );
+ return (-1);
+ }
+
+ attr_value_t *myattr = mallocAttribute(1);
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() parsing conf string\n");
+#endif
+
+ int rc = parseAttrString( inputBuffer, myattr );
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() parse completed\n");
+#endif
+ if ( rc == 0 ) {
+ applyConfiguration( myattr );
+ freeAttribute( myattr );
+ free(myattr);
+ }
+ return (rc);
+}
+
+//**************************************************************************
+void confio_t::checkInitialization( void )
+{
+ ConfTable::iterator iter;
+ confnode_t *cfnode;
+
+ for (iter = m_table.begin(); iter != m_table.end(); iter++) {
+ cfnode = (*iter).second;
+ if ( !cfnode->attr_is_set ) {
+ DEBUG_OUT(" warning: %s is not set in configuration file.\n", (*iter).first.c_str() );
+ }
+ }
+}
+
+/*------------------------------------------------------------------------*/
+/* Private methods */
+/*------------------------------------------------------------------------*/
+
+//**************************************************************************
+int confio_t::applyConfiguration( attr_value_t *attr )
+{
+ confnode_t *cfnode;
+ attr_value_t name;
+ attr_value_t value;
+ set_error_t seterr;
+
+#ifdef MODINIT_VERBOSE
+ DEBUG_OUT("confio_t() data in memory\n");
+ fprintMap( stdout, *attr );
+#endif
+
+ // apply the configuration the the m_table
+ if (attr->kind != Sim_Val_List ||
+ attr->u.list.size <= 0) {
+ ERROR_OUT("readconfiguration: internal error #1\n");
+ return -1;
+ }
+
+ for (int i = 0; i < attr->u.list.size; i++) {
+
+ if (attr->u.list.vector[i].kind != Sim_Val_List ||
+ attr->u.list.vector[i].u.list.size != 2) {
+ ERROR_OUT("readconfiguration: illegal configuration kind:%d size:%lld\n",
+ attr->u.list.vector[i].kind,
+ attr->u.list.vector[i].u.list.size);
+ continue;
+ }
+
+ name = attr->u.list.vector[i].u.list.vector[0];
+ value = attr->u.list.vector[i].u.list.vector[1];
+ string newstr((char *) name.u.string);
+ if ( m_table.find(newstr) != m_table.end()) {
+
+ // set the value found in the configuration
+ cfnode = m_table[newstr];
+ seterr = (*cfnode->set_attr)( cfnode->set_attr_data, NULL,
+ &(value) );
+ if ( seterr == Sim_Set_Ok ) {
+ cfnode->attr_is_set = true;
+ if (m_verbose)
+ DEBUG_OUT("configuration set for: %s\n", name.u.string);
+ } else {
+ ERROR_OUT("error: \"%s\" unable to set value: %d\n",
+ name.u.string, (int) seterr);
+ }
+ } else {
+ ERROR_OUT("error: \"%s\" not found. unable to set value.\n",
+ name.u.string);
+ }
+ }
+ return 0;
+}
+
+/*------------------------------------------------------------------------*/
+/* Static methods */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* Global functions */
+/*------------------------------------------------------------------------*/
+
+
+/** [Memo].
+ * [Internal Documentation]
+ */
+//**************************************************************************
+