Merge "fix(cpus): workaround for Cortex-A520 erratum 2858100" into integration
diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h
index 54c8643..5ea5a41 100644
--- a/include/lib/transfer_list.h
+++ b/include/lib/transfer_list.h
@@ -10,47 +10,57 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <common/ep_info.h>
 #include <lib/utils_def.h>
 
-#define	TRANSFER_LIST_SIGNATURE		U(0x006ed0ff)
-#define TRANSFER_LIST_VERSION		U(0x0001)
+#define TRANSFER_LIST_SIGNATURE U(0x4a0fb10b)
+#define TRANSFER_LIST_VERSION U(0x0001)
 
-// Init value of maximum alignment required by any TE data in the TL
-// specified as a power of two
-#define TRANSFER_LIST_INIT_MAX_ALIGN	U(3)
+/*
+ * Init value of maximum alignment required by any TE data in the TL
+ * specified as a power of two
+ */
+#define TRANSFER_LIST_INIT_MAX_ALIGN U(3)
 
-// alignment required by TE header start address, in bytes
-#define TRANSFER_LIST_GRANULE		U(8)
+/* Alignment required by TE header start address, in bytes */
+#define TRANSFER_LIST_GRANULE U(8)
 
-// version of the register convention used.
-// Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
+/*
+ * Version of the register convention used.
+ * Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
+ */
 #define REGISTER_CONVENTION_VERSION_MASK (1 << 24)
 
 #ifndef __ASSEMBLER__
 
