Merge "feat(rmm): update RMI VERSION command as per EAC5" into integration
diff --git a/Makefile b/Makefile
index 5edd625..7f781a0 100644
--- a/Makefile
+++ b/Makefile
@@ -448,6 +448,96 @@
 include common/backtrace/backtrace.mk
 
 ################################################################################
+# Generic definitions
+################################################################################
+include ${MAKE_HELPERS_DIRECTORY}plat_helpers.mk
+
+ifeq (${BUILD_BASE},)
+     BUILD_BASE		:=	./build
+endif
+BUILD_PLAT		:=	$(abspath ${BUILD_BASE})/${PLAT}/${BUILD_TYPE}
+
+SPDS			:=	$(sort $(filter-out none, $(patsubst services/spd/%,%,$(wildcard services/spd/*))))
+
+# Platforms providing their own TBB makefile may override this value
+INCLUDE_TBBR_MK		:=	1
+
+################################################################################
+# Include SPD Makefile if one has been specified
+################################################################################
+
+ifneq (${SPD},none)
+	ifeq (${ARCH},aarch32)
+                $(error "Error: SPD is incompatible with AArch32.")
+	endif
+
+	ifdef EL3_PAYLOAD_BASE
+                $(warning "SPD and EL3_PAYLOAD_BASE are incompatible build options.")
+                $(warning "The SPD and its BL32 companion will be present but \
+                ignored.")
+	endif
+
+	ifeq (${SPD},spmd)
+	# SPMD is located in std_svc directory
+		SPD_DIR := std_svc
+
+		ifeq ($(SPMD_SPM_AT_SEL2),1)
+			CTX_INCLUDE_EL2_REGS := 1
+			ifeq ($(SPMC_AT_EL3),1)
+                                $(error SPM cannot be enabled in both S-EL2 and EL3.)
+			endif
+		endif
+
+		ifeq ($(findstring optee_sp,$(ARM_SPMC_MANIFEST_DTS)),optee_sp)
+			DTC_CPPFLAGS	+=	-DOPTEE_SP_FW_CONFIG
+		endif
+
+		ifeq ($(TS_SP_FW_CONFIG),1)
+		DTC_CPPFLAGS	+=	-DTS_SP_FW_CONFIG
+		endif
+
+		ifneq ($(ARM_BL2_SP_LIST_DTS),)
+		DTC_CPPFLAGS += -DARM_BL2_SP_LIST_DTS=$(ARM_BL2_SP_LIST_DTS)
+		endif
+
+		ifneq ($(SP_LAYOUT_FILE),)
+		BL2_ENABLE_SP_LOAD := 1
+		endif
+	else
+		# All other SPDs in spd directory
+		SPD_DIR := spd
+	endif #(SPD)
+
+	# We expect to locate an spd.mk under the specified SPD directory
+	SPD_MAKE	:=	$(wildcard services/${SPD_DIR}/${SPD}/${SPD}.mk)
+
+	ifeq (${SPD_MAKE},)
+                $(error Error: No services/${SPD_DIR}/${SPD}/${SPD}.mk located)
+	endif
+        $(info Including ${SPD_MAKE})
+        include ${SPD_MAKE}
+
+	# If there's BL32 companion for the chosen SPD, we expect that the SPD's
+	# Makefile would set NEED_BL32 to "yes". In this case, the build system
+	# supports two mutually exclusive options:
+	# * BL32 is built from source: then BL32_SOURCES must contain the list
+	#   of source files to build BL32
+	# * BL32 is a prebuilt binary: then BL32 must point to the image file
+	#   that will be included in the FIP
+	# If both BL32_SOURCES and BL32 are defined, the binary takes precedence
+	# over the sources.
+endif #(SPD=none)
+
+ifeq (${ENABLE_SPMD_LP}, 1)
+ifneq (${SPD},spmd)
+        $(error Error: ENABLE_SPMD_LP requires SPD=spmd.)
+endif
+ifeq ($(SPMC_AT_EL3),1)
+        $(error SPMC at EL3 not supported when enabling SPMD Logical partitions.)
+endif
+endif
+
+################################################################################
 # Process BRANCH_PROTECTION value and set
 # Pointer Authentication and Branch Target Identification flags
 ################################################################################
@@ -491,6 +581,18 @@
 	BL_COMMON_SOURCES	+=	lib/extensions/pauth/pauth_helpers.S
 endif
 
+################################################################################
+# Include the platform specific Makefile after the SPD Makefile (the platform
+# makefile may use all previous definitions in this file)
+################################################################################
+include ${PLAT_MAKEFILE_FULL}
+
+################################################################################
+# Setup arch_features based on ARM_ARCH_MAJOR, ARM_ARCH_MINOR provided from
+# platform.
+################################################################################
+include ${MAKE_HELPERS_DIRECTORY}arch_features.mk
+
 ####################################################
 # Enable required options for Memory Stack Tagging.
 ####################################################
@@ -521,6 +623,9 @@
 ################################################################################
 # FEAT_RME
 ifeq (${ENABLE_RME},1)
+	# RME doesn't support BRBE
+	ENABLE_BRBE_FOR_NS := 0
+
 	# RME doesn't support PIE
 	ifneq (${ENABLE_PIE},0)
                 $(error ENABLE_RME does not support PIE)
@@ -670,12 +775,14 @@
 $(warning "RME is an experimental feature")
 endif
 
-################################################################################
-# Include the platform specific Makefile after the SPD Makefile (the platform
-# makefile may use all previous definitions in this file)
-################################################################################
-
-include ${PLAT_MAKEFILE_FULL}
+ifeq (${CTX_INCLUDE_EL2_REGS}, 1)
+	ifeq (${SPD},none)
+		ifeq (${ENABLE_RME},0)
+                        $(error CTX_INCLUDE_EL2_REGS is available only when SPD \
+                        or RME is enabled)
+		endif
+	endif
+endif
 
 ################################################################################
 # Platform specific Makefile might provide us ARCH_MAJOR/MINOR use that to come
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 1daad9b..146026b 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -335,26 +335,26 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 and
    it is still open.
 
-For Cortex-A78 AE, the following errata build flags are defined :
+For Cortex-A78AE, the following errata build flags are defined :
 
 - ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to
-   Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1.
+   Cortex-A78AE CPU. This needs to be enabled for revisions r0p0 and r0p1.
    This erratum is still open.
 
 - ``ERRATA_A78_AE_1951502`` : This applies errata 1951502 workaround to
-  Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
+  Cortex-A78AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
   erratum is still open.
 
 - ``ERRATA_A78_AE_2376748`` : This applies errata 2376748 workaround to
-  Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
-  erratum is still open.
+  Cortex-A78AE CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2.
+  This erratum is still open.
 
 - ``ERRATA_A78_AE_2395408`` : This applies errata 2395408 workaround to
-  Cortex-A78 AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
+  Cortex-A78AE CPU. This needs to be enabled for revisions r0p0 and r0p1. This
   erratum is still open.
 
 - ``ERRATA_A78_AE_2712574`` : This applies erratum 2712574 workaround to
-  Cortex-A78 AE CPU. This erratum affects system configurations that do not use
+  Cortex-A78AE CPU. This erratum affects system configurations that do not use
   an ARM interconnect IP. This needs to be enabled for revisions r0p0, r0p1 and
   r0p2. This erratum is still open.
 
@@ -498,7 +498,8 @@
    revision.  It is still open.
 
 -  ``ERRATA_V1_2294912``: This applies errata 2294912 workaround to Neoverse-V1
-   CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU.
+   CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 and r1p2 of
+   the CPU.
 
 -  ``ERRATA_V1_2372203``: This applies errata 2372203 workaround to Neoverse-V1
    CPU. This needs to be enabled for revisions r0p0, r1p0 and r1p1 of the CPU.
@@ -572,7 +573,7 @@
 
 -  ``ERRATA_A710_2058056``: This applies errata 2058056 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
-   of the CPU and is still open.
+   and r2p1 of the CPU and is still open.
 
 -  ``ERRATA_A710_2267065``: This applies errata 2267065 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
@@ -685,7 +686,7 @@
    it is still open.
 
 -  ``ERRATA_X2_2058056``: This applies errata 2058056 workaround to Cortex-X2
-   CPU. This needs to be enabled for revisions r0p0, r1p0, and r2p0 of the CPU,
+   CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the CPU,
    it is still open.
 
 -  ``ERRATA_X2_2083908``: This applies errata 2083908 workaround to Cortex-X2
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 654ddc5..347cf20 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -1195,7 +1195,8 @@
   The platform will use PSA compliant Crypto APIs during authentication and
   image measurement process by enabling this option. It uses APIs defined as
   per the `PSA Crypto API specification`_. This feature is only supported if
-  using MbedTLS 3.x version. By default it is disabled (``0``).
+  using MbedTLS 3.x version. By default it is disabled (``0``), and this is an
+  experimental feature.
 
 - ``ENABLE_CONSOLE_GETC``: Boolean option to enable `getc()` feature in console
   driver(s). By default it is disabled (``0``) because it constitutes an attack
diff --git a/drivers/auth/mbedtls/mbedtls_psa_crypto.c b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
index 2fa8e63..5891acf 100644
--- a/drivers/auth/mbedtls/mbedtls_psa_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_psa_crypto.c
@@ -28,6 +28,13 @@
 
 #define LIB_NAME		"mbed TLS PSA"
 
+/* Maximum length of R_S pair in the ECDSA signature in bytes */
+#define MAX_ECDSA_R_S_PAIR_LEN	64U
+
+/* Size of ASN.1 length and tag in bytes*/
+#define SIZE_OF_ASN1_LEN	1U
+#define SIZE_OF_ASN1_TAG	1U
+
 #if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
 CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
 /*
@@ -108,6 +115,7 @@
 
 static void construct_psa_key_alg_and_type(mbedtls_pk_type_t pk_alg,
 					   mbedtls_md_type_t md_alg,
+					   psa_ecc_family_t psa_ecc_family,
 					   psa_algorithm_t *psa_alg,
 					   psa_key_type_t *psa_key_type)
 {
@@ -118,14 +126,173 @@
 		*psa_alg = PSA_ALG_RSA_PSS(psa_md_alg);
 		*psa_key_type = PSA_KEY_TYPE_RSA_PUBLIC_KEY;
 		break;
+	case MBEDTLS_PK_ECDSA:
+		*psa_alg = PSA_ALG_ECDSA(psa_md_alg);
+		*psa_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_ecc_family);
+		break;
 	default:
 		*psa_alg = PSA_ALG_NONE;
 		*psa_key_type = PSA_KEY_TYPE_NONE;
 		break;
 	}
+}
+
+
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
+TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+
+/*
+ * This is a helper function to detect padding byte (if the MSB bit of the
+ * first data byte is set to 1, for example 0x80) and on detection, ignore the
+ * padded byte(0x00) and increase the buffer pointer beyond padded byte and
+ * decrease the length of the buffer by 1.
+ *
+ * On Success returns 0, error otherwise.
+ **/
+static inline int ignore_asn1_int_padding_byte(unsigned char **buf_start,
+					       size_t *buf_len)
+{
+	unsigned char *local_buf = *buf_start;
+
+	/* Check for negative number */
+	if ((local_buf[0] & 0x80U) != 0U) {
+		return -1;
+	}
+
+	if ((local_buf[0] == 0U) && (local_buf[1] > 0x7FU) &&
+	    (*buf_len > 1U)) {
+		*buf_start = &local_buf[1];
+		(*buf_len)--;
+	}
+
+	return 0;
+}
+
+/*
+ * This is a helper function that gets a pointer to the encoded ECDSA publicKey
+ * and its length (as per RFC5280) and returns corresponding decoded publicKey
+ * and its length. As well, it retrieves the family of ECC key in the PSA
+ * format.
+ *
+ * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
+ * otherwise success(0).
+ **/
+static int get_ecdsa_pkinfo_from_asn1(unsigned char **pk_start,
+				      unsigned int *pk_len,
+				      psa_ecc_family_t *psa_ecc_family)
+{
+	mbedtls_asn1_buf alg_oid, alg_params;
+	mbedtls_ecp_group_id grp_id;
+	int rc;
+	unsigned char *pk_end;
+	size_t len;
+	size_t curve_bits;
+	unsigned char *pk_ptr = *pk_start;
+
+	pk_end = pk_ptr + *pk_len;
+	rc = mbedtls_asn1_get_tag(&pk_ptr, pk_end, &len,
+				  MBEDTLS_ASN1_CONSTRUCTED |
+				  MBEDTLS_ASN1_SEQUENCE);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	pk_end = pk_ptr + len;
+	rc = mbedtls_asn1_get_alg(&pk_ptr, pk_end, &alg_oid, &alg_params);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	if (alg_params.tag == MBEDTLS_ASN1_OID) {
+		if (mbedtls_oid_get_ec_grp(&alg_params, &grp_id) != 0) {
+			return CRYPTO_ERR_SIGNATURE;
+		}
+		*psa_ecc_family = mbedtls_ecc_group_to_psa(grp_id,
+							   &curve_bits);
+	} else {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	pk_end = pk_ptr + len - (alg_oid.len + alg_params.len +
+		 2 * (SIZE_OF_ASN1_LEN + SIZE_OF_ASN1_TAG));
+	rc = mbedtls_asn1_get_bitstring_null(&pk_ptr, pk_end, &len);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	*pk_start = pk_ptr;
+	*pk_len = len;
+
+	return rc;
 }
 
 /*
+ * Ecdsa-Sig-Value  ::=  SEQUENCE  {
+ *   r     INTEGER,
+ *   s     INTEGER
+ * }
+ *
+ * This helper function that gets a pointer to the encoded ECDSA signature and
+ * its length (as per RFC5280) and returns corresponding decoded signature
+ * (R_S pair) and its size.
+ *
+ * This function returns error(CRYPTO_ERR_SIGNATURE) on ASN.1 parsing failure,
+ * otherwise success(0).
+ **/
+static int get_ecdsa_signature_from_asn1(unsigned char *sig_ptr,
+					 size_t *sig_len,
+					 unsigned char *r_s_pair)
+{
+	int rc;
+	unsigned char *sig_end;
+	size_t len, r_len, s_len;
+
+	sig_end = sig_ptr + *sig_len;
+	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &len,
+				  MBEDTLS_ASN1_CONSTRUCTED |
+				  MBEDTLS_ASN1_SEQUENCE);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	sig_end = sig_ptr + len;
+	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &r_len,
+				  MBEDTLS_ASN1_INTEGER);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	if (ignore_asn1_int_padding_byte(&sig_ptr, &r_len) != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	(void)memcpy((void *)&r_s_pair[0], (const void *)sig_ptr, r_len);
+
+	sig_ptr = sig_ptr + r_len;
+	sig_end = sig_ptr + len - (r_len + (SIZE_OF_ASN1_LEN +
+		  SIZE_OF_ASN1_TAG));
+	rc = mbedtls_asn1_get_tag(&sig_ptr, sig_end, &s_len,
+				  MBEDTLS_ASN1_INTEGER);
+	if (rc != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	if (ignore_asn1_int_padding_byte(&sig_ptr, &s_len) != 0) {
+		return CRYPTO_ERR_SIGNATURE;
+	}
+
+	(void)memcpy((void *)&r_s_pair[r_len], (const void *)sig_ptr, s_len);
+
+	*sig_len = s_len + r_len;
+
+	return 0;
+}
+#endif /*
+	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
+	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+	**/
+
+/*
  * Verify a signature.
  *
  * Parameters are passed using the DER encoding format following the ASN.1
@@ -143,6 +310,10 @@
 	int rc;
 	void *sig_opts = NULL;
 	unsigned char *p, *end;
+	unsigned char *local_sig_ptr;
+	size_t local_sig_len;
+	psa_ecc_family_t psa_ecc_family = 0U;
+	__unused unsigned char reformatted_sig[MAX_ECDSA_R_S_PAIR_LEN] = {0};
 
 	/* construct PSA key algo and type */
 	psa_status_t status = PSA_SUCCESS;
@@ -174,10 +345,36 @@
 		rc = CRYPTO_ERR_SIGNATURE;
 		goto end2;
 	}
-	signature.p = p;
+
+	local_sig_ptr = p;
+	local_sig_len = signature.len;
+
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
+TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+	if (pk_alg == MBEDTLS_PK_ECDSA) {
+		rc = get_ecdsa_signature_from_asn1(local_sig_ptr,
+						   &local_sig_len,
+						   reformatted_sig);
+		if (rc != 0) {
+			goto end2;
+		}
+
+		local_sig_ptr = reformatted_sig;
+
+		rc = get_ecdsa_pkinfo_from_asn1((unsigned char **)&pk_ptr,
+						&pk_len,
+						&psa_ecc_family);
+		if (rc != 0) {
+			goto end2;
+		}
+	}
+#endif /*
+	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA || \
+	* TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+	**/
 
 	/* Convert this pk_alg and md_alg to PSA key type and key algorithm */
-	construct_psa_key_alg_and_type(pk_alg, md_alg,
+	construct_psa_key_alg_and_type(pk_alg, md_alg, psa_ecc_family,
 				       &psa_alg, &psa_key_type);
 
 
@@ -208,7 +405,7 @@
 	 */
 	status = psa_verify_message(psa_key_id, psa_alg,
 				    data_ptr, data_len,
-				    signature.p, signature.len);
+				    local_sig_ptr, local_sig_len);
 
 	if (status != PSA_SUCCESS) {
 		rc = CRYPTO_ERR_SIGNATURE;
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 1881c91..c60820d 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -49,30 +49,43 @@
 static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry)
 {
 	size_t bytes_read;
-	uintptr_t offset;
 	int result;
+	mbr_entry_t *tmp;
 
 	assert(mbr_entry != NULL);
 	/* MBR partition table is in LBA0. */
 	result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
 	if (result != 0) {
-		WARN("Failed to seek (%i)\n", result);
+		VERBOSE("Failed to seek (%i)\n", result);
 		return result;
 	}
 	result = io_read(image_handle, (uintptr_t)&mbr_sector,
 			 PLAT_PARTITION_BLOCK_SIZE, &bytes_read);
-	if (result != 0) {
-		WARN("Failed to read data (%i)\n", result);
+	if ((result != 0) || (bytes_read != PLAT_PARTITION_BLOCK_SIZE)) {
+		VERBOSE("Failed to read data (%i)\n", result);
 		return result;
 	}
 
 	/* Check MBR boot signature. */
 	if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
 	    (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
+		VERBOSE("MBR boot signature failure\n");
 		return -ENOENT;
 	}
-	offset = (uintptr_t)&mbr_sector + MBR_PRIMARY_ENTRY_OFFSET;
-	memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t));
+
+	tmp = (mbr_entry_t *)(&mbr_sector[MBR_PRIMARY_ENTRY_OFFSET]);
+
+	if (tmp->first_lba != 1) {
+		VERBOSE("MBR header may have an invalid first LBA\n");
+		return -EINVAL;
+	}
+
+	if ((tmp->sector_nums == 0) || (tmp->sector_nums == UINT32_MAX)) {
+		VERBOSE("MBR header entry has an invalid number of sectors\n");
+		return -EINVAL;
+	}
+
+	memcpy(mbr_entry, tmp, sizeof(mbr_entry_t));
 	return 0;
 }
 
@@ -80,24 +93,31 @@
  * Load GPT header and check the GPT signature and header CRC.
  * If partition numbers could be found, check & update it.
  */
-static int load_gpt_header(uintptr_t image_handle)
+static int load_gpt_header(uintptr_t image_handle, size_t header_offset,
+			   unsigned long long *part_lba)
 {
 	gpt_header_t header;
 	size_t bytes_read;
 	int result;
 	uint32_t header_crc, calc_crc;
 
-	result = io_seek(image_handle, IO_SEEK_SET, GPT_HEADER_OFFSET);
+	result = io_seek(image_handle, IO_SEEK_SET, header_offset);
 	if (result != 0) {
+		VERBOSE("Failed to seek into the GPT image at offset (%zu)\n",
+			header_offset);
 		return result;
 	}
 	result = io_read(image_handle, (uintptr_t)&header,
 			 sizeof(gpt_header_t), &bytes_read);
 	if ((result != 0) || (sizeof(gpt_header_t) != bytes_read)) {
+		VERBOSE("GPT header read error(%i) or read mismatch occurred,"
+			"expected(%zu) and actual(%zu)\n", result,
+			sizeof(gpt_header_t), bytes_read);
 		return result;
 	}
 	if (memcmp(header.signature, GPT_SIGNATURE,
-		   sizeof(header.signature)) != 0) {
+			   sizeof(header.signature)) != 0) {
+		VERBOSE("GPT header signature failure\n");
 		return -EINVAL;
 	}
 
@@ -109,7 +129,7 @@
 	header_crc = header.header_crc;
 	header.header_crc = 0U;
 
-	calc_crc = tf_crc32(0U, (uint8_t *)&header, DEFAULT_GPT_HEADER_SIZE);
+	calc_crc = tf_crc32(0U, (uint8_t *)&header, sizeof(gpt_header_t));
 	if (header_crc != calc_crc) {
 		ERROR("Invalid GPT Header CRC: Expected 0x%x but got 0x%x.\n",
 		      header_crc, calc_crc);
@@ -123,11 +143,16 @@
 	if (list.entry_count > PLAT_PARTITION_MAX_ENTRIES) {
 		list.entry_count = PLAT_PARTITION_MAX_ENTRIES;
 	}
+
+	*part_lba = header.part_lba;
 	return 0;
 }
 
+/*
+ * Load a single MBR entry based on details from MBR header.
+ */
 static int load_mbr_entry(uintptr_t image_handle, mbr_entry_t *mbr_entry,
-			int part_number)
+			  int part_number)
 {
 	size_t bytes_read;
 	uintptr_t offset;
@@ -137,19 +162,20 @@
 	/* MBR partition table is in LBA0. */
 	result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
 	if (result != 0) {
-		WARN("Failed to seek (%i)\n", result);
+		VERBOSE("Failed to seek (%i)\n", result);
 		return result;
 	}
 	result = io_read(image_handle, (uintptr_t)&mbr_sector,
 			 PLAT_PARTITION_BLOCK_SIZE, &bytes_read);
 	if (result != 0) {
-		WARN("Failed to read data (%i)\n", result);
+		VERBOSE("Failed to read data (%i)\n", result);
 		return result;
 	}
 
 	/* Check MBR boot signature. */
 	if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
 	    (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
+		VERBOSE("MBR Entry boot signature failure\n");
 		return -ENOENT;
 	}
 	offset = (uintptr_t)&mbr_sector +
@@ -160,6 +186,9 @@
 	return 0;
 }
 
+/*
+ * Load MBR entries based on max number of partition entries.
+ */
 static int load_mbr_entries(uintptr_t image_handle)
 {
 	mbr_entry_t mbr_entry;
@@ -177,33 +206,60 @@
 	return 0;
 }
 
+/*
+ * Try to read and load a single GPT entry.
+ */
 static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry)
 {
-	size_t bytes_read;
+	size_t bytes_read = 0U;
 	int result;
 
 	assert(entry != NULL);
 	result = io_read(image_handle, (uintptr_t)entry, sizeof(gpt_entry_t),
-			 &bytes_read);
-	if (sizeof(gpt_entry_t) != bytes_read)
+			&bytes_read);
+	if ((result != 0) || (sizeof(gpt_entry_t) != bytes_read)) {
+		VERBOSE("GPT Entry read error(%i) or read mismatch occurred,"
+			"expected(%zu) and actual(%zu)\n", result,
+			sizeof(gpt_entry_t), bytes_read);
 		return -EINVAL;
+	}
+
 	return result;
 }
 
