FreeCalypso > hg > fc-selenite
changeset 78:95ef11e76c5b
src/cs/system/main/gcc: asm code pieced from Citrine
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 20 Jul 2018 06:46:56 +0000 |
parents | 6b6675a07b70 |
children | 621b358b760d |
files | src/cs/system/main/gcc/exceptions.S src/cs/system/main/gcc/irq_twiddle.S src/cs/system/main/gcc/irqfiq.S src/cs/system/main/gcc/ramvecs.S src/cs/system/main/gcc/vectors.S |
diffstat | 5 files changed, 207 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/system/main/gcc/exceptions.S Fri Jul 20 06:46:56 2018 +0000 @@ -0,0 +1,86 @@ +/* + * This module contains ARM exception handlers which used to be + * in chipsetsw/system/Main/int.s in TI's Leonardo code. + */ + + .section "except_stack","aw",%nobits + .balign 4 + .space 512 + .globl _Except_Stack_SP +_Except_Stack_SP: + + .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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/system/main/gcc/irq_twiddle.S Fri Jul 20 06:46:56 2018 +0000 @@ -0,0 +1,26 @@ +/* + * TI's L1 code (and possibly other parts of the software suite) calls + * functions named INT_DisableIRQ() and INT_EnableIRQ(); in TI's original + * fw they are implemented (in a very ugly manner, as usual) in the + * int.s entry point assembly module. Here we implement the same + * functions in a cleaner way. + */ + +#include "asm_defs.h" + + .code 32 + .text + + .globl INT_DisableIRQ +INT_DisableIRQ: + mrs r0, CPSR + orr r0, r0, #LOCKOUT + msr CPSR, r0 + bx lr + + .globl INT_EnableIRQ +INT_EnableIRQ: + mrs r0, CPSR + bic r0, r0, #LOCKOUT + msr CPSR, r0 + bx lr
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/system/main/gcc/irqfiq.S Fri Jul 20 06:46:56 2018 +0000 @@ -0,0 +1,73 @@ +/* + * This module contains the assembly shells for IRQ and FIQ, separated + * from the architectured vectors only by some simple unconditional + * branch instructions. + * + * Note that TI's way of handling interrupts sacrifices Nucleus' ability + * to nest interrupts and minimize the IRQ-disabled window: if my (Falcon's) + * understanding is correct, TI's code leaves all further IRQs disabled + * for the full execution duration of an IRQ handler. (IRQ handlers are + * really LISRs, but TI's GSM fw does not use Nucleus' LISR framework.) + */ + + .text + .code 32 + + .globl _INT_IRQ +_INT_IRQ: + STMDB sp!,{r0-r4} @ used to be a1-a4 + +/* + * Thanks to TI for discovering and documenting this apparent ARM7TDMI bug: + +BUG correction 1st part ------------------- +It looks like there is an issue with ARM7 IRQ masking in the CPSR register +which leads to crashes in Nucleus+ scheduler. +Basically the code below (correct as LOCKOUT = 0xC0) is used in many places by N+ but do not +prevent from having an interrupt after the execution of the third line (I mean execution, not +fetch). + MRS a1,CPSR ; Pickup current CPSR + ORR a1,a1,#LOCKOUT ; Build interrupt lockout value + MSR CPSR,a1 ; Lockout interrupts + * IRQ INTERRUPT ! * + Next instructions... + +SW workaround: +When a task is interrupted at this point an interrupted context is stored on its task and will +be resumed later on at the next instruction but to make a long story short it leads to some +problem as the OS does not expect to be interrupted there. +Further testing tends to show that the CPSR *seems* to be loaded with the proper masking value +but that the IRQ is still triggered (has been hardwarewise requested during the instruction +exectution by the ARM7 core?) +*/ + + MRS a1,spsr @ check for the IRQ bug: + TST a1,#0x80 @ if the I - flag is set, + BNE IRQBUG @ then postpone execution of this IRQ +/* Bug correction 1st part end --------------- */ + + SUB r4,lr,#4 @ Save IRQ's lr (return address) + BL TCT_Interrupt_Context_Save @ Call context save routine + + BL IQ_IRQ_isr @ Call int. service routine + + /* IRQ interrupt processing is complete. Restore context- Never + returns! */ + B TCT_Interrupt_Context_Restore + +/* BUG correction 2nd part ------------------ */ +IRQBUG: LDMFD sp!,{r0-r4} @ return from interrupt + SUBS pc,r14,#4 +/* BUG correction 2nd part end -------------- */ + + .globl _INT_FIQ +_INT_FIQ: + STMDB sp!,{r0-r4} @ used to be a1-a4 + SUB r4,lr,#4 @ Save FIQ's lr (return address) + BL TCT_Interrupt_Context_Save @ Call context save routine + + BL IQ_FIQ_isr @ Call the FIQ ISR + + /* FIQ interrupt processing is complete. Restore context- Never + returns! */ + B TCT_Interrupt_Context_Restore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/system/main/gcc/ramvecs.S Fri Jul 20 06:46:56 2018 +0000 @@ -0,0 +1,8 @@ +/* + * This assembly module provides the IRAM vectors + * to which the internal ROM is going to branch. + */ + + .section .ramvecs,"ax",%progbits + .code 32 +#include "vectors.S"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/system/main/gcc/vectors.S Fri Jul 20 06:46:56 2018 +0000 @@ -0,0 +1,14 @@ +/* + * These 7 branch instructions, corresponding to ARM exception and interrupt + * vectors, will be placed in different sections depending on the flashImage + * vs. ramImage configuration and which target we build for; this little + * snippet file will be #included where it is needed. + */ + + b _arm_undefined + b _arm_swi + b _arm_abort_prefetch + b _arm_abort_data + b _arm_reserved + b _INT_IRQ + b _INT_FIQ