FLEX-FORD-OBC-BM/Source/appl/ARMStartup_CortexR.c

755 lines
29 KiB
C
Raw Permalink Normal View History

2026-03-19 11:49:16 +01:00
/**********************************************************************************************************************
* 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*/