diff options
Diffstat (limited to 'src/mem/ruby/simics/commands.cc')
-rw-r--r-- | src/mem/ruby/simics/commands.cc | 867 |
1 files changed, 867 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 +} |