From 4da6f6cde3c72bd9786fc20141848c770c84f784 Mon Sep 17 00:00:00 2001 From: Sathees Balya Date: Mon, 3 Sep 2018 17:41:13 +0100 Subject: [PATCH] juno: Revert FWU update detect mechanism The patch 7b56928 unified the FWU mechanism on FVP and Juno platforms due to issues with MCC firmware not preserving the NVFLAGS. With MCCv150 firmware, this issue is resolved. Also writing to the NOR flash while executing from the same flash in Bypass mode had some stability issues. Hence, since the MCC firmware issue is resolved, this patch reverts to the NVFLAGS mechanism to detect FWU. Also, with the introduction of SDS (Shared Data Structure) by the SCP, the reset syndrome needs to queried from the appropriate SDS field. Change-Id: If9c08f1afaaa4fcf197f3186887068103855f554 Signed-off-by: Sathees Balya Signed-off-by: Soby Mathew --- include/plat/arm/board/common/v2m_def.h | 3 ++ include/plat/arm/common/plat_arm.h | 2 + plat/arm/board/juno/juno_bl1_setup.c | 57 +++++++++++++++++++++++++ plat/arm/board/juno/juno_err.c | 25 +++++++++++ plat/arm/board/juno/platform.mk | 18 +++++--- plat/arm/common/arm_bl1_setup.c | 13 +++++- plat/arm/common/arm_err.c | 9 +++- 7 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 plat/arm/board/juno/juno_err.c diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h index e5f537329..ce436d2ca 100644 --- a/include/plat/arm/board/common/v2m_def.h +++ b/include/plat/arm/board/common/v2m_def.h @@ -32,6 +32,9 @@ #define V2M_FUNC_SHUTDOWN 0x08 #define V2M_FUNC_REBOOT 0x09 +/* NVFLAGS in the V2M motherboard which is preserved after a watchdog reset */ + #define V2M_SYS_NVFLAGS_ADDR (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS) + /* * V2M sysled bit definitions. The values written to this * register are defined in arch.h & runtime_svc.h. Only diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 0770c0ec5..53b4a45c1 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -245,6 +245,8 @@ void plat_arm_interconnect_init(void); void plat_arm_interconnect_enter_coherency(void); void plat_arm_interconnect_exit_coherency(void); void plat_arm_program_trusted_mailbox(uintptr_t address); +int plat_arm_bl1_fwu_needed(void); +void plat_arm_error_handler(int err); #if ARM_PLAT_MT unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr); diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c index 836a67255..3dd2a227c 100644 --- a/plat/arm/board/juno/juno_bl1_setup.c +++ b/plat/arm/board/juno/juno_bl1_setup.c @@ -5,15 +5,72 @@ */ #include +#include #include #include #include +#include #include #include #include void juno_reset_to_aarch32_state(void); +static int is_watchdog_reset(void) +{ +#if !CSS_USE_SCMI_SDS_DRIVER + #define RESET_REASON_WDOG_RESET (0x2) + const uint32_t *reset_flags_ptr = (const uint32_t *)SSC_GPRETN; + + if ((*reset_flags_ptr & RESET_REASON_WDOG_RESET) != 0) + return 1; + + return 0; +#else + int ret; + uint32_t scp_reset_synd_flags; + + ret = sds_init(); + if (ret != SDS_OK) { + ERROR("SCP SDS initialization failed\n"); + panic(); + } + + ret = sds_struct_read(SDS_RESET_SYNDROME_STRUCT_ID, + SDS_RESET_SYNDROME_OFFSET, + &scp_reset_synd_flags, + SDS_RESET_SYNDROME_SIZE, + SDS_ACCESS_MODE_NON_CACHED); + if (ret != SDS_OK) { + ERROR("Getting reset reason from SDS failed\n"); + panic(); + } + + /* Check if the WATCHDOG_RESET_BIT is set in the reset syndrome */ + if (scp_reset_synd_flags & SDS_RESET_SYNDROME_AP_WD_RESET_BIT) + return 1; + + return 0; +#endif +} + +/******************************************************************************* + * The following function checks if Firmware update is needed, + * by checking if TOC in FIP image is valid or watchdog reset happened. + ******************************************************************************/ +int plat_arm_bl1_fwu_needed(void) +{ + const uint32_t *nv_flags_ptr = (const uint32_t *)V2M_SYS_NVFLAGS_ADDR; + + /* Check if TOC is invalid or watchdog reset happened. */ + if ((arm_io_is_toc_valid() != 1) || + (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT)) + && is_watchdog_reset())) + return 1; + + return 0; +} + /******************************************************************************* * On JUNO update the arg2 with address of SCP_BL2U image info. ******************************************************************************/ diff --git a/plat/arm/board/juno/juno_err.c b/plat/arm/board/juno/juno_err.c new file mode 100644 index 000000000..dd8e27881 --- /dev/null +++ b/plat/arm/board/juno/juno_err.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +/* + * Juno error handler + */ +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; + + /* Loop until the watchdog resets the system */ + for (;;) + wfi(); +} diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 16390fa4e..481844f0d 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -22,7 +22,12 @@ ifneq (${ENABLE_STACK_PROTECTOR}, 0) JUNO_SECURITY_SOURCES += plat/arm/board/juno/juno_stack_protector.c endif -PLAT_INCLUDES := -Iplat/arm/board/juno/include +# Select SCMI/SDS drivers instead of SCPI/BOM driver for communicating with the +# SCP during power management operations and for SCP RAM Firmware transfer. +CSS_USE_SCMI_SDS_DRIVER := 1 + +PLAT_INCLUDES := -Iplat/arm/board/juno/include \ + -Iplat/arm/css/drivers/sds PLAT_BL_COMMON_SOURCES := plat/arm/board/juno/${ARCH}/juno_helpers.S @@ -55,11 +60,13 @@ ifeq (${ARCH},aarch64) BL1_SOURCES += lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ lib/cpus/aarch64/cortex_a72.S \ + plat/arm/board/juno/juno_err.c \ plat/arm/board/juno/juno_bl1_setup.c \ ${JUNO_INTERCONNECT_SOURCES} \ ${JUNO_SECURITY_SOURCES} BL2_SOURCES += lib/utils/mem_region.c \ + plat/arm/board/juno/juno_err.c \ plat/arm/board/juno/juno_bl2_setup.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ ${JUNO_SECURITY_SOURCES} @@ -76,6 +83,11 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ ${JUNO_GIC_SOURCES} \ ${JUNO_INTERCONNECT_SOURCES} \ ${JUNO_SECURITY_SOURCES} + +ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) +BL1_SOURCES += plat/arm/css/drivers/sds/sds.c +endif + endif # Errata workarounds for Cortex-A53: @@ -112,10 +124,6 @@ ARM_BOARD_OPTIMISE_MEM := 1 # Do not enable SVE ENABLE_SVE_FOR_NS := 0 -# Select SCMI/SDS drivers instead of SCPI/BOM driver for communicating with the -# SCP during power management operations and for SCP RAM Firmware transfer. -CSS_USE_SCMI_SDS_DRIVER := 1 - include plat/arm/board/common/board_css.mk include plat/arm/common/arm_common.mk include plat/arm/soc/common/soc_css.mk diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index a4d2b44c1..d9104ee30 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -23,6 +23,8 @@ #pragma weak bl1_platform_setup #pragma weak bl1_plat_sec_mem_layout #pragma weak bl1_plat_prepare_exit +#pragma weak bl1_plat_get_next_image_id +#pragma weak plat_arm_bl1_fwu_needed #define MAP_BL1_TOTAL MAP_REGION_FLAT( \ bl1_tzram_layout.total_base, \ @@ -186,13 +188,22 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info) #endif } +/* + * On Arm platforms, the FWU process is triggered when the FIP image has + * been tampered with. + */ +int plat_arm_bl1_fwu_needed(void) +{ + return (arm_io_is_toc_valid() != 1); +} + /******************************************************************************* * The following function checks if Firmware update is needed, * by checking if TOC in FIP image is valid or not. ******************************************************************************/ unsigned int bl1_plat_get_next_image_id(void) { - if (!arm_io_is_toc_valid()) + if (plat_arm_bl1_fwu_needed() != 0) return NS_BL1U_IMAGE_ID; return BL2_IMAGE_ID; diff --git a/plat/arm/common/arm_err.c b/plat/arm/common/arm_err.c index 66568e7dc..e13e51f78 100644 --- a/plat/arm/common/arm_err.c +++ b/plat/arm/common/arm_err.c @@ -13,10 +13,12 @@ #include #include +#pragma weak plat_arm_error_handler + /* * ARM common implementation for error handler */ -void plat_error_handler(int err) +void __dead2 plat_arm_error_handler(int err) { int ret; @@ -44,3 +46,8 @@ void plat_error_handler(int err) for (;;) wfi(); } + +void __dead2 plat_error_handler(int err) +{ + plat_arm_error_handler(err); +}