/* * startup.S * * Copyright (c) 2020 Semidrive Semiconductor. * All rights reserved. * * Description: ARM start function. * * Revision History: * ----------------- */ INCLUDE config.h INCLUDE armv7-r/arm.h INCLUDE armv7-r/cache.h MODULE ?cstartup ;; Forward declaration of sections. SECTION IRQ_STACK:DATA:NOROOT(3) SECTION FIQ_STACK:DATA:NOROOT(3) SECTION SVC_STACK:DATA:NOROOT(3) SECTION ABT_STACK:DATA:NOROOT(3) SECTION UND_STACK:DATA:NOROOT(3) SECTION CSTACK:DATA:NOROOT(3) PUBLIC __vector PUBLIC __iar_program_start EXTERN tcma_enable_early EXTERN tcmb_enable_early EXTERN arch_enable_cache EXTERN arch_clean_invalidate_dcache_all EXTERN copy_intvec EXTERN call_constructors EXTERN device_init EXTERN Arm_Undefined_Handler EXTERN Arm_SWI_Handler EXTERN Arm_Prefetch_Handler EXTERN Arm_Abort_Handler EXTERN Arm_IRQ_Handler EXTERN Arm_FIQ_Handler PUBWEAK Undefined_Handler PUBWEAK SWI_Handler PUBWEAK Prefetch_Handler PUBWEAK Abort_Handler PUBWEAK IRQ_Handler PUBWEAK FIQ_Handler SECTION .intvec:CODE:NOROOT(2) __vector: ; All default exception handlers (except reset) are ; defined as weak symbol definitions. ; If a handler is defined by the application it will take precedence. LDR PC,Reset_Addr ; Reset LDR PC,Undefined_Addr ; Undefined instructions LDR PC,SWI_Addr ; Software interrupt (SWI/SVC) LDR PC,Prefetch_Addr ; Prefetch abort LDR PC,Abort_Addr ; Data abort DCD 0 ; RESERVED LDR PC,IRQ_Addr ; IRQ LDR PC,FIQ_Addr ; FIQ DATA Reset_Addr DC32 __iar_program_start Undefined_Addr DC32 Undefined_Handler SWI_Addr DC32 SWI_Handler Prefetch_Addr DC32 Prefetch_Handler Abort_Addr DC32 Abort_Handler IRQ_Addr DC32 IRQ_Handler FIQ_Addr DC32 FIQ_Handler SECTION .boot:CODE:NOROOT(2) EXTERN main REQUIRE __vector EXTWEAK __iar_data_init3 EXTWEAK __iar_init_core EXTWEAK __iar_init_vfp EXTWEAK __iar_argc_argv #if CONFIG_PM EXTERN arm_context_restore #endif ARM __iar_program_start: ?cstartup: /* do some early cpu setup */ mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) msr cpsr_c, r0 mrc p15, 0, r12, c1, c0, 0 bic r12, r12, #(SCTLR_M | SCTLR_A | SCTLR_C) bic r12, r12, #(SCTLR_SW | SCTLR_I | SCTLR_RR) bic r12, r12, #(SCTLR_EE | SCTLR_TE) orr r12, r12, #(SCTLR_Z) #if CONFIG_ARM_HIGHVECTORS orr r12, r12, #(SCTLR_V) #else bic r12, r12, #(SCTLR_V) #endif mcr p15, 0, r12, c1, c0, 0 /* Configure peripheral ports */ mrc p15, 0, r0, c15, c0, 1 tst r0, #(0x1F << 2) beq .Lno_normal_axi_pp /* Enable LLPP normal AXI interface */ orr r0, r0, #1 mcr p15, 0, r0, c15, c0, 1 .Lno_normal_axi_pp: mrc p15, 0, r0, c15, c0, 2 tst r0, #(0x1F << 2) beq .Lno_virtual_axi_pp /* Enable LLPP virtual AXI interface */ orr r0, r0, #1 mcr p15, 0, r0, c15, c0, 2 .Lno_virtual_axi_pp: mrc p15, 0, r0, c15, c0, 3 tst r0, #(0x1F << 2) beq .Lno_ahb_pp /* Enable AHB peripheral interface */ orr r0, r0, #1 mcr p15, 0, r0, c15, c0, 3 .Lno_ahb_pp: /* enable tcm before use stacks */ #if CONFIG_ARMV7R_USE_TCMA ldr r0, =CONFIG_ARMV7R_TCMA_BASE mov r1, #0 #if CONFIG_ARMV7R_TCMA_ECC add r1, #1 #endif bl tcma_enable_early #endif #if CONFIG_ARMV7R_USE_TCMB ldr r0, =CONFIG_ARMV7R_TCMB_BASE mov r1, #0 #if CONFIG_ARMV7R_TCMB_ECC add r1, #1 #endif bl tcmb_enable_early #endif ; Initialize the stack pointers. ; The pattern below can be used for any of the exception stacks: ; FIQ, IRQ, SVC, ABT, UND, SYS. ; The USR mode uses the same stack as SYS. ; The stack segments must be defined in the linker command file, ; and be declared above. cps #MODE_SVC ; Set Supervisor mode bits ldr sp,=SFE(SVC_STACK) ; End of SVC_STACK cps #MODE_ABT ; Change the mode ldr sp,=SFE(ABT_STACK) ; End of ABT_STACK cps #MODE_UND ; Change the mode ldr sp,=SFE(UND_STACK) ; End of UND_STACK cps #MODE_FIQ ; Change the mode ldr sp,=SFE(FIQ_STACK) ; End of FIQ_STACK cps #MODE_IRQ ; Change the mode ldr sp,=SFE(IRQ_STACK) ; End of IRQ_STACK cps #MODE_SYS ; Change the mode ldr sp,=SFE(CSTACK) ; End of CSTACK #if CONFIG_PM cps #MODE_SVC ; Set Supervisor mode bits ldr r0, arm_context_restore_const blx r0 #endif /* enable cache, use stack enable after stack init */ #if CONFIG_ARCH_EARLY_ENABLE_ICACHE ldr r0, =ICACHE bl arch_enable_cache #endif #if CONFIG_ARCH_EARLY_ENABLE_DCACHE ldr r0, =DCACHE bl arch_enable_cache #endif /* Turn on core features assumed to be enabled */ FUNCALL __iar_program_start, __iar_init_core bl __iar_init_core /* Initialize VFP (if needed) */ FUNCALL __iar_program_start, __iar_init_vfp bl __iar_init_vfp /* Execute relocations & zero BSS */ FUNCALL __iar_program_start, __iar_data_init3 bl __iar_data_init3 #if CONFIG_ARCH_EARLY_ENABLE_DCACHE bl arch_clean_invalidate_dcache_all #endif /* Setup command line */ mov r0, #0 FUNCALL __iar_program_start, __iar_argc_argv bl __iar_argc_argv /* change to system mode */ cpsid i, #MODE_SYS FUNCALL __iar_program_start, copy_intvec bl copy_intvec FUNCALL __iar_program_start, device_init bl device_init FUNCALL __iar_program_start, main bl main b . Undefined_Handler: b Arm_Undefined_Handler SWI_Handler: b Arm_SWI_Handler Prefetch_Handler: b Arm_Prefetch_Handler Abort_Handler: b Arm_Abort_Handler IRQ_Handler: b Arm_IRQ_Handler FIQ_Handler: b Arm_FIQ_Handler #if CONFIG_PM arm_context_restore_const DC32 arm_context_restore #endif END