juno: Revert FWU update detect mechanism
authorSathees Balya <sathees.balya@arm.com>
Mon, 3 Sep 2018 16:41:13 +0000 (17:41 +0100)
committerSathees Balya <sathees.balya@arm.com>
Fri, 7 Sep 2018 13:54:02 +0000 (14:54 +0100)
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 <sathees.balya@arm.com>
Signed-off-by: Soby Mathew <Soby.Mathew@arm.com>
include/plat/arm/board/common/v2m_def.h
include/plat/arm/common/plat_arm.h
plat/arm/board/juno/juno_bl1_setup.c
plat/arm/board/juno/juno_err.c [new file with mode: 0644]
plat/arm/board/juno/platform.mk
plat/arm/common/arm_bl1_setup.c
plat/arm/common/arm_err.c

index e5f53732921df8694d72ce1e6b743c7a2b5f5134..ce436d2ca28297731311347ccc7e3e64828ae63b 100644 (file)
@@ -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
index 0770c0ec5314b774d2d8de564c7966f61be5f90c..53b4a45c1d5d1ea1bb3c171743be2f620226da24 100644 (file)
@@ -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);
index 836a67255d428025a077f6ef63a77c48038d3f61..3dd2a227c19181fe41664f26a3a268d37e4a4575 100644 (file)
@@ -5,15 +5,72 @@
  */
 
 #include <bl_common.h>
+#include <debug.h>
 #include <errno.h>
 #include <plat_arm.h>
 #include <platform.h>
+#include <sds.h>
 #include <sp805.h>
 #include <tbbr_img_def.h>
 #include <v2m_def.h>
 
 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 (file)
index 0000000..dd8e278
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <errno.h>
+#include <platform.h>
+#include <v2m_def.h>
+
+/*
+ * 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();
+}
index 16390fa4e7e3e5d213f622f411441f1ce7d38e11..481844f0d0882f5ed1f9de9968dc2c7bd19661c4 100644 (file)
@@ -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
index a4d2b44c14029d91126ca77ac66bc36be4b9ee54..d9104ee302122964c44ef29811e9cf81675bd2ad 100644 (file)
@@ -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;
index 66568e7dc77160b51d6140beb38d19202fa4c09b..e13e51f783a8000e583cb0ec711e60ece2d94e83 100644 (file)
 #include <platform_def.h>
 #include <stdint.h>
 
+#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);
+}