Line 29... |
Line 29... |
|
|
#include "port.h"
|
#include "port.h"
|
#include "arch.h"
|
#include "arch.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "except.h"
|
#include "except.h"
|
#include "sprs.h"
|
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "debug_unit.h"
|
#include "debug_unit.h"
|
|
#include "opcode/or32.h"
|
|
#include "spr_defs.h"
|
#include "execute.h"
|
#include "execute.h"
|
|
#include "sprs.h"
|
|
|
extern int delay_insn;
|
|
extern oraddr_t pcprev;
|
extern oraddr_t pcprev;
|
extern oraddr_t pcdelay;
|
|
|
|
int except_pending = 0;
|
int except_pending = 0;
|
|
|
static const char *except_names[] = {
|
static const char *except_names[] = {
|
NULL,
|
NULL,
|
Line 73... |
Line 73... |
|
|
if (config.sim.verbose)
|
if (config.sim.verbose)
|
PRINTF("Exception 0x%"PRIxADDR" (%s) at 0x%"PRIxADDR", EA: 0x%"PRIxADDR
|
PRINTF("Exception 0x%"PRIxADDR" (%s) at 0x%"PRIxADDR", EA: 0x%"PRIxADDR
|
", ppc: 0x%"PRIxADDR", npc: 0x%"PRIxADDR", dpc: 0x%"PRIxADDR
|
", ppc: 0x%"PRIxADDR", npc: 0x%"PRIxADDR", dpc: 0x%"PRIxADDR
|
", cycles %lld, #%lld\n",
|
", cycles %lld, #%lld\n",
|
except, except_name(except), pcprev, ea, pc, pcnext, pcdelay,
|
except, except_name(except), pcprev, ea, cpu_state.pc, pcnext,
|
runtime.sim.cycles, runtime.cpu.instructions);
|
cpu_state.pc_delay, runtime.sim.cycles, runtime.cpu.instructions);
|
|
|
pcnext = except + (testsprbits (SPR_SR, SPR_SR_EPH) ? 0xf0000000 : 0x00000000);
|
pcnext = except + (testsprbits (SPR_SR, SPR_SR_EPH) ? 0xf0000000 : 0x00000000);
|
|
|
switch(except) {
|
switch(except) {
|
/* EPCR is irrelevent */
|
/* EPCR is irrelevent */
|
Line 93... |
Line 93... |
case EXCEPT_ILLEGAL:
|
case EXCEPT_ILLEGAL:
|
case EXCEPT_DTLBMISS:
|
case EXCEPT_DTLBMISS:
|
case EXCEPT_ITLBMISS:
|
case EXCEPT_ITLBMISS:
|
case EXCEPT_RANGE:
|
case EXCEPT_RANGE:
|
case EXCEPT_TRAP:
|
case EXCEPT_TRAP:
|
mtspr(SPR_EPCR_BASE, pc - (delay_insn ? 4 : 0));
|
mtspr(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:
|
mtspr(SPR_EPCR_BASE, (pc + 4) - (delay_insn ? 4 : 0));
|
mtspr(SPR_EPCR_BASE, (cpu_state.pc + 4) - (cpu_state.delay_insn ? 4 : 0));
|
break;
|
break;
|
/* These exceptions happen AFTER (or before) an instruction has been
|
/* These exceptions happen AFTER (or before) an instruction has been
|
* simulated, therefore the pc already points to the *next* instruction */
|
* simulated, therefore the pc already points to the *next* instruction */
|
case EXCEPT_TICK:
|
case EXCEPT_TICK:
|
case EXCEPT_INT:
|
case EXCEPT_INT:
|
mtspr(SPR_EPCR_BASE, pc - (delay_insn ? 4 : 0));
|
mtspr(SPR_EPCR_BASE, cpu_state.pc - (cpu_state.delay_insn ? 4 : 0));
|
/* If we don't update the pc now, then it will only happen *after* the next
|
/* If we don't update the pc now, then it will only happen *after* the next
|
* instruction (There would be serious problems if the next instruction just
|
* instruction (There would be serious problems if the next instruction just
|
* happens to be a branch), when it should happen NOW. */
|
* happens to be a branch), when it should happen NOW. */
|
pc = pcnext;
|
cpu_state.pc = pcnext;
|
pcnext += 4;
|
pcnext += 4;
|
break;
|
break;
|
}
|
}
|
|
|
mtspr(SPR_EEAR_BASE, ea);
|
mtspr(SPR_EEAR_BASE, ea);
|
Line 124... |
Line 124... |
mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_OVE); /* Disable overflow flag exception. */
|
mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_OVE); /* Disable overflow flag exception. */
|
|
|
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_SM); /* SUPV mode */
|
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_SM); /* SUPV mode */
|
mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IEE | SPR_SR_TEE)); /* Disable interrupts. */
|
mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IEE | SPR_SR_TEE)); /* Disable interrupts. */
|
|
|
delay_insn = 0;
|
cpu_state.delay_insn = 0;
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|