/* * Wrapper for exception handlers that saves registers on the stack * * Address of exception handler to be called must be in register k0 * This wrapper is not for interrupt exceptions. * * signature of the exception handler called by this wrapper: * pub extern "C" fn _general_exception_handler(cp0_cause: u32, cp0_status: u32); * */ #include #include .section .text.exception_context, "ax" .set noreorder .set noat .set nomips16 .globl _exception_context .ent _exception_context _exception_context: # Save off the non-callee saved registers that may get mucked with addiu sp, sp, -88 sw $1, 4(sp) // 1 sw v0, 8(sp) // 2 sw v1, 12(sp) // 3 sw a0, 16(sp) // 4 sw a1, 20(sp) // 5 sw a2, 24(sp) // 6 sw a3, 28(sp) // 7 sw t0, 32(sp) // 8 sw t1, 36(sp) // 9 sw t2, 40(sp) // 10 sw t3, 44(sp) // 11 sw t4, 48(sp) // 12 sw t5, 52(sp) // 13 sw t6, 56(sp) // 14 sw t7, 60(sp) // 15 // 16-23 s0-s7, callee saved sw t8, 64(sp) // 24 sw t9, 68(sp) // 25 // 26-27 kernel use // 28 Global pointer (GP) // 29 Stack pointer (SP) // 30 Frame Pointer (FP) or s8 (callee saved) sw ra, 72(sp) // 31 mflo t0 sw t0, 76(sp) mfhi t0 sw t0, 80(sp) # Pass Cause and Status to the handler function mfc0 a0, _CP0_CAUSE mfc0 a1, _CP0_STATUS jalr k0 nop lw t0, 80(sp) mthi t0 lw t0, 76(sp) mtlo t0 lw $1, 4(sp) lw v0, 8(sp) lw v1, 12(sp) lw a0, 16(sp) lw a1, 20(sp) lw a2, 24(sp) lw a3, 28(sp) lw t0, 32(sp) lw t1, 36(sp) lw t2, 40(sp) lw t3, 44(sp) lw t4, 48(sp) lw t5, 52(sp) lw t6, 56(sp) lw t7, 60(sp) lw t8, 64(sp) lw t9, 68(sp) lw ra, 72(sp) addiu sp, sp, 88 ehb eret .end _exception_context