# HG changeset patch # User Paul Boddie # Date 1540919978 -3600 # Node ID f9acc9c732f176764387f35589a77b4df1dc4105 # Parent 32cb6b232444bb6a0b045a6dbcfe94bb07e481b3 Fixed invocation of the interrupt handler function, avoiding $gp usage. The absence of any computation of $gp in the handler routine meant that where such computations (in function prologues, for instance) were being interrupted, a corrupt $gp was being used, causing an exception. Changed the exception handler routine to switch to the IRQ stack and to use the appropriate calling convention. diff -r 32cb6b232444 -r f9acc9c732f1 lib/cpu.S --- a/lib/cpu.S Mon Oct 29 01:46:31 2018 +0100 +++ b/lib/cpu.S Tue Oct 30 18:19:38 2018 +0100 @@ -21,6 +21,9 @@ #include "pic32.h" #include "cpu.h" +#define IRQ_STACK_LIMIT (KSEG0_BASE + IRQ_STACK_SIZE) +#define IRQ_STACK_TOP (IRQ_STACK_LIMIT - 34 * 4) + .globl enable_interrupts .globl handle_error_level .globl init_interrupts @@ -126,7 +129,19 @@ .org 0x180 exc_handler: - j exception_handler + move $k0, $sp + move $k1, $t9 + + /* Switch to the IRQ stack. */ + + lui $sp, %hi(IRQ_STACK_TOP) + ori $sp, $sp, %lo(IRQ_STACK_TOP) + + /* Obtain the address directly to avoid initialising $gp here. */ + + lui $t9, %hi(exception_handler) + ori $t9, $t9, %lo(exception_handler) + jr $t9 nop @@ -136,9 +151,6 @@ .org 0x200 .set noat -#define IRQ_STACK_LIMIT (KSEG0_BASE + IRQ_STACK_SIZE) -#define IRQ_STACK_TOP (IRQ_STACK_LIMIT - 34 * 4) - int_handler: /* Store affected registers from IRQ_STACK_LIMIT - 4 downwards. */ @@ -163,7 +175,11 @@ lui $sp, %hi(IRQ_STACK_TOP) ori $sp, $sp, %lo(IRQ_STACK_TOP) - jal interrupt_handler + /* Obtain the address directly to avoid initialising $gp here. */ + + lui $t9, %hi(interrupt_handler) + ori $t9, $t9, %lo(interrupt_handler) + jalr $t9 nop /* Restore affected registers. */