Merge "fix(plat/marvell/armada): select correct pcie reference clock source" into integration
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 30b2ab2..9cb5aa7 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -681,6 +681,20 @@
 :|F|: Makefile
 :|F|: make_helpers/
 
+Threat Model
+~~~~~~~~~~~~~
+:|M|: Zelalem Aweke <Zelalem.Aweke@arm.com>
+:|G|: `zelalem-aweke`_
+:|M|: Sandrine Bailleux <sandrine.bailleux@arm.com>
+:|G|: `sandrine-bailleux-arm`_
+:|M|: Joanna Farley <joanna.farley@arm.com>
+:|G|: `joannafarley-arm`_
+:|M|: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:|G|: `raghuncstate`_
+:|M|: Varun Wadekar <vwadekar@nvidia.com>
+:|G|: `vwadekar`_
+:|F|: docs/threat_model/
+
 .. _AlexeiFedorov: https://github.com/AlexeiFedorov
 .. _Andre-ARM: https://github.com/Andre-ARM
 .. _Anson-Huang: https://github.com/Anson-Huang
diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c
index 02fe97c..7377e5e 100644
--- a/drivers/marvell/comphy/phy-comphy-3700.c
+++ b/drivers/marvell/comphy/phy-comphy-3700.c
@@ -14,6 +14,7 @@
 
 #include <mvebu.h>
 #include <mvebu_def.h>
+#include <plat_marvell.h>
 
 #include "phy-comphy-3700.h"
 #include "phy-comphy-common.h"
@@ -29,15 +30,6 @@
 #define USB3_GBE1_PHY		(MVEBU_REGS_BASE + 0x5C000)
 #define COMPHY_SD_ADDR		(MVEBU_REGS_BASE + 0x1F000)
 
-/*
- * Below address in used only for reading, therefore no problem with concurrent
- * Linux access.
- */
-#define MVEBU_TEST_PIN_LATCH_N (MVEBU_NB_GPIO_REG_BASE + 0x8)
- #define MVEBU_XTAL_MODE_MASK		BIT(9)
- #define MVEBU_XTAL_MODE_OFFS		9
- #define MVEBU_XTAL_CLOCK_25MHZ		0x0
-
 struct sgmii_phy_init_data_fix {
 	uint16_t addr;
 	uint16_t value;
@@ -125,20 +117,6 @@
 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000	/*1F8 */
 };
 
-/* returns reference clock in MHz (25 or 40) */
-static uint32_t get_ref_clk(void)
-{
-	uint32_t val;
-
-	val = (mmio_read_32(MVEBU_TEST_PIN_LATCH_N) & MVEBU_XTAL_MODE_MASK) >>
-		MVEBU_XTAL_MODE_OFFS;
-
-	if (val == MVEBU_XTAL_CLOCK_25MHZ)
-		return 25;
-	else
-		return 40;
-}
-
 /* PHY selector configures with corresponding modes */
 static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index,
 						uint32_t comphy_mode)
diff --git a/include/plat/marvell/armada/a3k/common/plat_marvell.h b/include/plat/marvell/armada/a3k/common/plat_marvell.h
index ea7cdcd..cb31481 100644
--- a/include/plat/marvell/armada/a3k/common/plat_marvell.h
+++ b/include/plat/marvell/armada/a3k/common/plat_marvell.h
@@ -100,4 +100,6 @@
 
 const mmap_region_t *plat_marvell_get_mmap(void);
 
+uint32_t get_ref_clk(void);
+
 #endif /* PLAT_MARVELL_H */
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 730b09b..bd8f85f 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -144,7 +144,7 @@
 	 * If cpu_ops for the MIDR_EL1 cannot be found and
 	 * SUPPORT_UNKNOWN_MPID is enabled, it will try to look for a
 	 * default cpu_ops with an MIDR value of 0.
