/********************************************************************************************************************** * COPYRIGHT * ------------------------------------------------------------------------------------------------------------------- * \verbatim * Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved. * * This software is copyright protected and proprietary to Vector Informatik GmbH. * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. * All other rights remain with Vector Informatik GmbH. * \endverbatim * ------------------------------------------------------------------------------------------------------------------- * FILE DESCRIPTION * -----------------------------------------------------------------------------------------------------------------*/ /** \file File: ARMStartup_CortexR.c * Project: Vector Basic Runtime System * Module: BrsHw for all platforms with ARM core Cortex-R * Template: This file is reviewed according to Brs_Template@Implementation[1.03.12] * * \brief Description: This file contains the assembler part of the BRS StartUpCode. * * \attention Please note: * The demo and example programs only show special aspects of the software. With regard to the fact * that these programs are meant for demonstration purposes only, Vector Informatik liability shall be * expressly excluded in cases of ordinary negligence, to the extent admissible by law or statute. *********************************************************************************************************************/ /********************************************************************************************************************** * REVISION HISTORY * ------------------------------------------------------------------------------------------------------------------- * Refer to ARMBrsHw_CortexR.h. *********************************************************************************************************************/ /********************************************************************************************************************** * EXAMPLE CODE ONLY * ------------------------------------------------------------------------------------------------------------------- * This Example Code is only intended for illustrating an example of a possible BSW integration and BSW configuration. * The Example Code has not passed any quality control measures and may be incomplete. The Example Code is neither * intended nor qualified for use in series production. The Example Code as well as any of its modifications and/or * implementations must be tested with diligent care and must comply with all quality requirements which are necessary * according to the state of the art before their use. *********************************************************************************************************************/ #define ARMSTARTUP_CORTEXR_SOURCE /********************************************************************************************************************** * INCLUDES *********************************************************************************************************************/ #include "BrsHw.h" #if defined (BRS_FIRST_EXECUTION_INSTANCE) /* This code is only needed for the first instance/executable in the system */ #include "vBrs_Lcfg.h" #include "vLinkGen_Lcfg.h" /********************************************************************************************************************** * CONFIGURATION CHECK *********************************************************************************************************************/ #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) #else #error "Unknown compiler specified!" #endif #if (VLINKGEN_CFG_MAJOR_VERSION != 2u) #error "This StartUpCode is dependent to the vLinkGen version! vLinkGen major version does not fit!" #else # if (VLINKGEN_CFG_MINOR_VERSION < 5u) #error "This StartUpCode is dependent to the vLinkGen version! Your vLinkGen minor version is too old!" # endif #endif /********************************************************************************************************************** * DEFINITION + MACROS *********************************************************************************************************************/ #if defined (BRS_FIRST_EXECUTION_INSTANCE) extern void intvect_CoreExceptions(void); #endif #if defined (BRS_ENABLE_OS_MULTICORESUPPORT) extern ARMBrsHw_PhysicalCoreId_CoreExceptions_MappingType BrsHw_intvect_CoreExceptions_list[BRS_CPU_CORE_AMOUNT-1]; #endif /********************************************************************************************************************** * GLOBAL VARIABLES *********************************************************************************************************************/ #if defined (BRS_ENABLE_OS_MULTICORESUPPORT) /* used 32bit values for less assembler differences in accessing code */ const uint32 BrsHw_InitCoreID = (uint32) BRSHW_INIT_CORE_ID; const uint32 BrsHw_CpuCoreAmountMinus1 = (uint32) (BRS_CPU_CORE_AMOUNT-1); #endif /********************************************************************************************************************** * PROTOTYPES OF LOCAL FUNCTIONS *********************************************************************************************************************/ BRS_LOCAL_PROTOTYPE(_start) BRS_LOCAL_PROTOTYPE(brsStartupEntry) BRS_LOCAL_PROTOTYPE(brsStartupInvalidateCache) BRS_LOCAL_PROTOTYPE(brsStartupZeroInitLoop) BRS_LOCAL_PROTOTYPE(brsStartupStackSearch) BRS_LOCAL_PROTOTYPE(coreRegisterInit) BRS_LOCAL_PROTOTYPE(coreRegisterInit2) BRS_LOCAL_PROTOTYPE(coreRegisterInit3) BRS_LOCAL_PROTOTYPE(stackPointerInit) BRS_LOCAL_PROTOTYPE(brsPreAsmStartupHook) /* =========================================================================== */ /* */ /* Description: Entry point for all cores */ /* */ /* =========================================================================== */ BRS_SECTION_CODE(brsStartup) /* Alternativ entry point from OS default config */ BRS_GLOBAL(_start) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(_start) BRS_MULTILINE_ASM_END() BRS_GLOBAL_END() BRS_GLOBAL(brsStartupEntry) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(brsStartupEntry) #if defined (BRSHW_PRE_ASM_STARTUP_HOOK_AVAILABLE) #endif BRS_BRANCH(brsPreAsmStartupHook) BRS_MULTILINE_ASM_END() BRS_GLOBAL_END() /* =========================================================================== */ /* */ /* Description: Optional hook for platform specific tasks */ /* */ /* =========================================================================== */ #if !defined (BRSHW_PRE_ASM_STARTUP_HOOK_AVAILABLE) BRS_GLOBAL(brsPreAsmStartupHook) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(brsPreAsmStartupHook) /* Nothing to do here */ BRS_BRANCH(coreRegisterInit) BRS_MULTILINE_ASM_END() BRS_GLOBAL_END() #endif /*!BRSHW_PRE_ASM_STARTUP_HOOK_AVAILABLE*/ /* =========================================================================== */ /* */ /* Description: Initialize core ID independent core registers */ /* */ /* =========================================================================== */ BRS_GLOBAL(coreRegisterInit) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(coreRegisterInit) /* Note: ARMStartup_CortexR.c must be compiled in ARM mode, since * the exception table is implemented in ARM mode only */ __as1(LDR r0, =BrsStartupInstSetInit) #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ORR r0 ,r0, 0) #else __as2(ORR r0 ,r0, #0) #endif ___asm(BX r0) BRS_LABEL(BrsStartupInstSetInit) #if defined (BRS_FPU_USED) /* Allow full access to coprocessors 10,11 */ /* r0 gets the content of the Coprocessor Access Control Register */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as5(MRC p15, 0, r0, c1, c0, 2) # else __as5(MRC p15, #0x00, r0, c1, c0, #0x02) # endif __as2(ORR r0, r0, #0x00F00000) /* Write Coprocessor Access Control Register to set access rights for coprocessor cp10, cp11 to full access Note: Coprocessors cp10 and cp11 support floating-point and vector operations, and the control and configuration of the Floating-point and Advanced SIMD architecture extensions. */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as5(MCR p15, 0, r0, c1, c0, 2) # else __as5(MCR p15, #0x00, r0, c1, c0, #0x02) # endif /* Enable Advanced SIMD and Floating-point Extensions */ __as1(VMRS r0, FPEXC) __as1(MOV r1, #0x40000000) __as2(ORR r0, r0, r1) __as1(VMSR FPEXC, r0) #endif /*BRS_FPU_USED*/ /* Switch to System Mode */ __as1(MRS r0, CPSR) #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ORR r0, r0, 0x1f) __as1(MSR CPSR, r0) #else __as2(ORR r0, r0, #0x1f) __as1(MSR cpsr_cxsf, r0) #endif BRS_BRANCH(coreRegisterInit2) BRS_MULTILINE_ASM_END() BRS_GLOBAL_END() /* =========================================================================== */ /* */ /* Description: Initialize all core ID dependent core registers */ /* Setup exception table */ /* */ /* =========================================================================== */ BRS_GLOBAL(coreRegisterInit2) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(coreRegisterInit2) #if defined (BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0) # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as1(MOV R2, 0) # else __as1(MOV R2, #0) # endif #else /*(BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0)*/ # if defined (BRS_ENABLE_OS_MULTICORESUPPORT) __as1(LDR R1, =BrsHw_InitCoreID) __as1(LDR R3, [R1]) /* ==> R3 = BrsHw_InitCoreID */ BRS_READ_COREID(R0) /* ==> R0 = BRS_READ_COREID */ /* If actual running core is init core, directly jump to implemantation for init core. (ExceptionTable of init core is not part of BrsHw_intvect_CoreExceptions_list[]) */ BRS_BRANCH_EQUAL(R0, R3, set_exception_table_location_on_init_core) __as1(LDR R1, =BrsHw_CpuCoreAmountMinus1) __as1(LDR R5, [R1]) /* ==> R5 = BrsHw_CpuCoreAmountMinus1 */ __as1(LDR R4, =BrsHw_intvect_CoreExceptions_list) /* ==> R4 = BrsHw_intvect_CoreExceptions_list */ /* Use R6 as count register in the loop. Initialize with zero. */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as1(MOV R6, 0) # else __as1(MOV R6, #0) # endif BRS_LABEL(get_exception_table_location_for_this_core_loop) __as1(LDR R7, [R4]) /* ==> R7 = BrsHw_intvect_CoreExceptions_list[R6].PhysicalCoreId */ BRS_READ_COREID(R0) /* ==> R0 = BRS_READ_COREID */ /* Check, if BrsHw_intvect_CoreExceptions_list entry of actual running core is reached */ BRS_BRANCH_EQUAL(R0, R7, get_exception_table_location_for_this_core) /* Increase count register by one. */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R6, R6, 1) # else __as2(ADD R6, R6, #1) # endif /* Set R4 to point to next entry of BrsHw_intvect_CoreExceptions_list. */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R4, R4, 8) # else __as2(ADD R4, R4, #8) # endif /* Check if end of BrsHw_intvect_CoreExceptions_list has been reached. */ BRS_BRANCH_NOT_EQUAL(R6, R5, get_exception_table_location_for_this_core_loop) /* If no Exception Table address for running core has been found -> BrsMainExceptionStartup. */ BRS_BRANCH(get_exception_table_location_error) BRS_LABEL(get_exception_table_location_for_this_core) /* Set R4 to point to next attribute of the current (R6) struct ARMBrsHw_PhysicalCoreId_CoreExceptions_MappingType: CoreExceptions */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R4, R4, 4) # else __as2(ADD R4, R4, #4) # endif __as1(LDR R2, [R4]) /* ==> R2 = BrsHw_intvect_CoreExceptions_list[R6].CoreExceptions */ BRS_BRANCH(get_exception_table_location_end) BRS_LABEL(set_exception_table_location_on_init_core) # endif /*BRS_ENABLE_OS_MULTICORESUPPORT*/ # if defined (BRS_FIRST_EXECUTION_INSTANCE) __as1(LDR R2, =intvect_CoreExceptions) # else /* init core should be configured, but no 1st execution instance! -> BrsMainExceptionStartup. */ BRS_BRANCH(get_exception_table_location_error) # endif /*BRS_FIRST_EXECUTION_INSTANCE*/ BRS_LABEL(get_exception_table_location_end) #endif /*else BRSHW_ARMCOMMON_COREEXCEPTIONS_AT_ADDRESS_0*/ /* Copy backup exception vectors over exception vectors at address "intvect_CoreExceptions" See ARMv7_Cortex-R_BRS_Exception_Handling.pdf for details of the mechanism! R2 = destination address / R3 = source address / R6 = index / R4,R5 = data buffer */ __as1(MOV R3, R2) __as1(MOV R7, R2) /* save Exception Table address in R7 */ /* Use R6 as count register in the loop. Initialize with zero. */ #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as1(MOV R6, 0) __as2(ADD R2, R2, 32) __as2(ADD R3, R3, 64) #else __as1(MOV R6, #0) __as2(ADD R2, R2, #32) __as2(ADD R3, R3, #64) #endif BRS_LABEL(copy_exception_vectors_backup_to_active_start) __as3(LDRD R4, R5, [R3], #+8) __as3(STRD R4, R5, [R2], #+8) /* Increase count register by one. */ #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R6, R6, 1) #else __as2(ADD R6, R6, #1) #endif #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) BRS_BRANCH_EQUAL(R6, 4, copy_exception_vectors_backup_to_active_end) #else BRS_BRANCH_EQUAL(R6, #4, copy_exception_vectors_backup_to_active_end) #endif BRS_BRANCH(copy_exception_vectors_backup_to_active_start) BRS_LABEL(copy_exception_vectors_backup_to_active_end) /* Set Exception Table code for all 8 Exceptions to the default "LDR PC, [PC,0x18]" using R7 = Exception Table address. Use R6 as count register in the loop. Initialize with zero. */ #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as1(MOV R6, 0) __as1(MOVW R2, 0xF018) __as1(MOVT R2, 0xE59F) #else __as1(MOV R6, #0) __as1(MOVW R2, #0xF018) __as1(MOVT R2, #0xE59F) #endif BRS_LABEL(restore_exception_table_start) __as2(STR R2, [R7], #+4) /* Increase count register by one. */ #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R6, R6, 1) #else __as2(ADD R6, R6, #1) #endif #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) BRS_BRANCH_EQUAL(R6, 8, restore_exception_table_end) #else BRS_BRANCH_EQUAL(R6, #8, restore_exception_table_end) #endif BRS_BRANCH(restore_exception_table_start) BRS_LABEL(restore_exception_table_end) /* The exception table is implemented for ARM instrcutions -> The exception must be entered in ARM state * -> Set SCTLR.TE bit for ARM state */ __as5(MRC p15, #0, r0, c1, c0, #0) /* read SCTLR register */ __as2(BIC r0, r0, #(1 << 30)) /* clear the TE bit to enter Exc in ARM mode */ __as5(MCR p15, #0, r0, c1, c0, #0) /* write SCTLR register */ /* Assure V-Bit is cleard and low exception vectors at 0x00000000 were set * -> Set SCTLR.V bit for low exception base */ __as5(MRC p15, #0x00, r0, c1, c0, #0x0) /* Read SCTLR (System Control Register)*/ __as2(BIC r0, r0, #(1 << 13)) /* clear the V-bit */ __as5(MCR p15, #0x00, r0, c1, c0, #0x0) /* Write SCTLR (System Control Register) */ BRS_BRANCH(brsStartupInvalidateCache) BRS_LABEL(get_exception_table_location_error) BRS_MULTILINE_ASM_END() /* Branch to BrsMainExceptionStartup if no Exception Table address can be found. */ BRS_EXTERN_BRANCH(BrsMainExceptionStartup) BRS_GLOBAL_END() /* =========================================================================== */ /* */ /* Description: Invalidate cache memory */ /* */ /* =========================================================================== */ BRS_GLOBAL(brsStartupInvalidateCache) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(brsStartupInvalidateCache) #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as5(MRC p15, 1, r0, c0, c0, 0) /* read cache size id */ __as1(MOVW r3, 0x01ff) __as1(MOVT r3, 0x0000) __as3(AND r0, r3, r0, lsr #13) __as1(MOV r1, 0) BRS_LABEL(way_loop) __as1(MOV r3, 0) BRS_LABEL(set_loop) __as2(MOV r2, r1, lsl #30) __as3(ORR r2, r2, r3, lsl #5) BRS_LABEL(format) __as5(MCR p15, 0, r2, c7, c6, 2) /* invalidate */ ___asm(DSB) ___asm(ISB) __as2(ADD r3, r3, 1) BRS_BRANCH_GREATER_THAN(r0, r3, set_loop) __as2(ADD r1, r1, 1) BRS_BRANCH_NOT_EQUAL(r1, 4, way_loop) #else __as5(MRC p15, #1, r0, c0, c0, #0) /* read cache size id */ __as1(MOVW r3, #0x01ff) __as1(MOVT r3, #0x0000) __as3(AND r0, r3, r0, lsr #13) __as1(MOV r1, #0) BRS_LABEL(way_loop) __as1(MOV r3, #0) BRS_LABEL(set_loop) __as2(MOV r2, r1, lsl #30) __as3(ORR r2, r2, r3, lsl #5) BRS_LABEL(format) __as5(MCR p15, #0, r2, c7, c6, #2) /* invalidate */ ___asm(DSB) ___asm(ISB) __as2(ADD r3, r3, #1) BRS_BRANCH_GREATER_THAN(r0, r3, set_loop) __as2(ADD r1, r1, #1) BRS_BRANCH_NOT_EQUAL(r1, #4, way_loop) #endif /*BRS_COMP_x*/ BRS_BRANCH(brsStartupZeroInitLoop) BRS_MULTILINE_ASM_END() BRS_GLOBAL_END() /* =========================================================================== */ /* */ /* Description: Initialize memory blocks and groups with zero */ /* */ /* =========================================================================== */ BRS_GLOBAL(brsStartupZeroInitLoop) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(brsStartupZeroInitLoop) /* Initialize memory sections blocks with zeros */ #if defined (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS) # if (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS>1uL) __as1(LDR R1, =vLinkGen_ZeroInit_Early_Blocks) BRS_READ_COREID(R0) BRS_LABEL(startup_block_zero_init_start) __as1(MOV R2, R1) # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R1, R1, 16) # else __as2(ADD R1, R1, #16) # endif __as1(LDR R3, [R2]) /* vLinkGen_ZeroInit_Early_Blocks->start */ __as2(LDR R4, [R2, #4]) /* vLinkGen_ZeroInit_Early_Blocks->end */ __as2(LDR R5, [R2, #8]) /* vLinkGen_ZeroInit_Early_Blocks->core */ __as2(LDR R6, [R2, #12]) /* vLinkGen_ZeroInit_Early_Blocks->alignment */ /* Verify if the end of struct vLinkGen_ZeroInit_Early_Blocks is reached, by checking if start == 0, end == 0 and core == 0 */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as1(MOV R7, 0) # else __as1(MOV R7, #0) # endif __as2(ORR R7, R7, R3) /* Or with vLinkGen_ZeroInit_Early_Blocks->start */ __as2(ORR R7, R7, R4) /* Or with vLinkGen_ZeroInit_Early_Blocks->end */ __as2(ORR R7, R7, R5) /* Or with vLinkGen_ZeroInit_Early_Blocks->core */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) BRS_BRANCH_EQUAL(R7, 0, startup_block_zero_init_end) /* If start address, end address and core are equal to zero -> Finished */ # else BRS_BRANCH_EQUAL(R7, #0, startup_block_zero_init_end) /* If start address, end address and core are equal to zero -> Finished */ # endif BRS_BRANCH_NOT_EQUAL(R0, R5, startup_block_zero_init_start) /* If InitCore is not running -> go to the next array entry */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as1(MOV R7, 0) /* set R7 to '0', as value to write in memory later */ __as1(MOV R8, 0) /* set R8 to '0', as value to write in memory later */ # else __as1(MOV R7, #0) /* set R7 to '0', as value to write in memory later */ __as1(MOV R8, #0) /* set R8 to '0', as value to write in memory later */ # endif BRS_BRANCH_EQUAL(R6, #8, startup_block_zero_init_8byte_loop_start) /* if block is 8-Byte aligned, use specific init loop */ BRS_LABEL(startup_block_zero_init_loop_start) BRS_BRANCH_GREATER_THAN_OR_EQUAL(R3, R4, startup_block_zero_init_start) /* if start address is same with or higher than end address-> Finished. */ __as1(STR R7, [R3]) /* write value of R7 ('0') to address of R3 (4-byte access); must be an aligned memory access! */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R3, R3, 4) /* increase address value of R3 by '4' */ # else __as2(ADD R3, R3, #4) /* increase address value of R3 by '4' */ # endif /* End address of this block was not yet reached. Run through the loop again */ BRS_BRANCH(startup_block_zero_init_loop_start) /* ================================================================ */ /* 8-Byte aligned initialization, to support 8-Byte aligned ECC RAM */ /* ================================================================ */ BRS_LABEL(startup_block_zero_init_8byte_loop_start) BRS_BRANCH_GREATER_THAN_OR_EQUAL(R3, R4, startup_block_zero_init_start) /* if start address is same with or higher than end address-> Finished. */ /* Address stored in R3 must be 8 Byte aligned at this point! */ __as2(STMIA R3!, {R7, R8}) /* 8 Byte alignment store for ECC, R3 would be automatically updated after the write */ /* End address of this block was not yet reached. Run through the loop again */ BRS_BRANCH(startup_block_zero_init_8byte_loop_start) /* Zero-Init loop of blocks end label */ BRS_LABEL(startup_block_zero_init_end) # endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS>1uL*/ #else #error "Mandatory define VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS missing within vLinkGen configuration!" #endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_BLOCKS*/ /* Initialize memory sections groups with zeros */ #if defined (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS) # if (VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS>1uL) __as1(LDR R1, =vLinkGen_ZeroInit_Early_Groups) BRS_LABEL(startup_group_zero_init_start) __as1(MOV R2, R1) # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R1, R1, 16) # else __as2(ADD R1, R1, #16) # endif __as1(LDR R3, [R2]) /* vLinkGen_ZeroInit_Early_Groups->start */ __as2(LDR R4, [R2, #4]) /* vLinkGen_ZeroInit_Early_Groups->end */ __as2(LDR R5, [R2, #8]) /* vLinkGen_ZeroInit_Early_Groups->core */ __as2(LDR R6, [R2, #12]) /* vLinkGen_ZeroInit_Early_Groups->alignment */ /* Verify if the end of struct vLinkGen_ZeroInit_Early_Groups is reached, by checking if start == 0, end == 0 and core == 0 */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as1(MOV R7, 0) # else __as1(MOV R7, #0) # endif __as2(ORR R7, R7, R3) /* Or with vLinkGen_ZeroInit_Early_Groups->start */ __as2(ORR R7, R7, R4) /* Or with vLinkGen_ZeroInit_Early_Groups->end */ __as2(ORR R7, R7, R5) /* Or with vLinkGen_ZeroInit_Early_Groups->core */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) BRS_BRANCH_EQUAL(R7, 0, startup_group_zero_init_end) /* If start address, end address and core are equal to zero -> Finished */ # else BRS_BRANCH_EQUAL(R7, #0, startup_group_zero_init_end) /* If start address, end address and core are equal to zero -> Finished */ # endif BRS_BRANCH_NOT_EQUAL(R0, R5, startup_group_zero_init_start) /* If InitCore is not running -> go to the next array entry */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as1(MOV R7, 0) /* set R7 to '0', as value to write in memory later */ __as1(MOV R8, 0) /* set R8 to '0', as value to write in memory later */ # else __as1(MOV R7, #0) /* set R7 to '0', as value to write in memory later */ __as1(MOV R8, #0) /* set R8 to '0', as value to write in memory later */ # endif BRS_BRANCH_EQUAL(R6, #8, startup_group_zero_init_8byte_loop_start) /* if group is 8-Byte aligned, use specific init loop */ BRS_LABEL(startup_group_zero_init_loop_start) BRS_BRANCH_GREATER_THAN_OR_EQUAL(R3, R4, startup_group_zero_init_start) /* if start address is same with or higher than end address-> Finished. */ __as1(STR R7, [R3]) /* write value of R7 ('0') to address of R3 (4-byte access); must be an aligned memory access! */ # if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R3, R3, 4) /* increase address value of R3 by '4' */ # else __as2(ADD R3, R3, #4) /* increase address value of R3 by '4' */ # endif /* End address of this group was not yet reached. Run through the loop again */ BRS_BRANCH(startup_group_zero_init_loop_start) /* ================================================================ */ /* 8-Byte aligned initialization, to support 8-Byte aligned ECC RAM */ /* ================================================================ */ BRS_LABEL(startup_group_zero_init_8byte_loop_start) BRS_BRANCH_GREATER_THAN_OR_EQUAL(R3, R4, startup_group_zero_init_start) /* if start address is same with or higher than end address-> Finished. */ /* Address stored in R3 must be 8 Byte aligned at this point! */ __as2(STMIA R3!, {R7, R8}) /* 8 Byte alignment store for ECC, R3 would be automatically updated after the write */ /* End address of this group was not yet reached. Run through the loop again */ BRS_BRANCH(startup_group_zero_init_8byte_loop_start) /* Zero-Init loop of groups end label */ BRS_LABEL(startup_group_zero_init_end) # endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS>1uL*/ #else #error "Mandatory define VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS missing within vLinkGen configuration!" #endif /*VLINKGEN_CFG_NUM_ZERO_INIT_EARLY_GROUPS*/ /* Jump to routine to search for valid startup stack pointer of actual running core */ BRS_BRANCH(brsStartupStackSearch) BRS_MULTILINE_ASM_END() BRS_GLOBAL_END() /* =========================================================================== */ /* */ /* Description: Search for valid startup stack pointer of actual running core */ /* (vBRS is genearing the core specific configuration into the */ /* struct BrsMain_CoreConfig in vBrs_Lcfg.c) */ /* */ /* =========================================================================== */ BRS_GLOBAL(brsStartupStackSearch) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(brsStartupStackSearch) __as1(LDR R1, =BrsMain_CoreConfig_Size) BRS_LABEL(core_config_size_init) __as1(LDR R5, [R1]) /* R5 = BrsMain_CoreConfig_Size */ __as1(LDR R1, =BrsMain_CoreConfig) BRS_READ_COREID(R0) BRS_LABEL(core_config_init_start) /* Use R2 as count register in the loop. Initialize with zero. */ #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as1(MOV R2, 0) #else __as1(MOV R2, #0) #endif BRS_LABEL(brs_coreconfig_loop) __as2(LDR R4, [R1,#4]) /* BrsMain_CoreConfig->PhysicalCoreId */ /* Check if core id (R0) matches to physical core id of BrsMain_CoreConfig entry (R4). */ BRS_BRANCH_EQUAL(R0, R4, stackPointerInit) /* Increase count register by one. */ #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R2, R2, 1) #else __as2(ADD R2, R2, #1) #endif /* Set R1 to point to next entry of BrsMain_CoreConfig. */ #if defined (BRS_COMP_LLVMTEXASINSTRUMENTS) __as2(ADD R1, R1, 28) #else __as2(ADD R1, R1, #28) #endif /* Check if end of BrsMain_CoreConfig has been reached. */ BRS_BRANCH_NOT_EQUAL(R2, R5, brs_coreconfig_loop) BRS_MULTILINE_ASM_END() /* Branch to BrsMainExceptionStartup if there are no more entries in the array. */ BRS_EXTERN_BRANCH(BrsMainExceptionStartup) BRS_GLOBAL_END() /* =========================================================================== */ /* */ /* Description: Initialize all core registers of actual running core with */ /* specific init values */ /* */ /* =========================================================================== */ BRS_GLOBAL(stackPointerInit) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(stackPointerInit) __as2(LDR R4, [R1,#8]) /* BrsMain_CoreConfig->StartupStackEndLabel */ __as1(MOV SP, R4) BRS_BRANCH(coreRegisterInit3) BRS_MULTILINE_ASM_END() BRS_GLOBAL_END() /* =========================================================================== */ /* */ /* Description: Initialize additional core registers */ /* */ /* =========================================================================== */ BRS_GLOBAL(coreRegisterInit3) BRS_MULTILINE_ASM_BEGIN() BRS_LABEL(coreRegisterInit3) BRS_MULTILINE_ASM_END() /* =========================================================================== */ /* */ /* Description: Jump to Brs_PreMainStartup() (BrsMainStartup.c) */ /* */ /* =========================================================================== */ BRS_EXTERN_BRANCH(Brs_PreMainStartup) /* =========================================================================== */ /* */ /* Description: Jump to BrsMainExceptionStartup() in case of an unexpected */ /* return from PreMain/main */ /* */ /* =========================================================================== */ BRS_EXTERN_BRANCH(BrsMainExceptionStartup) BRS_GLOBAL_END() #endif /*BRS_FIRST_EXECUTION_INSTANCE*/