FreeCalypso > hg > fc-tourmaline
diff src/cs/system/main/gcc/bootentry.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/bootentry.S Fri Oct 16 06:23:26 2020 +0000 @@ -0,0 +1,390 @@ +/* + * 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