SEM_PC sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC pc) { SIM_DESC sd = CPU_STATE (current_cpu); #if 0 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) { h_bsm_set (current_cpu, h_sm_get (current_cpu)); h_bie_set (current_cpu, h_ie_get (current_cpu)); h_bcond_set (current_cpu, h_cond_get (current_cpu)); /* sm not changed */ h_ie_set (current_cpu, 0); h_cond_set (current_cpu, 0); h_bpc_set (current_cpu, cia); sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL, EIT_RSVD_INSN_ADDR); } else #endif sim_engine_halt (sd, current_cpu, NULL, cia, sim_stopped, SIM_SIGILL); return pc; }
void fr30_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia, unsigned int map, int nr_bytes, address_word addr, transfer_type transfer, sim_core_signals sig) { #if 0 if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) { h_bsm_set (current_cpu, h_sm_get (current_cpu)); h_bie_set (current_cpu, h_ie_get (current_cpu)); h_bcond_set (current_cpu, h_cond_get (current_cpu)); /* sm not changed */ h_ie_set (current_cpu, 0); h_cond_set (current_cpu, 0); h_bpc_set (current_cpu, cia); sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL, EIT_ADDR_EXCP_ADDR); } else #endif sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr, transfer, sig); }
void m32r_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia, unsigned int map, int nr_bytes, address_word addr, transfer_type transfer, sim_core_signals sig) { if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) { m32rbf_h_cr_set (current_cpu, H_CR_BBPC, m32rbf_h_cr_get (current_cpu, H_CR_BPC)); switch (MACH_NUM (CPU_MACH (current_cpu))) { case MACH_M32R: m32rbf_h_bpsw_set (current_cpu, m32rbf_h_psw_get (current_cpu)); /* sm not changed. */ m32rbf_h_psw_set (current_cpu, m32rbf_h_psw_get (current_cpu) & 0x80); break; case MACH_M32RX: m32rxf_h_bpsw_set (current_cpu, m32rxf_h_psw_get (current_cpu)); /* sm not changed. */ m32rxf_h_psw_set (current_cpu, m32rxf_h_psw_get (current_cpu) & 0x80); break; case MACH_M32R2: m32r2f_h_bpsw_set (current_cpu, m32r2f_h_psw_get (current_cpu)); /* sm not changed. */ m32r2f_h_psw_set (current_cpu, m32r2f_h_psw_get (current_cpu) & 0x80); break; default: abort (); } m32rbf_h_cr_set (current_cpu, H_CR_BPC, cia); sim_engine_restart (CPU_STATE (current_cpu), current_cpu, NULL, EIT_ADDR_EXCP_ADDR); } else sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr, transfer, sig); }
void cec_exception (SIM_CPU *cpu, int excp) { SIM_DESC sd = CPU_STATE (cpu); int sigrc = -1; TRACE_EVENTS (cpu, "processing exception %#x in EVT%i", excp, cec_get_ivg (cpu)); /* Ideally what would happen here for real hardware exceptions (not fake sim ones) is that: - For service exceptions (excp <= 0x11): RETX is the _next_ PC which can be tricky with jumps/hardware loops/... - For error exceptions (excp > 0x11): RETX is the _current_ PC (i.e. the one causing the exception) - PC is loaded with EVT3 MMR - ILAT/IPEND in CEC is updated depending on current IVG level - the fault address MMRs get updated with data/instruction info - Execution continues on in the EVT3 handler */ /* Handle simulator exceptions first. */ switch (excp) { case VEC_SIM_HLT: excp_to_sim_halt (sim_exited, 0); return; case VEC_SIM_ABORT: excp_to_sim_halt (sim_exited, 1); return; case VEC_SIM_TRAP: /* GDB expects us to step over EMUEXCPT. */ /* XXX: What about hwloops and EMUEXCPT at the end? Pretty sure gdb doesn't handle this already... */ SET_PCREG (PCREG + 2); /* Only trap when we are running in gdb. */ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) excp_to_sim_halt (sim_stopped, SIM_SIGTRAP); return; case VEC_SIM_DBGA: /* If running in gdb, simply trap. */ if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) excp_to_sim_halt (sim_stopped, SIM_SIGTRAP); else excp_to_sim_halt (sim_exited, 2); } if (excp <= 0x3f) { SET_EXCAUSE (excp); if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) { /* ICPLB regs always get updated. */ /* XXX: Should optimize this call path ... */ if (excp != VEC_MISALI_I && excp != VEC_MISALI_D && excp != VEC_CPLB_I_M && excp != VEC_CPLB_M && excp != VEC_CPLB_I_VL && excp != VEC_CPLB_VL && excp != VEC_CPLB_I_MHIT && excp != VEC_CPLB_MHIT) mmu_log_ifault (cpu); _cec_raise (cpu, CEC_STATE (cpu), IVG_EVX); /* We need to restart the engine so that we don't return and continue processing this bad insn. */ if (EXCAUSE >= 0x20) sim_engine_restart (sd, cpu, NULL, PCREG); return; } } TRACE_EVENTS (cpu, "running virtual exception handler"); switch (excp) { case VEC_SYS: bfin_syscall (cpu); break; case VEC_EXCPT01: /* Userspace gdb breakpoint. */ sigrc = SIM_SIGTRAP; break; case VEC_UNDEF_I: /* Undefined instruction. */ sigrc = SIM_SIGILL; break; case VEC_ILL_RES: /* Illegal supervisor resource. */ case VEC_MISALI_I: /* Misaligned instruction. */ sigrc = SIM_SIGBUS; break; case VEC_CPLB_M: case VEC_CPLB_I_M: sigrc = SIM_SIGSEGV; break; default: sim_io_eprintf (sd, "Unhandled exception %#x at 0x%08x (%s)\n", excp, PCREG, excp_decoded[excp]); sigrc = SIM_SIGILL; break; } if (sigrc != -1) excp_to_sim_halt (sim_stopped, sigrc); }