FreeCalypso > hg > fc-tourmaline
view src/cs/system/main/gcc/exceptions.S @ 303:f76436d19a7a default tip
!GPRS config: fix long-standing AT+COPS chance hanging bug
There has been a long-standing bug in FreeCalypso going back years:
sometimes in the AT command bring-up sequence of an ACI-only MS,
the AT+COPS command would produce only a power scan followed by
cessation of protocol stack activity (only L1 ADC traces), instead
of the expected network search sequence. This behaviour was seen
in different FC firmware versions going back to Citrine, and seemed
to follow some law of chance, not reliably repeatable.
This bug has been tracked down and found to be specific to !GPRS
configuration, stemming from our TCS2/TCS3 hybrid and reconstruction
of !GPRS support that was bitrotten in TCS3.2/LoCosto version.
ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3
version and had to be pulled from TCS2 - but as it turns out,
there is a new field in the MMR_REG_REQ primitive that needs to be
set correctly, and that psa_mms.c module is the place where this
initialization needed to be added.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 08 Jun 2023 08:23:37 +0000 |
parents | 4e78acac3d88 |
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