Enable v8.6 WFE trap delays

This patch enables the v8.6 extension to add a delay before WFE traps
are taken. A weak hook plat_arm_set_twedel_scr_el3 has been added in
plat/common/aarch64/plat_common.c that disables this feature by default
but platform-specific code can override it when needed.

The only hook provided sets the TWED fields in SCR_EL3, there are similar
fields in HCR_EL2, SCTLR_EL2, and SCTLR_EL1 to control WFE trap delays in
lower ELs but these should be configured by code running at EL2 and/or EL1
depending on the platform configuration and is outside the scope of TF-A.

Signed-off-by: John Powell <john.powell@arm.com>
Change-Id: I0a9bb814205efeab693a3d0a0623e62144abba2d
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 0314a85..64a2d7b 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -22,6 +22,7 @@
 #include <lib/extensions/mpam.h>
 #include <lib/extensions/spe.h>
 #include <lib/extensions/sve.h>
+#include <lib/extensions/twed.h>
 #include <lib/utils.h>
 
 
@@ -229,6 +230,24 @@
 	sctlr_elx |= SCTLR_IESB_BIT;
 #endif
 
+	/* Enable WFE trap delay in SCR_EL3 if supported and configured */
+	if (is_armv8_6_twed_present()) {
+		uint32_t delay = plat_arm_set_twedel_scr_el3();
+
+		if (delay != TWED_DISABLED) {
+			/* Make sure delay value fits */
+			assert((delay & ~SCR_TWEDEL_MASK) == 0U);
+
+			/* Set delay in SCR_EL3 */
+			scr_el3 &= ~(SCR_TWEDEL_MASK << SCR_TWEDEL_SHIFT);
+			scr_el3 |= ((delay & SCR_TWEDEL_MASK)
+					<< SCR_TWEDEL_SHIFT);
+
+			/* Enable WFE delay */
+			scr_el3 |= SCR_TWEDEn_BIT;
+		}
+	}
+
 	/*
 	 * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
 	 * and other EL2 registers are set up by cm_prepare_ns_entry() as they