+#define TL_FLAGS_HAS_CHECKSUM BIT(0)
+
 enum transfer_list_tag_id {
 	TL_TAG_EMPTY = 0,
 	TL_TAG_FDT = 1,
 	TL_TAG_HOB_BLOCK = 2,
 	TL_TAG_HOB_LIST = 3,
 	TL_TAG_ACPI_TABLE_AGGREGATE = 4,
+	TL_TAG_OPTEE_PAGABLE_PART = 0x100,
 };
 
 enum transfer_list_ops {
-	TL_OPS_NON,	// invalid for any operation
-	TL_OPS_ALL,	// valid for all operations
-	TL_OPS_RO,	// valid for read only
-	TL_OPS_CUS,	// either abort or switch to special code to interpret
+	TL_OPS_NON, /* invalid for any operation */
+	TL_OPS_ALL, /* valid for all operations */
+	TL_OPS_RO, /* valid for read only */
+	TL_OPS_CUS, /* abort or switch to special code to interpret */
 };
 
 struct transfer_list_header {
-	uint32_t	signature;
-	uint8_t		checksum;
-	uint8_t		version;
-	uint8_t		hdr_size;
-	uint8_t		alignment;	// max alignment of TE data
-	uint32_t	size;		// TL header + all TEs
-	uint32_t	max_size;
+	uint32_t signature;
+	uint8_t checksum;
+	uint8_t version;
+	uint8_t hdr_size;
+	uint8_t alignment; /* max alignment of TE data */
+	uint32_t size; /* TL header + all TEs */
+	uint32_t max_size;
+	uint32_t flags;
+	uint32_t reserved; /* spare bytes */
 	/*
 	 * Commented out element used to visualize dynamic part of the
 	 * data structure.
@@ -64,10 +74,10 @@
 };
 
 struct transfer_list_entry {
-	uint16_t	tag_id;
-	uint8_t		reserved0;	// place holder
-	uint8_t		hdr_size;
-	uint32_t	data_size;
+	uint16_t tag_id;
+	uint8_t reserved0; /* place holder */
+	uint8_t hdr_size;
+	uint32_t data_size;
 	/*
 	 * Commented out element used to visualize dynamic part of the
 	 * data structure.
@@ -80,11 +90,16 @@
 };
 
 void transfer_list_dump(struct transfer_list_header *tl);
+entry_point_info_t *
+transfer_list_set_handoff_args(struct transfer_list_header *tl,
+			       entry_point_info_t *ep_info);
 struct transfer_list_header *transfer_list_init(void *addr, size_t max_size);
 
-struct transfer_list_header *transfer_list_relocate(struct transfer_list_header *tl,
-						    void *addr, size_t max_size);
-enum transfer_list_ops transfer_list_check_header(const struct transfer_list_header *tl);
+struct transfer_list_header *
+transfer_list_relocate(struct transfer_list_header *tl, void *addr,
+		       size_t max_size);
+enum transfer_list_ops
+transfer_list_check_header(const struct transfer_list_header *tl);
 
 void transfer_list_update_checksum(struct transfer_list_header *tl);
 bool transfer_list_verify_checksum(const struct transfer_list_header *tl);
@@ -94,18 +109,22 @@
 				 uint32_t new_data_size);
 
 void *transfer_list_entry_data(struct transfer_list_entry *entry);
-bool transfer_list_rem(struct transfer_list_header *tl, struct transfer_list_entry *entry);
+bool transfer_list_rem(struct transfer_list_header *tl,
+		       struct transfer_list_entry *entry);
 
 struct transfer_list_entry *transfer_list_add(struct transfer_list_header *tl,
-					      uint16_t tag_id, uint32_t data_size,
+					      uint16_t tag_id,
+					      uint32_t data_size,
 					      const void *data);
 
-struct transfer_list_entry *transfer_list_add_with_align(struct transfer_list_header *tl,
-							 uint16_t tag_id, uint32_t data_size,
-							 const void *data, uint8_t alignment);
+struct transfer_list_entry *
+transfer_list_add_with_align(struct transfer_list_header *tl, uint16_t tag_id,
+			     uint32_t data_size, const void *data,
+			     uint8_t alignment);
 
-struct transfer_list_entry *transfer_list_next(struct transfer_list_header *tl,
-					       struct transfer_list_entry *last);
+struct transfer_list_entry *
+transfer_list_next(struct transfer_list_header *tl,
+		   struct transfer_list_entry *last);
 
 struct transfer_list_entry *transfer_list_find(struct transfer_list_header *tl,
 					       uint16_t tag_id);
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
index 477522f..a85d956 100644
--- a/lib/cpus/aarch64/neoverse_n2.S
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -252,9 +252,9 @@
 
 #if ENABLE_FEAT_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
-	sysreg_bit_set cptr_el3, TAM_BIT
+	sysreg_bit_clear cptr_el3, TAM_BIT
 	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
-	sysreg_bit_set cptr_el2, TAM_BIT
+	sysreg_bit_clear cptr_el2, TAM_BIT
 	/* No need to enable the counters as this would be done at el3 exit */
 #endif
 
diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c
index e38bf74..63969e9 100644
--- a/lib/transfer_list/transfer_list.c
+++ b/lib/transfer_list/transfer_list.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arch.h>
 #include <assert.h>
 #include <inttypes.h>
 #include <string.h>
@@ -20,29 +21,66 @@
 	if (!tl) {
 		return;
 	}
-	NOTICE("Dump transfer list:\n");
-	NOTICE("signature  0x%x\n", tl->signature);
-	NOTICE("checksum   0x%x\n", tl->checksum);
-	NOTICE("version    0x%x\n", tl->version);
-	NOTICE("hdr_size   0x%x\n", tl->hdr_size);
-	NOTICE("alignment  0x%x\n", tl->alignment);
-	NOTICE("size       0x%x\n", tl->size);
-	NOTICE("max_size   0x%x\n", tl->max_size);
+	INFO("Dump transfer list:\n");
+	INFO("signature  0x%x\n", tl->signature);
+	INFO("checksum   0x%x\n", tl->checksum);
+	INFO("version    0x%x\n", tl->version);
+	INFO("hdr_size   0x%x\n", tl->hdr_size);
+	INFO("alignment  0x%x\n", tl->alignment);
+	INFO("size       0x%x\n", tl->size);
+	INFO("max_size   0x%x\n", tl->max_size);
+	INFO("flags      0x%x\n", tl->flags);
 	while (true) {
 		te = transfer_list_next(tl, te);
 		if (!te) {
 			break;
 		}
-		NOTICE("Entry %d:\n", i++);
-		NOTICE("tag_id     0x%x\n", te->tag_id);
-		NOTICE("hdr_size   0x%x\n", te->hdr_size);
-		NOTICE("data_size  0x%x\n", te->data_size);
-		NOTICE("data_addr  0x%lx\n",
-		(unsigned long)transfer_list_entry_data(te));
+		INFO("Entry %d:\n", i++);
+		INFO("tag_id     0x%x\n", te->tag_id);
+		INFO("hdr_size   0x%x\n", te->hdr_size);
+		INFO("data_size  0x%x\n", te->data_size);
+		INFO("data_addr  0x%lx\n",
+		     (unsigned long)transfer_list_entry_data(te));
 	}
 }
 
 /*******************************************************************************
+ * Set the handoff arguments according to the transfer list payload
+ * Return pointer to the entry point info if arguments are set properly
+ * or NULL if not
+ ******************************************************************************/
+entry_point_info_t *
+transfer_list_set_handoff_args(struct transfer_list_header *tl,
+			       entry_point_info_t *ep_info)
+{
+	struct transfer_list_entry *te = NULL;
+	void *dt = NULL;
+
+	if (!ep_info || !tl || transfer_list_check_header(tl) == TL_OPS_NON) {
+		return NULL;
+	}
+
+	te = transfer_list_find(tl, TL_TAG_FDT);
+	dt = transfer_list_entry_data(te);
+
+	ep_info->args.arg1 = TRANSFER_LIST_SIGNATURE |
+			     REGISTER_CONVENTION_VERSION_MASK;
+	ep_info->args.arg3 = (uintptr_t)tl;
+
+	if (GET_RW(ep_info->spsr) == MODE_RW_32) {
+		/* aarch32 */
+		ep_info->args.arg0 = 0;
+		ep_info->args.arg2 = (uintptr_t)dt;
+	} else {
+		/* aarch64 */
+		ep_info->args.arg0 = (uintptr_t)dt;
+		ep_info->args.arg2 = 0;
+	}
+
+	return ep_info;
+}
+
+/*******************************************************************************
  * Creating a transfer list in a reserved memory region specified
  * Compliant to 2.4.5 of Firmware handoff specification (v0.9)
  * Return pointer to the created transfer list or NULL on error
@@ -65,9 +103,10 @@
 	tl->signature = TRANSFER_LIST_SIGNATURE;
 	tl->version = TRANSFER_LIST_VERSION;
 	tl->hdr_size = sizeof(*tl);
-	tl->alignment = TRANSFER_LIST_INIT_MAX_ALIGN; // initial max align
-	tl->size = sizeof(*tl); // initial size is the size of header
+	tl->alignment = TRANSFER_LIST_INIT_MAX_ALIGN; /* initial max align */
+	tl->size = sizeof(*tl); /* initial size is the size of header */
 	tl->max_size = max_size;
