250 lines
6.8 KiB
ArmAsm
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
|