summaryrefslogtreecommitdiff
path: root/src/mem/ruby/simics
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/ruby/simics')
-rw-r--r--src/mem/ruby/simics/commands.cc867
-rw-r--r--src/mem/ruby/simics/commands.hh106
-rw-r--r--src/mem/ruby/simics/interface.cc935
-rw-r--r--src/mem/ruby/simics/interface.hh152
-rw-r--r--src/mem/ruby/simics/simics_api_dummy.c105
5 files changed, 2165 insertions, 0 deletions
diff --git a/src/mem/ruby/simics/commands.cc b/src/mem/ruby/simics/commands.cc
new file mode 100644
index 000000000..e0a4f969e
--- /dev/null
+++ b/src/mem/ruby/simics/commands.cc
@@ -0,0 +1,867 @@
+
+/*
+ * Copyright (c) 1999-2008 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
+
+ ----------------------------------------------------------------------
+*/
+
+/*
+ * $Id$
+ *
+ */
+
+#include "protocol_name.hh"
+#include "Global.hh"
+#include "System.hh"
+#include "CacheRecorder.hh"
+//#include "Tracer.hh"
+#include "RubyConfig.hh"
+#include "interface.hh"
+#include "Network.hh"
+// #include "TransactionInterfaceManager.hh"
+// #include "TransactionVersionManager.hh"
+// #include "TransactionIsolationManager.hh"
+//#include "XactCommitArbiter.hh" // gem5:Arka for decomissioning of log_tm
+#include "Chip.hh"
+//#include "XactVisualizer.hh" // gem5:Arka for decomissioning of log_tm
+
+extern "C" {
+#include "commands.hh"
+}
+
+#ifdef CONTIGUOUS_ADDRESSES
+#include "ContiguousAddressTranslator.hh"
+
+/* Declared in interface.C */
+extern ContiguousAddressTranslator * g_p_ca_translator;
+
+memory_transaction_t local_memory_transaction_t_shadow;
+
+#endif // #ifdef CONTIGUOUS_ADDRESSES
+
+//////////////////////// extern "C" api ////////////////////////////////
+
+extern "C"
+void ruby_dump_cache(int cpuNumber)
+{
+ assert(0);
+ g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->dumpCaches(cout);
+}
+
+extern "C"
+void ruby_dump_cache_data(int cpuNumber, char* tag)
+{
+ assert(0);
+ if (tag == NULL) {
+ // No filename, dump to screen
+ g_system_ptr->printConfig(cout);
+ g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->dumpCacheData(cout);
+ } else {
+ // File name, dump to file
+ string filename(tag);
+
+ cout << "Dumping stats to output file '" << filename << "'..." << endl;
+ ofstream m_outputFile;
+ m_outputFile.open(filename.c_str());
+ if(m_outputFile == NULL){
+ cout << endl << "Error: error opening output file '" << filename << "'" << endl;
+ return;
+ }
+ g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->dumpCacheData(m_outputFile);
+ }
+}
+
+extern "C"
+void ruby_set_periodic_stats_file(char* filename)
+{
+ assert(0);
+ g_system_ptr->getProfiler()->setPeriodicStatsFile(filename);
+}
+
+extern "C"
+void ruby_set_periodic_stats_interval(int interval)
+{
+ assert(0);
+ g_system_ptr->getProfiler()->setPeriodicStatsInterval(interval);
+}
+
+extern "C"
+int mh_memorytracer_possible_cache_miss(memory_transaction_t *mem_trans)
+{
+
+ assert(0);
+ memory_transaction_t *p_mem_trans_shadow = mem_trans;
+
+#ifdef CONTIGUOUS_ADDRESSES
+ if(g_p_ca_translator!=NULL) {
+ memcpy( &local_memory_transaction_t_shadow, mem_trans, sizeof(memory_transaction_t) );
+ p_mem_trans_shadow = &local_memory_transaction_t_shadow;
+ uint64 contiguous_address = g_p_ca_translator->TranslateSimicsToRuby( p_mem_trans_shadow->s.physical_address );
+ p_mem_trans_shadow->s.physical_address = contiguous_address;
+ }
+#endif // #ifdef CONTIGUOUS_ADDRESSES
+
+
+ // Pass this request off to SimicsDriver::makeRequest()
+ // SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ // return simics_interface_ptr->makeRequest(p_mem_trans_shadow);
+ return 0;
+}
+
+extern "C"
+void mh_memorytracer_observe_memory(memory_transaction_t *mem_trans)
+{
+
+ assert(0);
+ memory_transaction_t *p_mem_trans_shadow = mem_trans;
+
+
+#ifdef CONTIGUOUS_ADDRESSES
+ if(g_p_ca_translator!=NULL) {
+ memcpy( &local_memory_transaction_t_shadow, mem_trans, sizeof(memory_transaction_t) );
+ p_mem_trans_shadow = &local_memory_transaction_t_shadow;
+ uint64 contiguous_address = g_p_ca_translator->TranslateSimicsToRuby( p_mem_trans_shadow->s.physical_address );
+ p_mem_trans_shadow->s.physical_address = contiguous_address;
+
+ }
+#endif // #ifdef CONTIGUOUS_ADDRESSES
+
+
+ // Pass this request off to SimicsDriver::makeRequest()
+ //SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ //simics_interface_ptr->observeMemoryAccess(p_mem_trans_shadow);
+}
+
+
+void ruby_set_g3_reg(void *cpu, void *parameter){
+ assert(0);
+#if 0
+ int proc_num = SIM_get_proc_no(cpu);
+ sparc_v9_interface_t * m_v9_interface = (sparc_v9_interface_t *) SIM_get_interface(cpu, SPARC_V9_INTERFACE);
+
+ for(int set=0; set < 4; set++) {
+ for(int i=0; i <8; i++) {
+ int registerNumber = i;
+ uinteger_t value = m_v9_interface->read_global_register((void *)cpu, set, registerNumber);
+ cout << "ruby_set_g3_reg BEFORE: proc =" << proc_num << " GSET = " << set << " GLOBAL_REG = " << i << " VALUE = " << value << endl;
+ }
+ }
+
+ uinteger_t value_ptr = (uinteger_t) parameter;
+ int g3_regnum = SIM_get_register_number(cpu, "g3");
+ SIM_write_register(cpu, g3_regnum, (uinteger_t) value_ptr);
+
+ cout << endl;
+ for(int set=0; set < 4; set++) {
+ for(int i=0; i <8; i++) {
+ int registerNumber = i;
+ uinteger_t value = m_v9_interface->read_global_register((void *)cpu, set, registerNumber);
+ cout << "ruby_set_g3_reg AFTER: proc =" << proc_num << " GSET = " << set << " GLOBAL_REG = " << i << " VALUE = " << value << endl;
+ }
+ }
+#endif
+
+}
+
+// #define XACT_MGR g_system_ptr->getChip(SIMICS_current_processor_number()/RubyConfig::numberOfProcsPerChip()/RubyConfig::numberofSMTThreads())->getTransactionInterfaceManager( (SIMICS_current_processor_number()/RubyConfig::numberofSMTThreads())%RubyConfig::numberOfProcsPerChip())
+
+extern "C"
+void magic_instruction_callback(void* desc, void* cpu, integer_t val)
+{
+ assert(0);
+#if 0
+ // Use magic callbacks to start and end transactions w/o opal
+ if (val > 0x10000) // older magic call numbers. Need to be right-shifted.
+ val = val >> 16;
+ int id = -1;
+ int proc_num = SIMICS_current_processor_number();
+ int sim_proc_num = proc_num / RubyConfig::numberofSMTThreads();
+ int thread_num = proc_num % RubyConfig::numberofSMTThreads();
+ int ruby_cycle = g_eventQueue_ptr->getTime();
+
+ if(proc_num < 0){
+ cout << "ERROR proc_num= " << proc_num << endl;
+ }
+ assert(proc_num >= 0);
+ if(thread_num < 0){
+ cout << "ERROR thread_num= " << thread_num << endl;
+ }
+ assert(thread_num >= 0);
+ if( sim_proc_num < 0){
+ cout << "ERROR sim_proc_num = " << sim_proc_num << endl;
+ }
+ assert(sim_proc_num >= 0);
+
+ if (val == 3) {
+ g_system_ptr->getProfiler()->startTransaction(sim_proc_num);
+ } else if (val == 4) {
+ ; // magic breakpoint
+ } else if (val == 5) {
+ g_system_ptr->getProfiler()->endTransaction(sim_proc_num);
+ } else if (val == 6){ // Begin Exposed Action
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "Begin exposed action for thread " << thread_num << " of proc " << proc_num << " PC " << SIMICS_get_program_counter(proc_num) << endl;
+ XACT_MGR->beginEscapeAction(thread_num);
+ } else if (val == 7){ // Begin Exposed Action
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "End exposed action for thread " << thread_num << " of proc " << proc_num << " PC " << SIMICS_get_program_counter(proc_num) << endl;
+ XACT_MGR->endEscapeAction(thread_num);
+ } else if (val == 8) {
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "Set log Base Address for thread " << thread_num << " of proc " << proc_num << endl;
+ XACT_MGR->setLogBase(thread_num);
+ } else if (val == 9) {
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "Setting Handler Address for thread " << thread_num << " of proc " << proc_num << endl;
+ XACT_MGR->setHandlerAddress(thread_num);
+ } else if (val == 10) {
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "Release Isolation for thread " << thread_num << " of proc " << proc_num << endl;
+ XACT_MGR->releaseIsolation(thread_num);
+ } else if (val == 11) {
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "Restart transaction for thread " << thread_num << " of proc " << proc_num << endl;
+ XACT_MGR->restartTransaction(thread_num);
+ } else if (val == 12) {
+ // NOTE: this is a functional magic call for the Java VM
+ // It is used by mfacet.py to check whether to use TM macros or JVM locking
+ return;
+ } else if (val == 13) {
+ // NOTE: this is a debug magic call for the Java VM
+ // Indicates BEGIN XACT
+ return;
+ } else if (val == 14) {
+ // NOTE: this is a debug magic call for the Java VM
+ // Indicates COMMIT_XACT
+ return;
+ } else if (val == 15) {
+ cout << "SIMICS SEG FAULT for thread " << thread_num << " of proc " << proc_num << endl;
+ SIM_break_simulation("SIMICS SEG FAULT");
+ return;
+ } else if (val == 16) {
+ // NOTE : this is a debug magic call for the Java VM
+ // Indicates LOCKING object
+ return;
+ } else if (val == 17) {
+ // NOTE : this is a debug magic call for the Java VM
+ // Indicates UNLOCKING object
+ return;
+ } else if (val == 18) {
+ // NOTE: this is a magic call to enable the xact mem macros in the Java VM
+ // The functionality is implemented in gen-scripts/mfacet.py because it can be independent of Ruby
+ return;
+ } else if (val == 19){
+ cout << "RUBY WATCH: " << endl;
+ g_system_ptr->getProfiler()->rubyWatch(SIMICS_current_processor_number());
+ } else if (val == 20) {
+ //XACT_MGR->setJavaPtrs(thread_num);
+ } else if (val == 21){
+ // NOTE : this is a debug magic call used to dump the registers for a processor
+ // Functionality is implemented in gen-scripts/mfacet.py because it can be independent of Ruby
+ return;
+ } else if (val == 23){
+ // register compensating action
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << proc_num << "," << thread_num << " REGISTER COMPENSATING ACTION " << endl;
+ XACT_MGR->registerCompensatingAction(thread_num);
+ } else if (val == 24){
+ // register commit action
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << proc_num << "," << thread_num << " REGISTER COMMIT ACTION " << endl;
+ XACT_MGR->registerCommitAction(thread_num);
+ } else if (val == 27){
+ // xmalloc
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << proc_num << "," << thread_num << " XMALLOC " << endl;
+ XACT_MGR->xmalloc(thread_num);
+ } else if (val == 29){
+ // Begin Barrier
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << proc_num << "," << thread_num << " BEGIN BARRIER " << endl;
+ g_system_ptr->getXactVisualizer()->moveToBarrier(proc_num);
+ } else if (val == 30){
+ // End Barrier
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << proc_num << "," << thread_num << " END BARRIER " << endl;
+ g_system_ptr->getXactVisualizer()->moveToNonXact(proc_num);
+ } else if (val == 28) {
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "Continue execution for thread " << thread_num << " of proc " << proc_num << endl;
+ XACT_MGR->continueExecution(thread_num);
+ } else if (val == 31){
+ // Begin Timer
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << proc_num << "," << thread_num << " BEGIN TIMER " << endl;
+ g_system_ptr->getProfiler()->getXactProfiler()->profileBeginTimer(proc_num);
+ } else if (val == 32){
+ // End Timer
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << proc_num << "," << thread_num << " END TIMER " << endl;
+ g_system_ptr->getProfiler()->getXactProfiler()->profileEndTimer(proc_num);
+ } else if (val == 40) {
+ // register a thread for virtualization
+ if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
+ SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ simics_interface_ptr->getHypervisor()->registerThreadWithHypervisor(proc_num);
+ }
+ } else if (val == 41) {
+ // get information about the last summary conflict
+ if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
+ Address addr = XACT_MGR->getXactIsolationManager()->getSummaryConflictAddress();
+ unsigned int conflictAddress = addr.getAddress();
+ unsigned int conflictType = XACT_MGR->getXactIsolationManager()->getSummaryConflictType();
+ SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g2"), conflictAddress);
+ SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g3"), conflictType);
+ }
+ } else if (val == 42) {
+ // resolve summary conflict magic callback
+ if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
+ SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ simics_interface_ptr->getHypervisor()->resolveSummarySignatureConflict(proc_num);
+ }
+ } else if (val == 50) {
+ // set summary signature bit
+ int index = SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2"));
+ XACT_MGR->writeBitSummaryWriteSetFilter(thread_num, index, 1);
+ } else if (val == 51) {
+ // unset summary signature bit
+ int index = SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2"));
+ XACT_MGR->writeBitSummaryWriteSetFilter(thread_num, index, 0);
+ } else if (val == 52) {
+ // add address in summary signature
+ Address addr = Address(SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2")));
+ cout << "Add to summary write set filter: " << addr << endl;
+ XACT_MGR->addToSummaryWriteSetFilter(thread_num, addr);
+ } else if (val == 53) {
+ // remove address from summary signature
+ Address addr = Address(SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2")));
+ XACT_MGR->removeFromSummaryWriteSetFilter(thread_num, addr);
+ } else if (val == 54) {
+ // translate address to summary signature index
+ Address addr = Address(SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2")));
+ SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g3"), XACT_MGR->getIndexSummaryFilter(thread_num, addr));
+ } else if (val == 55) {
+ XACT_MGR->setIgnoreWatchpointFlag(thread_num, true);
+ } else if (val == 56) {
+ g_system_ptr->getProfiler()->watchpointsFalsePositiveTrigger();
+ } else if (val == 57) {
+ g_system_ptr->getProfiler()->watchpointsTrueTrigger();
+ } else if (val == 60) {
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2) {
+ cout << "Set restorePC for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
+ }
+ unsigned int pc = SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2"));
+ XACT_MGR->setRestorePC(thread_num, pc);
+ } else if (val == 61) {
+ // get log size
+ SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g2"), XACT_MGR->getXactVersionManager()->getLogSize(thread_num));
+ } else if (val == 62) {
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2){
+ cout << " GET THREAD ID " << thread_num << " of proc " << proc_num << " TID " << XACT_MGR->getTID(thread_num) << endl;
+ }
+ // get thread id
+ SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g2"), XACT_MGR->getTID(thread_num));
+ } else if (val == 100) {
+ dump_registers((void*)cpu);
+ } else if (val >= 1024 && val < 2048) {
+ // begin closed
+ id = val - 1024;
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "Begin CLOSED transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
+ XACT_MGR->beginTransaction(thread_num, id, false);
+ //} else if (val >= min_closed_commit && val < XACT_OPEN_MIN_ID) {
+ } else if (val >= 2048 && val < 3072) {
+ // commit closed
+ id = val - 2048;
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "Commit CLOSED transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
+ XACT_MGR->commitTransaction(thread_num, id, false);
+ } else if (val >= 3072 && val < 4096) {
+ // begin open
+ id = val - 3072;
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "Begin OPEN transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
+ XACT_MGR->beginTransaction(thread_num, id, true);
+ } else if (val >= 4096 && val < 5120) {
+ // commit open
+ id = val - 4096;
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "COMMIT OPEN transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
+ XACT_MGR->commitTransaction(thread_num, id, true);
+ } else if (val >= 5120 && val < 6144){
+
+ cout << " SYSCALL " << val - 5120 << " of proc " << proc_num << " " << thread_num << " time = " << ruby_cycle << endl;
+ } else if (val >= 6144 && val < 7168) {
+ // commit open
+ id = val - 6144;
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
+ cout << "ABORT transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
+ XACT_MGR->abortTransaction(thread_num, id);
+ } else if (val == 8000) {
+ // transaction level
+ if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2) {
+ id = val - 8000;
+ cout << "Transaction Level for thread " << thread_num << " of proc " << proc_num << " XID " << id << " : "
+ << XACT_MGR->getTransactionLevel(thread_num)<< endl;
+ }
+ SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "i0"),(unsigned int) XACT_MGR->getTransactionLevel(thread_num));
+ } else if (val==8001) {
+ cout << " " << g_eventQueue_ptr->getTime() << " " << dec << proc_num << " [" << proc_num << "," << thread_num << " ]"
+ << " TID " << XACT_MGR->getTID(0)
+ << " DEBUGMSG " << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i0")) << " "
+ << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i1")) << " "
+ << "(0x" << hex << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i1")) << ") "
+ << dec << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i2")) << " "
+ << "(0x" << hex << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i2")) << ")" << dec
+ << " break = " << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i3")) << endl;
+ if (SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i3")) == 1) {
+ SIM_break_simulation("DEBUGMSG");
+ }
+ } else {
+ WARN_EXPR(val);
+ WARN_EXPR(SIMICS_get_program_counter(proc_num));
+ WARN_MSG("Unexpected magic call");
+ }
+#endif
+}
+
+/* -- Handle command to change the debugging verbosity for Ruby */
+extern "C"
+void ruby_change_debug_verbosity(char* new_verbosity_str)
+{
+ assert(0);
+ g_debug_ptr->setVerbosityString(new_verbosity_str);
+}
+
+/* -- Handle command to change the debugging filter for Ruby */
+extern "C"
+void ruby_change_debug_filter(char* new_filter_str)
+{
+ assert(0);
+ g_debug_ptr->setFilterString(new_filter_str);
+}
+
+/* -- Handle command to set the debugging output file for Ruby */
+extern "C"
+void ruby_set_debug_output_file (const char * new_filename)
+{
+ assert(0);
+ string filename(new_filename);
+
+ filename += "-";
+ filename += CURRENT_PROTOCOL;
+ // get the date and time to label the debugging file
+ const time_t T = time(NULL);
+ tm *localTime = localtime(&T);
+ char buf[100];
+ strftime(buf, 100, ".%b%d.%Y-%H.%M.%S", localTime);
+
+ filename += buf;
+ filename += ".debug";
+
+ cout << "Dumping debugging output to file '" << filename << "'...";
+ g_debug_ptr->setDebugOutputFile (filename.c_str());
+}
+
+extern "C"
+void ruby_set_debug_start_time(char* start_time_str)
+{
+ assert(0);
+ int startTime = atoi(start_time_str);
+ g_debug_ptr->setDebugTime(startTime);
+}
+
+/* -- Clear stats */
+extern "C"
+void ruby_clear_stats()
+{
+ assert(0);
+ cout << "Clearing stats...";
+ fflush(stdout);
+ g_system_ptr->clearStats();
+ cout << "Done." << endl;
+}
+
+/* -- Dump stats */
+extern "C"
+// File name, dump to file
+void ruby_dump_stats(char* filename)
+{
+ assert(0);
+ /*g_debug_ptr->closeDebugOutputFile();*/
+ if (filename == NULL) {
+ // No output file, dump to screen
+ cout << "Dumping stats to standard output..." << endl;
+ g_system_ptr->printConfig(cout);
+ g_system_ptr->printStats(cout);
+ } else {
+ cout << "Dumping stats to output file '" << filename << "'..." << endl;
+ ofstream m_outputFile;
+ m_outputFile.open(filename);
+ if(m_outputFile == NULL) {
+ cout << "Error: error opening output file '" << filename << "'" << endl;
+ return;
+ }
+ g_system_ptr->printConfig(m_outputFile);
+ g_system_ptr->printStats(m_outputFile);
+ }
+ cout << "Dumping stats completed." << endl;
+}
+
+/* -- Dump stats */
+extern "C"
+// File name, dump to file
+void ruby_dump_short_stats(char* filename)
+{
+ assert(0);
+ g_debug_ptr->closeDebugOutputFile();
+ if (filename == NULL) {
+ // No output file, dump to screen
+ //cout << "Dumping short stats to standard output..." << endl;
+ //g_system_ptr->printConfig(cout);
+ g_system_ptr->getProfiler()->printStats(cout, true);
+ } else {
+ cout << "Dumping stats to output file '" << filename << "'..." << endl;
+ ofstream m_outputFile;
+ m_outputFile.open(filename);
+ if(m_outputFile == NULL) {
+ cout << "Error: error opening output file '" << filename << "'" << endl;
+ return;
+ }
+ g_system_ptr->getProfiler()->printShortStats(m_outputFile);
+ cout << "Dumping stats completed." << endl;
+ }
+}
+
+extern "C"
+void ruby_load_caches(char* name)
+{
+ assert(0);
+ if (name == NULL) {
+ cout << "Error: ruby_load_caches requires a file name" << endl;
+ return;
+ }
+
+ cout << "Reading cache contents from '" << name << "'...";
+ /* gem5:Binkert for decomissiong of tracer
+ int read = Tracer::playbackTrace(name);
+ cout << "done. (" << read << " cache lines read)" << endl;
+ */
+ cout << "done. (TRACER DISABLED!)" << endl;
+ ruby_clear_stats();
+}
+
+extern "C"
+void ruby_save_caches(char* name)
+{
+ assert(0);
+ if (name == NULL) {
+ cout << "Error: ruby_save_caches requires a file name" << endl;
+ return;
+ }
+
+ cout << "Writing cache contents to '" << name << "'...";
+ CacheRecorder recorder;
+ g_system_ptr->recordCacheContents(recorder);
+ int written = recorder.dumpRecords(name);
+ cout << "done. (" << written << " cache lines written)" << endl;
+}
+
+extern "C"
+void ruby_set_tracer_output_file (const char * new_filename)
+{
+ assert(0);
+ //g_system_ptr->getTracer()->startTrace(string(new_filename));
+}
+
+/* -- Handle command to set the xact visualizer file for Ruby */
+extern "C"
+void ruby_xact_visualizer_file (char * new_filename)
+{
+ cout << "Dumping xact visualizer output to file '" << new_filename << "'...";
+ // g_system_ptr->getProfiler()->setXactVisualizerFile (new_filename);
+}
+
+extern "C"
+void ctrl_exception_start(void* desc, void* cpu, integer_t val)
+{
+#if 0
+ int proc_no = SIM_get_proc_no((void*) cpu);
+ void* cpu_obj = (void*) cpu;
+ uinteger_t trap_level = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tl"));
+
+ if (!XACT_MEMORY) return;
+ TransactionInterfaceManager *xact_mgr = XACT_MGR;
+
+ // level {10,14} interrupt
+ //
+ if (val == 0x4a || val == 0x4e) {
+ int rn_tick = SIM_get_register_number(cpu_obj, "tick");
+ uinteger_t tick = SIM_read_register(cpu_obj, rn_tick);
+ int rn_tick_cmpr = SIM_get_register_number(cpu_obj, "tick_cmpr");
+ uinteger_t tick_cmpr = SIM_read_register(cpu_obj, rn_tick_cmpr);
+ int rn_stick = SIM_get_register_number(cpu_obj, "stick");
+ uinteger_t stick = SIM_read_register(cpu_obj, rn_stick);
+ int rn_stick_cmpr = SIM_get_register_number(cpu_obj, "stick_cmpr");
+ uinteger_t stick_cmpr = SIM_read_register(cpu_obj, rn_stick_cmpr);
+ int rn_pc = SIM_get_register_number(cpu_obj, "pc");
+ uinteger_t pc = SIM_read_register(cpu_obj, rn_pc);
+ int rn_npc = SIM_get_register_number(cpu_obj, "npc");
+ uinteger_t npc = SIM_read_register(cpu_obj, rn_npc);
+ int rn_pstate = SIM_get_register_number(cpu_obj, "pstate");
+ uinteger_t pstate = SIM_read_register(cpu_obj, rn_pstate);
+ int rn_pil = SIM_get_register_number(cpu_obj, "pil");
+ int pil = SIM_read_register(cpu_obj, rn_pil);
+ g_system_ptr->getProfiler()->profileTimerInterrupt(proc_no,
+ tick, tick_cmpr,
+ stick, stick_cmpr,
+ trap_level,
+ pc, npc,
+ pstate, pil);
+ }
+
+ int smt_thread_num = proc_no % RubyConfig::numberofSMTThreads();
+ // The simulated processor number
+ int sim_proc_no = proc_no / RubyConfig::numberofSMTThreads();
+
+ uinteger_t pc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "pc"));
+ uinteger_t npc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "npc"));
+
+ g_system_ptr->getProfiler()->profileExceptionStart(xact_mgr->getTransactionLevel(smt_thread_num) > 0, sim_proc_no, smt_thread_num, val, trap_level, pc, npc);
+
+ if((val >= 0x80 && val <= 0x9f) || (val >= 0xc0 && val <= 0xdf)){
+ //xact_mgr->setLoggedException(smt_thread_num);
+ }
+ // CORNER CASE - You take an exception while stalling for a commit token
+ if (XACT_LAZY_VM && !XACT_EAGER_CD){
+ if (g_system_ptr->getXactCommitArbiter()->getTokenOwner() == proc_no)
+ g_system_ptr->getXactCommitArbiter()->releaseCommitToken(proc_no);
+ }
+#endif
+ assert(0);
+}
+
+extern "C"
+void ctrl_exception_done(void* desc, void* cpu, integer_t val)
+{
+ assert(0);
+#if 0
+ int proc_no = SIM_get_proc_no((void*) cpu);
+ void* cpu_obj = (void*) cpu;
+ uinteger_t trap_level = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tl"));
+ uinteger_t pc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "pc"));
+ uinteger_t npc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "npc"));
+ uinteger_t tpc = 0;
+ uinteger_t tnpc = 0;
+ //get the return PC,NPC pair based on the trap level
+ ASSERT(1 <= trap_level && trap_level <= 5);
+ if(trap_level == 1){
+ tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc1"));
+ tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc1"));
+ }
+ if(trap_level == 2){
+ tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc2"));
+ tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc2"));
+ }
+ if(trap_level == 3){
+ tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc3"));
+ tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc3"));
+ }
+ if(trap_level == 4){
+ tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc4"));
+ tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc4"));
+ }
+ if(trap_level == 5){
+ tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc5"));
+ tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc5"));
+ }
+
+ if (!XACT_MEMORY) return;
+ TransactionInterfaceManager *xact_mgr = XACT_MGR;
+
+ int smt_thread_num = proc_no % RubyConfig::numberofSMTThreads();
+ // The simulated processor number
+ int sim_proc_no = proc_no / RubyConfig::numberofSMTThreads();
+
+ if (proc_no != SIMICS_current_processor_number()){
+ WARN_EXPR(proc_no);
+ WARN_EXPR(SIMICS_current_processor_number());
+ WARN_MSG("Callback for a different processor");
+ }
+
+ g_system_ptr->getProfiler()->profileExceptionDone(xact_mgr->getTransactionLevel(smt_thread_num) > 0, sim_proc_no, smt_thread_num, val, trap_level, pc, npc, tpc, tnpc);
+
+ if((val >= 0x80 && val <= 0x9f) || (val >= 0xc0 && val <= 0xdf)){
+ //xact_mgr->clearLoggedException(smt_thread_num);
+ }
+
+ if ((val == 0x122) && xact_mgr->shouldTrap(smt_thread_num)){
+ // use software handler
+ if (xact_mgr->shouldUseHardwareAbort(smt_thread_num)){
+ xact_mgr->hardwareAbort(smt_thread_num);
+ } else {
+ xact_mgr->trapToHandler(smt_thread_num);
+ }
+ }
+#endif
+}
+
+extern "C"
+void change_mode_callback(void* desc, void* cpu, integer_t old_mode, integer_t new_mode)
+{
+ assert(0);
+#if 0
+ if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
+ SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ simics_interface_ptr->getHypervisor()->change_mode_callback(desc, cpu, old_mode, new_mode);
+ }
+#endif
+}
+
+extern "C"
+void dtlb_map_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg){
+ assert(0);
+#if 0
+ if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
+ SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ simics_interface_ptr->getHypervisor()->dtlb_map_callback(desc, chmmu, tag_reg, data_reg);
+ }
+#endif
+}
+
+extern "C"
+void dtlb_demap_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg){
+ assert(0);
+#if 0
+ if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
+ SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ simics_interface_ptr->getHypervisor()->dtlb_demap_callback(desc, chmmu, tag_reg, data_reg);
+ }
+#endif
+}
+
+extern "C"
+void dtlb_replace_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg){
+ assert(0);
+#if 0
+ if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
+ SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ simics_interface_ptr->getHypervisor()->dtlb_replace_callback(desc, chmmu, tag_reg, data_reg);
+ }
+#endif
+}
+
+extern "C"
+void dtlb_overwrite_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg){
+ assert(0);
+#if 0
+ if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
+ SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ simics_interface_ptr->getHypervisor()->dtlb_overwrite_callback(desc, chmmu, tag_reg, data_reg);
+ }
+#endif
+}
+
+extern "C"
+void core_control_register_write_callback(void* desc, void* cpu, integer_t register_number, integer_t value) {
+ assert(0);
+#if 0
+ int proc_no = SIM_get_proc_no((void*) cpu);
+ void* cpu_obj = (void*) cpu;
+#endif
+}
+
+integer_t
+read_reg(void *cpu, const char* reg_name)
+{
+ assert(0);
+#if 0
+ int reg_num = SIM_get_register_number(SIM_current_processor(), reg_name);
+ if (SIM_clear_exception()) {
+ fprintf(stderr, "read_reg: SIM_get_register_number(%s, %s) failed!\n",
+ cpu->name, reg_name);
+ assert(0);
+ }
+ integer_t val = SIM_read_register(cpu, reg_num);
+ if (SIM_clear_exception()) {
+ fprintf(stderr, "read_reg: SIM_read_register(%s, %d) failed!\n",
+ cpu->name, reg_num);
+ assert(0);
+ }
+ return val;
+#endif
+ return 0;
+}
+
+extern "C"
+void dump_registers(void *cpu)
+{
+ assert(0);
+#if 0
+ const char* reg_names[] = {
+ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
+ "ccr", "pc", "npc"
+ };
+
+ printf("Registers for %s\n", cpu->name);
+ printf("------------------\n");
+
+ for (int i = 0; i < (sizeof(reg_names) / sizeof(char*)); i++) {
+ const char* reg_name = reg_names[i];
+ printf(" %3s: 0x%016llx\n", reg_name, read_reg(cpu, reg_name));
+ if (i % 8 == 7) {
+ printf("\n");
+ }
+ }
+
+ int myID = SIMICS_get_proc_no(cpu);
+ Address myPC = SIMICS_get_program_counter(myID);
+ physical_address_t myPhysPC = SIMICS_translate_address(myID, myPC);
+ integer_t myInst = SIMICS_read_physical_memory(myID, myPhysPC, 4);
+ const char *myInstStr = SIMICS_disassemble_physical(myID, myPhysPC);
+ printf("\n *pc: 0x%llx: %s\n", myInst, myInstStr);
+
+ printf("\n\n");
+#endif
+}
diff --git a/src/mem/ruby/simics/commands.hh b/src/mem/ruby/simics/commands.hh
new file mode 100644
index 000000000..e7593c2c3
--- /dev/null
+++ b/src/mem/ruby/simics/commands.hh
@@ -0,0 +1,106 @@
+
+/*
+ * Copyright (c) 1999-2008 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
+
+ ----------------------------------------------------------------------
+*/
+
+/*
+ * $Id$
+ *
+ * Description:
+ *
+ */
+
+#ifndef COMMANDS_H
+#define COMMANDS_H
+
+#ifdef SPARC
+ #define MEMORY_TRANSACTION_TYPE void
+#else
+ #define MEMORY_TRANSACTION_TYPE void
+#endif
+
+int mh_memorytracer_possible_cache_miss(MEMORY_TRANSACTION_TYPE *mem_trans);
+void mh_memorytracer_observe_memory(MEMORY_TRANSACTION_TYPE *mem_trans);
+
+void magic_instruction_callback(void* desc, void * cpu, integer_t val);
+
+void ruby_change_debug_verbosity(char* new_verbosity_str);
+void ruby_change_debug_filter(char* new_filter_str);
+void ruby_set_debug_output_file (const char * new_filename);
+void ruby_set_debug_start_time(char* start_time_str);
+
+void ruby_clear_stats();
+void ruby_dump_stats(char* tag);
+void ruby_dump_short_stats(char* tag);
+
+void ruby_set_periodic_stats_file(char* filename);
+void ruby_set_periodic_stats_interval(int interval);
+
+void ruby_load_caches(char* name);
+void ruby_save_caches(char* name);
+
+void ruby_dump_cache(int cpuNumber);
+void ruby_dump_cache_data(int cpuNumber, char *tag);
+
+void ruby_set_tracer_output_file (const char * new_filename);
+void ruby_xact_visualizer_file (char * new_filename);
+
+void ctrl_exception_start(void* desc, void* cpu, integer_t val);
+void ctrl_exception_done(void* desc, void* cpu, integer_t val);
+
+void change_mode_callback(void* desc, void* cpu, integer_t old_mode, integer_t new_mode);
+void dtlb_map_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg);
+void dtlb_demap_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg);
+void dtlb_replace_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg);
+void dtlb_overwrite_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg);
+
+integer_t read_reg(void *cpu, const char* reg_name);
+void dump_registers(void *cpu);
+
+// Needed so that the ruby module will compile, but functions are
+// implemented in Rock.C.
+//
+void rock_exception_start(void* desc, void* cpu, integer_t val);
+void rock_exception_done(void* desc, void* cpu, integer_t val);
+
+#endif //COMMANDS_H
diff --git a/src/mem/ruby/simics/interface.cc b/src/mem/ruby/simics/interface.cc
new file mode 100644
index 000000000..92c30c23e
--- /dev/null
+++ b/src/mem/ruby/simics/interface.cc
@@ -0,0 +1,935 @@
+
+/*
+ * Copyright (c) 1999-2008 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.
+ */
+
+/*
+ * $Id: interface.C 1.39 05/01/19 13:12:31-06:00 mikem@maya.cs.wisc.edu $
+ *
+ */
+
+#include "Global.hh"
+#include "System.hh"
+#include "OpalInterface.hh"
+#include "EventQueue.hh"
+#include "mf_api.hh"
+#include "interface.hh"
+#include "Sequencer.hh"
+// #include "TransactionInterfaceManager.hh"
+
+#ifdef CONTIGUOUS_ADDRESSES
+#include "ContiguousAddressTranslator.hh"
+
+/* Also used in init.C, commands.C */
+ContiguousAddressTranslator * g_p_ca_translator = NULL;
+
+#endif // #ifdef CONTIGUOUS_ADDRESSES
+
+//////////////////////// Local helper functions //////////////////////
+
+// Callback when exception occur
+static void core_exception_callback(void *data, void *cpu,
+ integer_t exc)
+{
+ // SimicsDriver *simics_intf = dynamic_cast<SimicsDriver*>(g_system_ptr->getDriver());
+ // ASSERT( simics_intf );
+ // simics_intf->exceptionCallback(cpu, exc);
+ assert(0);
+}
+
+#ifdef SPARC
+// Callback when asi accesses occur
+// static exception_type_t core_asi_callback(void * cpu, generic_transaction_t *g)
+// {
+// SimicsDriver *simics_intf = dynamic_cast<SimicsDriver*>(g_system_ptr->getDriver());
+// assert( simics_intf );
+// return simics_intf->asiCallback(cpu, g);
+// }
+#endif
+
+static void runRubyEventQueue(void* obj, void* arg)
+{
+ Time time = g_eventQueue_ptr->getTime() + 1;
+ DEBUG_EXPR(NODE_COMP, HighPrio, time);
+ g_eventQueue_ptr->triggerEvents(time);
+// void* obj_ptr = (void*) SIM_proc_no_2_ptr(0); // Maurice
+// SIM_time_post_cycle(obj_ptr, SIMICS_RUBY_MULTIPLIER, Sim_Sync_Processor, &runRubyEventQueue, NULL); // Maurice
+ assert(0);
+}
+
+//////////////////////// Simics API functions //////////////////////
+
+int SIMICS_number_processors()
+{
+// return SIM_number_processors(); // Maurice
+ assert(0);
+ return 0;
+}
+
+void SIMICS_wakeup_ruby()
+{
+// void* obj_ptr = (void*) SIM_proc_no_2_ptr(0); // Maurice
+// SIM_time_post_cycle(obj_ptr, SIMICS_RUBY_MULTIPLIER, Sim_Sync_Processor, &runRubyEventQueue, NULL); // Maurice
+ assert(0);
+}
+
+// an analogue to wakeup ruby, this function ends the callbacks ruby normally
+// recieves from simics. (it removes ruby from simics's event queue). This
+// function should only be called when opal is installed. Opal advances ruby's
+// event queue independently of simics.
+void SIMICS_remove_ruby_callback( void )
+{
+// void* obj_ptr = (void*) SIM_proc_no_2_ptr(0); // Maurice
+// SIM_time_clean( obj_ptr, Sim_Sync_Processor, &runRubyEventQueue, NULL); // Maurice
+ assert(0);
+}
+
+// Install ruby as the timing model (analogous code exists in ruby/ruby.c)
+void SIMICS_install_timing_model( void )
+{
+// // void *phys_mem0 = SIM_get_object("phys_mem0"); // Maurice
+// attr_value_t val;
+// // val.kind = Sim_Val_String; // Maurice
+// val.u.string = "ruby0";
+// set_error_t install_error;
+//
+// if(phys_mem0==NULL) {
+// /* Look for "phys_mem" instead */
+// // SIM_clear_exception(); // Maurice
+// // phys_mem0 = SIM_get_object("phys_mem"); // Maurice
+// }
+//
+// if(phys_mem0==NULL) {
+// /* Okay, now panic... can't install ruby without a physical memory object */
+// WARN_MSG( "Cannot Install Ruby... no phys_mem0 or phys_mem object found" );
+// WARN_MSG( "Ruby is NOT installed." );
+// // SIM_clear_exception(); // Maurice
+// return;
+// }
+//
+// // install_error = SIM_set_attribute(phys_mem0, "timing_model", &val); // Maurice
+//
+// // if (install_error == Sim_Set_Ok) { // Maurice
+// WARN_MSG( "successful installation of the ruby timing model" );
+// } else {
+// WARN_MSG( "error installing ruby timing model" );
+// // WARN_MSG( SIM_last_error() ); // Maurice
+// }
+
+ assert(0);
+}
+
+// Removes ruby as the timing model interface
+void SIMICS_remove_timing_model( void )
+{
+// void *phys_mem0 = SIM_get_object("phys_mem0"); // Maurice
+// attr_value_t val;
+// memset( &val, 0, sizeof(attr_value_t) );
+// // val.kind = Sim_Val_Nil; // Maurice
+//
+// if(phys_mem0==NULL) {
+// /* Look for "phys_mem" instead */
+// // SIM_clear_exception(); // Maurice
+// // phys_mem0 = SIM_get_object("phys_mem"); // Maurice
+// }
+//
+// if(phys_mem0==NULL) {
+// /* Okay, now panic... can't uninstall ruby without a physical memory object */
+// WARN_MSG( "Cannot Uninstall Ruby... no phys_mem0 or phys_mem object found" );
+// WARN_MSG( "Uninstall NOT performed." );
+// // SIM_clear_exception(); // Maurice
+// return;
+// }
+//
+// // SIM_set_attribute(phys_mem0, "timing_model", &val); // Maurice
+ assert(0);
+}
+
+// Installs the (SimicsDriver) function to recieve the exeception callback
+void SIMICS_install_exception_callback( void )
+{
+ // install exception callback
+ // s_exception_hap_handle =
+// SIM_hap_add_callback("Core_Exception", // Maurice
+ // (obj_hap_func_t)core_exception_callback, NULL );
+ assert(0);
+}
+
+// removes the exception callback
+void SIMICS_remove_exception_callback( void )
+{
+ // uninstall exception callback
+// SIM_hap_delete_callback_id( "Core_Exception", // Maurice
+ // s_exception_hap_handle );
+ assert(0);
+}
+
+#ifdef SPARC
+// Installs the (SimicsDriver) function to recieve the asi callback
+void SIMICS_install_asi_callback( void )
+{
+// for(int i = 0; i < SIM_number_processors(); i++) { // Maurice
+ // sparc_v9_interface_t *v9_interface = (sparc_v9_interface_t *)
+// SIM_get_interface(SIM_proc_no_2_ptr(i), SPARC_V9_INTERFACE); // Maurice
+
+ // init asi callbacks, 16bit ASI
+ // for(int j = 0; j < MAX_ADDRESS_SPACE_ID; j++) {
+ // v9_interface->install_user_asi_handler(core_asi_callback, j);
+ // }
+ // }
+ assert(0);
+}
+
+// removes the asi callback
+void SIMICS_remove_asi_callback( void )
+{
+// for(int i = 0; i < SIM_number_processors(); i++) { // Maurice
+// sparc_v9_interface_t *v9_interface = (sparc_v9_interface_t *)
+// SIM_get_interface(SIM_proc_no_2_ptr(i), SPARC_V9_INTERFACE); // Maurice
+
+ // disable asi callback
+ // for(int j = 0; j < MAX_ADDRESS_SPACE_ID; j++) {
+ // v9_interface->remove_user_asi_handler(core_asi_callback, j);
+ // }
+ // }
+ assert(0);
+}
+#endif
+
+// Query simics for the presence of the opal object.
+// returns its interface if found, NULL otherwise
+mf_opal_api_t *SIMICS_get_opal_interface( void )
+{
+// void *opal = SIM_get_object("opal0"); // Maurice
+ //if (opal != NULL) {
+// mf_opal_api_t *opal_intf = (mf_opal_api_t *) SIM_get_interface( opal, "mf-opal-api" ); // Maurice
+ // if ( opal_intf != NULL ) {
+ // return opal_intf;
+// } else {
+// WARN_MSG("error: OpalInterface: opal does not implement mf-opal-api interface.\n");
+// return NULL;
+// }
+// }
+// SIM_clear_exception(); // Maurice
+ assert(0);
+ return NULL;
+}
+
+void * SIMICS_current_processor(){
+// return SIM_current_processor(); // Maurice
+ assert(0);
+ return NULL;
+}
+
+int SIMICS_current_processor_number()
+{
+// return (SIM_get_proc_no((processor_t *) SIM_current_processor())); // Maurice
+ assert(0);
+ return 0;
+}
+
+integer_t SIMICS_get_insn_count(int cpuNumber)
+{
+ // NOTE: we already pass in the logical cpuNumber (ie Simics simulated cpu number)
+ int num_smt_threads = RubyConfig::numberofSMTThreads();
+ integer_t total_insn = 0;
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// total_insn += SIM_step_count((void*) cpu); // Maurice
+ assert(0);
+ return total_insn;
+}
+
+integer_t SIMICS_get_cycle_count(int cpuNumber)
+{
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// integer_t result = SIM_cycle_count((void*) cpu); // Maurice
+ assert(0);
+ return 0;
+}
+
+void SIMICS_unstall_proc(int cpuNumber)
+{
+// void* proc_ptr = (void *) SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// SIM_stall_cycle(proc_ptr, 0); // Maurice
+ assert(0);
+}
+
+void SIMICS_unstall_proc(int cpuNumber, int cycles)
+{
+// void* proc_ptr = (void *) SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// SIM_stall_cycle(proc_ptr, cycles); // Maurice
+ assert(0);
+}
+
+void SIMICS_stall_proc(int cpuNumber, int cycles)
+{
+// void* proc_ptr = (void*) SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// if (SIM_stalled_until(proc_ptr) != 0){ // Maurice
+// cout << cpuNumber << " Trying to stall. Stall Count currently at " << SIM_stalled_until(proc_ptr) << endl; // Maurice
+// }
+// SIM_stall_cycle(proc_ptr, cycles); // Maurice
+ assert(0);
+}
+
+void SIMICS_post_stall_proc(int cpuNumber, int cycles)
+{
+// void* proc_ptr = (void*) SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// SIM_stacked_post(proc_ptr, ruby_stall_proc, (void *) cycles); // Maurice
+ assert(0);
+}
+
+integer_t SIMICS_read_physical_memory( int procID, physical_address_t address,
+ int len )
+{
+// // SIM_clear_exception(); // Maurice
+// ASSERT( len <= 8 );
+// #ifdef CONTIGUOUS_ADDRESSES
+// if(g_p_ca_translator != NULL) {
+// address = g_p_ca_translator->TranslateRubyToSimics( address );
+// }
+// #endif // #ifdef CONTIGUOUS_ADDRESSES
+// // integer_t result = SIM_read_phys_memory( SIM_proc_no_2_ptr(procID), // Maurice
+// // // address, len );
+// //
+// // // int isexcept = SIM_get_pending_exception(); // Maurice
+// // if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
+// // // sim_exception_t except_code = SIM_clear_exception(); // Maurice
+// // WARN_MSG( "SIMICS_read_physical_memory: raised exception." );
+// // // WARN_MSG( SIM_last_error() ); // Maurice
+// // WARN_MSG( Address(address) );
+// // WARN_MSG( procID );
+// // ASSERT(0);
+// // }
+// // return ( result );
+ assert(0);
+ return 0;
+}
+//
+// /*
+// * Read data into a buffer and assume the buffer is already allocated
+// */
+void SIMICS_read_physical_memory_buffer(int procID, physical_address_t addr,
+ char* buffer, int len ) {
+// // // processor_t* obj = SIM_proc_no_2_ptr(procID); // Maurice
+// //
+// // assert( obj != NULL);
+// // assert( buffer != NULL );
+// //
+// // #ifdef CONTIGUOUS_ADDRESSES
+// // if(g_p_ca_translator != NULL) {
+// // addr = g_p_ca_translator->TranslateRubyToSimics( addr );
+// // }
+// // #endif // #ifdef CONTIGUOUS_ADDRESSES
+// //
+// // int buffer_pos = 0;
+// // physical_address_t start = addr;
+// // do {
+// // int size = (len < 8)? len:8;
+// // // integer_t result = SIM_read_phys_memory( obj, start, size ); // Maurice
+// // // int isexcept = SIM_get_pending_exception(); // Maurice
+// // if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
+// // // sim_exception_t except_code = SIM_clear_exception(); // Maurice
+// // WARN_MSG( "SIMICS_read_physical_memory_buffer: raised exception." );
+// // // WARN_MSG( SIM_last_error() ); // Maurice
+// // WARN_MSG( addr );
+// // WARN_MSG( procID );
+// // ASSERT( 0 );
+// // }
+// //
+// // #ifdef SPARC
+// // // assume big endian (i.e. SPARC V9 target)
+// // for(int i = size-1; i >= 0; i--) {
+// // #else
+// // // assume little endian (i.e. x86 target)
+// // for(int i = 0; i<size; i++) {
+// // #endif
+// // buffer[buffer_pos++] = (char) ((result>>(i<<3))&0xff);
+// // }
+// //
+// // len -= size;
+// // start += size;
+// // } while(len != 0);
+ assert(0);
+}
+//
+void SIMICS_write_physical_memory( int procID, physical_address_t address,
+ integer_t value, int len )
+ {
+// // ASSERT( len <= 8 );
+// //
+// // // SIM_clear_exception(); // Maurice
+// //
+// // // processor_t* obj = SIM_proc_no_2_ptr(procID); // Maurice
+// //
+// // #ifdef CONTIGUOUS_ADDRESSES
+// // if(g_p_ca_translator != NULL) {
+// // address = g_p_ca_translator->TranslateRubyToSimics( address );
+// // }
+// // #endif // #ifdef CONTIGUOUS_ADDRESSES
+// //
+// // // int isexcept = SIM_get_pending_exception(); // Maurice
+// // if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
+// // // sim_exception_t except_code = SIM_clear_exception(); // Maurice
+// // WARN_MSG( "SIMICS_write_physical_memory 1: raised exception." );
+// // // WARN_MSG( SIM_last_error() ); // Maurice
+// // WARN_MSG( address );
+// // }
+// //
+// // // SIM_write_phys_memory(obj, address, value, len ); // Maurice
+// //
+// // // isexcept = SIM_get_pending_exception(); // Maurice
+// // if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
+// // // sim_exception_t except_code = SIM_clear_exception(); // Maurice
+// // WARN_MSG( "SIMICS_write_physical_memory 2: raised exception." );
+// // // WARN_MSG( SIM_last_error() ); // Maurice
+// // WARN_MSG( address );
+// // }
+ assert(0);
+}
+//
+// /*
+// * write data to simics memory from a buffer (assumes the buffer is valid)
+// */
+void SIMICS_write_physical_memory_buffer(int procID, physical_address_t addr,
+ char* buffer, int len ) {
+// // processor_t* obj = SIM_proc_no_2_ptr(procID); // Maurice
+//
+// assert( obj != NULL);
+// assert( buffer != NULL );
+//
+// #ifdef CONTIGUOUS_ADDRESSES
+// if(g_p_ca_translator != NULL) {
+// addr = g_p_ca_translator->TranslateRubyToSimics( addr );
+// }
+// #endif // #ifdef CONTIGUOUS_ADDRESSES
+//
+// int buffer_pos = 0;
+// physical_address_t start = addr;
+// do {
+// int size = (len < 8)? len:8;
+// // //integer_t result = SIM_read_phys_memory( obj, start, size ); // Maurice
+// integer_t value = 0;
+// #ifdef SPARC
+// // assume big endian (i.e. SPARC V9 target)
+// for(int i = size-1; i >= 0; i--) {
+// #else
+// // assume little endian (i.e. x86 target)
+// for(int i = 0; i<size; i++) {
+// #endif
+// integer_t mask = buffer[buffer_pos++];
+// value |= ((mask)<<(i<<3));
+// }
+//
+//
+// // SIM_write_phys_memory( obj, start, value, size); // Maurice
+// // int isexcept = SIM_get_pending_exception(); // Maurice
+// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
+// // sim_exception_t except_code = SIM_clear_exception(); // Maurice
+// WARN_MSG( "SIMICS_write_physical_memory_buffer: raised exception." );
+// // WARN_MSG( SIM_last_error() ); // Maurice
+// WARN_MSG( addr );
+// }
+//
+// len -= size;
+// start += size;
+// } while(len != 0);
+ assert(0);
+}
+
+bool SIMICS_check_memory_value(int procID, physical_address_t addr,
+ char* buffer, int len) {
+ char buf[len];
+ SIMICS_read_physical_memory_buffer(procID, addr, buf, len);
+ assert(0);
+ return (memcmp(buffer, buf, len) == 0)? true:false;
+}
+
+physical_address_t SIMICS_translate_address( int procID, Address address ) {
+// SIM_clear_exception(); // Maurice
+// physical_address_t physical_addr = SIM_logical_to_physical(SIM_proc_no_2_ptr(procID), Sim_DI_Instruction, address.getAddress() ); // Maurice
+// int isexcept = SIM_get_pending_exception(); // Maurice
+// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
+// sim_exception_t except_code = SIM_clear_exception(); // Maurice
+// /*
+// WARN_MSG( "SIMICS_translate_address: raised exception." );
+// WARN_MSG( procID );
+// WARN_MSG( address );
+// // WARN_MSG( SIM_last_error() ); // Maurice
+// */
+// return 0;
+// }
+//
+// #ifdef CONTIGUOUS_ADDRESSES
+// if(g_p_ca_translator != NULL) {
+// physical_addr = g_p_ca_translator->TranslateSimicsToRuby( physical_addr );
+// }
+// #endif // #ifdef CONTIGUOUS_ADDRESSES
+//
+// return physical_addr;
+ assert(0);
+ return 0;
+}
+
+physical_address_t SIMICS_translate_data_address( int procID, Address address ) {
+// SIM_clear_exception(); // Maurice
+// physical_address_t physical_addr = SIM_logical_to_physical(SIM_proc_no_2_ptr(procID), Sim_DI_Data, address.getAddress() ); // Maurice
+// int isexcept = SIM_get_pending_exception(); // Maurice
+// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
+// sim_exception_t except_code = SIM_clear_exception(); // Maurice
+ /*
+ WARN_MSG( "SIMICS_translate_data_address: raised exception." );
+ WARN_MSG( procID );
+ WARN_MSG( address );
+// WARN_MSG( SIM_last_error() ); // Maurice
+ */
+// }
+// return physical_addr;
+ assert(0);
+ return 0;
+}
+
+#ifdef SPARC
+bool SIMICS_is_ldda(const memory_transaction_t *mem_trans) {
+// void *cpu = mem_trans->s.ini_ptr;
+// int proc= SIMICS_get_proc_no(cpu);
+// Address addr = SIMICS_get_program_counter(cpu);
+// physical_address_t phys_addr = SIMICS_translate_address( proc, addr );
+// uint32 instr= SIMICS_read_physical_memory( proc, phys_addr, 4 );
+//
+// // determine if this is a "ldda" instruction (non-exclusive atomic)
+// // ldda bit mask: 1100 0001 1111 1000 == 0xc1f80000
+// // ldda match : 1100 0000 1001 1000 == 0xc0980000
+// if ( (instr & 0xc1f80000) == 0xc0980000 ) {
+// // should exactly be ldda instructions
+// ASSERT(!strncmp(SIMICS_disassemble_physical(proc, phys_addr), "ldda", 4));
+// //cout << "SIMICS_is_ldda END" << endl;
+// return true;
+// }
+// return false;
+ assert(0);
+ return false;
+}
+#endif
+
+const char *SIMICS_disassemble_physical( int procID, physical_address_t pa ) {
+//#ifdef CONTIGUOUS_ADDRESSES
+// if(g_p_ca_translator != NULL) {
+// pa = g_p_ca_translator->TranslateRubyToSimics( pa );
+// }
+//#endif // #ifdef CONTIGUOUS_ADDRESSES
+// return SIM_disassemble( SIM_proc_no_2_ptr(procID), pa , /* physical */ 0)->string; // Maurice
+ assert(0);
+ return "There is no spoon";
+}
+
+Address SIMICS_get_program_counter(void *cpu) {
+ assert(cpu != NULL);
+// return Address(SIM_get_program_counter((processor_t *) cpu)); // Maurice
+ assert(0);
+ return Address(0);
+}
+
+Address SIMICS_get_npc(int procID) {
+// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
+// return Address(SIM_read_register(cpu, SIM_get_register_number(cpu, "npc"))); // Maurice
+ assert(0);
+ return Address(0);
+}
+
+Address SIMICS_get_program_counter(int procID) {
+// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
+// assert(cpu != NULL);
+
+// Address addr = Address(SIM_get_program_counter(cpu)); // Maurice
+ assert(0);
+ return Address(0);
+}
+
+// /* NOTE: SIM_set_program_counter sets NPC to PC+4 */ // Maurice
+void SIMICS_set_program_counter(int procID, Address newPC) {
+// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
+// assert(cpu != NULL);
+
+// SIM_stacked_post(cpu, ruby_set_program_counter, (void*) newPC.getAddress()); // Maurice
+ assert(0);
+}
+
+void SIMICS_set_pc(int procID, Address newPC) {
+ // IMPORTANT: procID is the SIMICS simulated proc number (takes into account SMT)
+// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
+// assert(cpu != NULL);
+//
+// if(OpalInterface::isOpalLoaded() == false){
+// // SIM_set_program_counter(cpu, newPC.getAddress()); // Maurice
+// } else {
+// // explicitly change PC
+// ruby_set_pc( cpu, (void *) newPC.getAddress() );
+// }
+// // int isexcept = SIM_get_pending_exception(); // Maurice
+// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
+// // sim_exception_t except_code = SIM_clear_exception(); // Maurice
+// WARN_MSG( "SIMICS_set_pc: raised exception." );
+// // WARN_MSG( SIM_last_error() ); // Maurice
+// ASSERT(0);
+// }
+ assert(0);
+}
+
+void SIMICS_set_next_program_counter(int procID, Address newNPC) {
+// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
+// assert(cpu != NULL);
+
+// SIM_stacked_post(cpu, ruby_set_npc, (void*) newNPC.getAddress()); // Maurice
+ assert(0);
+}
+
+void SIMICS_set_npc(int procID, Address newNPC) {
+// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
+// assert(cpu != NULL);
+//
+// if(OpalInterface::isOpalLoaded() == false){
+// // SIM_write_register(cpu, SIM_get_register_number(cpu, "npc"), newNPC.getAddress()); // Maurice
+// } else {
+// // explicitly change NPC
+// ruby_set_npc( cpu, (void *) newNPC.getAddress() );
+// }
+//
+// // int isexcept = SIM_get_pending_exception(); // Maurice
+// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
+// // sim_exception_t except_code = SIM_clear_exception(); // Maurice
+// WARN_MSG( "SIMICS_set_npc: raised exception " );
+// // WARN_MSG( SIM_last_error() ); // Maurice
+// ASSERT(0);
+// }
+ assert(0);
+}
+
+void SIMICS_post_continue_execution(int procID){
+// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
+// assert(cpu != NULL);
+//
+// if(OpalInterface::isOpalLoaded() == false){
+// // SIM_stacked_post(cpu, ruby_continue_execution, (void *) NULL); // Maurice
+// } else{
+// ruby_continue_execution( cpu, (void *) NULL );
+// }
+ assert(0);
+}
+
+void SIMICS_post_restart_transaction(int procID){
+// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
+// assert(cpu != NULL);
+//
+// if(OpalInterface::isOpalLoaded() == false){
+// // SIM_stacked_post(cpu, ruby_restart_transaction, (void *) NULL); // Maurice
+// } else{
+// ruby_restart_transaction( cpu, (void *) NULL );
+// }
+ assert(0);
+}
+
+// return -1 when fail
+int SIMICS_get_proc_no(void *cpu) {
+// int proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
+// return proc_no;
+ assert(0);
+ return -1;
+}
+
+void SIMICS_disable_processor( int cpuNumber ) {
+// if(SIM_cpu_enabled(SIMICS_get_proc_ptr(cpuNumber))) { // Maurice
+// SIM_disable_processor(SIMICS_get_proc_ptr(cpuNumber)); // Maurice
+// } else {
+// WARN_MSG(cpuNumber);
+// WARN_MSG( "Tried to disable a 'disabled' processor");
+// ASSERT(0);
+// }
+ assert(0);
+}
+
+void SIMICS_post_disable_processor( int cpuNumber ) {
+// SIM_stacked_post(SIMICS_get_proc_ptr(cpuNumber), ruby_disable_processor, (void*) NULL); // Maurice
+ assert(0);
+}
+
+void SIMICS_enable_processor( int cpuNumber ) {
+// if(!SIM_cpu_enabled(SIMICS_get_proc_ptr(cpuNumber))) { // Maurice
+// SIM_enable_processor(SIMICS_get_proc_ptr(cpuNumber)); // Maurice
+// } else {
+// WARN_MSG(cpuNumber);
+// WARN_MSG( "Tried to enable an 'enabled' processor");
+// }
+ assert(0);
+}
+
+bool SIMICS_processor_enabled( int cpuNumber ) {
+// return SIM_cpu_enabled(SIMICS_get_proc_ptr(cpuNumber)); // Maurice
+ assert(0);
+ return false;
+}
+
+// return NULL when fail
+void* SIMICS_get_proc_ptr(int cpuNumber) {
+// return (void *) SIM_proc_no_2_ptr(cpuNumber); // Maurice
+ assert(0);
+ return NULL;
+}
+
+void SIMICS_print_version(ostream& out) {
+// const char* version = SIM_version(); // Maurice
+// if (version != NULL) {
+// out << "simics_version: " << SIM_version() << endl; // Maurice
+// }
+ out << "Mwa ha ha this is not Simics!!";
+}
+
+// KM -- From Nikhil's SN code
+//these functions should be in interface.C ??
+
+uinteger_t SIMICS_read_control_register(int cpuNumber, int registerNumber)
+{
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// uinteger_t result = SIM_read_register(cpu, registerNumber); // Maurice
+// return result;
+ assert(0);
+ return 0;
+}
+
+uinteger_t SIMICS_read_window_register(int cpuNumber, int window, int registerNumber)
+{
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// uinteger_t result = SIM_read_register(cpu, registerNumber); // Maurice
+// return result;
+ assert(0);
+ return 0;
+}
+
+uinteger_t SIMICS_read_global_register(int cpuNumber, int globals, int registerNumber)
+{
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// uinteger_t result = SIM_read_register(cpu, registerNumber); // Maurice
+// return result;
+ assert(0);
+ return 0;
+}
+
+/**
+ uint64 SIMICS_read_fp_register_x(int cpuNumber, int registerNumber)
+ {
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// return SIM_read_fp_register_x(cpu, registerNumber); // Maurice
+ }
+**/
+
+void SIMICS_write_control_register(int cpuNumber, int registerNumber, uinteger_t value)
+{
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// SIM_write_register(cpu, registerNumber, value); // Maurice
+ assert(0);
+}
+
+void SIMICS_write_window_register(int cpuNumber, int window, int registerNumber, uinteger_t value)
+{
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// SIM_write_register(cpu, registerNumber, value); // Maurice
+ assert(0);
+}
+
+void SIMICS_write_global_register(int cpuNumber, int globals, int registerNumber, uinteger_t value)
+{
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// SIM_write_register(cpu, registerNumber, value); // Maurice
+ assert(0);
+}
+
+/***
+ void SIMICS_write_fp_register_x(int cpuNumber, int registerNumber, uint64 value)
+ {
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// SIM_write_fp_register_x(cpu, registerNumber, value); // Maurice
+ }
+***/
+
+// KM -- Functions using new APIs (update from Nikhil's original)
+
+int SIMICS_get_register_number(int cpuNumber, const char * reg_name){
+// int result = SIM_get_register_number(SIM_proc_no_2_ptr(cpuNumber), reg_name); // Maurice
+// return result;
+ assert(0);
+ return 0;
+}
+
+const char * SIMICS_get_register_name(int cpuNumber, int reg_num){
+// const char * result = SIM_get_register_name(SIM_proc_no_2_ptr(cpuNumber), reg_num); // Maurice
+// return result;
+ assert(0);
+ return "Then we shall fight in the shade";
+}
+
+uinteger_t SIMICS_read_register(int cpuNumber, int registerNumber)
+{
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// uinteger_t result = SIM_read_register(cpu, registerNumber); // Maurice
+// return result;
+ assert(0);
+ return 0;
+}
+
+void SIMICS_write_register(int cpuNumber, int registerNumber, uinteger_t value)
+{
+// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
+// SIM_write_register(cpu, registerNumber, value); // Maurice
+ assert(0);
+}
+
+// This version is called whenever we are about to jump to the SW handler
+void ruby_set_pc(void *cpu, void *parameter){
+// physical_address_t paddr;
+// paddr = (physical_address_t) parameter;
+// // Simics' processor number
+// // int proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
+// int smt_proc_no = proc_no / RubyConfig::numberofSMTThreads();
+// // SIM_set_program_counter(cpu, paddr); // Maurice
+// //cout << "ruby_set_pc setting cpu[ " << proc_no << " ] smt_cpu[ " << smt_proc_no << " ] PC[ " << hex << paddr << " ]" << dec << endl;
+// // physical_address_t newpc = SIM_get_program_counter(cpu); // Maurice
+// // int pc_reg = SIM_get_register_number(cpu, "pc"); // Maurice
+// // int npc_reg = SIM_get_register_number( cpu, "npc"); // Maurice
+// // uinteger_t pc = SIM_read_register(cpu, pc_reg); // Maurice
+// // uinteger_t npc = SIM_read_register(cpu, npc_reg); // Maurice
+// //cout << "NEW PC[ 0x" << hex << newpc << " ]" << " PC REG[ 0x" << pc << " ] NPC REG[ 0x" << npc << " ]" << dec << endl;
+//
+// if(XACT_MEMORY){
+// if( !OpalInterface::isOpalLoaded() ){
+// // using SimicsDriver
+// ASSERT( proc_no == smt_proc_no );
+// SimicsDriver *simics_intf = dynamic_cast<SimicsDriver*>(g_system_ptr->getDriver());
+// ASSERT( simics_intf );
+// simics_intf->notifyTrapStart( proc_no, Address(paddr), 0 /*dummy threadID*/, 0 /* Simics uses 1 thread */ );
+// }
+// else{
+// // notify Opal about changing pc to SW handler
+// //cout << "informing Opal via notifyTrapStart proc = " << proc_no << endl;
+// //g_system_ptr->getSequencer(smt_proc_no)->notifyTrapStart( proc_no, Address(paddr) );
+// }
+//
+// if (XACT_DEBUG && XACT_DEBUG_LEVEL > 1){
+// cout << g_eventQueue_ptr->getTime() << " " << proc_no
+// << " ruby_set_pc PC: " << hex
+// // << SIM_get_program_counter(cpu) << // Maurice
+// // " NPC is: " << hex << SIM_read_register(cpu, 33) << " pc_val: " << paddr << dec << endl; // Maurice
+// }
+// }
+ assert(0);
+}
+
+// This version is called whenever we are about to return from SW handler
+void ruby_set_program_counter(void *cpu, void *parameter){
+// physical_address_t paddr;
+// paddr = (physical_address_t) parameter;
+// // Simics' processor number
+//// int proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
+// // SMT proc number
+// int smt_proc_no = proc_no / RubyConfig::numberofSMTThreads();
+//
+//// // SIM_set_program_counter() also sets the NPC to PC+4. // Maurice
+// // Need to ensure that NPC doesn't change especially for PCs in the branch delay slot
+//// uinteger_t npc_val = SIM_read_register(cpu, SIM_get_register_number(cpu, "npc")); // Maurice
+//// SIM_set_program_counter(cpu, paddr); // Maurice
+//// SIM_write_register(cpu, SIM_get_register_number(cpu, "npc"), npc_val); // Maurice
+//
+// //LUKE - notify Opal of PC change (ie end of all register updates and abort complete)
+// // I moved the register checkpoint restoration to here also, to jointly update the PC and the registers at the same time
+// if(XACT_MEMORY){
+// if( !OpalInterface::isOpalLoaded() ){
+// //using SimicsDriver
+// //we should only be running with 1 thread with Simics
+// ASSERT( proc_no == smt_proc_no );
+// SimicsDriver *simics_intf = dynamic_cast<SimicsDriver*>(g_system_ptr->getDriver());
+// ASSERT( simics_intf );
+// simics_intf->notifyTrapComplete(proc_no, Address( paddr ), 0 /* Simics uses 1 thread */ );
+// }
+// else{
+// //using OpalInterface
+// // g_system_ptr->getSequencer(smt_proc_no)->notifyTrapComplete( proc_no, Address(paddr) );
+// }
+// }
+// if (XACT_DEBUG && XACT_DEBUG_LEVEL > 1){
+// cout << g_eventQueue_ptr->getTime() << " " << proc_no
+// << " ruby_set_program_counter PC: " << hex
+//// << SIM_get_program_counter(cpu) << // Maurice
+//// " NPC is: " << hex << SIM_read_register(cpu, 33) << " pc_val: " << paddr << " npc_val: " << npc_val << dec << endl; // Maurice
+// }
+ assert(0);
+}
+
+void ruby_set_npc(void *cpu, void *parameter){
+// physical_address_t paddr;
+// paddr = (physical_address_t) parameter;
+// // int proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
+// // SMT proc number
+// int smt_proc_no = proc_no / RubyConfig::numberofSMTThreads();
+//
+// // SIM_write_register(cpu, SIM_get_register_number(cpu, "npc"), paddr); // Maurice
+// if (XACT_DEBUG && XACT_DEBUG_LEVEL > 1){
+// cout << g_eventQueue_ptr->getTime() << " " << proc_no
+// << " ruby_set_npc val: " << hex << paddr << " PC: " << hex
+// // << SIM_get_program_counter(cpu) << // Maurice
+// // " NPC is: " << hex << SIM_read_register(cpu, 33) << dec << endl; // Maurice
+// }
+ assert(0);
+}
+
+void ruby_continue_execution(void *cpu, void *parameter){
+// int logical_proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
+// int thread = logical_proc_no % RubyConfig::numberofSMTThreads();
+// int proc_no = logical_proc_no / RubyConfig::numberofSMTThreads();
+// g_system_ptr->getTransactionInterfaceManager(proc_no)->continueExecutionCallback(thread);
+ assert(0);
+}
+
+void ruby_restart_transaction(void *cpu, void *parameter){
+// int logical_proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
+// int thread = logical_proc_no % RubyConfig::numberofSMTThreads();
+// int proc_no = logical_proc_no / RubyConfig::numberofSMTThreads();
+// g_system_ptr->getTransactionInterfaceManager(proc_no)->restartTransactionCallback(thread);
+ assert(0);
+}
+
+void ruby_stall_proc(void *cpu, void *parameter){
+// int logical_proc_no = SIM_get_proc_no((processor_t*)cpu); // Maurice
+// int cycles = (uint64)parameter;
+
+// SIMICS_stall_proc(logical_proc_no, cycles);
+ assert(0);
+}
+
+void ruby_disable_processor(void *cpu, void *parameter){
+// int logical_proc_no = SIM_get_proc_no((processor_t*)cpu); // Maurice
+// SIMICS_disable_processor(logical_proc_no);
+ assert(0);
+}
+
diff --git a/src/mem/ruby/simics/interface.hh b/src/mem/ruby/simics/interface.hh
new file mode 100644
index 000000000..f8d9375d7
--- /dev/null
+++ b/src/mem/ruby/simics/interface.hh
@@ -0,0 +1,152 @@
+
+/*
+ * Copyright (c) 1999-2008 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.
+ */
+
+/*
+ * $Id: interface.h 1.33 05/01/19 13:12:32-06:00 mikem@maya.cs.wisc.edu $
+ *
+ * Description:
+ *
+ */
+
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include "Global.hh"
+#include "mf_api.hh"
+#include "Address.hh"
+
+// // Simics includes
+// extern "C" {
+// #include "simics/api.hh"
+// }
+
+typedef void memory_transaction_t;
+
+// simics memory access
+integer_t SIMICS_read_physical_memory(int procID, physical_address_t address,
+ int len );
+void SIMICS_read_physical_memory_buffer(int procID, physical_address_t addr,
+ char* buffer, int len );
+void SIMICS_write_physical_memory( int procID, physical_address_t address,
+ integer_t value, int len );
+void SIMICS_write_physical_memory_buffer(int procID, physical_address_t addr,
+ char* buffer, int len );
+bool SIMICS_check_memory_value(int procID, physical_address_t addr,
+ char* buffer, int len);
+const char *SIMICS_disassemble_physical( int procID, physical_address_t pa );
+
+// simics VM translation, decoding, etc.
+physical_address_t SIMICS_translate_address( int procID, Address address );
+physical_address_t SIMICS_translate_data_address( int procID, Address address );
+#ifdef SPARC
+bool SIMICS_is_ldda(const memory_transaction_t *mem_trans);
+#endif
+
+// simics timing
+void SIMICS_unstall_proc(int cpuNumber);
+void SIMICS_unstall_proc(int cpuNumber, int cycles);
+void SIMICS_stall_proc(int cpuNumber, int cycles);
+void SIMICS_post_stall_proc(int cpuNumber, int cycles);
+void SIMICS_wakeup_ruby();
+
+// simics callbacks
+void SIMICS_remove_ruby_callback( void );
+void SIMICS_install_timing_model( void );
+void SIMICS_remove_timing_model( void );
+void SIMICS_install_exception_callback( void );
+void SIMICS_remove_exception_callback( void );
+#ifdef SPARC
+void SIMICS_install_asi_callback( void );
+void SIMICS_remove_asi_callback( void );
+#endif
+
+// simics PC, IC
+integer_t SIMICS_get_insn_count( int cpuNumber );
+integer_t SIMICS_get_cycle_count(int cpuNumber);
+Address SIMICS_get_program_counter( void *cpu );
+Address SIMICS_get_program_counter( int procID );
+Address SIMICS_get_npc(int procID);
+void SIMICS_set_program_counter( int procID, Address newPC );
+void SIMICS_set_next_program_counter( int procID, Address newPC );
+void SIMICS_set_pc( int procID, Address newPC );
+void SIMICS_set_npc( int procID, Address newNPC );
+
+void SIMICS_post_continue_execution(int procID);
+void SIMICS_post_restart_transaction(int procID);
+
+// simics processor number
+int SIMICS_number_processors( void );
+void * SIMICS_current_processor( void );
+int SIMICS_current_processor_number( void );
+int SIMICS_get_proc_no( void *cpu );
+void* SIMICS_get_proc_ptr( int cpuNumber );
+
+// simics version
+void SIMICS_print_version(ostream& out);
+
+// opal
+mf_opal_api_t *SIMICS_get_opal_interface( void );
+
+// STC related, should not be used anymore!
+void SIMICS_flush_STC(int cpuNumber);
+void SIMICS_invalidate_from_STC(const Address& address, int cpuNumber);
+void SIMICS_downgrade_from_STC(const Address& address, int cpuNumber);
+
+// KM -- from Nikhil's SN code
+uinteger_t SIMICS_read_control_register(int cpuNumber, int registerNumber);
+uinteger_t SIMICS_read_window_register(int cpuNumber, int window, int registerNumber);
+uinteger_t SIMICS_read_global_register(int cpuNumber, int globals, int registerNumber);
+//uint64 SIMICS_read_fp_register_x(int cpuNumber, int registerNumber);
+
+// KM -- new version based on reg names
+int SIMICS_get_register_number(int cpuNumber, const char * reg_name);
+const char * SIMICS_get_register_name(int cpuNumber, int reg_num);
+uinteger_t SIMICS_read_register(int cpuNumber, int registerNumber);
+void SIMICS_write_register(int cpuNumber, int registerNumber, uinteger_t value);
+
+void SIMICS_write_control_register(int cpuNumber, int registerNumber, uinteger_t value);
+void SIMICS_write_window_register(int cpuNumber, int window, int registerNumber, uinteger_t value);
+void SIMICS_write_global_register(int cpuNumber, int globals, int registerNumber, uinteger_t value);
+void SIMICS_write_fp_register_x(int cpuNumber, int registerNumber, uint64 value);
+void SIMICS_enable_processor(int cpuNumber);
+void SIMICS_disable_processor(int cpuNumber);
+void SIMICS_post_disable_processor(int cpuNumber);
+bool SIMICS_processor_enabled(int cpuNumber);
+
+void ruby_abort_transaction(void *cpu, void *parameter);
+void ruby_set_program_counter(void *cpu, void *parameter);
+void ruby_set_pc(void *cpu, void *parameter);
+void ruby_set_npc(void *cpu, void *parameter);
+void ruby_continue_execution(void *cpu, void *parameter);
+void ruby_restart_transaction(void *cpu, void *parameter);
+void ruby_stall_proc(void *cpu, void *parameter);
+void ruby_disable_processor(void *cpu, void *parameter);
+
+#endif //INTERFACE_H
+
diff --git a/src/mem/ruby/simics/simics_api_dummy.c b/src/mem/ruby/simics/simics_api_dummy.c
new file mode 100644
index 000000000..e444b783c
--- /dev/null
+++ b/src/mem/ruby/simics/simics_api_dummy.c
@@ -0,0 +1,105 @@
+#include <assert.h>
+
+extern "C" {
+
+typedef int generic_transaction_t;
+typedef int generic_transaction;
+typedef int la_t;
+typedef int integer_t;
+typedef int uint64;
+typedef int attr_value_t;
+typedef int data_or_instr_t;
+typedef int sim_exception_t;
+typedef int processor_t;
+typedef int conf_object_t;
+typedef int conf_object;
+typedef int physical_address_t;
+typedef int logical_address_t;
+typedef int read_or_write_t;
+typedef int interface_t;
+typedef int set_error_t;
+typedef int ireg_t;
+typedef int pc_step_t;
+typedef int event_handler_t;
+typedef int lang_void;
+typedef int cycles_t;
+typedef int sync_t;
+typedef int FILE;
+typedef int va_list;
+typedef int log_object;
+typedef int hap_handle_t;
+typedef int str_hap_func_t;
+typedef int hap_type_t;
+typedef int cb_func_em_t;
+typedef int sync_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SIM_number_processors() { assert(0); return; };
+void SIM_c_set_mem_op_value_buf(generic_transaction_t *mem_op, char *buf) { assert(0); return; };
+void SIM_c_get_mem_op_value_buf(generic_transaction_t *mem_op, char *buf) { assert(0); return; };
+sim_exception_t SIM_clear_exception(void) { assert(0); return 0; };
+processor_t *SIM_conf_object_to_processor(conf_object_t* obj) { assert(0); return 0; };
+processor_t *SIM_current_processor(void) { assert(0); return 0; };
+const char *SIM_disassemble(processor_t *cpu_ptr, physical_address_t pa, int type) { assert(0); return 0; };
+interface_t *SIM_get_interface(conf_object const *object, const char *interface_name) { assert(0); return 0; };
+conf_object_t *SIM_get_object(const char *name) { assert(0); return 0; };
+sim_exception_t SIM_get_pending_exception(void) { assert(0); return 0; };
+int SIM_get_proc_no(const processor_t *cpu_ptr) { assert(0); return 0; };
+la_t SIM_get_program_counter(processor_t *cpu) { assert(0); return 0; };
+const char *SIM_last_error(void) { assert(0); return 0; };
+physical_address_t SIM_logical_to_physical(conf_object *cpu_ptr, data_or_instr_t data_or_instr, logical_address_t address) { assert(0); return 0; };
+const char * SIM_get_exception_name( processor_t * p, int exc ) { assert(0); return 0;};
+processor_t *SIM_proc_no_2_ptr(int cpu_nr) { assert(0); return 0; };
+conf_object_t *SIM_processor_to_conf_object(processor_t* p) { assert(0); return 0; };
+ireg_t SIM_read_control_register(processor_t *cpu_ptr, int reg) { assert(0); return 0; };
+double SIM_read_fp_register_d(processor_t *cpu_ptr, int reg) { assert(0); return 0; };
+uint64 SIM_read_fp_register_x(processor_t *cpu_ptr, int reg) { assert(0); return 0; };
+ireg_t SIM_read_global_register(processor_t *cpu_ptr, int globals, int reg) { assert(0); return 0; };
+integer_t SIM_read_phys_memory(conf_object *cpu, physical_address_t address, int len) { assert(0); return 0; };
+ireg_t SIM_read_window_register(processor_t *cpu_ptr, int window, int reg) { assert(0); return 0; };
+set_error_t SIM_set_attribute(conf_object_t *object, char const *name, attr_value_t *value) { assert(0); return 0; };
+void SIM_free_attribute(attr_value_t *value) { assert(0); };
+void SIM_stall_cycle(conf_object_t *obj, cycles_t stall) { assert(0); return; };
+cycles_t SIM_stall_count(conf_object_t *obj) { assert(0); return 0; };
+void SIM_stall(conf_object_t *obj, cycles_t stall) { assert(0); return; };
+pc_step_t SIM_step_count(conf_object_t *p) { assert(0); return 0; };
+cycles_t SIM_cycle_count(conf_object_t *p) { assert(0); return 0; };
+cycles_t SIM_stalled_until(conf_object_t *p) { assert(0); return 0; };
+void SIM_time_clean(conf_object_t *obj, sync_t t, event_handler_t handler, lang_void * arg) { assert(0); return; };
+void SIM_time_post_cycle(conf_object_t * obj, cycles_t delta, sync_t sync, event_handler_t handler, lang_void * arg) { assert(0); return; };
+const char *SIM_version(void) { return 0; };
+void SIM_set_program_counter(conf_object_t *cpu, logical_address_t pc){assert(0);};
+void SIM_write_control_register(processor_t *cpu_ptr, int reg, ireg_t value) { assert(0); return; };
+void SIM_write_fp_register_x(processor_t *cpu_ptr, int reg, uint64 value) { assert(0); return; };
+void SIM_write_global_register(processor_t *cpu_ptr, int globals, int reg, ireg_t value) { assert(0); return; };
+void SIM_write_window_register(processor_t *cpu_ptr, int window, int reg, ireg_t value) { assert(0); return; };
+void SIM_write_phys_memory(conf_object *cpu, physical_address_t address, integer_t value, int len) { assert(0); };
+int __sparc_v9_vtvfprintf(FILE *stream, const char *format, va_list va) { assert(0); return 0; };
+int __l32_p32_vtvfprintf(FILE *stream, const char *format, va_list va) { assert(0); return 0; };
+int __l32_p64_vtvfprintf(FILE *stream, const char *format, va_list va) { assert(0); return 0; };
+int __l64_p64_vtvfprintf(FILE *stream, const char *format, va_list va) { assert(0); return 0; };
+void __sparc_v9_vtdebug_log_vararg(int lvl, log_object *dev, char const *str, va_list va) { assert (0); return; };
+hap_handle_t SIM_hap_add_callback(const char *id, str_hap_func_t cb, lang_void *data) { assert(0); return 0; };
+hap_type_t SIM_hap_get_number(const char *id) { assert(0); return 0; };
+void SIM_hap_delete_callback_id(hap_type_t hap, hap_handle_t hdl) { assert (0); return; };
+int SIM_flush(void) { assert(0); return 0; };
+void SIM_write_register(processor_t *cpu_ptr, int registerNumber, integer_t value){ assert(0); };
+integer_t SIM_read_register(processor_t *cpu_ptr, int registerNumber) { assert(0); return 0; };
+int SIM_get_register_number(processor_t *cpu_ptr, const char * register_name){ assert(0); return 0; }
+const char * SIM_get_register_name(processor_t *cpu_ptr, int reg_num){ assert(0); return 0; }
+
+void SIM_break_simulation(const char * msg){ assert(0); }
+void SIM_printf(const char *format, va_list ap){ assert(0); }
+set_error_t ruby_session_set( void *id, conf_object_t *obj,
+ attr_value_t *val, attr_value_t *idx ) { assert (0); return 0; };
+attr_value_t ruby_session_get( void *id, conf_object_t *obj,
+ attr_value_t *idx ) { assert (0); return 0; };
+ void SIM_stacked_post(conf_object_t *obj, event_handler_t, lang_void *arg){};
+ pc_step_t SIM_step_next_occurrence( conf_object_t * obj, event_handler_t, lang_void * arg){ assert(0); return 0;};
+void SIM_enable_processor(conf_object_t *p) { assert(0); };
+void SIM_disable_processor(conf_object_t *p) { assert(0); };
+int SIM_cpu_enabled(conf_object_t *p) { assert(0); };
+
+attr_value_t SIM_get_attribute(conf_object_t *object, const char *name) { assert(0); };
+} // extern "C"