-static int verify_partition_gpt(uintptr_t image_handle)
+/*
+ * Retrieve each entry in the partition table, parse the data from each
+ * entry and store them in the list of partition table entries.
+ */
+static int load_partition_gpt(uintptr_t image_handle,
+			      unsigned long long part_lba)
 {
+	const signed long long gpt_entry_offset = LBA(part_lba);
 	gpt_entry_t entry;
 	int result, i;
 
+	result = io_seek(image_handle, IO_SEEK_SET, gpt_entry_offset);
+	if (result != 0) {
+		VERBOSE("Failed to seek (%i), Failed loading GPT partition"
+			"table entries\n", result);
+		return result;
+	}
+
 	for (i = 0; i < list.entry_count; i++) {
 		result = load_gpt_entry(image_handle, &entry);
-		assert(result == 0);
+		if (result != 0) {
+			VERBOSE("Failed to load gpt entry data(%i) error is (%i)\n",
+				i, result);
+			return result;
+		}
+
 		result = parse_gpt_entry(&entry, &list.list[i]);
 		if (result != 0) {
 			break;
 		}
 	}
 	if (i == 0) {
+		VERBOSE("No Valid GPT Entries found\n");
 		return -EINVAL;
 	}
 	/*
@@ -216,6 +272,94 @@
 	return 0;
 }
 
+/*
+ * Try retrieving and parsing the backup-GPT header and backup GPT entries.
+ * Last 33 blocks contains the backup-GPT entries and header.
+ */
+static int load_backup_gpt(unsigned int image_id, unsigned int sector_nums)
+{
+	int result;
+	unsigned long long part_lba = 0;
+	size_t gpt_header_offset;
+	uintptr_t dev_handle, image_spec, image_handle;
+	io_block_spec_t *block_spec;
+	int part_num_entries;
+
+	result = plat_get_image_source(image_id, &dev_handle, &image_spec);
+	if (result != 0) {
+		VERBOSE("Failed to obtain reference to image id=%u (%i)\n",
+			image_id, result);
+		return result;
+	}
+
+	block_spec = (io_block_spec_t *)image_spec;
+	/*
+	 * We need to read 32 blocks of GPT entries and one block of GPT header
+	 * try mapping only last 33 last blocks from the image to read the
+	 * Backup-GPT header and its entries.
+	 */
+	part_num_entries = (PLAT_PARTITION_MAX_ENTRIES / 4);
+	/* Move the offset base to LBA-33 */
+	block_spec->offset += LBA(sector_nums - part_num_entries);
+	/*
+	 * Set length as LBA-33, 32 blocks of backup-GPT entries and one
+	 * block of backup-GPT header.
+	 */
+	block_spec->length = LBA(part_num_entries + 1);
+
+	result = io_open(dev_handle, image_spec, &image_handle);
+	if (result != 0) {
+		VERBOSE("Failed to access image id (%i)\n", result);
+		return result;
+	}
+
+	INFO("Trying to retrieve back-up GPT header\n");
+	/* Last block is backup-GPT header, after the end of GPT entries */
+	gpt_header_offset = LBA(part_num_entries);
+	result = load_gpt_header(image_handle, gpt_header_offset, &part_lba);
+	if ((result != 0) || (part_lba == 0)) {
+		ERROR("Failed to retrieve Backup GPT header,"
+		      "Partition maybe corrupted\n");
+		goto out;
+	}
+
+	/*
+	 * Note we mapped last 33 blocks(LBA-33), first block here starts with
+	 * entries while last block was header.
+	 */
+	result = load_partition_gpt(image_handle, 0);
+
+out:
+	io_close(image_handle);
+	return result;
+}
+
+/*
+ * Load a GPT partition, Try retrieving and parsing the primary GPT header,
+ * if its corrupted try loading backup GPT header and then retrieve list
+ * of partition table entries found from the GPT.
+ */
+static int load_primary_gpt(uintptr_t image_handle, unsigned int first_lba)
+{
+	int result;
+	unsigned long long part_lba;
+	size_t gpt_header_offset;
+
+	/* Try to load Primary GPT header from LBA1 */
+	gpt_header_offset = LBA(first_lba);
+	result = load_gpt_header(image_handle, gpt_header_offset, &part_lba);
+	if ((result != 0) || (part_lba == 0)) {
+		VERBOSE("Failed to retrieve Primary GPT header,"
+			"trying to retrieve back-up GPT header\n");
+		return result;
+	}
+
+	return load_partition_gpt(image_handle, part_lba);
+}
+
+/*
+ * Load the partition table info based on the image id provided.
+ */
 int load_partition_table(unsigned int image_id)
 {
 	uintptr_t dev_handle, image_handle, image_spec = 0;
@@ -224,36 +368,41 @@
 
 	result = plat_get_image_source(image_id, &dev_handle, &image_spec);
 	if (result != 0) {
-		WARN("Failed to obtain reference to image id=%u (%i)\n",
+		VERBOSE("Failed to obtain reference to image id=%u (%i)\n",
 			image_id, result);
 		return result;
 	}
 
 	result = io_open(dev_handle, image_spec, &image_handle);
 	if (result != 0) {
-		WARN("Failed to access image id=%u (%i)\n", image_id, result);
+		VERBOSE("Failed to access image id=%u (%i)\n", image_id, result);
 		return result;
 	}
 
 	result = load_mbr_header(image_handle, &mbr_entry);
 	if (result != 0) {
-		WARN("Failed to access image id=%u (%i)\n", image_id, result);
-		return result;
+		VERBOSE("Failed to access image id=%u (%i)\n", image_id, result);
+		goto out;
 	}
 	if (mbr_entry.type == PARTITION_TYPE_GPT) {
-		result = load_gpt_header(image_handle);
-		assert(result == 0);
-		result = io_seek(image_handle, IO_SEEK_SET, GPT_ENTRY_OFFSET);
-		assert(result == 0);
-		result = verify_partition_gpt(image_handle);
+		result = load_primary_gpt(image_handle, mbr_entry.first_lba);
+		if (result != 0) {
+			io_close(image_handle);
+			return load_backup_gpt(BKUP_GPT_IMAGE_ID,
+					       mbr_entry.sector_nums);
+		}
 	} else {
 		result = load_mbr_entries(image_handle);
 	}
 
+out:
 	io_close(image_handle);
 	return result;
 }
 
+/*
+ * Try retrieving a partition table entry based on the name of the partition.
+ */
 const partition_entry_t *get_partition_entry(const char *name)
 {
 	int i;
@@ -266,6 +415,9 @@
 	return NULL;
 }
 
+/*
+ * Try retrieving a partition table entry based on the GUID.
+ */
 const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_uuid)
 {
 	int i;
@@ -279,6 +431,9 @@
 	return NULL;
 }
 
+/*
+ * Try retrieving a partition table entry based on the UUID.
+ */
 const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid)
 {
 	int i;
@@ -292,12 +447,32 @@
 	return NULL;
 }
 
