integer_t read_reg(conf_object_t *cpu, const char* reg_name) { 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; }
/** * SimicsProcessor is ready to retire the memory reference */ void TransactionSimicsProcessor::readyToRetireMemRef(bool success, memory_transaction_t *mem_trans, CacheRequestType type) { if (0 && XACT_DEBUG && XACT_DEBUG_LEVEL > 2) { if (m_xact_mgr->inTransaction(0)) cout << g_eventQueue_ptr->getTime() << " " << m_proc << " [" << m_proc / RubyConfig::numberofSMTThreads() << "," << m_proc % RubyConfig::numberofSMTThreads() << "] READY TO RETIRE MEM REF" << Address(mem_trans->s.physical_address) << " type " << type << " PC = " << SIMICS_get_program_counter(m_proc) << endl; } if (!success && !XACT_LAZY_VM) { conf_object_t* cpu_obj = (conf_object_t*) SIM_proc_no_2_ptr(m_proc); uinteger_t intr_receive = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "intr_receive")); uinteger_t intr_receive_busy_flag = (intr_receive & 0x20) >> 5; if (intr_receive_busy_flag) { // There is a pending interrupt and we are stalling SIMICS. How unfortunate! // SIMICS would not take the interrupt until we unstall this conflicting memory request! m_xact_mgr->setInterruptTrap(0); return; } }
void ctrl_exception_done(void* desc, void* cpu, integer_t val) { int proc_no = SIM_get_proc_no((conf_object_t*) cpu); conf_object_t* cpu_obj = (conf_object_t*) 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); } } }
void ctrl_exception_start(void* desc, void* cpu, integer_t val) { int proc_no = SIM_get_proc_no((conf_object_t*) cpu); conf_object_t* cpu_obj = (conf_object_t*) 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); } }