summaryrefslogtreecommitdiff
path: root/src/mem/ruby/simics
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
committerNathan Binkert <nate@binkert.org>2009-05-11 10:38:43 -0700
commit2f30950143cc70bc42a3c8a4111d7cf8198ec881 (patch)
tree708f6c22edb3c6feb31dd82866c26623a5329580 /src/mem/ruby/simics
parentc70241810d4e4f523f173c1646b008dc40faad8e (diff)
downloadgem5-2f30950143cc70bc42a3c8a4111d7cf8198ec881.tar.xz
ruby: Import ruby and slicc from GEMS
We eventually plan to replace the m5 cache hierarchy with the GEMS hierarchy, but for now we will make both live alongside eachother.
Diffstat (limited to 'src/mem/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"