diff --git a/software/libbase/crt0-or1k.S b/software/libbase/crt0-or1k.S index 6a5914e5b..33807f87b 100644 --- a/software/libbase/crt0-or1k.S +++ b/software/libbase/crt0-or1k.S @@ -19,7 +19,7 @@ #include -#define EXCEPTION_STACK_SIZE (128+128) +#define EXCEPTION_STACK_SIZE (4*32) #define HANDLE_EXCEPTION ; \ l.addi r1, r1, -EXCEPTION_STACK_SIZE ; \ @@ -193,11 +193,18 @@ _exception_handler: /* Save return address */ l.or r14, r0, r9 - /* send stack pointer as argument */ + /* Calculate exception vector from handler address */ + l.andi r3, r9, 0xf00 + l.srli r3, r3, 8 + /* Pass saved register state */ l.or r4, r0, r1 + /* Extract exception PC */ + l.mfspr r5, r0, SPR_EPCR_BASE + /* Extract exception effective address */ + l.mfspr r6, r0, SPR_EEAR_BASE /* Call exception handler with the link address as argument */ l.jal exception_handler - l.or r3, r0, r14 + l.nop /* Load return address */ l.or r9, r0, r14 diff --git a/software/libbase/exception.c b/software/libbase/exception.c index 73454e32d..542001ad8 100644 --- a/software/libbase/exception.c +++ b/software/libbase/exception.c @@ -2,12 +2,14 @@ void isr(void); #ifdef __or1k__ -#define EXTERNAL_IRQ 0x800 +#define EXTERNAL_IRQ 0x8 -void exception_handler(unsigned long vect, unsigned long *sp); -void exception_handler(unsigned long vect, unsigned long *sp) +void exception_handler(unsigned long vect, unsigned long *regs, + unsigned long pc, unsigned long ea); +void exception_handler(unsigned long vect, unsigned long *regs, + unsigned long pc, unsigned long ea) { - if((vect & 0xf00) == EXTERNAL_IRQ) { + if(vect == EXTERNAL_IRQ) { isr(); } else { /* Unhandled exception */