+/*
+ * Return entry to the list of partition table entries.
+ */
 const partition_entry_list_t *get_partition_entry_list(void)
 {
 	return &list;
 }
 
+/*
+ * Try loading partition table info for the given image ID.
+ */
 void partition_init(unsigned int image_id)
 {
+	int ret;
+
+	ret = load_partition_table(image_id);
+	if (ret != 0) {
+		ERROR("Failed to parse partition with image id = %u\n",
+		      image_id);
+	}
+}
+
+/*
+ * Load a GPT based image.
+ */
+int gpt_partition_init(void)
+{
-	load_partition_table(image_id);
+	return load_partition_table(GPT_IMAGE_ID);
 }
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index 1d28772..bf23917 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.h
@@ -32,7 +32,12 @@
  * buffers must be big enough to hold either. As RSA keys are bigger than ECDSA
  * ones for all key sizes we support, they impose the minimum size of these
  * buffers.
+ *
+ * If the platform employs its own mbedTLS configuration, it is the platform's
+ * responsibility to define TF_MBEDTLS_USE_RSA or TF_MBEDTLS_USE_ECDSA to
+ * establish the appropriate PK_DER_LEN size.
  */
+#ifdef MBEDTLS_CONFIG_FILE
 #if TF_MBEDTLS_USE_RSA
 #if TF_MBEDTLS_KEY_SIZE == 1024
 #define PK_DER_LEN                      162
