#************************************************************************* # *** STR912 Startup Code For GNU Tools (executed after Reset) *** # # (C) Hitex (UK) Ltd. 2006 # # Disclaimer: Whilst every effort has been made to ensure the correctness # of this code, Hitex (UK) Ltd. cannot be held responsible for the consequences # of its use. Users should therefore verify its operation before including it # in any program. #************************************************************************* # # # --------------------------------------------- # Include startup macros # --------------------------------------------- .include "./startup_generic.S" # reference to external interrupt handlers # # .extern SWI_Handler # .extern PAbt_Handler # .extern DAbt_Handler # .extern Undefined_Handler # .extern FIQ_Handler # # Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs # .equ Mode_USR, 0x10 .equ Mode_FIQ, 0x11 .equ Mode_IRQ, 0x12 .equ Mode_SVC, 0x13 .equ Mode_ABT, 0x17 .equ Mode_UND, 0x1B .equ Mode_SYS, 0x1F # .equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */ .equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */ # # # System Memory definitions # # Internal RAM definitions .equ RAM_Size, 0x00018000 /* 96K */ .equ RAM_Base, 0x04000000 #************************************************************************* # Control Startup Code Operation #************************************************************************* .equ SRAM_SETUP , 0 /* Enable setup of SRAM */ .equ FMI_SETUP , 0 /* Enable FMI Setup */ .equ CLOCK_SETUP , 1 /* Enable clock setup */ .equ ETM_SETUP , 0 /* Enable ETM setup */ #************************************************************************* # Hardware Definitions #************************************************************************* # Flash Memory Interface (FMI) definitions (Flash banks sizes and addresses) .equ FMI_BASE , 0x54000000 /* FMI Base Address (non-buffered) */ .equ FMI_BBSR_OFS , 0x00 /* Boot Bank Size Register */ .equ FMI_NBBSR_OFS , 0x04 /* Non-boot Bank Size Register */ .equ FMI_BBADR_OFS , 0x0C /* Boot Bank Base Address Register #!!! Documentation page 30,*/ .equ FMI_NBBADR_OFS , 0x10 /* Non-boot Bank Base Address Register #!!! adresseses do not correspond*/ .equ FMI_CR_OFS , 0x18 /* Control Register */ .equ FMI_SR_OFS , 0x1C /* Status Register */ .equ FMI_CR_Val , 0x00000018 .equ FMI_BBSR_Val , 0x00000004 .equ FMI_BBADR_Val , 0x00000000 .equ FMI_NBBSR_Val , 0x00000002 .equ FMI_NBBADR_Val , 0x00080000 .equ FLASH_CFG_Val , 0x00001010 .equ FMI_SR_Val , 0x00000003 /* Clear status errors (register not in STR912 manual! */ # System Control Unit (SCU) definitions .equ SCU_BASE , 0x5C002000 /* SCU Base Address (non-buffered) */ .equ SCU_CLKCNTR_OFS , 0x00 /* Clock Control register Offset */ .equ SCU_PLLCONF_OFS , 0x04 /* PLL Configuration register Offset */ .equ SCU_SYSTAT_OFS , 0x08 /* SCU status register offset */ .equ SCU_PCGR0_OFS , 0x14 /* Peripheral Clock Gating Register 0 Offset */ .equ SCU_PCGR1_OFS , 0x18 /* Peripheral Clock Gating Register 1 Offset */ .equ SCU_SCR0_OFS , 0x34 /* System Configuration Register 0 Offset */ .equ SCU_CLKCNTR_Val , 0x00030000 /* Use PLL, external memory ratio/2 */ .equ SCU_PLLCONF_Val , 0x000AC019 .equ SCU_PCGR0_Val , 0x000000DB /* Setup ext mem clock, EMI, SRAM, Prefetch Queue/Branch cache, FMI */ .equ SCU_PCGR1_Val , 0x00C40000 /* Setup GPIO8, 9 & 4 */ .equ SCU_SCR0_Val , 0x00000196 /* Disable Prefetch Queue and Branch cache, SRAM = 96kb */ .equ SCU_SYSSTAT_LOCK , 0x01 /* Check for PLL locked */ # APB Bridge 1 & 2 definitions (Peripherals) .equ APB0_BUF_BASE , 0x48001802 /* APB Bridge 0 Buffered Base Address */ .equ APB0_NBUF_BASE , 0x58000000 /* APB Bridge 0 Non-buffered Base Address */ .equ APB1_BUF_BASE , 0x4C000000 /* APB Bridge 1 Buffered Base Address */ .equ APB1_NBUF_BASE , 0x5C000000 /* APB Bridge 1 Non-buffered Base Address */ # ETM Definitions .equ IOPORT2_ETM_ENABLE_BASE , 0x5C00204C .equ IOPORT6_ETM_ENABLE_BASE , 0x5C00205C .equ IOPORT2_ETM_ENABLE_VAL , 0x0000FFFF .equ IOPORT6_ETM_ENABLE_VAL , 0x0000FFFF #************************************************************************* # Stack definitions #************************************************************************* .equ UND_Stack_Size, 8 .equ SVC_Stack_Size, 256 .equ ABT_Stack_Size, 8 .equ FIQ_Stack_Size, 32 .equ IRQ_Stack_Size, 512 .equ USR_Stack_Size, 512 .equ Top_Stack, RAM_Base + RAM_Size # NOTE: Startup Code must be linked first at Address at which it expects to run. #************************************************************************* # STARTUP EXECUTABLE CODE #************************************************************************* .text .arm .extern main .global _startup _startup: #************************************************************************* # Exception Vectors #************************************************************************* Vectors: LDR PC, Reset_Addr /* 0x0000 */ LDR PC, Undef_Addr /* 0x0004 */ LDR PC, SWI_Addr /* 0x0008 */ LDR PC, PAbt_Addr /* 0x000C */ LDR PC, DAbt_Addr /* 0x0010 */ NOP /* 0x0014 Reserved Vector */ LDR PC, [PC, #-0xFF0] /* 0x0018 wraps around address space to 0xFFFFFF030. Vector from VicVECAddr */ LDR PC, FIQ_Addr /* 0x001C FIQ has no VIC vector slot! */ #************************************************************************* # Interrupt Vectors #************************************************************************* Reset_Addr: .word Hard_Reset /* CPU reset vector and entry point */ Undef_Addr: .word Undefined_Handler SWI_Addr: .word SWI_Handler PAbt_Addr: .word PAbt_Handler DAbt_Addr: .word DAbt_Handler .word 0 /* Reserved Address */ IRQ_Addr: .word IRQ_Handler /* Does not get used due to "LDR PC, [PC, #-0xFF0]" above */ FIQ_Addr: .word FIQ_Handler # Dummy Interrupt Vector Table (real service routines in INTERRUPT.C) Undefined_Handler: B Undefined_Handler SWI_Handler: B SWI_Handler PAbt_Handler: B PAbt_Handler DAbt_Handler: B DAbt_Handler IRQ_Handler: B IRQ_Handler /* should never get here as IRQ is via VIC slot... */ FIQ_Handler: B FIQ_Handler #************************************************************************* # Reset Handler Entry Point #************************************************************************* Hard_Reset: StartupDelay 500000 #************************************************************************* # Setup SRAM Size .IF SRAM_SETUP == 1 LDR R0, =SCU_BASE LDR R1, =SCU_SCR0_Val STR R1, [R0, #SCU_SCR0_OFS] .ENDIF #************************************************************************* # Setup Flash Memory Interface (FMI) .IF FMI_SETUP == 1 LDR R0, =FMI_BASE LDR R1, =FMI_BBSR_Val STR R1, [R0, #FMI_BBSR_OFS] LDR R1, =FMI_NBBSR_Val STR R1, [R0, #FMI_NBBSR_OFS] LDR R1, =(FMI_BBADR_Val >> 2) STR R1, [R0, #FMI_BBADR_OFS] LDR R1, =(FMI_NBBADR_Val >> 2) STR R1, [R0, #FMI_NBBADR_OFS] LDR R2, =FMI_CR_Val STR R2, [R0, #FMI_CR_OFS] LDR R2, =FMI_SR_Val STR R2, [R0, #FMI_SR_OFS] # Write "Write flash configuration" command (60h) MOV R0, R1, LSL #2 MOV R1, #0x60 STRH R1, [R0, #0] # Write "Write flash configuration confirm" command (03h) LDR R2, =(FLASH_CFG_Val >> 2) ADD R0, R0, R2 MOV R1, #0x03 STRH R1, [R0, #0] .ENDIF #************************************************************************* # Setup Clock PLL .IF CLOCK_SETUP == 1 LDR R0, =SCU_BASE LDR R1, =0x00020002 STR R1, [R0, #SCU_CLKCNTR_OFS] /* Select OSC as clock src */ NOP /* Wait for oscillator stabilisation */ NOP /* Must be more than 10 oscillator periods */ NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP LDR R1, =0x0003C019 /* Disable PLL */ STR R1, [R0, #SCU_PLLCONF_OFS] LDR R1, =SCU_PLLCONF_Val STR R1, [R0, #SCU_PLLCONF_OFS] /* Set new PLL values */ .IF (SCU_PLLCONF_Val & 0x8000) /* See if PLL is being used */ LDR R1, =SCU_SYSSTAT_LOCK PLL_LOCK_LOOP: LDR R2,[R0, #SCU_SYSTAT_OFS] /* Wait for PLL lock */ ANDS R2, R2, R1 BEQ PLL_LOCK_LOOP .ENDIF LDR R1, =SCU_PLLCONF_Val STR R1, [R0, #SCU_PLLCONF_OFS] LDR R1, =SCU_CLKCNTR_Val STR R1, [R0, #SCU_CLKCNTR_OFS] LDR R1, =SCU_PCGR0_Val /* Enable clock gating */ STR R1, [R0, #SCU_PCGR0_OFS] LDR R1, =SCU_PCGR1_Val STR R1, [R0, #SCU_PCGR1_OFS] .ENDIF #************************************************************************* # Embedded Trace Module Setup #************************************************************************* .IF ETM_SETUP == 1 # Configure IOPORT2 for ETM operation LDR R0, =IOPORT2_ETM_ENABLE_BASE LDR R1, =IOPORT2_ETM_ENABLE_VAL STR R1, [R0, #0] # Configure IOPORT6 for ETM operation LDR R0, =IOPORT6_ETM_ENABLE_BASE LDR R1, =IOPORT6_ETM_ENABLE_VAL STR R1, [R0, #0] .ENDIF #************************************************************************* # Compiler Runtime Environment Setup #************************************************************************* # Note: R13 = SP # Setup Stack for each mode LDR R0, =Top_Stack # Set up Fast Interrupt Mode and set FIQ Mode Stack MSR CPSR_c, #Mode_FIQ|I_BIT|F_BIT mov r13, r0 sub r0, r0, #FIQ_Stack_Size # Set up Interrupt Mode and set IRQ Mode Stack msr CPSR_c, #Mode_IRQ|I_BIT|F_BIT mov r13, r0 sub r0, r0, #IRQ_Stack_Size # Set up Abort Mode and set Abort Mode Stack msr CPSR_c, #Mode_ABT|I_BIT|F_BIT mov r13, r0 sub r0, r0, #ABT_Stack_Size # Set up Undefined Instruction Mode and set Undef Mode Stack msr CPSR_c, #Mode_UND|I_BIT|F_BIT mov r13, r0 sub r0, r0, #UND_Stack_Size # Set up Supervisor Mode and set Supervisor Mode Stack msr CPSR_c, #Mode_SVC|I_BIT|F_BIT mov r13, r0 sub r0, r0, #SVC_Stack_Size # Set up User Mode and set User Mode Stack msr CPSR_c, #Mode_USR /* Leave interrupts enabled in user mode */ mov r13, r0 /* Note: interrupts will not happen until VIC is enabled */ # Setup a default Stack Limit (when compiled with "-mapcs-stack-check") SUB SL, SP, #1<<10 /* 1kB */ # Initialise current CPU status to prevent unwanted interrupts # msr CPSR_c,#0xD3 #************************************************************************* # Initialise RAM For Compiler Variables #************************************************************************* copy_section2 data, _etext, __data_start__, _edata #************************************************************************* # Clear .bss section #************************************************************************* clear_section bss, __bss_start__, __bss_end__ clear_section bss2, __bss2_start__, __bss2_end__ #************************************************************************* # Enter the C code #************************************************************************* # Jump to main() B main .size _startup, . - _startup #************************************************************************* # END #************************************************************************* .end