FreeCalypso > hg > fc-tourmaline
diff src/cs/system/main/gcc/exceptions.S @ 0:4e78acac3d88
src/{condat,cs,gpf,nucleus}: import from Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:23:26 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/system/main/gcc/exceptions.S Fri Oct 16 06:23:26 2020 +0000 @@ -0,0 +1,125 @@ +/* + * This module contains ARM exception handlers which used to be + * in chipsetsw/system/Main/int.s in TI's original version. + */ + + .text + .code 32 + +@ layout of xdump buffer: +@ struct xdump_s { +@ long registers[16] // svc mode registers +@ long cpsr // svc mode CPSR +@ long exception // magic word + index of vector taken +@ long stack[20] // bottom 20 words of usr mode stack +@ } + + .globl _arm_undefined +_arm_undefined: + @ store r12 for Xdump_buffer pointer, r11 for index + stmfd r13!,{r11,r12} + mov r11,#1 + b save_regs + + .globl _arm_swi +_arm_swi: + @ store r12 for Xdump_buffer pointer, r11 for index + stmfd r13!,{r11,r12} + mov r11,#2 + b save_regs + + .globl _arm_abort_prefetch +_arm_abort_prefetch: + @ store r12 for Xdump_buffer pointer, r11 for index + stmfd r13!,{r11,r12} + mov r11,#3 + b save_regs + + .globl _arm_abort_data +_arm_abort_data: + @ store r12 for Xdump_buffer pointer, r11 for index + stmfd r13!,{r11,r12} + mov r11,#4 + b save_regs + + .globl _arm_reserved +_arm_reserved: + ldr r13,=_Except_Stack_SP @ mode unknown + @ store r12 for Xdump_buffer pointer, r11 for index + stmfd r13!,{r11,r12} + mov r11,#5 + b save_regs + +save_regs: + ldr r12,=xdump_buffer + str r14,[r12,#4*15] @ save r14_abt (original PC) into r15 slot + + stmia r12,{r0-r10} @ save unbanked registers (except r11 and r12) + ldmfd r13!,{r0,r1} @ get original r11 and r12 + str r0,[r12,#4*11] @ save original r11 + str r1,[r12,#4*12] @ save original r12 + mrs r0,spsr @ get original psr + str r0,[r12,#4*16] @ save original cpsr + + mrs r1,cpsr @ save mode psr + bic r2,r1,#0x1f @ psr with mode bits cleared + and r0,r0,#0x1f @ get original mode bits + add r0,r0,r2 + + msr cpsr,r0 @ move to pre-exception mode + str r13,[r12,#4*13] @ save original SP + str r14,[r12,#4*14] @ save original LR + msr cpsr,r1 @ restore mode psr + + @ r11 has original index + orr r10,r11,#0xDE<<24 @ r10 = 0xDEAD0000 + index of vector taken + orr r10,r10,#0xAD<<16 + str r10,[r12,#4*17] @ save magic + index + + mov r0,r11 @ put index into 1st argument + b dar_exception + +@ the second part + +/* + * For the SP-in-RAM validity check, we use the following simplification: + * it doesn't really matter what the actual IRAM and XRAM sizes are on + * any given target, as the address decoder hooked up to the ARM7TDMI core + * always decodes the full 8 MiB address range for each, causing the + * actual memories to be aliased multiple times in those two ranges. + * Furthermore, the XRAM address range falls right after the IRAM one, + * thus we can get away with only a single range check. + */ + +#define RAM_LOW 0x00800000 +#define RAM_HIGH 0x01800000 + +#define XDUMP_STACK_SIZE 20 + + .globl exception +exception: + ldr r12,=xdump_buffer + ldr r11,[r12,#4*13] @ get svc mode r13 + add r12,r12,#4*18 @ base of stack buffer + + @ check if svc r13(sp) is within internal/external RAM. + @ It *could* be invalid. + cmp r11,#RAM_LOW + blt nostack + mov r0,#RAM_HIGH + sub r0,r0,#XDUMP_STACK_SIZE + cmp r11,r0 + bge nostack + +stack_range: + ldmfd r11!,{r0-r9} @ copy ten stack words.. + stmia r12!,{r0-r9} + ldmfd r11!,{r0-r9} @ copy ten stack words.. + stmia r12!,{r0-r9} + +nostack: + @ we're finished saving all state. + @ Now execute C code for more flexibility. + @ set up a stack for this C call + ldr sp,=_Stack_segment_end + b dar_reset