summaryrefslogtreecommitdiff
path: root/plat/arm/common
diff options
context:
space:
mode:
authorSoby Mathew <soby.mathew@arm.com>2018-03-07 11:32:04 +0000
committerSoby Mathew <soby.mathew@arm.com>2018-03-08 09:44:05 +0000
commit7b56928a122f4ba19b5f3d6b834590de2e82a978 (patch)
treeac94c4ff0449270294a78d5f9b08ba968927fbbf /plat/arm/common
parent74847ab203ca1801b450d32a61f3a3cb98adf83b (diff)
Juno: Change the Firmware update detect mechanism
Previously, Juno used to depend on the SSC_GPRETN register to inform about the reset syndrome. This method was removed when SCP migrated to the SDS framework. But even the SDS framework doesn't report the reset syndrome correctly and hence Juno failed to enter Firmware update mode if BL2 authentication failed. In addition to that, the error code populated in V2M_SYS_NVFLAGS register does not seem to be retained any more on Juno across resets. This could be down to the motherboard firmware not doing the necessary to preserve the value. Hence this patch modifies the Juno platform to use the same mechanism to trigger firmware update as FVP which is to corrupt the FIP TOC on authentication failure. The implementation in `fvp_err.c` is made common for ARM platforms and is moved to the new `arm_err.c` file in plat/arm/common folder. The BL1 and BL2 mmap table entries for Juno are modified to allow write to the Flash memory address. Change-Id: Ica7d49a3e8a46a90efd4cf340f19fda3b549e945 Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Diffstat (limited to 'plat/arm/common')
-rw-r--r--plat/arm/common/arm_bl1_setup.c12
-rw-r--r--plat/arm/common/arm_common.mk2
-rw-r--r--plat/arm/common/arm_err.c46
3 files changed, 60 insertions, 0 deletions
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 3a30eca6..379e87df 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -145,3 +145,15 @@ void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
sev();
#endif
}
+
+/*******************************************************************************
+ * 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())
+ return NS_BL1U_IMAGE_ID;
+
+ return BL2_IMAGE_ID;
+}
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index b3462ab8..015e454a 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -137,6 +137,7 @@ BL1_SOURCES += drivers/arm/sp805/sp805.c \
drivers/io/io_storage.c \
plat/arm/common/arm_bl1_setup.c \
plat/arm/common/arm_dyn_cfg.c \
+ plat/arm/common/arm_err.c \
plat/arm/common/arm_io_storage.c
ifdef EL3_PAYLOAD_BASE
# Need the arm_program_trusted_mailbox() function to release secondary CPUs from
@@ -150,6 +151,7 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \
drivers/io/io_memmap.c \
drivers/io/io_storage.c \
plat/arm/common/arm_bl2_setup.c \
+ plat/arm/common/arm_err.c \
plat/arm/common/arm_io_storage.c
# Add `libfdt` and Arm common helpers required for Dynamic Config
diff --git a/plat/arm/common/arm_err.c b/plat/arm/common/arm_err.c
new file mode 100644
index 00000000..59c58618
--- /dev/null
+++ b/plat/arm/common/arm_err.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <board_arm_def.h>
+#include <console.h>
+#include <debug.h>
+#include <errno.h>
+#include <norflash.h>
+#include <platform.h>
+#include <stdint.h>
+
+/*
+ * ARM common implementation for error handler
+ */
+void plat_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");
+ nor_unlock(PLAT_ARM_FIP_BASE);
+ ret = nor_word_program(PLAT_ARM_FIP_BASE, 0);
+ if (ret != 0) {
+ ERROR("Cannot erase ToC\n");
+ } else {
+ INFO("Done\n");
+ }
+ break;
+ default:
+ /* Unexpected error */
+ break;
+ }
+
+ (void)console_flush();
+
+ /* Loop until the watchdog resets the system */
+ for (;;)
+ wfi();
+}