diff options
Diffstat (limited to 'src/mem/ruby/simics')
-rw-r--r-- | src/mem/ruby/simics/commands.cc | 867 | ||||
-rw-r--r-- | src/mem/ruby/simics/commands.hh | 106 | ||||
-rw-r--r-- | src/mem/ruby/simics/interface.cc | 935 | ||||
-rw-r--r-- | src/mem/ruby/simics/interface.hh | 152 | ||||
-rw-r--r-- | src/mem/ruby/simics/simics_api_dummy.c | 105 |
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" |