/* * 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(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(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>(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; iTranslateSimicsToRuby( 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(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(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); }