diff options
Diffstat (limited to 'plat/arm/board/arm_fpga/fpga_bl31_setup.c')
-rw-r--r-- | plat/arm/board/arm_fpga/fpga_bl31_setup.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index e4b9767d40..6eeff451cc 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -7,23 +7,23 @@ #include <assert.h> #include <common/fdt_wrappers.h> +#include <drivers/delay_timer.h> #include <drivers/generic_delay_timer.h> -#include <lib/mmio.h> #include <libfdt.h> +#include "fpga_private.h" #include <plat/common/platform.h> #include <platform_def.h> -#include "fpga_private.h" - static entry_point_info_t bl33_image_ep_info; +volatile uint32_t secondary_core_spinlock; uintptr_t plat_get_ns_image_entrypoint(void) { #ifdef PRELOADED_BL33_BASE return PRELOADED_BL33_BASE; #else - return 0; + return 0ULL; #endif } @@ -35,6 +35,17 @@ uint32_t fpga_get_spsr_for_bl33_entry(void) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { + /* Add this core to the VALID mpids list */ + fpga_valid_mpids[plat_my_core_pos()] = VALID_MPID; + + /* + * Notify the secondary CPUs that the C runtime is ready + * so they can announce themselves. + */ + secondary_core_spinlock = C_RUNTIME_READY_KEY; + dsbish(); + sev(); + fpga_console_init(); bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); @@ -54,11 +65,37 @@ void bl31_plat_arch_setup(void) void bl31_platform_setup(void) { - /* Initialize the GIC driver, cpu and distributor interfaces */ - plat_fpga_gic_init(); - /* Write frequency to CNTCRL and initialize timer */ generic_delay_timer_init(); + + /* + * Before doing anything else, wait for some time to ensure that + * the secondary CPUs have populated the fpga_valid_mpids array. + * As the number of secondary cores is unknown and can even be 0, + * it is not possible to rely on any signal from them, so use a + * delay instead. + */ + mdelay(5); + + /* + * On the event of a cold reset issued by, for instance, a reset pin + * assertion, we cannot guarantee memory to be initialized to zero. + * In such scenario, if the secondary cores reached + * plat_secondary_cold_boot_setup before the primary one initialized + * .BSS, we could end up having a race condition if the spinlock + * was not cleared before. + * + * Similarly, if there were a reset before the spinlock had been + * cleared, the secondary cores would find the lock opened before + * .BSS is cleared, causing another race condition. + * + * So clean the spinlock as soon as we think it is safe to reduce the + * chances of any race condition on a reset. + */ + secondary_core_spinlock = 0UL; + + /* Initialize the GIC driver, cpu and distributor interfaces */ + plat_fpga_gic_init(); } entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) |