mips: consolidate exception handling, add exception backtraces

Merge the x1000 and jz47xx exception handling code since they use
the same exception vectors and handlers. The interrupt handler is
now called from the common exception vector, but remains separate
for each board since they have different IRQ layouts.

The new exception handler can provide a stack traceback from the
interrupted code, rather than the (uninteresting) caller traceback
displayed by panicf. This allows you to see what led up to a null
pointer deref or division by zero, which makes it _much_ easier to
track down errors that occur in common leaf functions like strcmp.

Change-Id: I59a0ebb5e40fcb36505c3bfdb47f8cac2f9936b1
This commit is contained in:
Aidan MacDonald 2022-05-17 14:48:01 +01:00
parent 56d4227897
commit 4bd97c6535
16 changed files with 430 additions and 463 deletions

View file

@ -45,6 +45,7 @@
.global _start
.section .init.text
.set push
.set mips32
.set noreorder
.set noat
@ -169,8 +170,8 @@ _stack_loop:
Set up interrupt stack
----------------------------------------------------
*/
la k0, irqstackend
la t0, irqstackbegin
la k0, _irqstackend
la t0, _irqstackbegin
_irq_stack_loop:
addiu t0, 4
@ -187,162 +188,4 @@ _irq_stack_loop:
j main
move ra, zero /* init backtrace root */
/*
* 0x0 - Simple TLB refill handler
* 0x100 - Cache error handler
* 0x180 - Exception/Interrupt handler
* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE)
*/
.section .vectors.1, "ax", %progbits
j tlb_refill_handler
ssnop
.section .vectors.2, "ax", %progbits
j real_exception_handler
ssnop
.section .vectors.3, "ax", %progbits
j real_exception_handler
ssnop
.section .vectors.4, "ax", %progbits
j real_exception_handler
ssnop
.section .vectors, "ax", %progbits
real_exception_handler:
/* Store stack pointer */
move k0, sp
/* jump to IRQ stack */
la sp, irqstackend
/* Push crap on frame */
addiu sp, -0x84
/* store current stack pointer */
sw k0, 0x80(sp)
sw ra, 0(sp)
sw fp, 4(sp)
sw gp, 8(sp)
sw t9, 0xC(sp)
sw t8, 0x10(sp)
sw s7, 0x14(sp)
sw s6, 0x18(sp)
sw s5, 0x1C(sp)
sw s4, 0x20(sp)
sw s3, 0x24(sp)
sw s2, 0x28(sp)
sw s1, 0x2C(sp)
sw s0, 0x30(sp)
sw t7, 0x34(sp)
sw t6, 0x38(sp)
sw t5, 0x3C(sp)
sw t4, 0x40(sp)
sw t3, 0x44(sp)
sw t2, 0x48(sp)
sw t1, 0x4C(sp)
sw t0, 0x50(sp)
sw a3, 0x54(sp)
sw a2, 0x58(sp)
sw a1, 0x5C(sp)
sw a0, 0x60(sp)
sw v1, 0x64(sp)
sw v0, 0x68(sp)
sw $1, 0x6C(sp)
mflo k0
ssnop
sw k0, 0x70(sp)
mfhi k0
ssnop
sw k0, 0x74(sp)
mfc0 k0, C0_STATUS
ssnop
ssnop
ssnop
sw k0, 0x78(sp)
mfc0 k0, C0_EPC
ssnop
ssnop
ssnop
sw k0, 0x7C(sp)
li k1, M_CauseExcCode
mfc0 k0, C0_CAUSE
and k0, k1
beq zero, k0, _int
ssnop
j _exception
ssnop
_int:
jal intr_handler
ssnop
j _exception_return
_exception:
move a0, sp
mfc0 a1, C0_CAUSE
ssnop
ssnop
ssnop
mfc0 a2, C0_EPC
ssnop
ssnop
ssnop
jal exception_handler
ssnop
_exception_return:
lw ra, 0(sp)
lw fp, 4(sp)
lw gp, 8(sp)
lw t9, 0xC(sp)
lw t8, 0x10(sp)
lw s7, 0x14(sp)
lw s6, 0x18(sp)
lw s5, 0x1C(sp)
lw s4, 0x20(sp)
lw s3, 0x24(sp)
lw s2, 0x28(sp)
lw s1, 0x2C(sp)
lw s0, 0x30(sp)
lw t7, 0x34(sp)
lw t6, 0x38(sp)
lw t5, 0x3C(sp)
lw t4, 0x40(sp)
lw t3, 0x44(sp)
lw t2, 0x48(sp)
lw t1, 0x4C(sp)
lw t0, 0x50(sp)
lw a3, 0x54(sp)
lw a2, 0x58(sp)
lw a1, 0x5C(sp)
lw a0, 0x60(sp)
lw v1, 0x64(sp)
lw v0, 0x68(sp)
lw $1, 0x6C(sp)
lw k0, 0x70(sp)
mtlo k0
ssnop
lw k0, 0x74(sp)
mthi k0
ssnop
lw k0, 0x78(sp)
mtc0 k0, C0_STATUS
ssnop
ssnop
ssnop
lw k0, 0x7C(sp)
mtc0 k0, C0_EPC
ssnop
ssnop
ssnop
/* Restore previous stack pointer */
lw sp, 0x80(sp)
eret
ssnop
.set reorder
.set at
.set pop