@@ -45,7 +50,7 @@
 #else
 #error "Invalid value for TF_MBEDTLS_KEY_SIZE"
 #endif
-#else /* Only using ECDSA keys. */
+#elif TF_MBEDTLS_USE_ECDSA
 #if TF_MBEDTLS_KEY_SIZE == 384
 #define PK_DER_LEN                      120
 #elif TF_MBEDTLS_KEY_SIZE == 256
@@ -53,7 +58,9 @@
 #else
 #error "Invalid value for TF_MBEDTLS_KEY_SIZE"
 #endif
-#endif
+#else
+#error "Invalid value of algorithm"
+#endif /* TF_MBEDTLS_USE_RSA */
 
 #if TF_MBEDTLS_HASH_ALG_ID == TF_MBEDTLS_SHA256
 #define HASH_DER_LEN                    51
@@ -64,5 +71,6 @@
 #else
 #error "Invalid value for TF_MBEDTLS_HASH_ALG_ID"
 #endif
+#endif /* MBEDTLS_CONFIG_FILE */
 
 #endif /* COT_DEF_H */
diff --git a/include/drivers/partition/gpt.h b/include/drivers/partition/gpt.h
index c2a229e..383c17d 100644
--- a/include/drivers/partition/gpt.h
+++ b/include/drivers/partition/gpt.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,10 +12,6 @@
 #include <tools_share/uuid.h>
 
 #define PARTITION_TYPE_GPT		0xee
-#define GPT_HEADER_OFFSET		PLAT_PARTITION_BLOCK_SIZE
-#define GPT_ENTRY_OFFSET		(GPT_HEADER_OFFSET +		\
-					 PLAT_PARTITION_BLOCK_SIZE)
-
 #define GPT_SIGNATURE			"EFI PART"
 
 typedef struct gpt_entry {
@@ -45,7 +41,7 @@
 	/* size of a single partition entry (usually 128) */
 	unsigned int		part_size;
 	unsigned int		part_crc;
-} gpt_header_t;
+} __packed gpt_header_t;
 
 int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry);
 
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
index 6cb59c3..d567d4c 100644
--- a/include/drivers/partition/partition.h
+++ b/include/drivers/partition/partition.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -29,7 +29,7 @@
 
 #define LEGACY_PARTITION_BLOCK_SIZE	512
 
-#define DEFAULT_GPT_HEADER_SIZE 	92
+#define LBA(n) ((unsigned long long)(n) * PLAT_PARTITION_BLOCK_SIZE)
 
 typedef struct partition_entry {
 	uint64_t		start;
@@ -50,5 +50,6 @@
 const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid);
 const partition_entry_list_t *get_partition_entry_list(void);
 void partition_init(unsigned int image_id);
+int gpt_partition_init(void);
 
 #endif /* PARTITION_H */
diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h
index 98a0099..ce17b4a 100644
--- a/include/export/common/tbbr/tbbr_img_def_exp.h
+++ b/include/export/common/tbbr/tbbr_img_def_exp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -79,41 +79,44 @@
 /* NT_FW_CONFIG */
 #define NT_FW_CONFIG_ID			U(27)
 
-/* GPT Partition */
+/* GPT primary header and entries */
 #define GPT_IMAGE_ID			U(28)
 
+/* GPT backup header and entries */
+#define BKUP_GPT_IMAGE_ID		U(29)
+
 /* Binary with STM32 header */
-#define STM32_IMAGE_ID			U(29)
+#define STM32_IMAGE_ID			U(30)
 
 /* Encrypted image identifier */
-#define ENC_IMAGE_ID			U(30)
+#define ENC_IMAGE_ID			U(31)
 
 /* FW_CONFIG */
-#define FW_CONFIG_ID			U(31)
+#define FW_CONFIG_ID			U(32)
 
 /*
  * Primary FWU metadata image ID
  */
-#define FWU_METADATA_IMAGE_ID		U(32)
+#define FWU_METADATA_IMAGE_ID		U(33)
 
 /*
  * Backup FWU metadata image ID
  */
-#define BKUP_FWU_METADATA_IMAGE_ID	U(33)
+#define BKUP_FWU_METADATA_IMAGE_ID	U(34)
 
 /* Realm Monitor Manager (RMM) */
-#define RMM_IMAGE_ID			U(34)
+#define RMM_IMAGE_ID			U(35)
 
 /* CCA Content Certificate ID */
-#define CCA_CONTENT_CERT_ID		U(35)
+#define CCA_CONTENT_CERT_ID		U(36)
 
 /* Core SWD Key Certificate ID */
-#define CORE_SWD_KEY_CERT_ID		U(36)
+#define CORE_SWD_KEY_CERT_ID		U(37)
 
 /* Platform Key Certificate ID */
-#define PLAT_KEY_CERT_ID		U(37)
+#define PLAT_KEY_CERT_ID		U(38)
 
 /* Max Images */
-#define MAX_IMAGE_IDS			U(38)
+#define MAX_IMAGE_IDS			U(39)
 
 #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */
diff --git a/include/lib/cpus/aarch64/travis.h b/include/lib/cpus/aarch64/travis.h
new file mode 100644
index 0000000..a8a2556
--- /dev/null
+++ b/include/lib/cpus/aarch64/travis.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TRAVIS_H
+#define TRAVIS_H
+
+#define TRAVIS_MIDR					U(0x410FD8C0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions
+ ******************************************************************************/
+#define TRAVIS_IMP_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions
+ ******************************************************************************/
+#define TRAVIS_IMP_CPUPWRCTLR_EL1			S3_0_C15_C2_7
+#define TRAVIS_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT	U(1)
+
+/*******************************************************************************
+ * SME Control registers
+ ******************************************************************************/
+#define TRAVIS_SVCRSM					S0_3_C4_C2_3
+#define TRAVIS_SVCRZA					S0_3_C4_C4_3
+
+#endif /* TRAVIS_H */
diff --git a/include/plat/arm/common/aarch64/arm_macros.S b/include/plat/arm/common/aarch64/arm_macros.S
index d47e4e0..8aacfb0 100644
--- a/include/plat/arm/common/aarch64/arm_macros.S
+++ b/include/plat/arm/common/aarch64/arm_macros.S
@@ -39,11 +39,17 @@
 	 * ---------------------------------------------
 	 */
 	.macro arm_print_gic_regs
-	/* Check for GICv3 system register access */
+	/* Check for GICv3/v4 system register access.
+	 * ID_AA64PFR0_GIC indicates presence of the CPU
+	 * system registers by either 0b0011 or 0xb0001.
+	 * A value of 0b000 means CPU system registers aren't
+	 * available and the code needs to use the memory
+	 * mapped registers like in GICv2.
+	 */
 	mrs	x7, id_aa64pfr0_el1
 	ubfx	x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
-	cmp	x7, #1
-	b.ne	print_gicv2
+	cmp	x7, #0
+	b.eq	print_gicv2
 
 	/* Check for SRE enable */
 	mrs	x8, ICC_SRE_EL3
diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S
index eab5ada..c618d98 100644
--- a/lib/cpus/aarch64/cortex_a710.S
+++ b/lib/cpus/aarch64/cortex_a710.S
@@ -80,14 +80,14 @@
 	sysreg_bit_set	CORTEX_A710_CPUACTLR_EL1, CORTEX_A710_CPUACTLR_EL1_BIT_46
 workaround_reset_end cortex_a710, ERRATUM(2055002)
 
-check_erratum_ls cortex_a710, ERRATUM(2055002), CPU_REV(2, 0)
+check_erratum_range cortex_a710, ERRATUM(2055002), CPU_REV(1, 0), CPU_REV(2, 0)
 
 workaround_reset_start cortex_a710, ERRATUM(2058056), ERRATA_A710_2058056
 	sysreg_bitfield_insert CORTEX_A710_CPUECTLR2_EL1, CORTEX_A710_CPUECTLR2_EL1_PF_MODE_CNSRV, \
 		CPUECTLR2_EL1_PF_MODE_LSB, CPUECTLR2_EL1_PF_MODE_WIDTH
 workaround_reset_end cortex_a710, ERRATUM(2058056)
 
-check_erratum_ls cortex_a710, ERRATUM(2058056), CPU_REV(2, 0)
+check_erratum_ls cortex_a710, ERRATUM(2058056), CPU_REV(2, 1)
 
 workaround_reset_start cortex_a710, ERRATUM(2081180), ERRATA_A710_2081180
 	ldr	x0,=0x3
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index 94f6465..d3a3e5d 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -70,7 +70,7 @@
 	sysreg_bit_set CORTEX_A78_AE_ACTLR2_EL1, CORTEX_A78_AE_ACTLR2_EL1_BIT_0
 workaround_reset_end cortex_a78_ae, ERRATUM(2376748)
 
-check_erratum_ls cortex_a78_ae, ERRATUM(2376748), CPU_REV(0, 1)
+check_erratum_ls cortex_a78_ae, ERRATUM(2376748), CPU_REV(0, 2)
 
 workaround_reset_start cortex_a78_ae, ERRATUM(2395408), ERRATA_A78_AE_2395408
 	/* --------------------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_x2.S b/lib/cpus/aarch64/cortex_x2.S
index 816a58f..855d196 100644
--- a/lib/cpus/aarch64/cortex_x2.S
+++ b/lib/cpus/aarch64/cortex_x2.S
@@ -50,7 +50,7 @@
 	CORTEX_X2_CPUECTLR2_EL1_PF_MODE_SHIFT, CORTEX_X2_CPUECTLR2_EL1_PF_MODE_WIDTH
 workaround_reset_end cortex_x2, ERRATUM(2058056)
 
-check_erratum_ls cortex_x2, ERRATUM(2058056), CPU_REV(2, 0)
+check_erratum_ls cortex_x2, ERRATUM(2058056), CPU_REV(2, 1)
 
 workaround_reset_start cortex_x2, ERRATUM(2081180), ERRATA_X2_2081180
 	/* Apply instruction patching sequence */
diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S
index 35d2c48..2a49134 100644
--- a/lib/cpus/aarch64/neoverse_v1.S
+++ b/lib/cpus/aarch64/neoverse_v1.S
@@ -161,7 +161,7 @@
 	msr	NEOVERSE_V1_CPUECTLR_EL1, x1
 workaround_reset_end neoverse_v1, ERRATUM(2108267)
 
-check_erratum_ls neoverse_v1, ERRATUM(2108267), CPU_REV(1, 1)
+check_erratum_ls neoverse_v1, ERRATUM(2108267), CPU_REV(1, 2)
 
 workaround_reset_start neoverse_v1, ERRATUM(2139242), ERRATA_V1_2139242
 	mov	x0, #0x3
@@ -194,7 +194,7 @@
 	sysreg_bit_set NEOVERSE_V1_ACTLR2_EL1, NEOVERSE_V1_ACTLR2_EL1_BIT_0
 workaround_reset_end neoverse_v1, ERRATUM(2294912)
 
-check_erratum_ls neoverse_v1, ERRATUM(2294912), CPU_REV(1, 1)
+check_erratum_ls neoverse_v1, ERRATUM(2294912), CPU_REV(1, 2)
 
 workaround_reset_start neoverse_v1, ERRATUM(2372203), ERRATA_V1_2372203
 	/* Set bit 40 in ACTLR2_EL1 */
diff --git a/lib/cpus/aarch64/travis.S b/lib/cpus/aarch64/travis.S
new file mode 100644
index 0000000..2abefe9
--- /dev/null
+++ b/lib/cpus/aarch64/travis.S
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <common/bl_common.h>
+#include <travis.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Travis must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Travis supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+cpu_reset_func_start travis
+	/* ----------------------------------------------------
+	 * Disable speculative loads
+	 * ----------------------------------------------------
+	 */
+	msr	SSBS, xzr
+cpu_reset_func_end travis
+
+func travis_core_pwr_dwn
+#if ENABLE_SME_FOR_NS
+        /* ---------------------------------------------------
+         * Disable SME if enabled and supported
+         * ---------------------------------------------------
+         */
+	mrs     x0, ID_AA64PFR1_EL1
+	ubfx	x0, x0, #ID_AA64PFR1_EL1_SME_SHIFT, \
+		#ID_AA64PFR1_EL1_SME_WIDTH
+        cmp     x0, #ID_AA64PFR1_EL1_SME_NOT_SUPPORTED
+	b.eq	1f
+	msr	TRAVIS_SVCRSM, xzr
+	msr	TRAVIS_SVCRZA, xzr
+1:
+#endif
+	/* ---------------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------------
+	 */
+	sysreg_bit_set TRAVIS_IMP_CPUPWRCTLR_EL1, \
+		TRAVIS_IMP_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
+	isb
+	ret
+endfunc travis_core_pwr_dwn
+
+errata_report_shim travis
+
+.section .rodata.travis_regs, "aS"
+travis_regs: /* The ASCII list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func travis_cpu_reg_dump
+	adr 	x6, travis_regs
+	mrs	x8, TRAVIS_IMP_CPUECTLR_EL1
+	ret
+endfunc travis_cpu_reg_dump
+
+declare_cpu_ops travis, TRAVIS_MIDR, \
+	travis_reset_func, \
+	travis_core_pwr_dwn
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index e7b0e54..ea29047 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -352,7 +352,7 @@
 CPU_FLAG_LIST += ERRATA_A78_AE_1951502
 
 # Flag to apply erratum 2376748 workaround during reset. This erratum applies
-# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+# to revisions r0p0, r0p1 and r0p2 of the A78 AE cpu. It is still open.
 CPU_FLAG_LIST += ERRATA_A78_AE_2376748
 
 # Flag to apply erratum 2395408 workaround during reset. This erratum applies
@@ -517,7 +517,7 @@
 CPU_FLAG_LIST += ERRATA_V1_2216392
 
 # Flag to apply erratum 2294912 workaround during reset. This erratum applies
-# to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open.
+# to revisions r0p0, r1p0, and r1p1 and r1p2 of the Neoverse V1 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_V1_2294912
 
 # Flag to apply erratum 2372203 workaround during reset. This erratum applies
@@ -557,7 +557,8 @@
 CPU_FLAG_LIST += ERRATA_A710_2083908
 
 # Flag to apply erratum 2058056 workaround during reset. This erratum applies
-# to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open.
+# to revisions r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is still
+# open.
 CPU_FLAG_LIST += ERRATA_A710_2058056
 
 # Flag to apply erratum 2055002 workaround during reset. This erratum applies
@@ -689,7 +690,7 @@
 CPU_FLAG_LIST += ERRATA_X2_2002765
 
 # Flag to apply erratum 2058056 workaround during reset. This erratum applies
-# to revisions r0p0, r1p0, and r2p0 of the Cortex-X2 cpu and is still open.
+# to revisions r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_X2_2058056
 
 # Flag to apply erratum 2083908 workaround during reset. This erratum applies
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
index c92b4a5..f957f0d 100644
--- a/make_helpers/arch_features.mk
+++ b/make_helpers/arch_features.mk
@@ -8,12 +8,64 @@
 # and enables them based on the configured architecture version.
 
 # This file follows the following format:
-#   - By default disable any mandatory features.
-#   - Then Enable mandatory feature if applicable to an Arch Version.
+#   - Enable mandatory feature if applicable to an Arch Version.
+#   - By default disable any mandatory features if they have not been defined yet.
 #   - Disable or enable any optional feature this would be enabled/disabled if needed by platform.
 
 #
 ################################################################################
+# Enable Mandatory features based on Arch versions.
+################################################################################
+#
+
+# Enable the features which are mandatory from ARCH version 8.1 and upwards.
+ifeq "8.1" "$(word 1, $(sort 8.1 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_PAN				:=	1
+ENABLE_FEAT_VHE				:=	1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.2 and upwards.
+ifeq "8.2" "$(word 1, $(sort 8.2 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_RAS				:=	1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.4 and upwards.
+ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_SEL2			:=	1
+ENABLE_TRF_FOR_NS			:=	1
+ENABLE_FEAT_DIT				:=	1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.5 and upwards.
+ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_RNG				:=	1
+ENABLE_FEAT_SB				:=	1
+
+# Enable Memory tagging, Branch Target Identification for aarch64 only.
+ifeq ($(ARCH), aarch64)
+	mem_tag_arch_support		:= 	yes
+endif #(ARCH=aarch64)
+
+endif
+
+# Enable the features which are mandatory from ARCH version 8.6 and upwards.
+ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_ECV				:=	1
+ENABLE_FEAT_FGT				:=	1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.7 and upwards.
+ifeq "8.7" "$(word 1, $(sort 8.7 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_HCX				:=	1
+endif
+
+# Enable the features which are mandatory from ARCH version 8.9 and upwards.
+ifeq "8.9" "$(word 1, $(sort 8.9 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_TCR2			:=	1
+endif
+
+#
+################################################################################
 # Set mandatory features by default to zero.
 ################################################################################
 #
@@ -23,17 +75,17 @@
 #----
 
 # Flag to enable access to Privileged Access Never bit of PSTATE.
-ENABLE_FEAT_PAN			:=	0
+ENABLE_FEAT_PAN			?=	0
 
 # Flag to enable Virtualization Host Extensions.
-ENABLE_FEAT_VHE			:=	0
+ENABLE_FEAT_VHE			?=	0
 
 #----
 # 8.2
 #----
 
 # Enable RAS Support.
-ENABLE_FEAT_RAS			:=	0
+ENABLE_FEAT_RAS			?=	0
 
 #----
 # 8.3
@@ -41,118 +93,67 @@
 
 # Flag to enable Pointer Authentication. Internal flag not meant for
 # direct setting. Use BRANCH_PROTECTION to enable PAUTH.
-ENABLE_PAUTH			:=	0
+ENABLE_PAUTH			?=	0
 
 # Include pointer authentication (ARMv8.3-PAuth) registers in cpu context. This
 # must be set to 1 if the platform wants to use this feature in the Secure
 # world. It is not necessary for use in the Non-secure world.
-CTX_INCLUDE_PAUTH_REGS		:=	0
+CTX_INCLUDE_PAUTH_REGS		?=	0
+
 
 #----
 # 8.4
 #----
 
 # Flag to enable Secure EL-2 feature.
-ENABLE_FEAT_SEL2		:=	0
+ENABLE_FEAT_SEL2		?=	0
 
 # By default, disable trace filter control register access to lower non-secure
 # exception levels, i.e. NS-EL2, or NS-EL1 if NS-EL2 is implemented, but
 # trace filter control register access is unused if FEAT_TRF is implemented.
-ENABLE_TRF_FOR_NS		:=	0
+ENABLE_TRF_FOR_NS		?=	0
 
 # Flag to enable Data Independent Timing instructions.
-ENABLE_FEAT_DIT			:=	0
+ENABLE_FEAT_DIT			?=	0
 
 #----
 # 8.5
 #----
 
-# Flag to enable access to the Random Number Generator registers.
-ENABLE_FEAT_RNG			:=	0
-
-# Flag to enable Speculation Barrier Instruction.
-ENABLE_FEAT_SB			:=	0
-
 # Flag to enable Branch Target Identification.
 # Internal flag not meant for direct setting.
 # Use BRANCH_PROTECTION to enable BTI.
-ENABLE_BTI			:=	0
+ENABLE_BTI			?=	0
+
+# Flag to enable access to the Random Number Generator registers.
+ENABLE_FEAT_RNG			?=	0
+
+# Flag to enable Speculation Barrier Instruction.
+ENABLE_FEAT_SB			?=	0
 
 #----
 # 8.6
 #----
 
 # Flag to enable access to the CNTPOFF_EL2 register.
-ENABLE_FEAT_ECV			:=	0
+ENABLE_FEAT_ECV			?=	0
 
 # Flag to enable access to the HDFGRTR_EL2 register.
-ENABLE_FEAT_FGT			:=	0
+ENABLE_FEAT_FGT			?=	0
 
 #----
 # 8.7
 #----
 
 # Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
-ENABLE_FEAT_HCX			:=	0
+ENABLE_FEAT_HCX			?=	0
 
 #----
 # 8.9
 #----
 
 # Flag to enable access to TCR2 (FEAT_TCR2).
-ENABLE_FEAT_TCR2		:=	0
-
-#
-################################################################################
-# Enable Mandatory features based on Arch versions.
-################################################################################
-#
-
-# Enable the features which are mandatory from ARCH version 8.1 and upwards.
-ifeq "8.1" "$(word 1, $(sort 8.1 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_PAN				:=	1
-ENABLE_FEAT_VHE				:=	1
-endif
-
-# Enable the features which are mandatory from ARCH version 8.2 and upwards.
-ifeq "8.2" "$(word 1, $(sort 8.2 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_RAS				:=	1
-endif
-
-# Enable the features which are mandatory from ARCH version 8.4 and upwards.
-ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_SEL2			:=	1
-ENABLE_TRF_FOR_NS			:=	1
-ENABLE_FEAT_DIT				:=	1
-endif
-
-# Enable the features which are mandatory from ARCH version 8.5 and upwards.
-ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_RNG				:=	1
-ENABLE_FEAT_SB				:=	1
-
-# Enable Memory tagging, Branch Target Identification for aarch64 only.
-ifeq ($(ARCH), aarch64)
-	mem_tag_arch_support		:= 	yes
-endif #(ARCH=aarch64)
-
-endif
-
-# Enable the features which are mandatory from ARCH version 8.6 and upwards.
-ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_ECV				:=	1
-ENABLE_FEAT_FGT				:=	1
-endif
-
-# Enable the features which are mandatory from ARCH version 8.7 and upwards.
-ifeq "8.7" "$(word 1, $(sort 8.7 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_HCX				:=	1
-endif
-
-# Enable the features which are mandatory from ARCH version 8.9 and upwards.
-ifeq "8.9" "$(word 1, $(sort 8.9 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_TCR2			:=	1
-endif
+ENABLE_FEAT_TCR2		?=	0
 
 #
 ################################################################################
@@ -184,7 +185,7 @@
 ifeq (${ARCH},aarch64)
        ENABLE_SPE_FOR_NS		?=	2
 else ifeq (${ARCH},aarch32)
-       ifdef ENABLE_SPE_FOR_NS
+       ifneq ($(or $(ENABLE_SPE_FOR_NS),0),0)
               $(error ENABLE_SPE_FOR_NS is not supported for AArch32)
        else
               ENABLE_SPE_FOR_NS		:=	0
@@ -196,7 +197,7 @@
        ENABLE_SVE_FOR_NS		?=	2
 # SVE is only supported on AArch64 so disable it on AArch32.
 else ifeq (${ARCH},aarch32)
-       ifdef ENABLE_SVE_FOR_NS
+       ifneq ($(or $(ENABLE_SVE_FOR_NS),0),0)
               $(error ENABLE_SVE_FOR_NS is not supported for AArch32)
        else
               ENABLE_SVE_FOR_NS 	:=	0
@@ -302,10 +303,10 @@
 ifeq (${ARCH},aarch64)
         ENABLE_TRBE_FOR_NS		?=	0
 else ifeq (${ARCH},aarch32)
-        ifdef ENABLE_TRBE_FOR_NS
-                $(error ENABLE_TRBE_FOR_NS is not supported for AArch32)
+        ifneq ($(or $(ENABLE_TRBE_FOR_NS),0),0)
+               $(error ENABLE_TRBE_FOR_NS is not supported for AArch32)
         else
-                ENABLE_TRBE_FOR_NS 	:=	0
+               ENABLE_TRBE_FOR_NS 	:=	0
         endif
 endif
 
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index b93922a..d3dc5a3 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -11,6 +11,7 @@
 #include <drivers/arm/sp804_delay_timer.h>
 #include <lib/fconf/fconf.h>
 #include <lib/fconf/fconf_dyn_cfg_getter.h>
+#include <lib/transfer_list.h>
 
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
@@ -42,6 +43,8 @@
 	struct bl_params *arm_bl_params;
 	const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
 	bl_mem_params_node_t *param_node __unused;
+	static struct transfer_list_header *ns_tl __unused;
+	struct transfer_list_entry *te __unused;
 
 	arm_bl_params = arm_get_next_bl_params();
 
@@ -81,6 +84,23 @@
 	param_node = get_bl_mem_params_node(HW_CONFIG_ID);
 	assert(param_node != NULL);
 
+	bl_mem_params_node_t *bl33_param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
+	assert(bl33_param_node != NULL);
+
+#if TRANSFER_LIST
+	ns_tl = transfer_list_init((void *)FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE);
+	assert(ns_tl != NULL);
+
+	/* Update BL33's ep info with NS HW config address  */
+	te = transfer_list_add(ns_tl, TL_TAG_FDT, param_node->image_info.image_size,
+			       (void *)hw_config_info->config_addr);
+	assert(te != NULL);
+
+	bl33_param_node->ep_info.args.arg1 = TRANSFER_LIST_SIGNATURE | REGISTER_CONVENTION_VERSION_MASK;
+	bl33_param_node->ep_info.args.arg2 = 0;
+	bl33_param_node->ep_info.args.arg3 = (uintptr_t)ns_tl;
+	bl33_param_node->ep_info.args.arg0 = te ? (uintptr_t)transfer_list_entry_data(te) : 0;
+#else
 	/* Copy HW config from Secure address to NS address */
 	memcpy((void *)hw_config_info->secondary_config_addr,
 	       (void *)hw_config_info->config_addr,
@@ -94,11 +114,8 @@
 	flush_dcache_range(hw_config_info->secondary_config_addr,
 			   param_node->image_info.image_size);
 
-	param_node = get_bl_mem_params_node(BL33_IMAGE_ID);
-	assert(param_node != NULL);
-
-	/* Update BL33's ep info with NS HW config address  */
-	param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr;
+	bl33_param_node->ep_info.args.arg1 = hw_config_info->secondary_config_addr;
+#endif /* TRANSFER_LIST */
 #endif /* !RESET_TO_BL2 && !EL3_PAYLOAD_BASE */
 
 	return arm_bl_params;
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 283918b..c40a3ce 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -71,6 +71,14 @@
 					DEVICE2_SIZE,			\
 					MT_DEVICE | MT_RW | MT_SECURE)
 
