From ac2de3fa7c68d356507779d99442dd86fe68f61e Mon Sep 17 00:00:00 2001 From: Sudan Landge Date: Fri, 26 Jul 2024 14:14:22 +0100 Subject: [PATCH] arch: arm: cortex_a_r: Set VBAR for all cores What is changed? Secondary cores can now boot successfully on cache and non-cache coherent systems if the Zephyr image/vector table is loaded at an address other than the default address 0x0. How is it changed? 1. By calling the relocate_vector() from reset.S as part of EL1 reset initialization instead of prep_c to have VBAR set for all cores and not just for the primary core. 2. Remove dead code under CONFIG_SW_VECTOR_RELAY and CONFIG_SW_VECTOR_RELAY_CLIENT. Why do we need this change? 1. As reported in issue #76182, on Cortex_ar, VBAR is set only for the primary cores while VBAR for the secondary cores are left with default value 0. This results in Zephyr not booting on secondary cores if the vector table for secondary cores is loaded at an address other than 0x0. VBAR is set in relocate_vector() so we move it to reboot.c which is better suited to have configs related to system control block. 2. The two SW_VECTOR_RELAY configs have a direct dependency on CONFIG_CPU_CORTEX_M, which is disabled while compiling for Cortex-A and Cortex-R hence leading to a dead code. How is the change verified? Verified with fvp_baser_aemv8r/fvp_aemv8r_aarch32/smp. Signed-off-by: Sudan Landge --- arch/arm/core/cortex_a_r/prep_c.c | 52 +------------------------------ arch/arm/core/cortex_a_r/reboot.c | 51 ++++++++++++++++++++++++++++++ arch/arm/core/cortex_a_r/reset.S | 3 ++ 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/arch/arm/core/cortex_a_r/prep_c.c b/arch/arm/core/cortex_a_r/prep_c.c index 74d0855a620..8e068f2e392 100644 --- a/arch/arm/core/cortex_a_r/prep_c.c +++ b/arch/arm/core/cortex_a_r/prep_c.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2014 Wind River Systems, Inc. + * Copyright 2024 Arm Limited and/or its affiliates * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,24 +29,6 @@ #include #endif -#if defined(__GNUC__) -/* - * GCC can detect if memcpy is passed a NULL argument, however one of - * the cases of relocate_vector_table() it is valid to pass NULL, so we - * suppress the warning for this case. We need to do this before - * string.h is included to get the declaration of memcpy. - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnonnull" -#endif - -#include - -#if defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) -Z_GENERIC_SECTION(.vt_pointer_section) __attribute__((used)) -void *_vector_table_pointer; -#endif - #ifdef CONFIG_ARM_MPU extern void z_arm_mpu_init(void); extern void z_arm_configure_static_mpu_regions(void); @@ -53,38 +36,6 @@ extern void z_arm_configure_static_mpu_regions(void); extern int z_arm_mmu_init(void); #endif -#if defined(CONFIG_AARCH32_ARMV8_R) - -#define VECTOR_ADDRESS ((uintptr_t)_vector_start) - -static inline void relocate_vector_table(void) -{ - write_sctlr(read_sctlr() & ~HIVECS); - write_vbar(VECTOR_ADDRESS & VBAR_MASK); - barrier_isync_fence_full(); -} - -#else -#define VECTOR_ADDRESS 0 - -void __weak relocate_vector_table(void) -{ -#if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \ - !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) - write_sctlr(read_sctlr() & ~HIVECS); - size_t vector_size = (size_t)_vector_end - (size_t)_vector_start; - (void)memcpy(VECTOR_ADDRESS, _vector_start, vector_size); -#elif defined(CONFIG_SW_VECTOR_RELAY) || defined(CONFIG_SW_VECTOR_RELAY_CLIENT) - _vector_table_pointer = _vector_start; -#endif -} - -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - -#endif /* CONFIG_AARCH32_ARMV8_R */ - #if defined(CONFIG_CPU_HAS_FPU) static inline void z_arm_floating_point_init(void) @@ -155,7 +106,6 @@ void z_prep_c(void) /* Initialize tpidruro with our struct _cpu instance address */ write_tpidruro((uintptr_t)&_kernel.cpus[0]); - relocate_vector_table(); #if defined(CONFIG_CPU_HAS_FPU) z_arm_floating_point_init(); #endif diff --git a/arch/arm/core/cortex_a_r/reboot.c b/arch/arm/core/cortex_a_r/reboot.c index dac892cf518..b5cea619f09 100644 --- a/arch/arm/core/cortex_a_r/reboot.c +++ b/arch/arm/core/cortex_a_r/reboot.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2014 Wind River Systems, Inc. + * Copyright 2024 Arm Limited and/or its affiliates * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +13,56 @@ #include #include #include +#include + +#if defined(CONFIG_AARCH32_ARMV8_R) + +#define VECTOR_ADDRESS ((uintptr_t)_vector_start) + +static inline void relocate_vector_table(void) +{ + write_sctlr(read_sctlr() & ~HIVECS); + write_vbar(VECTOR_ADDRESS & VBAR_MASK); + barrier_isync_fence_full(); +} + +#else + +#if defined(__GNUC__) +/* + * GCC can detect if memcpy is passed a NULL argument, however one of + * the cases of relocate_vector_table() it is valid to pass NULL, so we + * suppress the warning for this case. We need to do this before + * string.h is included to get the declaration of memcpy. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnonnull" +#endif /* __GNUC__ */ + +#include + +#define VECTOR_ADDRESS 0 + +void __weak relocate_vector_table(void) +{ +#if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \ + !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) + write_sctlr(read_sctlr() & ~HIVECS); + size_t vector_size = (size_t)_vector_end - (size_t)_vector_start; + (void)memcpy(VECTOR_ADDRESS, _vector_start, vector_size); +#endif +} + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#endif /* !CONFIG_AARCH32_ARMV8_R */ + +void z_arm_relocate_vector_table(void) +{ + relocate_vector_table(); +} /** * diff --git a/arch/arm/core/cortex_a_r/reset.S b/arch/arm/core/cortex_a_r/reset.S index efb04d249ec..591973e24e4 100644 --- a/arch/arm/core/cortex_a_r/reset.S +++ b/arch/arm/core/cortex_a_r/reset.S @@ -1,6 +1,7 @@ /* * Copyright (c) 2013-2014 Wind River Systems, Inc. * Copyright (c) 2019 Stephanos Ioannidis + * Copyright 2024 Arm Limited and/or its affiliates * * SPDX-License-Identifier: Apache-2.0 */ @@ -319,4 +320,6 @@ _primary_core: bl z_arm_tcm_disable_ecc #endif + bl z_arm_relocate_vector_table + bx r4