Files
1CAR/devices/E3106/startup/iar/startup.S
2025-10-25 21:11:06 +08:00

250 lines
6.8 KiB
ArmAsm

/*
* 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