+#if TRANSFER_LIST
+#ifdef FW_NS_HANDOFF_BASE
+#define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, \
+					  FW_HANDOFF_SIZE,    \
+					  MT_MEMORY | MT_RW | MT_NS)
+#endif
+#endif
+
 /*
  * Table of memory regions for various BL stages to map using the MMU.
  * This doesn't include Trusted SRAM as setup_page_tables() already takes care
@@ -183,6 +191,9 @@
 	ARM_MAP_GPT_L1_DRAM,
 	ARM_MAP_EL3_RMM_SHARED_MEM,
 #endif
+#ifdef MAP_FW_NS_HANDOFF
+	MAP_FW_NS_HANDOFF,
+#endif
 	{0}
 };
 
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 826fca2..aad0417 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -128,6 +128,11 @@
  */
 #define PLAT_ARM_NS_IMAGE_BASE		(ARM_DRAM1_BASE + UL(0x8000000))
 
+#if TRANSFER_LIST
+#define FW_HANDOFF_SIZE			0x4000
+#define FW_NS_HANDOFF_BASE		(PLAT_ARM_NS_IMAGE_BASE - FW_HANDOFF_SIZE)
+#endif
+
 /*
  * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
  * plat_arm_mmap array defined for each BL stage.
@@ -188,8 +193,10 @@
 /*
  * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
  * plus a little space for growth.
+ * In case of PSA Crypto API, few algorithms like ECDSA needs bigger BL1 RW
+ * area.
  */
-#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
+#if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA || PSA_CRYPTO
 #define PLAT_ARM_MAX_BL1_RW_SIZE	UL(0xC000)
 #else
 #define PLAT_ARM_MAX_BL1_RW_SIZE	UL(0xB000)
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 165b1610..902a5df 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -72,9 +72,7 @@
 
 # enable unconditionally for all builds
 ifeq (${ARCH}, aarch64)
-ifeq (${ENABLE_RME},0)
-	ENABLE_BRBE_FOR_NS		:= 2
-endif
+    ENABLE_BRBE_FOR_NS		:= 2
     ENABLE_TRBE_FOR_NS		:= 2
 endif
 ENABLE_SYS_REG_TRACE_FOR_NS	:= 2
@@ -216,7 +214,8 @@
 					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/cortex_x2.S		\
 					lib/cpus/aarch64/cortex_gelas.S		\
-					lib/cpus/aarch64/nevis.S
+					lib/cpus/aarch64/nevis.S		\
+					lib/cpus/aarch64/travis.S
 	endif
 	# AArch64/AArch32 cores
 	FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S		\
@@ -359,6 +358,10 @@
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config,${FVP_TOS_FW_CONFIG}))
 endif
 
+ifeq (${TRANSFER_LIST}, 1)
+include lib/transfer_list/transfer_list.mk
+endif
+
 ifeq (${SPD},spmd)
 
 ifeq ($(ARM_SPMC_MANIFEST_DTS),)
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index bd62614..f937ee7 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -14,6 +14,10 @@
 
 N1SDP_CPU_SOURCES	:=	lib/cpus/aarch64/neoverse_n1.S
 
+# Neoverse N1 cores support Armv8.2 extensions
+ARM_ARCH_MAJOR := 8
+ARM_ARCH_MINOR := 2
+
 # GIC-600 configuration
 GICV3_SUPPORT_GIC600		:=	1
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index b142b62..6f3d0e9 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -69,6 +69,8 @@
 void arm_bl2_early_platform_setup(uintptr_t fw_config,
 				  struct meminfo *mem_layout)
 {
+	int __maybe_unused ret;
+
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
 
@@ -82,9 +84,13 @@
 
 	/* Load partition table */
 #if ARM_GPT_SUPPORT
-	partition_init(GPT_IMAGE_ID);
-#endif /* ARM_GPT_SUPPORT */
+	ret = gpt_partition_init();
+	if (ret != 0) {
+		ERROR("GPT partition initialisation failed!\n");
+		panic();
+	}
 
+#endif /* ARM_GPT_SUPPORT */
 }
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index 27acc3a..07f6a82 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -45,10 +45,21 @@
 	 * each sector has 4 partition entries, and there are
 	 * 2 reserved sectors i.e. protective MBR and primary
 	 * GPT header hence length gets calculated as,
