view src/cs/system/main/gcc/bootentry.S @ 287:3dee79757ae4

UI fw: load handheld audio mode on boot We have now reached the point where use of audio mode config files should be considered mandatory. In ACI usage we can tell users that they need to perform an AT@AUL of some appropriate audio mode, but in UI-enabled fw we really need to have the firmware load audio modes on its own, so that correct audio config gets established when the handset or development board runs on its own, without a connected host computer. Once have FC Venus with both main and headset audio channels and headset plug insertion detection, our fw will need to automatically load the handheld mode or the headset mode depending on the plug insertion state. For now we load only the handheld mode, which has been tuned for FC-HDS4 on FC Luna.
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 13 Nov 2021 03:20:57 +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