Newer
Older
uwuboot / source / arm9 / exception.s
#include "mem_map.h"

.arm
.cpu arm946e-s
.fpu softvfp

.global undefInstrHandler
.global prefetchAbortHandler
.global dataAbortHandler
.global irqHandler

.type undefInstrHandler STT_FUNC
.type prefetchAbortHandler STT_FUNC
.type dataAbortHandler STT_FUNC
.type exceptionHandler STT_FUNC
.type irqHandler STT_FUNC

.extern deinitCpu
.extern guruMeditation
.extern irqHandlerTable

.section ".text"



undefInstrHandler:
	msr cpsr_f, #(0<<29)        @ Abuse conditional flags in cpsr for temporary exception type storage
	b exceptionHandler
prefetchAbortHandler:
	msr cpsr_f, #(1<<29)
	b exceptionHandler
dataAbortHandler:
	msr cpsr_f, #(2<<29)
exceptionHandler:
	mov sp, #A9_EXC_STACK_END
	stmfd sp!, {r0-r14}^        @ Save all user/system mode regs except pc
	mrs r4, cpsr
	lsr r4, r4, #29             @ Get back the exception type from cpsr
	mrs r1, spsr                @ Get saved cpsr
	stmfd sp!, {r1, lr}         @ Save spsr and lr (pc) on exception stack
	mov r5, sp
	msr cpsr_cxsf, #0xDF        @ Disable all interrupts, system mode
	bl deinitCpu
	mov r0, r4
	mov sp, r5
	mov r1, r5
	b guruMeditation            @ r0 = exception type, r1 = reg dump ptr {cpsr, pc (unmodified), r0-r14}
.pool


irqHandler:
	stmfd sp!, {r0-r3, r12, lr}
	ldr r12, =(IO_MEM_ARM9_ONLY + 0x1000) @ REG_IRQ_IE
	ldmia r12, {r1, r2}
	and r1, r1, r2
	mov r3, #0x80000000
irqHandler_find_first_lp:
	clz r0, r1
	bics r1, r1, r3, lsr r0
	bne irqHandler_find_first_lp
	mov r1, r3, lsr r0
	str r1, [r12, #4]           @ REG_IRQ_IF
	rsb r2, r0, #31             @ r2 = 31 - r0
	ldr r1, =irqHandlerTable
	ldr r0, [r1, r2, lsl #2]
	cmp r0, #0
	blxne r0
	ldmfd sp!, {r0-r3, r12, lr}
	subs pc, lr, #4
.pool