From 59ea36485ad59fda4055c86917df23b7ae51a36f Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 23 May 2021 13:16:46 +0100 Subject: [PATCH 1/3] refactor(plat/arm): update NV flags on image load/authentication failure Erasing the FIP TOC header present in a flash is replaced by updating NV flags with an error code on image load/authentication failure. BL1 component uses these NV flags to detect whether a firmware update is needed or not. These NV flags get cleared once the firmware update gets completed. Signed-off-by: Manish V Badarkhe Change-Id: I6232a0db07c89b2373b7b9d28acd37df6203d914 --- plat/arm/board/fvp/fvp_bl1_setup.c | 22 +++++++++++++++++++++- plat/arm/board/fvp/fvp_err.c | 24 ++++-------------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c index e713bbc44..06ee037dc 100644 --- a/plat/arm/board/fvp/fvp_bl1_setup.c +++ b/plat/arm/board/fvp/fvp_bl1_setup.c @@ -1,15 +1,17 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include #include #include #include +#include #include #include #include @@ -61,6 +63,12 @@ void bl1_platform_setup(void) __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) { + uint32_t nv_flags = mmio_read_32(V2M_SYS_NVFLAGS_ADDR); + + /* Clear the NV flags register. */ + mmio_write_32((V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR), + nv_flags); + /* Setup the watchdog to reset the system as soon as possible */ sp805_refresh(ARM_SP805_TWDG_BASE, 1U); @@ -124,3 +132,15 @@ int bl1_plat_handle_post_image_load(unsigned int image_id) return 0; } #endif /* MEASURED_BOOT */ + +/******************************************************************************* + * The following function checks if Firmware update is needed by checking error + * reported in NV flag. + ******************************************************************************/ +bool plat_arm_bl1_fwu_needed(void) +{ + int32_t nv_flags = (int32_t)mmio_read_32(V2M_SYS_NVFLAGS_ADDR); + + /* if image load/authentication failed */ + return ((nv_flags == -EAUTH) || (nv_flags == -ENOENT)); +} diff --git a/plat/arm/board/fvp/fvp_err.c b/plat/arm/board/fvp/fvp_err.c index 2928b3a48..1f9f0dd14 100644 --- a/plat/arm/board/fvp/fvp_err.c +++ b/plat/arm/board/fvp/fvp_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * Copyright (c) 2019-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -17,25 +18,8 @@ */ __dead2 void plat_arm_error_handler(int err) { - int ret; - - switch (err) { - case -ENOENT: - case -EAUTH: - /* Image load or authentication error. Erase the ToC */ - INFO("Erasing FIP ToC from flash...\n"); - (void)nor_unlock(PLAT_ARM_FLASH_IMAGE_BASE); - ret = nor_word_program(PLAT_ARM_FLASH_IMAGE_BASE, 0); - if (ret != 0) { - ERROR("Cannot erase ToC\n"); - } else { - INFO("Done\n"); - } - break; - default: - /* Unexpected error */ - break; - } + /* Propagate the err code in the NV-flags register */ + mmio_write_32(V2M_SYS_NVFLAGS_ADDR, (uint32_t)err); console_flush(); From 79d8be3c143d6d7edd1da04dd05d246e194adea1 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 16 Jun 2021 16:50:43 +0100 Subject: [PATCH 2/3] refactor(plat/arm): mark the flash region as read-only In the FVP platform, BL1 uses flash only for read purpose hence marked this flash region as read-only. Change-Id: I3b57130fd4f3b4df522ac075f66e9799f237ebb7 Signed-off-by: Manish V Badarkhe --- plat/arm/board/fvp/fvp_common.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index fe0903b2a..9d3c03133 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -72,14 +72,11 @@ arm_config_t arm_config; * Table of memory regions for various BL stages to map using the MMU. * This doesn't include Trusted SRAM as setup_page_tables() already takes care * of mapping it. - * - * The flash needs to be mapped as writable in order to erase the FIP's Table of - * Contents in case of unrecoverable error (see plat_error_handler()). */ #ifdef IMAGE_BL1 const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, - V2M_MAP_FLASH0_RW, + V2M_MAP_FLASH0_RO, V2M_MAP_IOFPGA, MAP_DEVICE0, #if FVP_INTERCONNECT_DRIVER == FVP_CCN From aa79421c16b98aad5920410d7658039dfa16c345 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 16 Jun 2021 19:59:41 +0100 Subject: [PATCH 3/3] refactor(plat/arm): use mmio* functions to read/write NVFLAGS registers Used mmio* functions to read/write NVFLAGS registers to avoid possibile reordering of instructions by compiler. Change-Id: Iae50ac30e5413259cf8554f0fff47512ad83b0fd Signed-off-by: Manish V Badarkhe --- plat/arm/board/juno/juno_bl1_setup.c | 16 +++++++--------- plat/arm/board/juno/juno_err.c | 6 ++---- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c index 2234055d4..a9d5cc37f 100644 --- a/plat/arm/board/juno/juno_bl1_setup.c +++ b/plat/arm/board/juno/juno_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -62,11 +62,11 @@ static int is_watchdog_reset(void) ******************************************************************************/ bool plat_arm_bl1_fwu_needed(void) { - const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR; + int32_t nv_flags = (int32_t)mmio_read_32(V2M_SYS_NVFLAGS_ADDR); /* Check if TOC is invalid or watchdog reset happened. */ - return (!arm_io_is_toc_valid() || (((*nv_flags_ptr == -EAUTH) || - (*nv_flags_ptr == -ENOENT)) && is_watchdog_reset())); + return (!arm_io_is_toc_valid() || (((nv_flags == -EAUTH) || + (nv_flags == -ENOENT)) && is_watchdog_reset())); } /******************************************************************************* @@ -86,13 +86,11 @@ void bl1_plat_set_ep_info(unsigned int image_id, ******************************************************************************/ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) { - unsigned int *nv_flags_clr = (unsigned int *) - (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR); - unsigned int *nv_flags_ptr = (unsigned int *) - (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS); + uint32_t nv_flags = mmio_read_32(V2M_SYS_NVFLAGS_ADDR); /* Clear the NV flags register. */ - *nv_flags_clr = *nv_flags_ptr; + mmio_write_32((V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR), + nv_flags); /* Setup the watchdog to reset the system as soon as possible */ sp805_refresh(ARM_SP805_TWDG_BASE, 1U); diff --git a/plat/arm/board/juno/juno_err.c b/plat/arm/board/juno/juno_err.c index 60699cc73..02d751e9a 100644 --- a/plat/arm/board/juno/juno_err.c +++ b/plat/arm/board/juno/juno_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,10 +16,8 @@ */ void __dead2 plat_arm_error_handler(int err) { - uint32_t *flags_ptr = (uint32_t *)V2M_SYS_NVFLAGS_ADDR; - /* Propagate the err code in the NV-flags register */ - *flags_ptr = err; + mmio_write_32(V2M_SYS_NVFLAGS_ADDR, (uint32_t)err); /* Setup the watchdog to reset the system as soon as possible */ sp805_refresh(ARM_SP805_TWDG_BASE, 1U);