FreeCalypso > hg > fc-tourmaline
view src/cs/system/main/gcc/bootentry.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 assembly module is our counterpart to TI's int.s: all boot entry * point code that needs to be at the beginning of the flash resides here. */ #include "asm_defs.h" #include "fc-target.h" #include "rf.cfg" #if defined(FLASH) && !defined(CONFIG_TARGET_COMPAL) /* * Put something sensible in the boot ROM overlay area, just for the * heck of it, or for extra robustness. */ .section bootrom.overlay,"ax",%progbits .code 32 .org 0 b BootROM_disabled_entry #include "vectors.S" BootROM_disabled_entry: /* copy the boot ROM switch code to IRAM and jump to it */ ldr r4, =__romswitch_flash_addr ldr r5, =__romswitch_ram_addr ldr r2, =__romswitch_size 1: ldr r0, [r4], #4 str r0, [r5], #4 subs r2, r2, #4 bhi 1b ldr pc, =__romswitch_ram_addr .section bootrom.switch,"ax",%progbits .code 32 .org 0 @ enable the Calypso boot ROM ldr r1, =0xFFFFFB10 mov r2, #0x0100 strh r2, [r1] @ jump to it! mov pc, #0 #endif .section .inttext,"ax",%progbits .code 32 #ifdef FLASH .org 0 #ifndef CONFIG_TARGET_COMPAL /* sane targets with Calypso boot ROM enabled by the PCB wiring */ /* provide the necessary magic words for the boot ROM */ .word 0 .word _Firmware_boot_entry #elif defined(CONFIG_TARGET_C11X) || defined(CONFIG_TARGET_C139) || \ defined(CONFIG_TARGET_J100) /* * On this target we'll put a patched version of Compal's boot code in * flash sector 0 (the brickable one); the main fw images will then be * flashed starting at 0x10000, which is where our modified boot code * expects them to be. The interface between our hacked boot code and * the main fw has been made to mimic TI's TCS211 reference fw. */ #include "vectors.S" .org 0x58 /* entry point at 0x10058 */ b _Firmware_boot_entry #elif defined(CONFIG_TARGET_C155) /* * On this target the hand-off point between the bootloader and the main * fw image coincides with a flash erase block boundary, thus we can reuse * the original bootloader without having to reflash the brickable sector * at all. The following bits will appear at 0x20000. */ .asciz "FreeCalypso firmware for C155/156 target" .org 0xE0 /* C155/156 bootloader jumps here */ b _Firmware_boot_entry #include "vectors.S" #else #error "Unsupported flash boot configuration" #endif #endif /* definitions from TI's int.s */ #define IRQ_STACK_SIZE 128 #define FIQ_STACK_SIZE 512 #define SYSTEM_SIZE 1024 #define TIMER_SIZE 1024 #define TIMER_PRIORITY 2 @ TI's literal pool before the entry point addrCS0: .word 0xfffffb00 @ CS0 address space EX_MPU_CONF_REG: .word 0xFFFEF006 @ Extended MPU configuration register address EX_FLASH_VALUE: .short 0x0008 @ set bit to enable A22 .balign 4 CNTL_ARM_CLK_REG: .word 0xFFFFFD00 @ CNTL_ARM_CLK register address DPLL_CNTRL_REG: .word 0xFFFF9800 @ DPLL control register address EXTRA_CONTROL_REG: .word 0xFFFFFB10 @ Extra Control register CONF address MPU_CTL_REG: .word 0xFFFFFF08 @ MPU_CTL register address CNTL_ARM_CLK_RST: .short 0x1081 @ Initialization of CNTL_ARM_CLK register @ Use DPLL, Divide by 1 DPLL_CONTROL_RST: .short 0x2002 @ Configure DPLL in default state DISABLE_DU_MASK: .short 0x0800 @ Mask to Disable the DU module ENABLE_DU_MASK: .short 0xF7FF @ Mask to Enable the DU module MPU_CTL_RST: .short 0x0000 @ Reset value of MPU_CTL register - All protections disabled @ FreeCalypso change, please see MEMIF-wait-states document @ in the freecalypso-docs repository for the explanation. #if (RF_FAM == 12) CS0_MEM_REG: .short 0x2a2 @ 1 Dummy Cycle 16 bit 2 WS SW BP enable CS1_MEM_REG: .short 0x2a2 @ 1 Dummy Cycle 16 bit 2 WS SW BP enable CS2_MEM_REG: .short 0x2a2 @ 1 Dummy Cycle 16 bit 2 WS SW BP enable #else CS0_MEM_REG: .short 0x2a1 @ 1 Dummy Cycle 16 bit 1 WS SW BP enable CS1_MEM_REG: .short 0x2a1 @ 1 Dummy Cycle 16 bit 1 WS SW BP enable CS2_MEM_REG: .short 0x2a1 @ 1 Dummy Cycle 16 bit 1 WS SW BP enable #endif CS3_MEM_REG: .short 0x283 @ 1 Dummy Cycle 8 bit 3 WS SW BP enable CS4_MEM_REG: .short 0xe85 @ default reset value CS6_MEM_REG: .short 0x2c0 @ Internal RAM init : 0 WS, 32 bits, little, write enable CS7_MEM_REG: .short 0x040 @ Internal BOOT ROM init : 0 WS, 32 bits, little, write disable CTL_MEM_REG: .short 0x02a @ rhea strobe 0/1 + API access size adaptation .balign 4 .globl _Firmware_boot_entry _Firmware_boot_entry: @ TI's code from int.s follows @ @ Configure DPLL register with reset value @ ldr r1,DPLL_CNTRL_REG @ Load address of DPLL register in R1 ldrh r2,DPLL_CONTROL_RST @ Load DPLL reset value in R2 strh r2,[r1] @ Store DPLL reset value in DPLL register @ @ Wait that DPLL goes in BYPASS mode @ Wait_DPLL_Bypass: ldr r2,[r1] @ Load DPLL register and r2,r2,#1 @ Perform a mask on bit 0 cmp r2,#1 @ Compare DPLL lock bit beq Wait_DPLL_Bypass @ Wait Bypass mode (i.e. bit[0]='0') @ @ Configure CNTL_ARM_CLK register with reset value: DPLL is used to @ generate ARM clock with division factor of 1. @ ldr r1,CNTL_ARM_CLK_REG @ Load address of CNTL_ARM_CLK register in R1 ldrh r2,CNTL_ARM_CLK_RST @ Load CNTL_ARM_CLK reset value in R2 strh r2,[r1] @ Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register @ @ Disable/Enable the DU module by setting/resetting bit 11 to '1'/'0' @ ldr r1,EXTRA_CONTROL_REG @ Load address of Extra Control register CONF ldrh r2,ENABLE_DU_MASK @ Load mask to write in Extra Control register CONF ldrh r0,[r1] @ Load Extra Control register CONF in r0 and r0,r0,r2 @ Enable DU module strh r0,[r1] @ Store configuration in Extra Control register CONF @ @ Disable all MPU protections @ ldr r1,MPU_CTL_REG @ Load address of MPU_CTL register ldrh r2,MPU_CTL_RST @ Load reset value of MPU_CTL register strh r2,[r1] @ Store reset value of MPU_CTL register @ MEMIF timing setup ldr r1,addrCS0 ldrh r2,CS0_MEM_REG @ ROM initialization strh r2,[r1] @ CS0 ldrh r2,CS1_MEM_REG @ RAM Initialization strh r2,[r1,#2] @ CS1 ldrh r2,CS2_MEM_REG @ RAM Initialization strh r2,[r1,#4] @ CS2 ldrh r2,CS3_MEM_REG @ Parallel I/O on B-Sample strh r2,[r1,#6] @ CS3 (unused on EVA4?) ldrh r2,CS4_MEM_REG @ Latch on B-Sample strh r2,[r1,#0xa] @ CS4 (unused on EVA4) ldrh r2,CS6_MEM_REG @ Internal SRAM initialization strh r2,[r1,#0xc] @ CS6 Internal RAM ldrh r2,CS7_MEM_REG @ Internal SRAM initialization strh r2,[r1,#0x8] @ CS7 Internal Boot ROM ldrh r2,CTL_MEM_REG @ API-RHEA configuration strh r2,[r1,#0xe] @ enable ADD22 ldr r1,EX_MPU_CONF_REG ldrh r2,[r1] ldr r0,EX_FLASH_VALUE orr r0, r0, r2 strh r0,[r1] /* Ensure that the processor is in supervisor mode. */ MRS a1,CPSR @ Pickup current CPSR BIC a1,a1,#MODE_MASK @ Clear the mode bits ORR a1,a1,#SUP_MODE @ Set the supervisor mode bits ORR a1,a1,#LOCKOUT @ Ensure IRQ and FIQ interrupts are @ locked out MSR CPSR,a1 @ Setup the new CPSR /* * FreeCalypso Selenite: if this is a flash build, * copy IRAM code and .data from flash to RAM. */ #ifdef FLASH /* copy iram.text to where it's supposed to be */ ldr r8, =__iramtext_flash_addr ldr r9, =__iramtext_ram_addr ldr r10, =__iramtext_size 1: ldmia r8!, {r0-r7} stmia r9!, {r0-r7} subs r10, r10, #0x20 bhi 1b /* likewise copy .data from flash to XRAM */ ldr r8, =__initdata_flash_addr ldr r9, =__initdata_ram_addr ldr r10, =__initdata_size 1: ldmia r8!, {r0-r7} stmia r9!, {r0-r7} subs r10, r10, #0x20 bhi 1b #endif /* Both flash and XRAM builds: zero .bss */ ldr r0, =__intbss_start ldr r1, =__intbss_size bl bzero ldr r0, =__extbss_start ldr r1, =__extbss_size bl bzero @ TI's int.s code continues @ @ Initialize the system stack pointers. This is done after the BSS is @ cleared because the TCD_System_Stack pointer is a BSS variable! It is @ assumed that the .cmd file is written to direct where these stacks should @ be allocated and to align them on double word boundaries. @ LDR a1,StackSegment @ Pickup the begining address from .cmd file @ (is aligned on 8 byte boundary) MOV a2,#SYSTEM_SIZE @ Pickup system stack size SUB a2,a2,#4 @ Subtract one word for first addr ADD a3,a1,a2 @ Build start of system stack area MOV v7,a1 @ Setup initial stack limit LDR a4,System_Limit @ Pickup system stack limit address STR v7,[a4, #0] @ Save stack limit MOV sp,a3 @ Setup initial stack pointer LDR a4,System_Stack @ Pickup system stack address STR sp,[a4, #0] @ Save stack pointer MOV a2,#IRQ_STACK_SIZE @ Pickup IRQ stack size in bytes ADD a3,a3,a2 @ Allocate IRQ stack area MRS a1,CPSR @ Pickup current CPSR BIC a1,a1,#MODE_MASK @ Clear the mode bits ORR a1,a1,#IRQ_MODE @ Set the IRQ mode bits MSR CPSR,a1 @ Move to IRQ mode MOV sp,a3 @ Setup IRQ stack pointer MOV a2,#FIQ_STACK_SIZE @ Pickup FIQ stack size in bytes ADD a3,a3,a2 @ Allocate FIQ stack area MRS a1,CPSR @ Pickup current CPSR BIC a1,a1,#MODE_MASK @ Clear the mode bits ORR a1,a1,#FIQ_MODE @ Set the FIQ mode bits MSR CPSR,a1 @ Move to the FIQ mode MOV sp,a3 @ Setup FIQ stack pointer MRS a1,CPSR @ Pickup current CPSR BIC a1,a1,#MODE_MASK @ Clear the mode bits ORR a1,a1,#ABORT_MODE @ Set the Abort mode bits MSR CPSR,a1 @ Move to the Abort mode LDR sp,Exception_Stack @ Setup Abort stack pointer MRS a1,CPSR @ Pickup current CPSR BIC a1,a1,#MODE_MASK @ Clear the mode bits ORR a1,a1,#UNDEF_MODE @ Set the Undefined mode bits MSR CPSR,a1 @ Move to the Undefined mode LDR sp,Exception_Stack @ Setup Undefined stack pointer @ (should never be used) @ go to Supervisor Mode MRS a1,CPSR @ Pickup current CPSR BIC a1,a1,#MODE_MASK @ Clear mode bits ORR a1,a1,#SUP_MODE @ Set the supervisor mode bits MSR CPSR,a1 @ All interrupt stacks are setup, @ return to supervisor mode @ @ /* Define the global data structures that need to be initialized by this @ routine. These structures are used to define the system timer @ management HISR. */ @ TMD_HISR_Stack_Ptr = (VOID *) a3; @ TMD_HISR_Stack_Size = TIMER_SIZE; @ TMD_HISR_Priority = TIMER_PRIORITY; @ @ TMD_HISR_Stack_Ptr points at the top (the lowest address) of the allocated @ area. The Timer HISR (called "SYSTEM H") and its related stack will be created @ in TMI_Initialize(). The current stack pointer will be set at the bottom (the @ lowest address) of the expected area. LDR a4,HISR_Stack_Ptr @ Pickup variable's address ADD a3,a3,#4 @ Increment to next available word STR a3,[a4, #0] @ Setup timer HISR stack pointer MOV a2,#TIMER_SIZE @ Pickup the timer HISR stack size BIC a2,a2,#3 @ Insure word alignment ADD a3,a3,a2 @ Allocate the timer HISR stack @ from available memory LDR a4,HISR_Stack_Size @ Pickup variable's address STR a2,[a4, #0] @ Setup timer HISR stack size MOV a2,#TIMER_PRIORITY @ Pickup timer HISR priority (0-2) LDR a4,HISR_Priority @ Pickup variable's address STR a2,[a4, #0] @ Setup timer HISR priority /* TI's original code called f_load_int_mem() at this point */ /* let's do our internal ROM enable step here */ ldr r1, EXTRA_CONTROL_REG ldrh r0, [r1, #0] bic r0, #0x0300 orr r0, #0x0100 strh r0, [r1, #0] @ We now fill up the System, IRQ, FIQ and System Timer HISR stacks with 0xFE for @ checking the status of the stacks later. @ inputs: @ a3 still has the bottom of all four stacks and is aligned. @ algorithm: @ We start from the top of all four stacks (*System_Limit), which is @ necessarily aligned. We store 0xFEFEFEFE until we have filled the @ bottom of the fourth stack @ outputs: @ memory has 0xFE on all four stacks: System, FIQ, IRQ and System Timer HISR @ a3 still has the bottom of all four stacks LDR a2,System_Limit @ pickup system stack limit address LDR a1,[a2] @ a1 = StackSegment LDR a4,=0xFEFEFEFE fill_stack: STR a4,[a1],#4 @ store a word and increment by four CMP a1,a3 @ is this the last address? BLT fill_stack @ if not, loop back @ @ /* Call INC_Initialize with a pointer to the first available memory @ address after the compiler's global data. This memory may be used @ by the application. */ @ INC_Initialize(first_available_memory); @ MOV a1,a3 @ Pass the first available memory B INC_Initialize @ to high-level initialization @ literal pool from int.s (after the code) StackSegment: .word _Stack_segment_start System_Limit: .word TCT_System_Limit System_Stack: .word TCD_System_Stack HISR_Stack_Ptr: .word TMD_HISR_Stack_Ptr HISR_Stack_Size: .word TMD_HISR_Stack_Size HISR_Priority: .word TMD_HISR_Priority Exception_Stack: .word _Except_Stack_SP