diff src/cs/system/main/gcc/bootentry.S @ 0:92470e5d0b9e

src: partial import from FC Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 15 May 2020 01:28:16 +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 May 15 01:28:16 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