-	 * length = 512 * (128/4 + 2)
+	 * length = PLAT_PARTITION_BLOCK_SIZE * (128/4 + 2)
 	 */
-	.length         = PLAT_PARTITION_BLOCK_SIZE *
-			  (PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
+	.length         = LBA(PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
+};
+
+/*
+ * length will be assigned at runtime based on MBR header data.
+ * Backup GPT Header is present in Last LBA-1 and its entries
+ * are last 32 blocks starts at LBA-33, On runtime update these
+ * before device usage. Update offset to beginning LBA-33 and
+ * length to LBA-33.
+ */
+static io_block_spec_t bkup_gpt_spec = {
+	.offset         = PLAT_ARM_FLASH_IMAGE_BASE,
+	.length         = 0,
 };
 #endif /* ARM_GPT_SUPPORT */
 
@@ -107,6 +118,11 @@
 		(uintptr_t)&gpt_spec,
 		open_memmap
 	},
+	[BKUP_GPT_IMAGE_ID] = {
+		&memmap_dev_handle,
+		(uintptr_t)&bkup_gpt_spec,
+		open_memmap
+	},
 #endif /* ARM_GPT_SUPPORT */
 #if PSA_FWU_SUPPORT
 	[FWU_METADATA_IMAGE_ID] = {
diff --git a/plat/aspeed/ast2700/plat_bl31_setup.c b/plat/aspeed/ast2700/plat_bl31_setup.c
index fde5dbb..92a48ff 100644
--- a/plat/aspeed/ast2700/plat_bl31_setup.c
+++ b/plat/aspeed/ast2700/plat_bl31_setup.c
@@ -76,6 +76,12 @@
 			BL_END - BL_CODE_END,
 			MT_RW_DATA | MT_SECURE);
 
+#if USE_COHERENT_MEM
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
 	mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE,
 			MT_MEMORY | MT_RW);
 
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index bbfb5bb..c5f60fe 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -20,14 +20,20 @@
 #include <k3_gicv3.h>
 #include <ti_sci.h>
 
