Line 69... |
Line 69... |
const char *except_name(oraddr_t except)
|
const char *except_name(oraddr_t except)
|
{
|
{
|
return except_names[except >> 8];
|
return except_names[except >> 8];
|
}
|
}
|
|
|
#if DYNAMIC_EXECUTION
|
|
/* FIXME: Remove the need for this */
|
|
/* This is needed because immu_translate can be called from do_rfe and do_jump
|
|
* in which case the scheduler does not need to get run. immu_translate can also
|
|
* be called from mtspr in which case the exceptions that it generates happen
|
|
* during an instruction and the scheduler needs to get run. */
|
|
int immu_ex_from_insn = 0;
|
|
#endif
|
|
|
|
/* Asserts OR1K exception. */
|
/* Asserts OR1K exception. */
|
/* WARNING: Don't excpect except_handle to return. Sometimes it _may_ return at
|
/* WARNING: Don't excpect except_handle to return. Sometimes it _may_ return at
|
* other times it may not. */
|
* other times it may not. */
|
void except_handle(oraddr_t except, oraddr_t ea)
|
void except_handle(oraddr_t except, oraddr_t ea)
|
{
|
{
|
Line 133... |
Line 124... |
case EXCEPT_RESET:
|
case EXCEPT_RESET:
|
break;
|
break;
|
/* EPCR is loaded with address of instruction that caused the exception */
|
/* EPCR is loaded with address of instruction that caused the exception */
|
case EXCEPT_ITLBMISS:
|
case EXCEPT_ITLBMISS:
|
case EXCEPT_IPF:
|
case EXCEPT_IPF:
|
|
cpu_state.sprs[SPR_EPCR_BASE] = ea - (cpu_state.delay_insn ? 4 : 0);
|
#if DYNAMIC_EXECUTION
|
#if DYNAMIC_EXECUTION
|
/* In immu_translate except_handle is called with except_handle(..., virtaddr) */
|
op_join_mem_cycles();
|
/* Add the immu miss delay to the cycle counter */
|
|
if(!immu_ex_from_insn) {
|
|
cpu_state.sprs[SPR_EPCR_BASE] = get_pc() - (cpu_state.delay_insn ? 4 : 0);
|
|
} else
|
|
/* This exception came from an l.mtspr instruction in which case the pc
|
|
* points to the l.mtspr instruction when in acutal fact, it is the next
|
|
* instruction that would have faulted/missed. ea is used instead of
|
|
* cpu_state.pc + 4 because in the event that the l.mtspr instruction is
|
|
* in the delay slot of a page local jump the fault must happen on the
|
|
* instruction that was jumped to. This is handled in recheck_immu. */
|
|
cpu_state.sprs[SPR_EPCR_BASE] = ea;
|
|
run_sched_out_of_line(immu_ex_from_insn);
|
|
/* Save the registers that are in the temporaries */
|
|
immu_ex_from_insn = 0;
|
|
break;
|
|
#endif
|
#endif
|
/* All these exceptions happen during a simulated instruction */
|
break;
|
case EXCEPT_BUSERR:
|
case EXCEPT_BUSERR:
|
case EXCEPT_DPF:
|
case EXCEPT_DPF:
|
case EXCEPT_ALIGN:
|
case EXCEPT_ALIGN:
|
case EXCEPT_ILLEGAL:
|
case EXCEPT_ILLEGAL:
|
case EXCEPT_DTLBMISS:
|
case EXCEPT_DTLBMISS:
|
case EXCEPT_RANGE:
|
case EXCEPT_RANGE:
|
case EXCEPT_TRAP:
|
case EXCEPT_TRAP:
|
|
/* All these exceptions happen during a simulated instruction */
|
#if DYNAMIC_EXECUTION
|
#if DYNAMIC_EXECUTION
|
/* Since these exceptions happen during a simulated instruction and this
|
/* Since these exceptions happen during a simulated instruction and this
|
* function jumps out to the exception vector the scheduler would never have
|
* function jumps out to the exception vector the scheduler would never have
|
* a chance to run, therefore run it now */
|
* a chance to run, therefore run it now */
|
run_sched_out_of_line(1);
|
run_sched_out_of_line();
|
#endif
|
#endif
|
cpu_state.sprs[SPR_EPCR_BASE] = cpu_state.pc - (cpu_state.delay_insn ? 4 : 0);
|
cpu_state.sprs[SPR_EPCR_BASE] = cpu_state.pc - (cpu_state.delay_insn ? 4 : 0);
|
break;
|
break;
|
/* EPCR is loaded with address of next not-yet-executed instruction */
|
/* EPCR is loaded with address of next not-yet-executed instruction */
|
case EXCEPT_SYSCALL:
|
case EXCEPT_SYSCALL:
|