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 <sudan.landge@arm.com>
This commit is contained in:
Sudan Landge 2024-07-26 14:14:22 +01:00 committed by Anas Nashif
parent 2c95978f3b
commit ac2de3fa7c
3 changed files with 55 additions and 51 deletions

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
* Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -28,24 +29,6 @@
#include <cortex_a_r/stack.h>
#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 <string.h>
#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

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
* Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -12,6 +13,56 @@
#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/sys/util.h>
#include <zephyr/linker/linker-defs.h>
#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 <string.h>
#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();
}
/**
*

View File

@ -1,6 +1,7 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
* Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
* Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* 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