view src/cs/system/main/gcc/exceptions.S @ 0:92470e5d0b9e

src: partial import from FC Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 15 May 2020 01:28:16 +0000
parents
children
line wrap: on
line source

/*
 * 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