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 <sathees.balya@arm.com>
Signed-off-by: Soby Mathew <Soby.Mathew@arm.com>
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index 836a672..3dd2a22 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -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
index 0000000..dd8e278
--- /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 <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();
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 16390fa..481844f 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -22,7 +22,12 @@
 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 @@
 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,8 +83,13 @@
 				${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:
 ERRATA_A53_826319		:=	1
 ERRATA_A53_835769		:=	1
@@ -112,10 +124,6 @@
 # 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