-	 * (Implementation number 0x0 should be reseverd for software use
+	 * (Implementation number 0x0 should be reserved for software use
 	 * and therefore no clashes should happen with that default value).
 	 *
 	 * Return :
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 2443001..81d793b 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -49,7 +49,7 @@
  *
  * To prepare the register state for entry call cm_prepare_el3_exit() and
  * el3_exit(). For Secure-EL1 cm_prepare_el3_exit() is equivalent to
- * cm_e1_sysreg_context_restore().
+ * cm_el1_sysregs_context_restore().
  ******************************************************************************/
 void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
 {
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index e0e4298..96023b6 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -60,7 +60,7 @@
  *
  * To prepare the register state for entry call cm_prepare_el3_exit() and
  * el3_exit(). For Secure-EL1 cm_prepare_el3_exit() is equivalent to
- * cm_e1_sysreg_context_restore().
+ * cm_el1_sysregs_context_restore().
  ******************************************************************************/
 void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
 {
@@ -286,7 +286,7 @@
 
 	/*
 	 * 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
+	 * and other EL2 registers are set up by cm_prepare_el3_exit() as they
 	 * are not part of the stored cpu_context.
 	 */
 	write_ctx_reg(get_el1_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
index 57d6792..088179b 100644
--- a/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
+++ b/plat/arm/board/fvp/fdts/fvp_spmc_optee_sp_manifest.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,7 +33,6 @@
 			is_ffa_partition;
 			debug_name = "op-tee";
 			load_address = <0x6280000>;
-			smc_whitelist = <0xbe000000>;
 			vcpu_count = <8>;
 			mem_size = <1048576>;
 		};
diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
index 14ad5f5..8ea6ba3 100644
--- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
@@ -51,14 +51,14 @@
 			scp_bl2_uuid = "9766fd3d-89be-e849-ae5d-78a140608213";
 			bl31_uuid = "47d4086d-4cfe-9846-9b95-2950cbbd5a00";
 			bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38";
-			bl32_extra1_uuid = "0b70c28b-2a5a-7840-9f65-0a5682738288";
+			bl32_extra1_uuid = "0b70c29b-2a5a-7840-9f65-0a5682738288";
 			bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9";
 			bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4";
 			hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc";
 			soc_fw_cfg_uuid = "9979814b-0376-fb46-8c8e-8d267f7859e0";
 			tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021";
 			nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9";
-			t_key_cert_uuid = "827ee890-f860-e411-a1b4-77a721b4f94c";
+			t_key_cert_uuid = "827ee890-f860-e411-a1b4-777a21b4f94c";
 			scp_fw_key_uuid = "024221a1-f860-e411-8d9b-f33c0e15a014";
 			soc_fw_key_uuid = "8ab8becc-f960-e411-9ad0-eb4822d8dcf8";
 			tos_fw_key_cert_uuid = "9477d603-fb60-e411-85dd-b7105b8cee04";
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index f9f5577..d4b3425 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -14,6 +14,7 @@
 #include <common/runtime_svc.h>
 #include <imx_sip_svc.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
 #include <sci/sci.h>
 
 #if defined(PLAT_imx8qm) || defined(PLAT_imx8qx)
@@ -145,6 +146,37 @@
 
 #endif /* defined(PLAT_imx8qm) || defined(PLAT_imx8qx) */
 
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+int imx_src_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    void *handle)
+{
+	uint32_t val;
+
+	switch (x1) {
+	case IMX_SIP_SRC_SET_SECONDARY_BOOT:
+		if (x2 != 0U) {
+			mmio_setbits_32(IMX_SRC_BASE + SRC_GPR10_OFFSET,
+					SRC_GPR10_PERSIST_SECONDARY_BOOT);
+		} else {
+			mmio_clrbits_32(IMX_SRC_BASE + SRC_GPR10_OFFSET,
+					SRC_GPR10_PERSIST_SECONDARY_BOOT);
+		}
+		break;
+	case IMX_SIP_SRC_IS_SECONDARY_BOOT:
+		val = mmio_read_32(IMX_SRC_BASE + SRC_GPR10_OFFSET);
+		return !!(val & SRC_GPR10_PERSIST_SECONDARY_BOOT);
+	default:
+		return SMC_UNK;
+
+	};
+
+	return 0;
+}
+#endif /* defined(PLAT_imx8mm) || defined(PLAT_imx8mq) */
+
 static uint64_t imx_get_commit_hash(u_register_t x2,
 		    u_register_t x3,
 		    u_register_t x4)
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 20e1479..fd54820 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -48,6 +48,11 @@
 	case IMX_SIP_MISC_SET_TEMP:
 		SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
 #endif
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+	case IMX_SIP_SRC:
+		SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
+		break;
+#endif
 	case  IMX_SIP_BUILDINFO:
 		SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4));
 	default:
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 0a2d750..6c7a760 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -17,6 +17,10 @@
 #define IMX_SIP_BUILDINFO			0xC2000003
 #define IMX_SIP_BUILDINFO_GET_COMMITHASH	0x00
 