+	tl->flags = TL_FLAGS_HAS_CHECKSUM;
 
 	transfer_list_update_checksum(tl);
 
@@ -77,11 +116,11 @@
 /*******************************************************************************
  * Relocating a transfer list to a reserved memory region specified
  * Compliant to 2.4.6 of Firmware handoff specification (v0.9)
- * Return true on success or false on error
+ * Return pointer to the relocated transfer list or NULL on error
  ******************************************************************************/
-struct transfer_list_header *transfer_list_relocate(
-						struct transfer_list_header *tl,
-						void *addr, size_t max_size)
+struct transfer_list_header *
+transfer_list_relocate(struct transfer_list_header *tl, void *addr,
+		       size_t max_size)
 {
 	uintptr_t new_addr, align_mask, align_off;
 	struct transfer_list_header *new_tl;
@@ -101,7 +140,7 @@
 
 	new_max_size = max_size - (new_addr - (uintptr_t)addr);
 
-	// the new space is not sufficient for the tl
+	/* the new space is not sufficient for the tl */
 	if (tl->size > new_max_size) {
 		return NULL;
 	}
@@ -120,37 +159,39 @@
  * Compliant to 2.4.1 of Firmware handoff specification (v0.9)
  * Return transfer list operation status code
  ******************************************************************************/
-enum transfer_list_ops transfer_list_check_header(
-					const struct transfer_list_header *tl)
+enum transfer_list_ops
+transfer_list_check_header(const struct transfer_list_header *tl)
 {
 	if (!tl) {
 		return TL_OPS_NON;
 	}
 
 	if (tl->signature != TRANSFER_LIST_SIGNATURE) {
-		ERROR("Bad transfer list signature %#"PRIx32"\n",
+		ERROR("Bad transfer list signature %#" PRIx32 "\n",
 		      tl->signature);
 		return TL_OPS_NON;
 	}
 
 	if (!tl->max_size) {
-		ERROR("Bad transfer list max size %#"PRIx32"\n",
+		ERROR("Bad transfer list max size %#" PRIx32 "\n",
 		      tl->max_size);
 		return TL_OPS_NON;
 	}
 
 	if (tl->size > tl->max_size) {
-		ERROR("Bad transfer list size %#"PRIx32"\n", tl->size);
+		ERROR("Bad transfer list size %#" PRIx32 "\n", tl->size);
 		return TL_OPS_NON;
 	}
 
 	if (tl->hdr_size != sizeof(struct transfer_list_header)) {
-		ERROR("Bad transfer list header size %#"PRIx32"\n", tl->hdr_size);
+		ERROR("Bad transfer list header size %#" PRIx32 "\n",
+		      tl->hdr_size);
 		return TL_OPS_NON;
 	}
 
 	if (!transfer_list_verify_checksum(tl)) {
-		ERROR("Bad transfer list checksum %#"PRIx32"\n", tl->checksum);
+		ERROR("Bad transfer list checksum %#" PRIx32 "\n",
+		      tl->checksum);
 		return TL_OPS_NON;
 	}
 
@@ -190,14 +231,13 @@
 
 	if (last) {
 		va = (uintptr_t)last;
-		// check if the total size overflow
-		if (add_overflow(last->hdr_size,
-			last->data_size, &sz)) {
+		/* check if the total size overflow */
+		if (add_overflow(last->hdr_size, last->data_size, &sz)) {
 			return NULL;
 		}
-		// roundup to the next entry
-		if (add_with_round_up_overflow(va, sz,
-			TRANSFER_LIST_GRANULE, &va)) {
+		/* roundup to the next entry */
+		if (add_with_round_up_overflow(va, sz, TRANSFER_LIST_GRANULE,
+					       &va)) {
 			return NULL;
 		}
 	} else {
@@ -207,9 +247,8 @@
 	te = (struct transfer_list_entry *)va;
 
 	if (va + sizeof(*te) > tl_ev || te->hdr_size < sizeof(*te) ||
-		add_overflow(te->hdr_size, te->data_size, &sz) ||
-		add_overflow(va, sz, &ev) ||
-		ev > tl_ev) {
+	    add_overflow(te->hdr_size, te->data_size, &sz) ||
+	    add_overflow(va, sz, &ev) || ev > tl_ev) {
 		return NULL;
 	}
 
@@ -226,10 +265,6 @@
 	uint8_t cs = 0;
 	size_t n = 0;
 
-	if (!tl) {
-		return 0;
-	}
-
 	for (n = 0; n < tl->size; n++) {
 		cs += b[n];
 	}
@@ -245,7 +280,7 @@
 {
 	uint8_t cs;
 
-	if (!tl) {
+	if (!tl || !(tl->flags & TL_FLAGS_HAS_CHECKSUM)) {
 		return;
 	}
 
@@ -262,6 +297,14 @@
  ******************************************************************************/
 bool transfer_list_verify_checksum(const struct transfer_list_header *tl)
 {
+	if (!tl) {
+		return false;
+	}
+
+	if (!(tl->flags & TL_FLAGS_HAS_CHECKSUM)) {
+		return true;
+	}
+
 	return !calc_byte_sum(tl);
 }
 
@@ -284,27 +327,31 @@
 	}
 	tl_old_ev = (uintptr_t)tl + tl->size;
 
-	// calculate the old and new end of TE
-	// both must be roundup to align with TRANSFER_LIST_GRANULE
+	/*
+	 * calculate the old and new end of TE
+	 * both must be roundup to align with TRANSFER_LIST_GRANULE
+	 */
 	if (add_overflow(te->hdr_size, te->data_size, &sz) ||
-		add_with_round_up_overflow((uintptr_t)te, sz,
-		TRANSFER_LIST_GRANULE, &old_ev)) {
+	    add_with_round_up_overflow((uintptr_t)te, sz, TRANSFER_LIST_GRANULE,
+				       &old_ev)) {
 		return false;
 	}
 	if (add_overflow(te->hdr_size, new_data_size, &sz) ||
-		add_with_round_up_overflow((uintptr_t)te, sz,
-		TRANSFER_LIST_GRANULE, &new_ev)) {
+	    add_with_round_up_overflow((uintptr_t)te, sz, TRANSFER_LIST_GRANULE,
+				       &new_ev)) {
 		return false;
 	}
 
 	if (new_ev > old_ev) {
-		// move distance should be roundup
-		// to meet the requirement of TE data max alignment
-		// ensure that the increased size doesn't exceed
-		// the max size of TL
+		/*
+		 * move distance should be roundup
+		 * to meet the requirement of TE data max alignment
+		 * ensure that the increased size doesn't exceed
+		 * the max size of TL
+		 */
 		mov_dis = new_ev - old_ev;
-		if (round_up_overflow(mov_dis, 1 << tl->alignment,
-			&mov_dis) || tl->size + mov_dis > tl->max_size) {
+		if (round_up_overflow(mov_dis, 1 << tl->alignment, &mov_dis) ||
+		    tl->size + mov_dis > tl->max_size) {
 			return false;
 		}
 		ru_new_ev = old_ev + mov_dis;
@@ -316,7 +363,7 @@
 	}
 
 	if (gap >= sizeof(*dummy_te)) {
-		// create a dummy TE to fill up the gap
+		/* create a dummy TE to fill up the gap */
 		dummy_te = (struct transfer_list_entry *)new_ev;
 		dummy_te->tag_id = TL_TAG_EMPTY;
 		dummy_te->reserved0 = 0;
@@ -335,7 +382,7 @@
  * Return true on success or false on error
  ******************************************************************************/
 bool transfer_list_rem(struct transfer_list_header *tl,
-			struct transfer_list_entry *te)
+		       struct transfer_list_entry *te)
 {
 	if (!tl || !te || (uintptr_t)te > (uintptr_t)tl + tl->size) {
 		return false;
@@ -369,11 +416,13 @@
 	tl_ev = (uintptr_t)tl + tl->size;
 	ev = tl_ev;
 
-	// skip the step 1 (optional step)
-	// new TE will be added into the tail
+	/*
+	 * skip the step 1 (optional step)
+	 * new TE will be added into the tail
+	 */
 	if (add_overflow(sizeof(*te), data_size, &sz) ||
-		add_with_round_up_overflow(ev, sz,
-		TRANSFER_LIST_GRANULE, &ev) || ev > max_tl_ev) {
+	    add_with_round_up_overflow(ev, sz, TRANSFER_LIST_GRANULE, &ev) ||
+	    ev > max_tl_ev) {
 		return NULL;
 	}
 
@@ -385,7 +434,7 @@
 	tl->size += ev - tl_ev;
 
 	if (data) {
-		// get TE data pointer
+		/* get TE data pointer */
 		te_data = transfer_list_entry_data(te);
 		if (!te_data) {
 			return NULL;
@@ -404,10 +453,10 @@
  * Compliant to 2.4.4 of Firmware handoff specification (v0.9)
  * Return pointer to the added transfer entry or NULL on error
  ******************************************************************************/
-struct transfer_list_entry *transfer_list_add_with_align(
-					struct transfer_list_header *tl,
-					uint16_t tag_id, uint32_t data_size,
-					const void *data, uint8_t alignment)
+struct transfer_list_entry *
+transfer_list_add_with_align(struct transfer_list_header *tl, uint16_t tag_id,
+			     uint32_t data_size, const void *data,
+			     uint8_t alignment)
 {
 	struct transfer_list_entry *te = NULL;
 	uintptr_t tl_ev, ev, new_tl_ev;
@@ -421,15 +470,17 @@
 	ev = tl_ev + sizeof(struct transfer_list_entry);
 
 	if (!is_aligned(ev, 1 << alignment)) {
-		// TE data address is not aligned to the new alignment
-		// fill the gap with an empty TE as a placeholder before
-		// adding the desire TE
+		/*
+		 * TE data address is not aligned to the new alignment
+		 * fill the gap with an empty TE as a placeholder before
+		 * adding the desire TE
+		 */
 		new_tl_ev = round_up(ev, 1 << alignment) -
-				sizeof(struct transfer_list_entry);
-		dummy_te_data_sz = new_tl_ev - tl_ev -
-					sizeof(struct transfer_list_entry);
+			    sizeof(struct transfer_list_entry);
+		dummy_te_data_sz =
+			new_tl_ev - tl_ev - sizeof(struct transfer_list_entry);
 		if (!transfer_list_add(tl, TL_TAG_EMPTY, dummy_te_data_sz,
-					NULL)) {
+				       NULL)) {
 			return NULL;
 		}
 	}
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index 77d3af9..29fbf92 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -68,6 +68,7 @@
 
 /* SEU Commands */
 #define MBOX_CMD_SEU_ERR_READ				0x3C
+#define MBOX_CMD_SAFE_INJECT_SEU_ERR			0x41
 
 /* RSU Commands */
 #define MBOX_GET_SUBPARTITION_TABLE			0x5A
@@ -107,7 +108,7 @@
 #define MBOX_GET_MEASUREMENT				0x183
 
 /* Miscellaneous commands */
-#define MBOX_GET_ROM_PATCH_SHA384	0x1B0
+#define MBOX_GET_ROM_PATCH_SHA384			0x1B0
 
 /* Mailbox Definitions */
 
@@ -196,9 +197,9 @@
 #define RSU_VERSION_ACMF_MASK				0xff00
 
 /* Config Status Macros */
-#define CONFIG_STATUS_WORD_SIZE			16U
-#define CONFIG_STATUS_FW_VER_OFFSET		1
-#define CONFIG_STATUS_FW_VER_MASK		0x00FFFFFF
+#define CONFIG_STATUS_WORD_SIZE				16U
+#define CONFIG_STATUS_FW_VER_OFFSET			1
+#define CONFIG_STATUS_FW_VER_MASK			0x00FFFFFF
 
 /* Data structure */
 
@@ -249,5 +250,6 @@
 int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf);
 int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf);
 int mailbox_seu_err_status(uint32_t *resp_buf, uint32_t resp_buf_len);
+int mailbox_safe_inject_seu_err(uint32_t *arg, unsigned int len);
 
 #endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index 0668301..d45ab11 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,82 +9,82 @@
 
 
 /* SiP status response */
-#define INTEL_SIP_SMC_STATUS_OK					0
-#define INTEL_SIP_SMC_STATUS_BUSY				0x1
-#define INTEL_SIP_SMC_STATUS_REJECTED				0x2
-#define INTEL_SIP_SMC_STATUS_NO_RESPONSE			0x3
-#define INTEL_SIP_SMC_STATUS_ERROR				0x4
-#define INTEL_SIP_SMC_RSU_ERROR					0x7
-#define INTEL_SIP_SMC_SEU_ERR_READ_ERROR		0x8
+#define INTEL_SIP_SMC_STATUS_OK						0
+#define INTEL_SIP_SMC_STATUS_BUSY					0x1
+#define INTEL_SIP_SMC_STATUS_REJECTED					0x2
+#define INTEL_SIP_SMC_STATUS_NO_RESPONSE				0x3
+#define INTEL_SIP_SMC_STATUS_ERROR					0x4
+#define INTEL_SIP_SMC_RSU_ERROR						0x7
+#define INTEL_SIP_SMC_SEU_ERR_READ_ERROR				0x8
 
 /* SiP mailbox error code */
-#define GENERIC_RESPONSE_ERROR					0x3FF
+#define GENERIC_RESPONSE_ERROR						0x3FF
 
 /* SiP V2 command code range */
-#define INTEL_SIP_SMC_CMD_MASK					0xFFFF
-#define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN			0x400
-#define INTEL_SIP_SMC_CMD_V2_RANGE_END				0x4FF
+#define INTEL_SIP_SMC_CMD_MASK						0xFFFF
+#define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN				0x400
+#define INTEL_SIP_SMC_CMD_V2_RANGE_END					0x4FF
 
 /* SiP V2 protocol header */
-#define INTEL_SIP_SMC_HEADER_JOB_ID_MASK			0xF
-#define INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET			0U
-#define INTEL_SIP_SMC_HEADER_CID_MASK				0xF
-#define INTEL_SIP_SMC_HEADER_CID_OFFSET				4U
-#define INTEL_SIP_SMC_HEADER_VERSION_MASK			0xF
-#define INTEL_SIP_SMC_HEADER_VERSION_OFFSET			60U
+#define INTEL_SIP_SMC_HEADER_JOB_ID_MASK				0xF
+#define INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET				0U
+#define INTEL_SIP_SMC_HEADER_CID_MASK					0xF
+#define INTEL_SIP_SMC_HEADER_CID_OFFSET					4U
+#define INTEL_SIP_SMC_HEADER_VERSION_MASK				0xF
+#define INTEL_SIP_SMC_HEADER_VERSION_OFFSET				60U
 
 /* SMC SiP service function identifier for version 1 */
 
 /* FPGA Reconfig */
-#define INTEL_SIP_SMC_FPGA_CONFIG_START				0xC2000001
-#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE				0x42000002
-#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE		0xC2000003
-#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE			0xC2000004
-#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM			0xC2000005
+#define INTEL_SIP_SMC_FPGA_CONFIG_START					0xC2000001
+#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE					0x42000002
+#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE			0xC2000003
+#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE				0xC2000004
+#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM				0xC2000005
 
 /* FPGA Bitstream Flag */
-#define FLAG_PARTIAL_CONFIG					BIT(0)
-#define FLAG_AUTHENTICATION					BIT(1)
-#define CONFIG_TEST_FLAG(_flag, _type)				(((flag) & FLAG_##_type) \
-								== FLAG_##_type)
+#define FLAG_PARTIAL_CONFIG						BIT(0)
+#define FLAG_AUTHENTICATION						BIT(1)
+#define CONFIG_TEST_FLAG(_flag, _type)					(((flag) & FLAG_##_type) \
+									== FLAG_##_type)
 
 /* Secure Register Access */
-#define INTEL_SIP_SMC_REG_READ				0xC2000007
-#define INTEL_SIP_SMC_REG_WRITE				0xC2000008
-#define INTEL_SIP_SMC_REG_UPDATE			0xC2000009
+#define INTEL_SIP_SMC_REG_READ						0xC2000007
+#define INTEL_SIP_SMC_REG_WRITE						0xC2000008
+#define INTEL_SIP_SMC_REG_UPDATE					0xC2000009
 
 /* Remote System Update */
-#define INTEL_SIP_SMC_RSU_STATUS				0xC200000B
-#define INTEL_SIP_SMC_RSU_UPDATE				0xC200000C
-#define INTEL_SIP_SMC_RSU_NOTIFY				0xC200000E
-#define INTEL_SIP_SMC_RSU_RETRY_COUNTER				0xC200000F
-#define INTEL_SIP_SMC_RSU_DCMF_VERSION				0xC2000010
-#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION			0xC2000011
-#define INTEL_SIP_SMC_RSU_MAX_RETRY				0xC2000012
-#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY			0xC2000013
-#define INTEL_SIP_SMC_RSU_DCMF_STATUS				0xC2000014
-#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS			0xC2000015
+#define INTEL_SIP_SMC_RSU_STATUS					0xC200000B
+#define INTEL_SIP_SMC_RSU_UPDATE					0xC200000C
+#define INTEL_SIP_SMC_RSU_NOTIFY					0xC200000E
+#define INTEL_SIP_SMC_RSU_RETRY_COUNTER					0xC200000F
+#define INTEL_SIP_SMC_RSU_DCMF_VERSION					0xC2000010
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION				0xC2000011
+#define INTEL_SIP_SMC_RSU_MAX_RETRY					0xC2000012
+#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY				0xC2000013
+#define INTEL_SIP_SMC_RSU_DCMF_STATUS					0xC2000014
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS				0xC2000015
 
 /* Hardware monitor */
-#define INTEL_SIP_SMC_HWMON_READTEMP				0xC2000020
-#define INTEL_SIP_SMC_HWMON_READVOLT				0xC2000021
-#define TEMP_CHANNEL_MAX					(1 << 15)
-#define VOLT_CHANNEL_MAX					(1 << 15)
+#define INTEL_SIP_SMC_HWMON_READTEMP					0xC2000020
+#define INTEL_SIP_SMC_HWMON_READVOLT					0xC2000021
+#define TEMP_CHANNEL_MAX						(1 << 15)
+#define VOLT_CHANNEL_MAX						(1 << 15)
 
 /* ECC */
-#define INTEL_SIP_SMC_ECC_DBE					0xC200000D
+#define INTEL_SIP_SMC_ECC_DBE						0xC200000D
 
 /* Generic Command */
-#define INTEL_SIP_SMC_SERVICE_COMPLETED				0xC200001E
-#define INTEL_SIP_SMC_FIRMWARE_VERSION				0xC200001F
-#define INTEL_SIP_SMC_HPS_SET_BRIDGES				0xC2000032
-#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384			0xC2000040
+#define INTEL_SIP_SMC_SERVICE_COMPLETED					0xC200001E
+#define INTEL_SIP_SMC_FIRMWARE_VERSION					0xC200001F
+#define INTEL_SIP_SMC_HPS_SET_BRIDGES					0xC2000032
+#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384				0xC2000040
 
-#define SERVICE_COMPLETED_MODE_ASYNC				0x00004F4E
+#define SERVICE_COMPLETED_MODE_ASYNC					0x00004F4E
 
 /* Mailbox Command */
-#define INTEL_SIP_SMC_MBOX_SEND_CMD				0xC200003C
-#define INTEL_SIP_SMC_GET_USERCODE				0xC200003D
+#define INTEL_SIP_SMC_MBOX_SEND_CMD					0xC200003C
+#define INTEL_SIP_SMC_GET_USERCODE					0xC200003D
 
 /* FPGA Crypto Services */
 #define INTEL_SIP_SMC_FCS_RANDOM_NUMBER					0xC200005A
@@ -140,21 +140,22 @@
 #define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE				0xC200008E
 
 /* SEU ERR */
-#define INTEL_SIP_SMC_SEU_ERR_STATUS				0xC2000099
+#define INTEL_SIP_SMC_SEU_ERR_STATUS					0xC2000099
+#define INTEL_SIP_SMC_SAFE_INJECT_SEU_ERR				0xC200009A
 
-#define INTEL_SIP_SMC_FCS_SHA_MODE_MASK				0xF
-#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK			0xF
-#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET			4U
-#define INTEL_SIP_SMC_FCS_ECC_ALGO_MASK				0xF
+#define INTEL_SIP_SMC_FCS_SHA_MODE_MASK					0xF
+#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK				0xF
+#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET				4U
+#define INTEL_SIP_SMC_FCS_ECC_ALGO_MASK					0xF
 
 /* ECC DBE */
-#define WARM_RESET_WFI_FLAG					BIT(31)
-#define SYSMGR_ECC_DBE_COLD_RST_MASK				(SYSMGR_ECC_OCRAM_MASK |\
-								SYSMGR_ECC_DDR0_MASK |\
-								SYSMGR_ECC_DDR1_MASK)
+#define WARM_RESET_WFI_FLAG						BIT(31)
+#define SYSMGR_ECC_DBE_COLD_RST_MASK					(SYSMGR_ECC_OCRAM_MASK |\
+									SYSMGR_ECC_DDR0_MASK |\
+									SYSMGR_ECC_DDR1_MASK)
 
 /* Non-mailbox SMC Call */
-#define INTEL_SIP_SMC_SVC_VERSION				0xC2000200
+#define INTEL_SIP_SMC_SVC_VERSION					0xC2000200
 
 /**
  * SMC SiP service function identifier for version 2
@@ -162,31 +163,31 @@
  */
 
 /* V2: Non-mailbox function identifier */
-#define INTEL_SIP_SMC_V2_GET_SVC_VERSION			0xC2000400
-#define INTEL_SIP_SMC_V2_REG_READ				0xC2000401
-#define INTEL_SIP_SMC_V2_REG_WRITE				0xC2000402
-#define INTEL_SIP_SMC_V2_REG_UPDATE				0xC2000403
-#define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES			0xC2000404
-#define INTEL_SIP_SMC_V2_RSU_UPDATE_ADDR			0xC2000405
+#define INTEL_SIP_SMC_V2_GET_SVC_VERSION				0xC2000400
+#define INTEL_SIP_SMC_V2_REG_READ					0xC2000401
+#define INTEL_SIP_SMC_V2_REG_WRITE					0xC2000402
+#define INTEL_SIP_SMC_V2_REG_UPDATE					0xC2000403
+#define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES				0xC2000404
+#define INTEL_SIP_SMC_V2_RSU_UPDATE_ADDR				0xC2000405
 
 /* V2: Mailbox function identifier */
-#define INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND			0xC2000420
-#define INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE			0xC2000421
+#define INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND				0xC2000420
+#define INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE				0xC2000421
 
 /* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT					0x8200ff00
-#define SIP_SVC_UID						0x8200ff01
-#define SIP_SVC_VERSION						0x8200ff03
+#define SIP_SVC_CALL_COUNT						0x8200ff00
+#define SIP_SVC_UID							0x8200ff01
+#define SIP_SVC_VERSION							0x8200ff03
 
 /* SiP Service Calls version numbers */
 /*
  * Increase if there is any backward compatibility impact
  */
-#define SIP_SVC_VERSION_MAJOR					2
+#define SIP_SVC_VERSION_MAJOR						2
 /*
  * Increase if there is new SMC function ID being added
  */
-#define SIP_SVC_VERSION_MINOR					2
+#define SIP_SVC_VERSION_MINOR						2
 
 
 /* Structure Definitions */
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index d93fc8a..e2a25ea 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -696,3 +696,9 @@
 				CMD_CASUAL, resp_buf,
 				&resp_buf_len);
 }
+
+int mailbox_safe_inject_seu_err(uint32_t *arg, unsigned int len)
+{
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SAFE_INJECT_SEU_ERR, arg, len,
+			CMD_CASUAL, NULL, NULL);
+}
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index c6530cf..13e49ea 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -689,15 +689,25 @@
 }
 
 /* SDM SEU Error services */
-static uint32_t intel_sdm_seu_err_read(uint64_t *respbuf, unsigned int respbuf_sz)
+static uint32_t intel_sdm_seu_err_read(uint32_t *respbuf, unsigned int respbuf_sz)
 {
-	if (mailbox_seu_err_status((uint32_t *)respbuf, respbuf_sz) < 0) {
+	if (mailbox_seu_err_status(respbuf, respbuf_sz) < 0) {
 		return INTEL_SIP_SMC_SEU_ERR_READ_ERROR;
 	}
 
 	return INTEL_SIP_SMC_STATUS_OK;
 }
 
+/* SDM SAFE SEU Error inject services */
+static uint32_t intel_sdm_safe_inject_seu_err(uint32_t *command, uint32_t len)
+{
+	if (mailbox_safe_inject_seu_err(command, len) < 0) {
+		return INTEL_SIP_SMC_SEU_ERR_READ_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
 /*
  * This function is responsible for handling all SiP calls from the NS world
  */
@@ -714,7 +724,8 @@
 	uint32_t retval = 0, completed_addr[3];
 	uint32_t retval2 = 0;
 	uint32_t mbox_error = 0;
-	uint64_t retval64, rsu_respbuf[9], seu_respbuf[3];
+	uint64_t retval64, rsu_respbuf[9];
+	uint32_t seu_respbuf[3];
 	int status = INTEL_SIP_SMC_STATUS_OK;
 	int mbox_status;
 	unsigned int len_in_resp;
@@ -1229,6 +1240,10 @@
 			SMC_RET3(handle, seu_respbuf[0], seu_respbuf[1], seu_respbuf[2]);
 		}
 
+	case INTEL_SIP_SMC_SAFE_INJECT_SEU_ERR:
+		status = intel_sdm_safe_inject_seu_err((uint32_t *)&x1, (uint32_t)x2);
+		SMC_RET1(handle, status);
+
 	default:
 		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
 			cookie, handle, flags);