137,7 → 137,12 |
PROCESS_EXCEPTION(EXC_IRQ); |
} |
|
static void prefetch_abort_exception(int exc_no, istate_t* istate) |
{ |
//aux_puts("(PREFETCH|DATA) ABORT exception caught, not processed.\n"); |
} |
|
|
/** Interrupt Exception handler. |
* Determines the sources of interrupt, and calls their handlers. |
*/ |
208,6 → 213,20 |
(unsigned*)EXC_FIQ_VEC); |
} |
|
/** Activates using high exception vectors addresses. */ |
static void high_vectors() |
{ |
uint32_t control_reg; |
|
asm volatile( "mrc p15, 0, %0, c1, c1": "=r" (control_reg)); |
|
//switch on the high vectors bit |
control_reg |= CP15_R1_HIGH_VECTORS_BIT; |
|
asm volatile( "mcr p15, 0, %0, c1, c1" : : "r" (control_reg)); |
} |
|
|
/** Initializes exception handling. |
* |
* Installs low-level exception handlers and then registers |
215,9 → 234,15 |
*/ |
void exception_init(void) |
{ |
#ifdef HIGH_EXCEPTION_VECTORS |
high_vectors(); |
#endif |
|
install_exception_handlers(); |
|
exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception); |
exc_register(EXC_PREFETCH_ABORT, "prefetch abort", (iroutine) prefetch_abort_exception); |
exc_register(EXC_DATA_ABORT, "data abort", (iroutine) prefetch_abort_exception); |
/* TODO add next */ |
} |
|
225,16 → 250,27 |
void setup_exception_stacks() |
{ |
/* switch to particular mode and set "sp" there */ |
|
uint32_t cspr = current_status_reg_read(); |
|
/* IRQ stack */ |
current_status_reg_control_write( |
(cspr & ~STATUS_REG_MODE_MASK) | IRQ_MODE |
); |
asm("ldr sp, =irq_stack"); |
current_status_reg_control_write( cspr); |
|
|
/* abort stack */ |
current_status_reg_control_write( |
(cspr & ~STATUS_REG_MODE_MASK) | ABORT_MODE |
); |
asm("ldr sp, =abort_stack"); |
|
/* TODO if you want to test other exceptions than IRQ, |
make stack analogous to irq_stack (in start.S), |
and then set stack pointer here */ |
|
current_status_reg_control_write( cspr); |
|
} |
|
/** @} |