+#define IMX_SIP_SRC			0xC2000005
+#define IMX_SIP_SRC_SET_SECONDARY_BOOT	0x10
+#define IMX_SIP_SRC_IS_SECONDARY_BOOT	0x11
+
 #define IMX_SIP_GET_SOC_INFO		0xC2000006
 
 #define IMX_SIP_WAKEUP_SRC		0xC2000009
@@ -38,6 +42,11 @@
 			 u_register_t x2, u_register_t x3);
 #endif
 
+#if defined(PLAT_imx8mm) || defined(PLAT_imx8mq)
+int imx_src_handler(uint32_t smc_fid, u_register_t x1,
+		    u_register_t x2, u_register_t x3, void *handle);
+#endif
+
 #if (defined(PLAT_imx8qm) || defined(PLAT_imx8qx))
 int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
 			u_register_t x2, u_register_t x3);
diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h
index ec915ad..f8efa56 100644
--- a/plat/imx/imx8m/imx8mm/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mm/include/platform_def.h
@@ -124,6 +124,8 @@
 #define SRC_OTG1PHY_SCR			U(0x20)
 #define SRC_OTG2PHY_SCR			U(0x24)
 #define SRC_GPR1_OFFSET			U(0x74)
+#define SRC_GPR10_OFFSET		U(0x98)
+#define SRC_GPR10_PERSIST_SECONDARY_BOOT	BIT(30)
 
 #define SNVS_LPCR			U(0x38)
 #define SNVS_LPCR_SRTC_ENV		BIT(0)
diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h
index 9db3a13..6d6a865 100644
--- a/plat/imx/imx8m/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8m/imx8mq/include/platform_def.h
@@ -103,6 +103,8 @@
 #define SRC_OTG1PHY_SCR			U(0x20)
 #define SRC_OTG2PHY_SCR			U(0x24)
 #define SRC_GPR1_OFFSET			U(0x74)
+#define SRC_GPR10_OFFSET		U(0x98)
+#define SRC_GPR10_PERSIST_SECONDARY_BOOT	BIT(30)
 
 #define SNVS_LPCR			U(0x38)
 #define SNVS_LPCR_SRTC_ENV		BIT(0)
diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk
index 79097f3..7d95e48 100644
--- a/plat/marvell/armada/a3k/common/a3700_common.mk
+++ b/plat/marvell/armada/a3k/common/a3700_common.mk
@@ -38,6 +38,7 @@
 				-I$/drivers/arm/gic/common/
 
 PLAT_BL_COMMON_SOURCES	:=	$(PLAT_COMMON_BASE)/aarch64/a3700_common.c \