+#define ADDR_DOWN(_adr) (_adr & XLAT_ADDR_MASK(2U))
+#define SIZE_UP(_adr, _sz) (round_up((_adr + _sz), XLAT_BLOCK_SIZE(2U)) - ADDR_DOWN(_adr))
+
+#define K3_MAP_REGION_FLAT(_adr, _sz, _attr) \
+	MAP_REGION_FLAT(ADDR_DOWN(_adr), SIZE_UP(_adr, _sz), _attr)
+
 /* Table of regions to map using the MMU */
 const mmap_region_t plat_k3_mmap[] = {
-	MAP_REGION_FLAT(K3_USART_BASE,       K3_USART_SIZE,       MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(K3_GIC_BASE,         K3_GIC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(K3_GTC_BASE,         K3_GTC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(SEC_PROXY_RT_BASE,   SEC_PROXY_RT_SIZE,   MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(K3_USART_BASE,       K3_USART_SIZE,       MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(K3_GIC_BASE,         K3_GIC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(K3_GTC_BASE,         K3_GTC_SIZE,         MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(SEC_PROXY_RT_BASE,   SEC_PROXY_RT_SIZE,   MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	K3_MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	{ /* sentinel */ }
 };
 
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index ae3775a..a2cc62d 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -70,11 +70,7 @@
  * used, choose the smallest value needed to map the required virtual addresses
  * for each BL stage.
  */
-#if USE_COHERENT_MEM
-#define MAX_XLAT_TABLES		10
-#else
-#define MAX_XLAT_TABLES		9
-#endif
+#define MAX_XLAT_TABLES		4
 
 /*
  * Defines the maximum number of regions that are allocated by the translation
@@ -86,7 +82,11 @@
  * runtime memory used, choose the smallest value needed to register the
  * required regions for each BL stage.
  */
+#if USE_COHERENT_MEM
 #define MAX_MMAP_REGIONS	11
+#else
+#define MAX_MMAP_REGIONS	10
+#endif
 
 /*
  * Defines the total size of the address space in bytes. For example, for a 32
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index 4c02402..286a706 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -35,10 +35,10 @@
 # define BL31_BASE			U(0xfffe0000)
 # define BL31_LIMIT			U(0x100000000)
 #else
-# define BL31_BASE			(VERSAL_ATF_MEM_BASE)
-# define BL31_LIMIT			(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_SIZE)
+# define BL31_BASE			U(VERSAL_ATF_MEM_BASE)
+# define BL31_LIMIT			U(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_SIZE)
 # ifdef VERSAL_ATF_MEM_PROGBITS_SIZE
-#  define BL31_PROGBITS_LIMIT		(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_PROGBITS_SIZE)
+#  define BL31_PROGBITS_LIMIT		U(VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_PROGBITS_SIZE)
 # endif
 #endif
 
@@ -49,8 +49,8 @@
 # define BL32_BASE			U(0x60000000)
 # define BL32_LIMIT			U(0x80000000)
 #else
-# define BL32_BASE			(VERSAL_BL32_MEM_BASE)
-# define BL32_LIMIT			(VERSAL_BL32_MEM_BASE + VERSAL_BL32_MEM_SIZE)
+# define BL32_BASE			U(VERSAL_BL32_MEM_BASE)
+# define BL32_LIMIT			U(VERSAL_BL32_MEM_BASE + VERSAL_BL32_MEM_SIZE)
 #endif
 
 /*******************************************************************************
@@ -59,7 +59,7 @@
 #ifndef PRELOADED_BL33_BASE
 # define PLAT_ARM_NS_IMAGE_BASE		U(0x8000000)
 #else
-# define PLAT_ARM_NS_IMAGE_BASE		PRELOADED_BL33_BASE
+# define PLAT_ARM_NS_IMAGE_BASE		U(PRELOADED_BL33_BASE)
 #endif
 
 /*******************************************************************************
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
index abb86c7..38ba638 100644
--- a/services/std_svc/errata_abi/errata_abi_main.c
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -163,10 +163,12 @@
 		[5] = {1262606, 0x00, 0x30, ERRATA_A76_1262606},
 		[6] = {1262888, 0x00, 0x30, ERRATA_A76_1262888},
 		[7] = {1275112, 0x00, 0x30, ERRATA_A76_1275112},
-		[8] = {1791580, 0x00, 0x40, ERRATA_A76_1791580},
-		[9] = {1868343, 0x00, 0x40, ERRATA_A76_1868343},
-		[10] = {1946160, 0x30, 0x41, ERRATA_A76_1946160},
-		[11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[8] = {1286807, 0x00, 0x30, ERRATA_A76_1286807},
+		[9] = {1791580, 0x00, 0x40, ERRATA_A76_1791580},
+		[10] = {1868343, 0x00, 0x40, ERRATA_A76_1868343},
+		[11] = {1946160, 0x30, 0x41, ERRATA_A76_1946160},
+		[12] = {2743102, 0x00, 0x41, ERRATA_A76_2743102},
+		[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A76_H_INC */
@@ -216,7 +218,7 @@
 	.cpu_errata_list = {
 		[0] = {1941500, 0x00, 0x01, ERRATA_A78_AE_1941500},
 		[1] = {1951502, 0x00, 0x01, ERRATA_A78_AE_1951502},
-		[2] = {2376748, 0x00, 0x01, ERRATA_A78_AE_2376748},
+		[2] = {2376748, 0x00, 0x02, ERRATA_A78_AE_2376748},
 		[3] = {2395408, 0x00, 0x01, ERRATA_A78_AE_2395408},
 		[4] = {2712574, 0x00, 0x02, ERRATA_A78_AE_2712574, \
 			ERRATA_NON_ARM_INTERCONNECT},
@@ -229,15 +231,17 @@
 {
 	.cpu_partnumber = CORTEX_A78C_MIDR,
 	.cpu_errata_list = {
-		[0] = {2132064, 0x01, 0x02, ERRATA_A78C_2132064},
-		[1] = {2242638, 0x01, 0x02, ERRATA_A78C_2242638},
-		[2] = {2376749, 0x01, 0x02, ERRATA_A78C_2376749},
-		[3] = {2395411, 0x01, 0x02, ERRATA_A78C_2395411},
-		[4] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \
+		[0] = {1827430, 0x00, 0x00, ERRATA_A78C_1827430},
+		[1] = {1827440, 0x00, 0x00, ERRATA_A78C_1827440},
+		[2] = {2132064, 0x01, 0x02, ERRATA_A78C_2132064},
+		[3] = {2242638, 0x01, 0x02, ERRATA_A78C_2242638},
+		[4] = {2376749, 0x01, 0x02, ERRATA_A78C_2376749},
+		[5] = {2395411, 0x01, 0x02, ERRATA_A78C_2395411},
+		[6] = {2712575, 0x01, 0x02, ERRATA_A78C_2712575, \
 			ERRATA_NON_ARM_INTERCONNECT},
-		[5] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121},
-		[6] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484},
-		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[7] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121},
+		[8] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484},
+		[9 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* CORTEX_A78C_H_INC */
@@ -258,21 +262,22 @@
 {
 	.cpu_partnumber = NEOVERSE_N1_MIDR,
 	.cpu_errata_list = {
-		[0] = {1073348, 0x00, 0x10, ERRATA_N1_1073348},
-		[1] = {1130799, 0x00, 0x20, ERRATA_N1_1130799},
-		[2] = {1165347, 0x00, 0x20, ERRATA_N1_1165347},
-		[3] = {1207823, 0x00, 0x20, ERRATA_N1_1207823},
-		[4] = {1220197, 0x00, 0x20, ERRATA_N1_1220197},
-		[5] = {1257314, 0x00, 0x30, ERRATA_N1_1257314},
-		[6] = {1262606, 0x00, 0x30, ERRATA_N1_1262606},
-		[7] = {1262888, 0x00, 0x30, ERRATA_N1_1262888},
-		[8] = {1275112, 0x00, 0x30, ERRATA_N1_1275112},
-		[9] = {1315703, 0x00, 0x30, ERRATA_N1_1315703},
-		[10] = {1542419, 0x30, 0x40, ERRATA_N1_1542419},
-		[11] = {1868343, 0x00, 0x40, ERRATA_N1_1868343},
-		[12] = {1946160, 0x30, 0x41, ERRATA_N1_1946160},
-		[13] = {2743102, 0x00, 0x41, ERRATA_N1_2743102},
-		[14 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[0] = {1043202, 0x00, 0x10, ERRATA_N1_1043202},
+		[1] = {1073348, 0x00, 0x10, ERRATA_N1_1073348},
+		[2] = {1130799, 0x00, 0x20, ERRATA_N1_1130799},
+		[3] = {1165347, 0x00, 0x20, ERRATA_N1_1165347},
+		[4] = {1207823, 0x00, 0x20, ERRATA_N1_1207823},
+		[5] = {1220197, 0x00, 0x20, ERRATA_N1_1220197},
+		[6] = {1257314, 0x00, 0x30, ERRATA_N1_1257314},
+		[7] = {1262606, 0x00, 0x30, ERRATA_N1_1262606},
+		[8] = {1262888, 0x00, 0x30, ERRATA_N1_1262888},
+		[9] = {1275112, 0x00, 0x30, ERRATA_N1_1275112},
+		[10] = {1315703, 0x00, 0x30, ERRATA_N1_1315703},
+		[11] = {1542419, 0x30, 0x40, ERRATA_N1_1542419},
+		[12] = {1868343, 0x00, 0x40, ERRATA_N1_1868343},
+		[13] = {1946160, 0x30, 0x41, ERRATA_N1_1946160},
+		[14] = {2743102, 0x00, 0x41, ERRATA_N1_2743102},
+		[15 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_N1_H_INC */
@@ -281,23 +286,24 @@
 {
 	.cpu_partnumber = NEOVERSE_V1_MIDR,
 	.cpu_errata_list = {
-		[0] = {1618635, 0x00, 0x0F, ERRATA_V1_1618635},
+		[0] = {1618635, 0x00, 0x00, ERRATA_V1_1618635},
 		[1] = {1774420, 0x00, 0x10, ERRATA_V1_1774420},
 		[2] = {1791573, 0x00, 0x10, ERRATA_V1_1791573},
 		[3] = {1852267, 0x00, 0x10, ERRATA_V1_1852267},
 		[4] = {1925756, 0x00, 0x11, ERRATA_V1_1925756},
 		[5] = {1940577, 0x10, 0x11, ERRATA_V1_1940577},
 		[6] = {1966096, 0x10, 0x11, ERRATA_V1_1966096},
-		[7] = {2108267, 0x00, 0x11, ERRATA_V1_2108267},
+		[7] = {2108267, 0x00, 0x12, ERRATA_V1_2108267},
 		[8] = {2139242, 0x00, 0x11, ERRATA_V1_2139242},
 		[9] = {2216392, 0x10, 0x11, ERRATA_V1_2216392},
-		[10] = {2294912, 0x00, 0x11, ERRATA_V1_2294912},
+		[10] = {2294912, 0x00, 0x12, ERRATA_V1_2294912},
 		[11] = {2372203, 0x00, 0x11, ERRATA_V1_2372203},
 		[12] = {2701953, 0x00, 0x11, ERRATA_V1_2701953, \
 			ERRATA_NON_ARM_INTERCONNECT},
 		[13] = {2743093, 0x00, 0x12, ERRATA_V1_2743093},
-		[14] = {2779461, 0x00, 0x12, ERRATA_V1_2779461},
-		[15 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+		[14] = {2743233, 0x00, 0x12, ERRATA_V1_2743233},
+		[15] = {2779461, 0x00, 0x12, ERRATA_V1_2779461},
+		[16 ... ERRATA_LIST_END] = UNDEF_ERRATA,
 	}
 },
 #endif /* NEOVERSE_V1_H_INC */
@@ -310,7 +316,7 @@
 		[1] = {2008768, 0x00, 0x20, ERRATA_A710_2008768},
 		[2] = {2017096, 0x00, 0x20, ERRATA_A710_2017096},
 		[3] = {2055002, 0x10, 0x20, ERRATA_A710_2055002},
-		[4] = {2058056, 0x00, 0x20, ERRATA_A710_2058056},
+		[4] = {2058056, 0x00, 0x21, ERRATA_A710_2058056},
 		[5] = {2081180, 0x00, 0x20, ERRATA_A710_2081180},
 		[6] = {2083908, 0x20, 0x20, ERRATA_A710_2083908},
 		[7] = {2136059, 0x00, 0x20, ERRATA_A710_2136059},
@@ -336,7 +342,7 @@
 		[1] = {2009478, 0x00, 0x00, ERRATA_N2_2009478},
 		[2] = {2025414, 0x00, 0x00, ERRATA_N2_2025414},
 		[3] = {2067956, 0x00, 0x00, ERRATA_N2_2067956},
-		[4] = {2138953, 0x00, 0x00, ERRATA_N2_2138953},
+		[4] = {2138953, 0x00, 0x03, ERRATA_N2_2138953},
 		[5] = {2138956, 0x00, 0x00, ERRATA_N2_2138956},
 		[6] = {2138958, 0x00, 0x00, ERRATA_N2_2138958},
 		[7] = {2189731, 0x00, 0x00, ERRATA_N2_2189731},
@@ -344,7 +350,7 @@
 		[9] = {2242415, 0x00, 0x00, ERRATA_N2_2242415},
 		[10] = {2280757, 0x00, 0x00, ERRATA_N2_2280757},
 		[11] = {2326639, 0x00, 0x00, ERRATA_N2_2326639},
-		[12] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
+		[12] = {2376738, 0x00, 0x03, ERRATA_N2_2376738},
 		[13] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
 		[14] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
 			ERRATA_NON_ARM_INTERCONNECT},
@@ -362,13 +368,13 @@
 	.cpu_errata_list = {
 		[0] = {2002765, 0x00, 0x20, ERRATA_X2_2002765},
 		[1] = {2017096, 0x00, 0x20, ERRATA_X2_2017096},
-		[2] = {2058056, 0x00, 0x20, ERRATA_X2_2058056},
+		[2] = {2058056, 0x00, 0x21, ERRATA_X2_2058056},
 		[3] = {2081180, 0x00, 0x20, ERRATA_X2_2081180},
-		[4] = {2083908, 0x00, 0x20, ERRATA_X2_2083908},
+		[4] = {2083908, 0x20, 0x20, ERRATA_X2_2083908},
 		[5] = {2147715, 0x20, 0x20, ERRATA_X2_2147715},
 		[6] = {2216384, 0x00, 0x20, ERRATA_X2_2216384},
 		[7] = {2282622, 0x00, 0x21, ERRATA_X2_2282622},
-		[8] = {2371105, 0x00, 0x21, ERRATA_X2_2371105},
+		[8] = {2371105, 0x00, 0x20, ERRATA_X2_2371105},
 		[9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \
 			ERRATA_NON_ARM_INTERCONNECT},
 		[10] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index d830403..066571e 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -110,6 +110,12 @@
 		 spmd_spmc_id_get());
 	write_ctx_reg(gpregs, CTX_GPREG_X2, BIT(31) | target_func);
 	write_ctx_reg(gpregs, CTX_GPREG_X3, message);
+
+	/* Zero out x4-x7 for the direct request emitted towards the SPMC. */
+	write_ctx_reg(gpregs, CTX_GPREG_X4, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X5, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X6, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X7, 0);
 }
 
 
@@ -945,6 +951,21 @@
 						SPMD_FWK_MSG_FFA_VERSION_REQ,
 						input_version);
 
+			/*
+			 * Ensure x8-x17 NS GP register values are untouched when returning
+			 * from the SPMC.
+			 */
+			write_ctx_reg(gpregs, CTX_GPREG_X8, SMC_GET_GP(handle, CTX_GPREG_X8));
+			write_ctx_reg(gpregs, CTX_GPREG_X9, SMC_GET_GP(handle, CTX_GPREG_X9));
+			write_ctx_reg(gpregs, CTX_GPREG_X10, SMC_GET_GP(handle, CTX_GPREG_X10));
+			write_ctx_reg(gpregs, CTX_GPREG_X11, SMC_GET_GP(handle, CTX_GPREG_X11));
+			write_ctx_reg(gpregs, CTX_GPREG_X12, SMC_GET_GP(handle, CTX_GPREG_X12));
+			write_ctx_reg(gpregs, CTX_GPREG_X13, SMC_GET_GP(handle, CTX_GPREG_X13));
+			write_ctx_reg(gpregs, CTX_GPREG_X14, SMC_GET_GP(handle, CTX_GPREG_X14));
+			write_ctx_reg(gpregs, CTX_GPREG_X15, SMC_GET_GP(handle, CTX_GPREG_X15));
+			write_ctx_reg(gpregs, CTX_GPREG_X16, SMC_GET_GP(handle, CTX_GPREG_X16));
+			write_ctx_reg(gpregs, CTX_GPREG_X17, SMC_GET_GP(handle, CTX_GPREG_X17));
+
 			rc = spmd_spm_core_sync_entry(ctx);
 
 			if ((rc != 0ULL) ||
@@ -960,6 +981,14 @@
 			}
 
 			/*
+			 * x0-x4 are updated by spmd_smc_forward below.
+			 * Zero out x5-x7 in the FFA_VERSION response.
+			 */
+			write_ctx_reg(gpregs, CTX_GPREG_X5, 0);
+			write_ctx_reg(gpregs, CTX_GPREG_X6, 0);
+			write_ctx_reg(gpregs, CTX_GPREG_X7, 0);
+
+			/*
 			 * Return here after SPMC has handled FFA_VERSION.
 			 * The returned SPMC version is held in X3.
 			 * Forward this version in X0 to the non-secure caller.
diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c
index a2704dd..fd89c81 100644
--- a/services/std_svc/spmd/spmd_pm.c
+++ b/services/std_svc/spmd/spmd_pm.c
@@ -122,8 +122,20 @@
 	assert(ctx->state != SPMC_STATE_OFF);
 
 	/* Build an SPMD to SPMC direct message request. */
-	spmd_build_spmc_message(get_gpregs_ctx(&ctx->cpu_ctx),
-				FFA_FWK_MSG_PSCI, PSCI_CPU_OFF);
+	gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
+	spmd_build_spmc_message(gpregs, FFA_FWK_MSG_PSCI, PSCI_CPU_OFF);
+
+	/* Clear remaining x8 - x17 at EL3/SEL2 or EL3/SEL1 boundary. */
+	write_ctx_reg(gpregs, CTX_GPREG_X8, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X9, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X10, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X11, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X12, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X13, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X14, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X15, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X16, 0);
+	write_ctx_reg(gpregs, CTX_GPREG_X17, 0);
 
 	rc = spmd_spm_core_sync_entry(ctx);
 	if (rc != 0ULL) {