+				$(PLAT_COMMON_BASE)/aarch64/a3700_clock.S \
 				$(MARVELL_DRV_BASE)/uart/a3700_console.S
 
 BL1_SOURCES		+=	$(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \
diff --git a/plat/marvell/armada/a3k/common/aarch64/a3700_clock.S b/plat/marvell/armada/a3k/common/aarch64/a3700_clock.S
new file mode 100644
index 0000000..f79516f
--- /dev/null
+++ b/plat/marvell/armada/a3k/common/aarch64/a3700_clock.S
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <asm_macros.S>
+#include <platform_def.h>
+
+/*
+ * Below address in used only for reading, therefore no problem with concurrent
+ * Linux access.
+ */
+#define MVEBU_TEST_PIN_LATCH_N (MVEBU_NB_GPIO_REG_BASE + 0x8)
+ #define MVEBU_XTAL_MODE_MASK		BIT(9)
+
+	/* -----------------------------------------------------
+	 * uint32_t get_ref_clk (void);
+	 *
+	 * returns reference clock in MHz (25 or 40)
+	 * -----------------------------------------------------
+	 */
+.globl	get_ref_clk
+func get_ref_clk
+	mov_imm	x0, MVEBU_TEST_PIN_LATCH_N
+	ldr	w0, [x0]
+	tst	w0, #MVEBU_XTAL_MODE_MASK
+	bne	40
+	mov	w0, #25
+	ret
+40:
+	mov	w0, #40
+	ret
+endfunc get_ref_clk
diff --git a/plat/marvell/armada/a3k/common/include/platform_def.h b/plat/marvell/armada/a3k/common/include/platform_def.h
index 06a00e4..f19d96b 100644
--- a/plat/marvell/armada/a3k/common/include/platform_def.h
+++ b/plat/marvell/armada/a3k/common/include/platform_def.h
@@ -163,14 +163,7 @@
 /*
  * PL011 related constants
  */
-#define PLAT_MARVELL_BOOT_UART_BASE		(MVEBU_REGS_BASE + 0x12000)
-#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ	25000000
-
-#define PLAT_MARVELL_CRASH_UART_BASE		PLAT_MARVELL_BOOT_UART_BASE
-#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ	PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
-
-#define PLAT_MARVELL_BL31_RUN_UART_BASE		PLAT_MARVELL_BOOT_UART_BASE
-#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ	PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
+#define PLAT_MARVELL_UART_BASE			(MVEBU_REGS_BASE + 0x12000)
 
 /* Required platform porting definitions */
 #define PLAT_MAX_PWR_LVL			MPIDR_AFFLVL1
diff --git a/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c b/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c
index 5147dd5..eb00874 100644
--- a/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c
+++ b/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c
@@ -41,8 +41,8 @@
 	len = sizeof(system_off_now);
 	system_off_now[len - 1] = add_xor_checksum(system_off_now, len);
 
-	console_16550_register(PLAT_MARVELL_BOOT_UART_BASE + 0x100,
-		PLAT_MARVELL_BOOT_UART_CLK_IN_HZ, 115200, &console);
+	console_16550_register(PLAT_MARVELL_UART_BASE + 0x100,
+		PLAT_MARVELL_UART_CLK_IN_HZ, 115200, &console);
 
 	/* Send system_off_now to console */
 	for (i = 0; i < len; i++) {
diff --git a/plat/marvell/armada/a8k/common/include/platform_def.h b/plat/marvell/armada/a8k/common/include/platform_def.h
index 7d85059..45860ba 100644
--- a/plat/marvell/armada/a8k/common/include/platform_def.h
+++ b/plat/marvell/armada/a8k/common/include/platform_def.h
@@ -168,14 +168,8 @@
 /*
  * PL011 related constants
  */
-#define PLAT_MARVELL_BOOT_UART_BASE		(MVEBU_REGS_BASE + 0x512000)
-#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ	200000000
-
-#define PLAT_MARVELL_CRASH_UART_BASE		PLAT_MARVELL_BOOT_UART_BASE
-#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ	PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
-
-#define PLAT_MARVELL_BL31_RUN_UART_BASE		PLAT_MARVELL_BOOT_UART_BASE
-#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ	PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
+#define PLAT_MARVELL_UART_BASE			(MVEBU_REGS_BASE + 0x512000)
+#define PLAT_MARVELL_UART_CLK_IN_HZ		200000000
 
 /* Recovery image enable */
 #define PLAT_RECOVERY_IMAGE_ENABLE		0
diff --git a/plat/marvell/armada/common/aarch64/marvell_helpers.S b/plat/marvell/armada/common/aarch64/marvell_helpers.S
index b798f17..3038ec0 100644
--- a/plat/marvell/armada/common/aarch64/marvell_helpers.S
+++ b/plat/marvell/armada/common/aarch64/marvell_helpers.S
@@ -63,8 +63,16 @@
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_init
-	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
-	mov_imm	x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ
+#ifdef PLAT_a3700
+	mov	x1, x30
+	bl	get_ref_clk
+	mov	x30, x1
+	mov_imm	x1, 1000000
+	mul	x1, x0, x1
+#else
+	mov_imm	x1, PLAT_MARVELL_UART_CLK_IN_HZ
+#endif
+	mov_imm	x0, PLAT_MARVELL_UART_BASE
 	mov_imm	x2, MARVELL_CONSOLE_BAUDRATE
 #ifdef PLAT_a3700
 	b	console_a3700_core_init
@@ -81,7 +89,7 @@
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_putc
-	mov_imm	x1, PLAT_MARVELL_CRASH_UART_BASE
+	mov_imm	x1, PLAT_MARVELL_UART_BASE
 #ifdef PLAT_a3700
 
 	b	console_a3700_core_putc
@@ -99,7 +107,7 @@
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_flush
-	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
+	mov_imm	x0, PLAT_MARVELL_UART_BASE
 #ifdef PLAT_a3700
 	b	console_a3700_core_flush
 #else
diff --git a/plat/marvell/armada/common/marvell_console.c b/plat/marvell/armada/common/marvell_console.c
index c84b004..ef54bff 100644
--- a/plat/marvell/armada/common/marvell_console.c
+++ b/plat/marvell/armada/common/marvell_console.c
@@ -14,6 +14,7 @@
 
 #ifdef PLAT_a3700
 #include <drivers/marvell/uart/a3700_console.h>
+#define PLAT_MARVELL_UART_CLK_IN_HZ (get_ref_clk() * 1000000)
 #define console_marvell_register console_a3700_register
 #else
 #include <drivers/ti/uart/uart_16550.h>
@@ -31,8 +32,8 @@
 void marvell_console_boot_init(void)
 {
 	int rc =
-	console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE,
-				 PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+	console_marvell_register(PLAT_MARVELL_UART_BASE,
+				 PLAT_MARVELL_UART_CLK_IN_HZ,
 				 MARVELL_CONSOLE_BAUDRATE,
 				 &marvell_boot_console);
 	if (rc == 0) {
@@ -58,8 +59,8 @@
 void marvell_console_runtime_init(void)
 {
 	int rc =
-	console_marvell_register(PLAT_MARVELL_BOOT_UART_BASE,
-				 PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+	console_marvell_register(PLAT_MARVELL_UART_BASE,
+				 PLAT_MARVELL_UART_CLK_IN_HZ,
 				 MARVELL_CONSOLE_BAUDRATE,
 				 &marvell_runtime_console);
 	if (rc == 0)
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 6dedc98..a25643b 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -31,9 +31,11 @@
 #include <plat/common/platform.h>
 
 /* IO devices */
+#ifndef AARCH32_SP_OPTEE
 static const io_dev_connector_t *dummy_dev_con;
 static uintptr_t dummy_dev_handle;
 static uintptr_t dummy_dev_spec;
+#endif
 
 static uintptr_t image_dev_handle;
 static uintptr_t storage_dev_handle;
@@ -102,9 +104,9 @@
 	.binary_type = OPTEE_HEADER_BINARY_TYPE,
 };
 
-static const struct stm32image_part_info optee_pager_partition_spec = {
-	.name = OPTEE_PAGER_IMAGE_NAME,
-	.binary_type = OPTEE_PAGER_BINARY_TYPE,
+static const struct stm32image_part_info optee_core_partition_spec = {
+	.name = OPTEE_CORE_IMAGE_NAME,
+	.binary_type = OPTEE_CORE_BINARY_TYPE,
 };
 
 static const struct stm32image_part_info optee_paged_partition_spec = {
@@ -118,11 +120,6 @@
 };
 #endif
 
-static const io_block_spec_t bl2_block_spec = {
-	.offset = BL2_BASE,
-	.length = STM32MP_BL2_SIZE,
-};
-
 static const struct stm32image_part_info bl33_partition_spec = {
 	.name = BL33_IMAGE_NAME,
 	.binary_type = BL33_BINARY_TYPE,
@@ -132,7 +129,7 @@
 	IMG_IDX_BL33,
 #ifdef AARCH32_SP_OPTEE
 	IMG_IDX_OPTEE_HEADER,
-	IMG_IDX_OPTEE_PAGER,
+	IMG_IDX_OPTEE_CORE,
 	IMG_IDX_OPTEE_PAGED,
 #endif
 	IMG_IDX_NUM
@@ -149,9 +146,9 @@
 		.name = OPTEE_HEADER_IMAGE_NAME,
 		.binary_type = OPTEE_HEADER_BINARY_TYPE,
 	},
-	.part_info[IMG_IDX_OPTEE_PAGER] = {
-		.name = OPTEE_PAGER_IMAGE_NAME,
-		.binary_type = OPTEE_PAGER_BINARY_TYPE,
+	.part_info[IMG_IDX_OPTEE_CORE] = {
+		.name = OPTEE_CORE_IMAGE_NAME,
+		.binary_type = OPTEE_CORE_BINARY_TYPE,
 	},
 	.part_info[IMG_IDX_OPTEE_PAGED] = {
 		.name = OPTEE_PAGED_IMAGE_NAME,
@@ -167,7 +164,9 @@
 
 static const io_dev_connector_t *stm32image_dev_con __unused;
 
+#ifndef AARCH32_SP_OPTEE
 static int open_dummy(const uintptr_t spec);
+#endif
 static int open_image(const uintptr_t spec);
 static int open_storage(const uintptr_t spec);
 
@@ -178,11 +177,6 @@
 };
 
 static const struct plat_io_policy policies[] = {
-	[BL2_IMAGE_ID] = {
-		.dev_handle = &dummy_dev_handle,
-		.image_spec = (uintptr_t)&bl2_block_spec,
-		.check = open_dummy
-	},
 #ifdef AARCH32_SP_OPTEE
 	[BL32_IMAGE_ID] = {
 		.dev_handle = &image_dev_handle,
@@ -191,7 +185,7 @@
 	},
 	[BL32_EXTRA1_IMAGE_ID] = {
 		.dev_handle = &image_dev_handle,
-		.image_spec = (uintptr_t)&optee_pager_partition_spec,
+		.image_spec = (uintptr_t)&optee_core_partition_spec,
 		.check = open_image
 	},
 	[BL32_EXTRA2_IMAGE_ID] = {
@@ -225,10 +219,12 @@
 	}
 };
 
+#ifndef AARCH32_SP_OPTEE
 static int open_dummy(const uintptr_t spec)
 {
 	return io_dev_init(dummy_dev_handle, 0);
 }
+#endif
 
 static int open_image(const uintptr_t spec)
 {
@@ -396,7 +392,7 @@
 	part->part_offset = STM32MP_NOR_TEED_OFFSET;
 	part->bkp_offset = 0U;
 
-	idx = IMG_IDX_OPTEE_PAGER;
+	idx = IMG_IDX_OPTEE_CORE;
 	part = &stm32image_dev_info_spec.part_info[idx];
 	part->part_offset = STM32MP_NOR_TEEX_OFFSET;
 	part->bkp_offset = 0U;
@@ -449,7 +445,7 @@
 	part->part_offset = STM32MP_NAND_TEED_OFFSET;
 	part->bkp_offset = nand_dev_spec.erase_size;
 
-	idx = IMG_IDX_OPTEE_PAGER;
+	idx = IMG_IDX_OPTEE_CORE;
 	part = &stm32image_dev_info_spec.part_info[idx];
 	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
 	part->bkp_offset = nand_dev_spec.erase_size;
@@ -503,7 +499,7 @@
 	part->part_offset = STM32MP_NAND_TEED_OFFSET;
 	part->bkp_offset = spi_nand_dev_spec.erase_size;
 
-	idx = IMG_IDX_OPTEE_PAGER;
+	idx = IMG_IDX_OPTEE_CORE;
 	part = &stm32image_dev_info_spec.part_info[idx];
 	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
 	part->bkp_offset = spi_nand_dev_spec.erase_size;
@@ -533,12 +529,14 @@
 		     boot_context->boot_partition_used_toboot);
 	}
 
+#ifndef AARCH32_SP_OPTEE
 	io_result = register_io_dev_dummy(&dummy_dev_con);
 	assert(io_result == 0);
 
 	io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
 				&dummy_dev_handle);
 	assert(io_result == 0);
+#endif
 
 	switch (boot_context->boot_interface_selected) {
 #if STM32MP_SDMMC
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index b45f8fb..9a2f54a 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -27,10 +27,10 @@
 
 #ifdef AARCH32_SP_OPTEE
 #define OPTEE_HEADER_IMAGE_NAME		"teeh"
+#define OPTEE_CORE_IMAGE_NAME		"teex"
 #define OPTEE_PAGED_IMAGE_NAME		"teed"
-#define OPTEE_PAGER_IMAGE_NAME		"teex"
 #define OPTEE_HEADER_BINARY_TYPE	U(0x20)
-#define OPTEE_PAGER_BINARY_TYPE		U(0x21)
+#define OPTEE_CORE_BINARY_TYPE		U(0x21)
 #define OPTEE_PAGED_BINARY_TYPE		U(0x22)
 #endif
 
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 2796840..143385d 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -36,7 +36,7 @@
  * little space for growth.
  */
 #ifndef ZYNQMP_ATF_MEM_BASE
-#if !DEBUG && defined(SPD_none)
+#if !DEBUG && defined(SPD_none) && !SDEI_SUPPORT
 # define BL31_BASE			0xfffea000
 # define BL31_LIMIT			0xffffffff
 #else
@@ -91,6 +91,13 @@
 #define CACHE_WRITEBACK_SHIFT   6
 #define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
 
+#define ZYNQMP_SDEI_SGI_PRIVATE		U(8)
+
+/* Platform macros to support exception handling framework */
+#define PLAT_PRI_BITS			U(3)
+#define PLAT_SDEI_CRITICAL_PRI		0x10
+#define PLAT_SDEI_NORMAL_PRI		0x20
+
 #define PLAT_ARM_GICD_BASE	BASE_GICD_BASE
 #define PLAT_ARM_GICC_BASE	BASE_GICC_BASE
 /*
@@ -102,8 +109,6 @@
 #define PLAT_ARM_G1S_IRQ_PROPS(grp) \
 	INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
-	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
 	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
 	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
@@ -124,8 +129,6 @@
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(IRQ_TTC3_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
 	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE), \
 	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
@@ -142,6 +145,8 @@
 			GIC_INTR_CFG_EDGE)
 #endif
 
-#define PLAT_ARM_G0_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI,	grp, \
+			GIC_INTR_CFG_EDGE)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 99a4beb..5e69151 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -14,6 +14,8 @@
 override GICV2_G0_FOR_EL3 := 1
 override WARMBOOT_ENABLE_DCACHE_EARLY := 1
 
+EL3_EXCEPTION_HANDLING := $(SDEI_SUPPORT)
+
 # Do not enable SVE
 ENABLE_SVE_FOR_NS	:= 0
 
@@ -107,6 +109,11 @@
 				plat/xilinx/zynqmp/pm_service/pm_api_clock.c	\
 				plat/xilinx/zynqmp/pm_service/pm_client.c
 
+ifeq (${SDEI_SUPPORT},1)
+BL31_SOURCES		+=	plat/xilinx/zynqmp/zynqmp_ehf.c			\
+				plat/xilinx/zynqmp/zynqmp_sdei.c
+endif
+
 BL31_CPPFLAGS		+=	-fno-jump-tables
 
 ifneq (${RESET_TO_BL31},1)
diff --git a/plat/xilinx/zynqmp/zynqmp_ehf.c b/plat/xilinx/zynqmp/zynqmp_ehf.c
new file mode 100644
index 0000000..fbf1ed0
--- /dev/null
+++ b/plat/xilinx/zynqmp/zynqmp_ehf.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) Siemens AG, 2020-2021
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+
+/*
+ * Enumeration of priority levels on ARM platforms.
+ */
+ehf_pri_desc_t zynqmp_exceptions[] = {
+	/* Critical priority SDEI */
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_CRITICAL_PRI),
+
+	/* Normal priority SDEI */
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
+};
+
+/* Plug in ARM exceptions to Exception Handling Framework. */
+EHF_REGISTER_PRIORITIES(zynqmp_exceptions, ARRAY_SIZE(zynqmp_exceptions), PLAT_PRI_BITS);
diff --git a/plat/xilinx/zynqmp/zynqmp_sdei.c b/plat/xilinx/zynqmp/zynqmp_sdei.c
new file mode 100644
index 0000000..7e92b58
--- /dev/null
+++ b/plat/xilinx/zynqmp/zynqmp_sdei.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) Siemens AG, 2020-2021
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* SDEI configuration for ARM platforms */
+
+#include <bl31/ehf.h>
+#include <common/debug.h>
+#include <services/sdei.h>
+
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+int arm_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	return (entrypoint < BL31_BASE || entrypoint > BL31_LIMIT) ? 0 : -1;
+}
+
+/* Private event mappings */
+static sdei_ev_map_t zynqmp_sdei_private[] = {
+	SDEI_DEFINE_EVENT_0(ZYNQMP_SDEI_SGI_PRIVATE),
+};
+
+/* Shared event mappings */
+static sdei_ev_map_t zynqmp_sdei_shared[] = {
+};
+
+void plat_sdei_setup(void)
+{
+	INFO("SDEI platform setup\n");
+}
+
+/* Export ARM SDEI events */
+REGISTER_SDEI_MAP(zynqmp_sdei_private, zynqmp_sdei_shared);
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 06039f0..e18d94c 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -108,9 +108,10 @@
 	cm_set_context(&(spmc_ctx->cpu_ctx), SECURE);
 
 	/* Restore the context assigned above */
-	cm_el1_sysregs_context_restore(SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_restore(SECURE);
+#else
+	cm_el1_sysregs_context_restore(SECURE);
 #endif
 	cm_set_next_eret_context(SECURE);
 
@@ -118,9 +119,10 @@
 	rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx);
 
 	/* Save secure state */
-	cm_el1_sysregs_context_save(SECURE);
 #if SPMD_SPM_AT_SEL2
 	cm_el2_sysregs_context_save(SECURE);
+#else
+	cm_el1_sysregs_context_save(SECURE);
 #endif
 
 	return rc;
@@ -346,15 +348,23 @@
 	unsigned int secure_state_out = (!secure_origin) ? SECURE : NON_SECURE;
 
 	/* Save incoming security state */
-	cm_el1_sysregs_context_save(secure_state_in);
 #if SPMD_SPM_AT_SEL2
+	if (secure_state_in == NON_SECURE) {
+		cm_el1_sysregs_context_save(secure_state_in);
+	}
 	cm_el2_sysregs_context_save(secure_state_in);
+#else
+	cm_el1_sysregs_context_save(secure_state_in);
 #endif
 
 	/* Restore outgoing security state */
-	cm_el1_sysregs_context_restore(secure_state_out);
 #if SPMD_SPM_AT_SEL2
+	if (secure_state_out == NON_SECURE) {
+		cm_el1_sysregs_context_restore(secure_state_out);
+	}
 	cm_el2_sysregs_context_restore(secure_state_out);
+#else
+	cm_el1_sysregs_context_restore(secure_state_out);
 #endif
 	cm_set_next_eret_context(secure_state_out);