Merge changes from topic "mp/feat_ras" into integration

* changes:
  refactor(cpufeat): enable FEAT_RAS for FEAT_STATE_CHECKED
  refactor(ras): replace RAS_EXTENSION with FEAT_RAS
diff --git a/Makefile b/Makefile
index edd435c..1a80244 100644
--- a/Makefile
+++ b/Makefile
@@ -922,11 +922,20 @@
     endif
 endif
 
+ifneq (${ENABLE_SME_FOR_NS},0)
+    ifeq (${ENABLE_SVE_FOR_NS},0)
+        $(error "ENABLE_SME_FOR_NS requires ENABLE_SVE_FOR_NS")
+    endif
+endif
+
 # Secure SME/SVE requires the non-secure component as well
 ifeq (${ENABLE_SME_FOR_SWD},1)
     ifeq (${ENABLE_SME_FOR_NS},0)
         $(error "ENABLE_SME_FOR_SWD requires ENABLE_SME_FOR_NS")
     endif
+    ifeq (${ENABLE_SVE_FOR_SWD},0)
+        $(error "ENABLE_SME_FOR_SWD requires ENABLE_SVE_FOR_SWD")
+    endif
 endif
 ifeq (${ENABLE_SVE_FOR_SWD},1)
     ifeq (${ENABLE_SVE_FOR_NS},0)
@@ -1174,6 +1183,8 @@
         SIMICS_BUILD \
         FEATURE_DETECTION \
 	TRNG_SUPPORT \
+	ERRATA_ABI_SUPPORT \
+	ERRATA_NON_ARM_INTERCONNECT \
 	CONDITIONAL_CMO \
 	RAS_FFH_SUPPORT \
 )))
@@ -1308,6 +1319,8 @@
         TRUSTED_BOARD_BOOT \
         CRYPTO_SUPPORT \
         TRNG_SUPPORT \
+        ERRATA_ABI_SUPPORT \
+	ERRATA_NON_ARM_INTERCONNECT \
         USE_COHERENT_MEM \
         USE_DEBUGFS \
         ARM_IO_IN_DTB \
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 9b5cf55..d7c9a52 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -91,6 +91,10 @@
 BL31_SOURCES		+=	lib/extensions/spe/spe.c
 endif
 
+ifeq (${ERRATA_ABI_SUPPORT},1)
+BL31_SOURCES		+=	services/std_svc/errata_abi/errata_abi_main.c
+endif
+
 ifneq (${ENABLE_FEAT_AMU},0)
 BL31_SOURCES		+=	${AMU_SOURCES}
 endif
@@ -101,12 +105,10 @@
 
 ifneq (${ENABLE_SME_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/sme/sme.c
-BL31_SOURCES		+=	lib/extensions/sve/sve.c
-else
+endif
 ifneq (${ENABLE_SVE_FOR_NS},0)
 BL31_SOURCES		+=	lib/extensions/sve/sve.c
 endif
-endif
 
 ifneq (${ENABLE_MPAM_FOR_LOWER_ELS},0)
 BL31_SOURCES		+=	lib/extensions/mpam/mpam.c
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index fb0161c..ec75d88 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -46,6 +46,10 @@
 				services/std_svc/trng/trng_entropy_pool.c
 endif
 
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+BL32_SOURCES		+=	services/std_svc/errata_abi/errata_abi_main.c
+endif
+
 ifneq (${ENABLE_SYS_REG_TRACE_FOR_NS},0)
 BL32_SOURCES		+=	lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c
 endif
diff --git a/changelog.yaml b/changelog.yaml
index c969b2c..9114dad 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -662,6 +662,9 @@
       - title: TRNG
         scope: trng
 
+      - title: ERRATA_ABI
+        scope: errata_abi
+
   - title: Libraries
 
     subsections:
diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst
index cd52460..0ba0a7a 100644
--- a/docs/about/release-information.rst
+++ b/docs/about/release-information.rst
@@ -67,7 +67,7 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| plat_convert_pk() function     |   Nov'22    |   2.9   | Platform conversion to manage specific PK hash          |
+| None at this time              |             |         |                                                         |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 
 Removal of Deprecated Drivers
@@ -82,8 +82,6 @@
 |                                | Date        | after   |                                                         |
 |                                |             | Release |                                                         |
 +================================+=============+=========+=========================================================+
-| io_dummy driver                |   Nov'22    |   2.9   | No more used by any upstream platform                   |
-+--------------------------------+-------------+---------+---------------------------------------------------------+
 | CryptoCell-712                 |     2.9     |   3.0   | No longer maintained.                                   |
 +--------------------------------+-------------+---------+---------------------------------------------------------+
 | CryptoCell-713                 |     2.9     |   3.0   | No longer maintained.                                   |
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 0f1f92a..758d62b 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -317,6 +317,11 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2, and
    it is still open.
 
+- ``ERRATA_A78_2712571``: This applies erratum 2712571 workaround to Cortex-A78
+   CPU, this erratum affects system configurations that do not use an ARM
+   interconnect IP. This needs to be enabled for revisions r0p0, r1p0, r1p1
+   and r1p2 and it is still open.
+
 -  ``ERRATA_A78_2742426``: This applies erratum 2742426 workaround to Cortex-A78
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 and
    it is still open.
@@ -347,6 +352,11 @@
   Cortex-A78 AE 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
+  an ARM interconnect IP. This needs to be enabled for revisions r0p0, r0p1 and
+  r0p2. This erratum is still open.
+
 For Cortex-A78C, the following errata build flags are defined :
 
 - ``ERRATA_A78C_1827430`` : This applies errata 1827430 workaround to
@@ -373,6 +383,11 @@
   Cortex-A78C CPU. This needs to be enabled for revisions r0p1 and r0p2. This
   erratum is still open.
 
+- ``ERRATA_A78C_2712575`` : This applies erratum 2712575 workaround to
+  Cortex-A78C CPU, this erratum affects system configurations that do not use
+  an ARM interconnect IP. This needs to be enabled for revisions r0p1 and r0p2
+  and is still open.
+
 - ``ERRATA_A78C_2772121`` : This applies errata 2772121 workaround to
   Cortex-A78C CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2.
   This erratum is still open.
@@ -488,6 +503,11 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0 and r1p1 of the CPU.
    It is still open.
 
+- ``ERRATA_V1_2701953``: This applies erratum 2701953 workaround to Neoverse-V1
+   CPU, this erratum affects system configurations that do not use an ARM
+   interconnect IP. This needs to be enabled for revisions r0p0, r1p0 and r1p1.
+   It has been fixed in r1p2.
+
 -  ``ERRATA_V1_2743093``: This applies errata 2743093 workaround to Neoverse-V1
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1 and r1p2 of the
    CPU. It is still open.
@@ -500,6 +520,13 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, r1p2 of the
    CPU. It is still open.
 
+For Neoverse V2, the following errata build flags are defined :
+
+-  ``ERRATA_V2_2719103``: This applies errata 2719103 workaround to Neoverse-V2
+   CPU, this affects system configurations that do not use and ARM interconnect
+   IP. This needs to be enabled for revisions r0p0 and r0p1. It has been fixed
+   in r0p2.
+
 For Cortex-A710, the following errata build flags are defined :
 
 -  ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to
@@ -558,6 +585,11 @@
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0
    of the CPU and is fixed in r2p1.
 
+-  ``ERRATA_A710_2701952``: This applies erratum 2701952 workaround to Cortex-A710
+   CPU, and applies to system configurations that do not use and ARM
+   interconnect IP. This needs to be enabled for r0p0, r1p0, r2p0 and r2p1 and
+   is still open.
+
 -  ``ERRATA_A710_2768515``: This applies errata 2768515 workaround to
    Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and
    r2p1 of the CPU and is still open.
@@ -610,6 +642,11 @@
    CPU. This needs to be enabled for revisions r0p0, r0p1 and r0p2. It is fixed
    in r0p3.
 
+- ``ERRATA_N2_2728475``: This applies erratum 2728475 workaround to Neoverse-N2
+   CPU, this erratum affects system configurations that do not use and ARM
+   interconnect IP. This needs to be enabled for revisions r0p0, r0p1 and r0p2.
+   It is fixed in r0p3.
+
 For Cortex-X2, the following errata build flags are defined :
 
 -  ``ERRATA_X2_2002765``: This applies errata 2002765 workaround to Cortex-X2
@@ -647,6 +684,11 @@
    CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0 of the CPU
    and is fixed in r2p1.
 
+- ``ERRATA_X2_2701952``: This applies erratum 2701952 workaround to Cortex-X2
+   CPU and affects system configurations that do not use an ARM interconnect IP.
+   This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 and is
+   still open.
+
 -  ``ERRATA_X2_2768515``: This applies errata 2768515 workaround to Cortex-X2
    CPU. This needs to be enabled for revisions r0p0, r1p0, r2p0 and r2p1 of the
    CPU and is still open.
@@ -709,6 +751,13 @@
    Cortex-A510 CPU. This needs to be applied to revision r0p0, r0p1, r0p2,
    r0p3, r1p0, r1p1 and r1p2. It is fixed in r1p3.
 
+For Cortex-A715, the following errata build flags are defined :
+
+-  ``ERRATA_A715_2701951``: This applies erratum 2701951 workaround to Cortex-A715
+   CPU and affects system configurations that do not use an ARM interconnect
+   IP. This needs to be applied to revisions r0p0, r1p0 and r1p1. It is fixed
+   in r1p2.
+
 DSU Errata Workarounds
 ----------------------
 
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 97f3550..2c9b76a 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -1759,6 +1759,10 @@
 
                    DRAM
     0xffffffff +----------+
+               | EL3 TZC  |
+    0xffe00000 |----------| (secure)
+               | AP TZC   |
+    0xff000000 +----------+
                :          :
     0x82100000 |----------|
                |HW_CONFIG |
@@ -1800,6 +1804,10 @@
 
                      DRAM
     0xffffffff +--------------+
+               |   EL3 TZC    |
+    0xffe00000 |--------------|  (secure)
+               |   AP TZC     |
+    0xff000000 +--------------+
                :              :
     0x82100000 |--------------|
                |  HW_CONFIG   |
@@ -1840,7 +1848,10 @@
 
                    DRAM
     0xffffffff +----------+
-               |  BL32    |  (secure)
+               |  EL3 TZC |
+    0xffe00000 |----------|  (secure)
+               |  AP TZC  |
+               |  (BL32)  |
     0xff000000 +----------+
                |          |
     0x82100000 |----------|
@@ -1880,6 +1891,20 @@
 
 ::
 
+                  DRAM
+    0xFFFFFFFF +----------+
+               |  SCP TZC |
+    0xFFE00000 |----------|
+               |  EL3 TZC |
+    0xFFC00000 |----------|  (secure)
+               |  AP TZC  |
+    0xFF000000 +----------+
+               |          |
+               :          :  (non-secure)
+               |          |
+    0x80000000 +----------+
+
+
                   Flash0
     0x0C000000 +----------+
                :          :
@@ -1909,9 +1934,14 @@
 ::
 
                    DRAM
-    0xFFE00000 +----------+
-               |  BL32    |  (secure)
-    0xFF000000 |----------|
+    0xFFFFFFFF +----------+
+               |  SCP TZC |
+    0xFFE00000 |----------|
+               |  EL3 TZC |
+    0xFFC00000 |----------|  (secure)
+               |  AP TZC  |
+               |  (BL32)  |
+    0xFF000000 +----------+
                |          |
                :          :  (non-secure)
                |          |
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 3694b1c..4eafb39 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -436,7 +436,8 @@
    (SME), SVE, and FPU/SIMD for the non-secure world only. These features share
    registers so are enabled together. Using this option without
    ENABLE_SME_FOR_SWD=1 will cause SME, SVE, and FPU/SIMD instructions in secure
-   world to trap to EL3. SME is an optional architectural feature for AArch64
+   world to trap to EL3. Requires ``ENABLE_SVE_FOR_NS`` to be set as SME is a
+   superset of SVE. SME is an optional architectural feature for AArch64
    and TF-A support is experimental. At this time, this build option cannot be
    used on systems that have SPD=spmd/SPM_MM or ENABLE_RME, and attempting to
    build with these options will fail. This flag can take the values 0 to 2, to
@@ -450,10 +451,9 @@
    align with the ``FEATURE_DETECTION`` mechanism. Default is 0.
 
 -  ``ENABLE_SME_FOR_SWD``: Boolean option to enable the Scalable Matrix
-   Extension for secure world use along with SVE and FPU/SIMD, ENABLE_SME_FOR_NS
-   must also be set to use this. If enabling this, the secure world MUST
-   handle context switching for SME, SVE, and FPU/SIMD registers to ensure that
-   no data is leaked to non-secure world. This is experimental. Default is 0.
+   Extension for secure world. Used along with SVE and FPU/SIMD.
+   ENABLE_SME_FOR_NS and ENABLE_SVE_FOR_SWD must also be set to use this.
+   This is experimental. Default is 0.
 
 -  ``ENABLE_SPE_FOR_NS`` : Numeric value to enable Statistical Profiling
    extensions. This is an optional architectural feature for AArch64.
@@ -469,17 +469,15 @@
    This is to avoid corruption of the Non-secure world data in the Z-registers
    which are aliased by the SIMD and FP registers. The build option is not
    compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
-   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` enabled.
-   This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
-   mechanism. The default is 2 but is automatically disabled when
-   ENABLE_SME_FOR_NS is enabled ( set to 1 or 2) since SME encompasses SVE.
-   At this time, this build option cannot be used on systems that have SPM_MM
-   enabled.
+   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS``
+   enabled.  This flag can take the values 0 to 2, to align with the
+   ``FEATURE_DETECTION`` mechanism. At this time, this build option cannot be
+   used on systems that have SPM_MM enabled. The default is 1.
 
 -  ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world.
    SVE is an optional architectural feature for AArch64. Note that this option
-   requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it
-   is automatically disabled when the target architecture is AArch32.
+   requires ENABLE_SVE_FOR_NS to be enabled. The default is 0 and it is
+   automatically disabled when the target architecture is AArch32.
 
 -  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
    checks in GCC. Allowed values are "all", "strong", "default" and "none". The
@@ -1131,6 +1129,13 @@
   means platform hook won't be checked and CMOs will always be performed when
   related functions are called.
 
+- ``ERRATA_ABI_SUPPORT``: Boolean option to enable support for Errata management
+  firmware interface for the BL31 image. By default its disabled (``0``).
+
+- ``ERRATA_NON_ARM_INTERCONNECT``: Boolean option to enable support for the
+  errata mitigation for platforms with a non-arm interconnect using the errata
+  ABI. By default its disabled (``0``).
+
 GICv3 driver options
 --------------------
 
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index 9428fe9..80012e7 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -69,3 +69,4 @@
 .. |UEFI| replace:: :term:`UEFI`
 .. |WDOG| replace:: :term:`WDOG`
 .. |XLAT| replace:: :term:`XLAT`
+.. |ERRATA_ABI| replace:: :term:`ERRATA_ABI`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 12c6ab7..58b7d99 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -70,6 +70,9 @@
    EHF
       Exception Handling Framework
 
+   ERRATA_ABI
+      Errata management firmware interface
+
    FCONF
       Firmware Configuration Framework
 
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 168d0eb..2c74800 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -330,6 +330,8 @@
 	/* Enable Group1 Secure interrupts */
 	write_icc_igrpen1_el3(read_icc_igrpen1_el3() |
 				IGRPEN1_EL3_ENABLE_G1S_BIT);
+	/* and restore the original */
+	write_scr_el3(scr_el3);
 	isb();
 	/* Add DSB to ensure visibility of System register writes */
 	dsb();
diff --git a/drivers/io/io_dummy.c b/drivers/io/io_dummy.c
deleted file mode 100644
index 4f0cda6..0000000
--- a/drivers/io/io_dummy.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <common/debug.h>
-#include <drivers/io/io_driver.h>
-#include <drivers/io/io_dummy.h>
-#include <drivers/io/io_storage.h>
-
-struct file_state {
-	int in_use;
-	size_t size;
-};
-
-static struct file_state current_file = {0};
-
-/* Identify the device type as dummy */
-static io_type_t device_type_dummy(void)
-{
-	return IO_TYPE_DUMMY;
-}
-
-/* Dummy device functions */
-static int dummy_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
-static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
-			     io_entity_t *entity);
-static int dummy_block_len(io_entity_t *entity, size_t *length);
-static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
-			     size_t length, size_t *length_read);
-static int dummy_block_close(io_entity_t *entity);
-static int dummy_dev_close(io_dev_info_t *dev_info);
-
-
-static const io_dev_connector_t dummy_dev_connector = {
-	.dev_open = dummy_dev_open
-};
-
-
-static const io_dev_funcs_t dummy_dev_funcs = {
-	.type = device_type_dummy,
-	.open = dummy_block_open,
-	.seek = NULL,
-	.size = dummy_block_len,
-	.read = dummy_block_read,
-	.write = NULL,
-	.close = dummy_block_close,
-	.dev_init = NULL,
-	.dev_close = dummy_dev_close,
-};
-
-
-static const io_dev_info_t dummy_dev_info = {
-	.funcs = &dummy_dev_funcs,
-	.info = (uintptr_t)NULL
-};
-
-
-/* Open a connection to the dummy device */
-static int dummy_dev_open(const uintptr_t dev_spec __attribute__((unused)),
-			   io_dev_info_t **dev_info)
-{
-	assert(dev_info != NULL);
-	*dev_info = (io_dev_info_t *)&dummy_dev_info;
-
-	return 0;
-}
-
-
-/* Close a connection to the dummy device */
-static int dummy_dev_close(io_dev_info_t *dev_info)
-{
-	return 0;
-}
-
-
-/* Open a file on the dummy device */
-static int dummy_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
-			     io_entity_t *entity)
-{
-	int result;
-	const io_block_spec_t *block_spec = (io_block_spec_t *)spec;
-
-	if (current_file.in_use == 0) {
-		assert(block_spec != NULL);
-		assert(entity != NULL);
-
-		current_file.in_use = 1;
-		current_file.size = block_spec->length;
-		entity->info = (uintptr_t)&current_file;
-		result = 0;
-	} else {
-		WARN("A Dummy device is already active. Close first.\n");
-		result = -ENOMEM;
-	}
-
-	return result;
-}
-
-
-/* Return the size of a file on the dummy device */
-static int dummy_block_len(io_entity_t *entity, size_t *length)
-{
-	assert(entity != NULL);
-	assert(length != NULL);
-
-	*length =  ((struct file_state *)entity->info)->size;
-
-	return 0;
-}
-
-
-/* Read data from a file on the dummy device */
-static int dummy_block_read(io_entity_t *entity, uintptr_t buffer,
-			     size_t length, size_t *length_read)
-{
-	assert(length_read != NULL);
-
-	*length_read = length;
-
-	return 0;
-}
-
-
-/* Close a file on the dummy device */
-static int dummy_block_close(io_entity_t *entity)
-{
-	assert(entity != NULL);
-
-	entity->info = 0;
-	current_file.in_use = 0;
-
-	return 0;
-}
-
-
-/* Exported functions */
-
-/* Register the dummy driver with the IO abstraction */
-int register_io_dev_dummy(const io_dev_connector_t **dev_con)
-{
-	int result;
-
-	assert(dev_con != NULL);
-
-	result = io_register_device(&dummy_dev_info);
-	if (result == 0)
-		*dev_con = &dummy_dev_connector;
-
-	return result;
-}
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index 8678bf3..3691497 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.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
  */
@@ -16,8 +16,10 @@
 #define MIDR_IMPL_SHIFT		U(24)
 #define MIDR_VAR_SHIFT		U(20)
 #define MIDR_VAR_BITS		U(4)
+#define MIDR_VAR_MASK		U(0xf)
 #define MIDR_REV_SHIFT		U(0)
 #define MIDR_REV_BITS		U(4)
+#define MIDR_REV_MASK		U(0xf)
 #define MIDR_PN_MASK		U(0xfff)
 #define MIDR_PN_SHIFT		U(4)
 
diff --git a/include/drivers/io/io_dummy.h b/include/drivers/io/io_dummy.h
deleted file mode 100644
index edfc699..0000000
--- a/include/drivers/io/io_dummy.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef IO_DUMMY_H
-#define IO_DUMMY_H
-
-int register_io_dev_dummy(const struct io_dev_connector **dev_con);
-
-#endif /* IO_DUMMY_H */
diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h
index 8f30ed0..3179383 100644
--- a/include/drivers/io/io_storage.h
+++ b/include/drivers/io/io_storage.h
@@ -19,7 +19,6 @@
 	IO_TYPE_INVALID,
 	IO_TYPE_SEMIHOSTING,
 	IO_TYPE_MEMMAP,
-	IO_TYPE_DUMMY,
 	IO_TYPE_FIRMWARE_IMAGE_PACKAGE,
 	IO_TYPE_BLOCK,
 	IO_TYPE_MTD,
diff --git a/include/services/errata_abi_svc.h b/include/services/errata_abi_svc.h
new file mode 100644
index 0000000..1250066
--- /dev/null
+++ b/include/services/errata_abi_svc.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ERRATA_ABI_SVC_H
+#define ERRATA_ABI_SVC_H
+
+#include <lib/smccc.h>
+
+#define ARM_EM_VERSION			U(0x840000F0)
+#define ARM_EM_FEATURES			U(0x840000F1)
+#define ARM_EM_CPU_ERRATUM_FEATURES	U(0x840000F2)
+
+/* EM version numbers */
+#define EM_VERSION_MAJOR		(0x1)
+#define EM_VERSION_MINOR		(0x0)
+
+/* EM CPU_ERRATUM_FEATURES return codes */
+#define EM_HIGHER_EL_MITIGATION		(3)
+#define EM_NOT_AFFECTED			(2)
+#define EM_AFFECTED			(1)
+#define EM_SUCCESS			(0)
+#define EM_NOT_SUPPORTED		(-1)
+#define EM_INVALID_PARAMETERS		(-2)
+#define EM_UNKNOWN_ERRATUM		(-3)
+
+#if ERRATA_ABI_SUPPORT
+bool is_errata_fid(uint32_t smc_fid);
+#else
+static inline bool is_errata_fid(uint32_t smc_fid)
+{
+	return false;
+}
+#endif /* ERRATA_ABI_SUPPORT */
+uintptr_t errata_abi_smc_handler(
+	uint32_t smc_fid,
+	u_register_t x1,
+	u_register_t x2,
+	u_register_t x3,
+	u_register_t x4,
+	void *cookie,
+	void *handle,
+	u_register_t flags
+);
+#endif /* ERRATA_ABI_SVC_H */
+
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 82a4890..e16c8e4 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -324,6 +324,11 @@
 # to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open.
 CPU_FLAG_LIST += ERRATA_A78_2395406
 
+# Flag to apply erratum 2712571 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu.
+# It is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_A78_2712571
+
 # Flag to apply erratum 2742426 workaround during reset. This erratum
 # applies to revisions r0p0, r1p0, r1p1 and r1p2 of the A78 cpu. It is still
 # open.
@@ -362,6 +367,11 @@
 # to revision r0p0 of the A78C cpu. It is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_A78C_1827440
 
+# Flag to apply erratum 2712574 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p0, r0p1 and r0p2 of the A78 AE cpu.
+# It is still open.
+CPU_FLAG_LIST += ERRATA_A78_AE_2712574
+
 # Flag to apply erratum 2132064 workaround during reset. This erratum applies
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
 CPU_FLAG_LIST += ERRATA_A78C_2132064
@@ -378,6 +388,11 @@
 # to revisions r0p1 and r0p2 of the A78C cpu. It is still open.
 CPU_FLAG_LIST += ERRATA_A78C_2395411
 
+# Flag to apply erratum 2712575 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p1 and r0p2 of the A78C cpu.
+# It is still open.
+CPU_FLAG_LIST += ERRATA_A78C_2712575
+
 # Flag to apply erratum 2772121 workaround during powerdown. This erratum
 # applies to revisions r0p0, r0p1 and r0p2 of the A78C cpu. It is still open.
 CPU_FLAG_LIST += ERRATA_A78C_2772121
@@ -509,6 +524,11 @@
 # to revisions r0p0, r1p0 and r1p1 of the Neoverse V1 cpu and is still open.
 CPU_FLAG_LIST += ERRATA_V1_2372203
 
+# Flag to apply erratum 2701953 workaround to non-arm interconnect ip. This
+# erratum applies to revisions r0p0, r1p0, r1p1 of the Neoverse V1 cpu,
+# it is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_V1_2701953
+
 # Flag to apply erratum 2743093 workaround during powerdown. This erratum
 # applies to revisions r0p0, r1p0, r1p1 and r1p2  of the Neoverse V1 cpu and is
 # still open.
@@ -581,6 +601,11 @@
 # to revision r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is fixed in r2p1.
 CPU_FLAG_LIST += ERRATA_A710_2371105
 
+# Flag to apply erratum 2701952 workaround for non-arm interconnect ip. This
+# erratum applies to revision r0p0, r1p0, r2p0, r2p1 of the Cortex-A710 cpu
+# and is still open.
+CPU_FLAG_LIST += ERRATA_A710_2701952
+
 # Flag to apply erratum 2768515 workaround during power down. This erratum
 # applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-A710 cpu and is
 # still open.
@@ -638,6 +663,11 @@
 # to revision r0p0 of the Neoverse N2 cpu, it is fixed in r0p1.
 CPU_FLAG_LIST += ERRATA_N2_2388450
 
+# Flag to apply erratum 2728475 workaround for non-arm interconnect ip. This
+# erratum applies to r0p0, r0p1, r0p2 of the Neoverse N2 cpu, it is fixed in
+# r0p3.
+CPU_FLAG_LIST += ERRATA_N2_2728475
+
 # Flag to apply erratum 2743089 workaround during during powerdown. This erratum
 # applies to all revisions <= r0p2 of the Neoverse N2 cpu, it is fixed in r0p3.
 CPU_FLAG_LIST += ERRATA_N2_2743089
@@ -682,6 +712,11 @@
 # to revision r0p0, r1p0 and r2p0 of the Cortex-X2 cpu and is fixed in r2p1.
 CPU_FLAG_LIST += ERRATA_X2_2371105
 
+# Flag to apply erratum 2701952 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p0, r1p0, r2p0, r2p1 of the Cortex-x2 cpu
+# and is still open.
+CPU_FLAG_LIST += ERRATA_X2_2701952
+
 # Flag to apply erratum 2768515 workaround during power down. This erratum
 # applies to revision r0p0, r1p0, r2p0 and r2p1 of the Cortex-X2 cpu and is
 # still open.
@@ -743,6 +778,14 @@
 # Cortex-A510 cpu and is fixed in r1p3.
 CPU_FLAG_LIST += ERRATA_A510_2684597
 
+# Flag to apply erratum 2719103 workaround for non-arm interconnect ip. This
+# erratum applies to revisions r0p0, rop1. Fixed in r0p2.
+CPU_FLAG_LIST += ERRATA_V2_2719103
+
+# Flag to apply erratum 2701951 workaround for non-arm interconnect ip.
+# This erratum applies to revisions r0p0, r1p0, and r1p1. Its is fixed in r1p2.
+CPU_FLAG_LIST += ERRATA_A715_2701951
+
 # Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0.
 # Applying the workaround results in higher DSU power consumption on idle.
 CPU_FLAG_LIST += ERRATA_DSU_798953
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index e107f5a..2a9bb59 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -517,12 +517,13 @@
 		amu_enable(el2_unused, ctx);
 	}
 
-	/* Enable SME, SVE, and FPU/SIMD for non-secure world. */
+	/* Enable SVE and FPU/SIMD */
+	if (is_feat_sve_supported()) {
+		sve_enable(ctx);
+	}
+
 	if (is_feat_sme_supported()) {
 		sme_enable(ctx);
-	} else if (is_feat_sve_supported()) {
-		/* Enable SVE and FPU/SIMD for non-secure world. */
-		sve_enable(ctx);
 	}
 
 	if (is_feat_mpam_supported()) {
@@ -553,22 +554,7 @@
 static void manage_extensions_secure(cpu_context_t *ctx)
 {
 #if IMAGE_BL31
-
-	if (is_feat_sme_supported()) {
-		if (ENABLE_SME_FOR_SWD) {
-		/*
-		 * Enable SME, SVE, FPU/SIMD in secure context, secure manager
-		 * must ensure SME, SVE, and FPU/SIMD context properly managed.
-		 */
-			sme_enable(ctx);
-		} else {
-		/*
-		 * Disable SME, SVE, FPU/SIMD in secure context so non-secure
-		 * world can safely use the associated registers.
-		 */
-			sme_disable(ctx);
-		}
-	} else if (is_feat_sve_supported()) {
+	if (is_feat_sve_supported()) {
 		if (ENABLE_SVE_FOR_SWD) {
 		/*
 		 * Enable SVE and FPU in secure context, secure manager must
@@ -585,6 +571,21 @@
 		}
 	}
 
+	if (is_feat_sme_supported()) {
+		if (ENABLE_SME_FOR_SWD) {
+		/*
+		 * Enable SME, SVE, FPU/SIMD in secure context, secure manager
+		 * must ensure SME, SVE, and FPU/SIMD context properly managed.
+		 */
+			sme_enable(ctx);
+		} else {
+		/*
+		 * Disable SME, SVE, FPU/SIMD in secure context so non-secure
+		 * world can safely use the associated registers.
+		 */
+			sme_disable(ctx);
+		}
+	}
 #endif /* IMAGE_BL31 */
 }
 
diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c
index f888d12..3423dba 100644
--- a/lib/extensions/sme/sme.c
+++ b/lib/extensions/sme/sme.c
@@ -65,9 +65,6 @@
 	/* Reset CPTR_EL3 value. */
 	write_cptr_el3(cptr_el3);
 	isb();
-
-	/* Enable SVE/FPU in addition to SME. */
-	sve_enable(context);
 }
 
 void sme_disable(cpu_context_t *context)
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index fd9ad92..f9077eb 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -292,6 +292,12 @@
 # True Random Number firmware Interface support
 TRNG_SUPPORT			:= 0
 
+# Check to see if Errata ABI is supported
+ERRATA_ABI_SUPPORT		:= 0
+
+# Check to enable Errata ABI for platforms with non-arm interconnect
+ERRATA_NON_ARM_INTERCONNECT	:= 0
+
 # SMCCC PCI support
 SMC_PCI_SUPPORT			:= 0
 
@@ -402,14 +408,6 @@
 # SME defaults to disabled
 ENABLE_SME_FOR_NS		:= 0
 ENABLE_SME_FOR_SWD		:= 0
-
-# If SME is enabled then force SVE off
-ifneq (${ENABLE_SME_FOR_NS},0)
-	override ENABLE_SVE_FOR_NS	:= 0
-	override ENABLE_SVE_FOR_SWD	:= 0
-endif
-
-# SME2 defaults to disabled
 ENABLE_SME2_FOR_NS		:= 0
 
 SANITIZE_UB := off
diff --git a/plat/arm/board/fvp/fvp_cpu_errata.mk b/plat/arm/board/fvp/fvp_cpu_errata.mk
new file mode 100644
index 0000000..944571d
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_cpu_errata.mk
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+#/*
+# * TODO: below lines of code to be removed
+# * after abi and framework are synchronized
+# */
+
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+# enable the cpu macros for errata abi interface
+ifeq (${ARCH}, aarch64)
+ifeq (${HW_ASSISTED_COHERENCY}, 0)
+CORTEX_A35_H_INC	:= 1
+CORTEX_A53_H_INC	:= 1
+CORTEX_A57_H_INC	:= 1
+CORTEX_A72_H_INC	:= 1
+CORTEX_A73_H_INC	:= 1
+$(eval $(call add_define, CORTEX_A35_H_INC))
+$(eval $(call add_define, CORTEX_A53_H_INC))
+$(eval $(call add_define, CORTEX_A57_H_INC))
+$(eval $(call add_define, CORTEX_A72_H_INC))
+$(eval $(call add_define, CORTEX_A73_H_INC))
+else
+ifeq (${CTX_INCLUDE_AARCH32_REGS}, 0)
+CORTEX_A76_H_INC	:= 1
+CORTEX_A77_H_INC	:= 1
+CORTEX_A78_H_INC	:= 1
+NEOVERSE_N1_H_INC	:= 1
+NEOVERSE_V1_H_INC	:= 1
+CORTEX_A78_AE_H_INC	:= 1
+CORTEX_A510_H_INC	:= 1
+CORTEX_A710_H_INC	:= 1
+CORTEX_A715_H_INC 	:= 1
+CORTEX_A78C_H_INC	:= 1
+CORTEX_X2_H_INC		:= 1
+$(eval $(call add_define, CORTEX_A76_H_INC))
+$(eval $(call add_define, CORTEX_A77_H_INC))
+$(eval $(call add_define, CORTEX_A78_H_INC))
+$(eval $(call add_define, NEOVERSE_N1_H_INC))
+$(eval $(call add_define, NEOVERSE_V1_H_INC))
+$(eval $(call add_define, CORTEX_A78_AE_H_INC))
+$(eval $(call add_define, CORTEX_A510_H_INC))
+$(eval $(call add_define, CORTEX_A710_H_INC))
+$(eval $(call add_define, CORTEX_A715_H_INC))
+$(eval $(call add_define, CORTEX_A78C_H_INC))
+$(eval $(call add_define, CORTEX_X2_H_INC))
+endif
+CORTEX_A55_H_INC	:= 1
+CORTEX_A75_H_INC	:= 1
+$(eval $(call add_define, CORTEX_A55_H_INC))
+$(eval $(call add_define, CORTEX_A75_H_INC))
+endif
+else
+CORTEX_A32_H_INC	:= 1
+$(eval $(call add_define, CORTEX_A32_H_INC))
+endif
+endif
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 8a6aa00..0433b61 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -525,3 +525,7 @@
          $(error "PLATFORM_TEST_RAS_FFH expects RAS_EXTENSION to be 1")
     endif
 endif
+
+ifeq (${ERRATA_ABI_SUPPORT}, 1)
+include plat/arm/board/fvp/fvp_cpu_errata.mk
+endif
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
index 0b792ab..c8a2d4c 100644
--- a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_bus26m.c
@@ -53,6 +53,7 @@
 static struct mt_irqremain *refer2remain_irq;
 
 static struct mt_spm_cond_tables cond_bus26m = {
+	.name = "bus26m",
 	.table_cg = {
 		0xFF5DD002,	/* MTCMOS1 */
 		0x0000003C,	/* MTCMOS2 */
@@ -175,7 +176,7 @@
 		(IS_PLAT_SUSPEND_ID(state_id) || (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
 }
 
-static int update_rc_condition(const void *val)
+static int update_rc_condition(int state_id, const void *val)
 {
 	const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val;
 	const struct mt_spm_cond_tables *tlb_check =
@@ -185,7 +186,7 @@
 		return MT_RM_STATUS_BAD;
 	}
 
-	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+	status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check,
 						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
 						 &cond_bus26m_res : NULL);
 	status.all_pll_dump = mt_spm_dump_all_pll(tlb, tlb_check,
@@ -279,7 +280,7 @@
 
 	switch (type) {
 	case PLAT_RC_UPDATE_CONDITION:
-		res = update_rc_condition(val);
+		res = update_rc_condition(state_id, val);
 		break;
 	case PLAT_RC_UPDATE_REMAIN_IRQS:
 		update_rc_remain_irqs(val);
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
index d1a2435..82b38ad 100644
--- a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_dram.c
@@ -37,6 +37,7 @@
 #define CONSTRAINT_DRAM_RESOURCE_REQ (MT_SPM_SYSPLL | MT_SPM_INFRA | MT_SPM_26M)
 
 static struct mt_spm_cond_tables cond_dram = {
+	.name = "dram",
 	.table_cg = {
 		0xFF5DD002,	/* MTCMOS1 */
 		0x0000003C,	/* MTCMOS2 */
@@ -104,7 +105,7 @@
 		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
 }
 
-static int update_rc_condition(const void *val)
+static int update_rc_condition(int state_id, const void *val)
 {
 	const struct mt_spm_cond_tables *tlb = (const struct mt_spm_cond_tables *)val;
 	const struct mt_spm_cond_tables *tlb_check = (const struct mt_spm_cond_tables *)&cond_dram;
@@ -113,7 +114,7 @@
 		return MT_RM_STATUS_BAD;
 	}
 
-	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+	status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check,
 						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
 						  &cond_dram_res : NULL);
 	return MT_RM_STATUS_OK;
@@ -185,7 +186,7 @@
 
 	switch (type) {
 	case PLAT_RC_UPDATE_CONDITION:
-		res = update_rc_condition(val);
+		res = update_rc_condition(state_id, val);
 		break;
 	case PLAT_RC_CLKBUF_STATUS:
 		update_rc_clkbuf_status(val);
diff --git a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
index 700f500..5359c7c 100644
--- a/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
+++ b/plat/mediatek/drivers/spm/mt8188/constraints/mt_spm_rc_syspll.c
@@ -49,6 +49,7 @@
 static unsigned short ext_status_syspll;
 
 static struct mt_spm_cond_tables cond_syspll = {
+	.name = "syspll",
 	.table_cg = {
 		0xFF5DD002,	/* MTCMOS1 */
 		0x0000003C,	/* MTCMOS2 */
@@ -113,7 +114,7 @@
 		 (state_id == MT_PLAT_PWR_STATE_SYSTEM_BUS)));
 }
 
-static int update_rc_condition(const void *val)
+static int update_rc_condition(int state_id, const void *val)
 {
 	int res = MT_RM_STATUS_OK;
 
@@ -126,7 +127,7 @@
 		return MT_RM_STATUS_BAD;
 	}
 
-	status.is_cond_block = mt_spm_cond_check(tlb, tlb_check,
+	status.is_cond_block = mt_spm_cond_check(state_id, tlb, tlb_check,
 						 (status.is_valid & MT_SPM_RC_VALID_COND_LATCH) ?
 						 &cond_syspll_res : NULL);
 	return res;
@@ -228,7 +229,7 @@
 
 	switch (type) {
 	case PLAT_RC_UPDATE_CONDITION:
-		res = update_rc_condition(val);
+		res = update_rc_condition(state_id, val);
 		break;
 	case PLAT_RC_CLKBUF_STATUS:
 		update_rc_clkbuf_status(val);
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
index fe6e598..bed55c9 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.c
@@ -126,12 +126,14 @@
 #define PLL_APLL4	MT_LP_TZ_APMIXEDSYS(0x404)
 #define PLL_APLL5	MT_LP_TZ_APMIXEDSYS(0x418)
 
-unsigned int mt_spm_cond_check(const struct mt_spm_cond_tables *src,
+unsigned int mt_spm_cond_check(int state_id,
+			       const struct mt_spm_cond_tables *src,
 			       const struct mt_spm_cond_tables *dest,
 			       struct mt_spm_cond_tables *res)
 {
 	unsigned int b_res = 0U;
 	unsigned int i;
+	bool is_system_suspend = IS_PLAT_SUSPEND_ID(state_id);
 
 	if ((src == NULL) || (dest == NULL)) {
 		return SPM_COND_CHECK_FAIL;
@@ -140,6 +142,11 @@
 	for (i = 0; i < PLAT_SPM_COND_MAX; i++) {
 		if (res != NULL) {
 			res->table_cg[i] = (src->table_cg[i] & dest->table_cg[i]);
+			if (is_system_suspend && ((res->table_cg[i]) != 0U)) {
+				INFO("suspend: %s block[%u](0x%lx) = 0x%08x\n",
+				     dest->name, i, idle_cg_info[i].addr,
+				     res->table_cg[i]);
+			}
 
 			if ((res->table_cg[i]) != 0U) {
 				b_res |= BIT(i);
@@ -161,6 +168,10 @@
 		b_res |= SPM_COND_CHECK_BLOCKED_PLL;
 	}
 
+	if (is_system_suspend && ((b_res) != 0U)) {
+		INFO("suspend: %s total blocked = 0x%08x\n", dest->name, b_res);
+	}
+
 	return b_res;
 }
 
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
index 793d5e8..d93df57 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_cond.h
@@ -75,13 +75,15 @@
 #define SPM_COND_CHECK_FAIL		BIT(31)
 
 struct mt_spm_cond_tables {
+	char *name;
 	unsigned int table_cg[PLAT_SPM_COND_MAX];
 	unsigned int table_pll;
 	unsigned int table_all_pll;
 	void *priv;
 };
 
-unsigned int mt_spm_cond_check(const struct mt_spm_cond_tables *src,
+unsigned int mt_spm_cond_check(int state_id,
+			       const struct mt_spm_cond_tables *src,
 			       const struct mt_spm_cond_tables *dest,
 			       struct mt_spm_cond_tables *res);
 unsigned int mt_spm_dump_all_pll(const struct mt_spm_cond_tables *src,
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
index bcb2df6..395448a 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_conservation.c
@@ -61,6 +61,14 @@
 
 	__spm_send_cpu_wakeup_event();
 
+	INFO("cpu%d: wakesrc = 0x%x, settle = 0x%x, sec = %u\n",
+	     cpu, pwrctrl->wake_src, mmio_read_32(SPM_CLK_SETTLE),
+	     (mmio_read_32(PCM_TIMER_VAL) / 32768));
+	INFO("sw_flag = 0x%x 0x%x, req = 0x%x, pwr = 0x%x 0x%x\n",
+	     pwrctrl->pcm_flags, pwrctrl->pcm_flags1,
+	     mmio_read_32(SPM_SRC_REQ), mmio_read_32(PWR_STATUS),
+	     mmio_read_32(PWR_STATUS_2ND));
+
 	return ret;
 }
 
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
index b38a6d0..5eb16b3 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.c
@@ -24,6 +24,7 @@
 
 wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta)
 {
+	uint32_t bk_vtcxo_dur, spm_26m_off_pct;
 	wake_reason_t wr = WR_UNKNOWN;
 
 	if (wakesta == NULL) {
@@ -46,6 +47,33 @@
 		}
 	}
 
+	INFO("r12 = 0x%x, r12_ext = 0x%x, r13 = 0x%x, debug_flag = 0x%x 0x%x\n",
+	     wakesta->tr.comm.r12, wakesta->r12_ext, wakesta->tr.comm.r13, wakesta->tr.comm.debug_flag,
+	     wakesta->tr.comm.debug_flag1);
+	INFO("raw_sta = 0x%x 0x%x 0x%x, idle_sta = 0x%x, cg_check_sta = 0x%x\n",
+	     wakesta->tr.comm.raw_sta, wakesta->md32pcm_wakeup_sta,
+	     wakesta->md32pcm_event_sta, wakesta->idle_sta,
+	     wakesta->cg_check_sta);
+	INFO("req_sta = 0x%x 0x%x 0x%x 0x%x 0x%x, isr = 0x%x\n",
+	     wakesta->tr.comm.req_sta0, wakesta->tr.comm.req_sta1, wakesta->tr.comm.req_sta2,
+	     wakesta->tr.comm.req_sta3, wakesta->tr.comm.req_sta4, wakesta->isr);
+	INFO("rt_req_sta0 = 0x%x, rt_req_sta1 = 0x%x, rt_req_sta2 = 0x%x\n",
+	     wakesta->rt_req_sta0, wakesta->rt_req_sta1, wakesta->rt_req_sta2);
+	INFO("rt_req_sta3 = 0x%x, dram_sw_con_3 = 0x%x, raw_ext_sta = 0x%x\n",
+	     wakesta->rt_req_sta3, wakesta->rt_req_sta4, wakesta->raw_ext_sta);
+	INFO("wake_misc = 0x%x, pcm_flag = 0x%x 0x%x 0x%x 0x%x, req = 0x%x\n",
+	     wakesta->wake_misc, wakesta->sw_flag0, wakesta->sw_flag1,
+	     wakesta->tr.comm.b_sw_flag0, wakesta->tr.comm.b_sw_flag1, wakesta->src_req);
+	INFO("clk_settle = 0x%x, wlk_cntcv_l = 0x%x, wlk_cntcv_h = 0x%x\n",
+	     wakesta->clk_settle, mmio_read_32(SYS_TIMER_VALUE_L),
+	     mmio_read_32(SYS_TIMER_VALUE_H));
+
+	if (wakesta->tr.comm.timer_out != 0U) {
+		bk_vtcxo_dur = mmio_read_32(SPM_BK_VTCXO_DUR);
+		spm_26m_off_pct = (100 * bk_vtcxo_dur) / wakesta->tr.comm.timer_out;
+		INFO("spm_26m_off_pct = %u\n", spm_26m_off_pct);
+	}
+
 	return wr;
 }
 
@@ -331,6 +359,18 @@
 	wakesta->tr.comm.b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7);	/* SPM_SW_RSV_7 */
 	wakesta->tr.comm.b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8);	/* SPM_SW_RSV_8 */
 
+	/* record below spm info for debug */
+	wakesta->src_req = mmio_read_32(SPM_SRC_REQ);
+
+	/* get HW CG check status */
+	wakesta->cg_check_sta = mmio_read_32(SPM_CG_CHECK_STA);
+
+	wakesta->rt_req_sta0 = mmio_read_32(SPM_SW_RSV_2);
+	wakesta->rt_req_sta1 = mmio_read_32(SPM_SW_RSV_3);
+	wakesta->rt_req_sta2 = mmio_read_32(SPM_SW_RSV_4);
+	wakesta->rt_req_sta3 = mmio_read_32(SPM_SW_RSV_5);
+	wakesta->rt_req_sta4 = mmio_read_32(SPM_SW_RSV_6);
+
 	/* get ISR status */
 	wakesta->isr = mmio_read_32(SPM_IRQ_STA);
 
@@ -338,6 +378,9 @@
 	wakesta->sw_flag0 = mmio_read_32(SPM_SW_FLAG_0);
 	wakesta->sw_flag1 = mmio_read_32(SPM_SW_FLAG_1);
 
+	/* get CLK SETTLE */
+	wakesta->clk_settle = mmio_read_32(SPM_CLK_SETTLE);
+
 	/* check abort */
 	wakesta->is_abort = wakesta->tr.comm.debug_flag & DEBUG_ABORT_MASK;
 	wakesta->is_abort |= wakesta->tr.comm.debug_flag1 & DEBUG_ABORT_MASK_1;
diff --git a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
index c719caf..5e3390f 100644
--- a/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
+++ b/plat/mediatek/drivers/spm/mt8188/mt_spm_internal.h
@@ -628,11 +628,19 @@
 	uint32_t md32pcm_event_sta;	/* MD32PCM_EVENT_STA */
 	uint32_t wake_misc;		/* SPM_SW_RSV_5 */
 	uint32_t idle_sta;		/* SUBSYS_IDLE_STA */
+	uint32_t cg_check_sta;		/* SPM_CG_CHECK_STA */
 	uint32_t sw_flag0;		/* SPM_SW_FLAG_0 */
 	uint32_t sw_flag1;		/* SPM_SW_FLAG_1 */
 	uint32_t isr;			/* SPM_IRQ_STA */
+	uint32_t clk_settle;		/* SPM_CLK_SETTLE */
+	uint32_t src_req;		/* SPM_SRC_REQ */
 	uint32_t log_index;
 	uint32_t is_abort;
+	uint32_t rt_req_sta0;		/* SPM_SW_RSV_2 */
+	uint32_t rt_req_sta1;		/* SPM_SW_RSV_3 */
+	uint32_t rt_req_sta2;		/* SPM_SW_RSV_4 */
+	uint32_t rt_req_sta3;		/* SPM_SW_RSV_5 */
+	uint32_t rt_req_sta4;		/* SPM_SW_RSV_6 */
 };
 
 struct spm_lp_scen {
diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk
index 7b3129c..8b8d76b 100644
--- a/plat/qemu/qemu_sbsa/platform.mk
+++ b/plat/qemu/qemu_sbsa/platform.mk
@@ -139,3 +139,6 @@
 # Later QEMU versions support SME and SVE.
 ENABLE_SVE_FOR_NS	:= 2
 ENABLE_SME_FOR_NS	:= 2
+
+# QEMU 7.2+ has support for FGT and Linux needs it enabled to boot on max
+ENABLE_FEAT_FGT 	:= 2
diff --git a/services/std_svc/errata_abi/cpu_errata_info.h b/services/std_svc/errata_abi/cpu_errata_info.h
new file mode 100644
index 0000000..671a694
--- /dev/null
+++ b/services/std_svc/errata_abi/cpu_errata_info.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ERRATA_CPUSPEC_H
+#define ERRATA_CPUSPEC_H
+
+#include <stdint.h>
+#include <arch_helpers.h>
+
+#if __aarch64__
+#include <cortex_a35.h>
+#include <cortex_a510.h>
+#include <cortex_a53.h>
+#include <cortex_a57.h>
+#include <cortex_a55.h>
+#include <cortex_a710.h>
+#include <cortex_a72.h>
+#include <cortex_a73.h>
+#include <cortex_a75.h>
+#include <cortex_a76.h>
+#include <cortex_a77.h>
+#include <cortex_a78.h>
+#include <cortex_a78_ae.h>
+#include <cortex_a78c.h>
+#include <cortex_makalu.h>
+#include <cortex_x1.h>
+#include <cortex_x2.h>
+#include <neoverse_n1.h>
+#include <neoverse_n2.h>
+#include <neoverse_v1.h>
+#include <neoverse_v2.h>
+#else
+#include <cortex_a15.h>
+#include <cortex_a17.h>
+#include <cortex_a57.h>
+#include <cortex_a9.h>
+#endif
+
+#define MAX_ERRATA_ENTRIES	16
+
+#define ERRATA_LIST_END		(MAX_ERRATA_ENTRIES - 1)
+
+/* Default values for unused memory in the array */
+#define UNDEF_ERRATA		{UINT_MAX, UCHAR_MAX, UCHAR_MAX, false, false}
+
+#define EXTRACT_PARTNUM(x)	((x >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+
+#define RXPX_RANGE(x, y, z)	(((x >= y) && (x <= z)) ? true : false)
+
+/*
+ * CPU specific values for errata handling
+ */
+struct em_cpu{
+	unsigned int em_errata_id;
+	unsigned char em_rxpx_lo;	/* lowest revision of errata applicable for the cpu */
+	unsigned char em_rxpx_hi;	/* highest revision of errata applicable for the cpu */
+	bool errata_enabled;		/* indicate if errata enabled */
+	/* flag to indicate if errata query is based out of non-arm interconnect */
+	bool non_arm_interconnect;
+};
+
+struct em_cpu_list{
+	/* field to hold cpu specific part number defined in midr reg */
+	unsigned long cpu_partnumber;
+	struct   em_cpu cpu_errata_list[MAX_ERRATA_ENTRIES];
+};
+
+int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag);
+#endif /* ERRATA_CPUSPEC_H */
diff --git a/services/std_svc/errata_abi/errata_abi_main.c b/services/std_svc/errata_abi/errata_abi_main.c
new file mode 100644
index 0000000..bf9409d
--- /dev/null
+++ b/services/std_svc/errata_abi/errata_abi_main.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include "cpu_errata_info.h"
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+#include <services/errata_abi_svc.h>
+#include <smccc_helpers.h>
+
+/*
+ * Global pointer that points to the specific
+ * structure based on the MIDR part number
+ */
+struct em_cpu_list *cpu_ptr;
+
+extern uint8_t cpu_get_rev_var(void);
+
+/* Structure array that holds CPU specific errata information */
+struct em_cpu_list cpu_list[] = {
+#if CORTEX_A9_H_INC
+{
+	.cpu_partnumber = CORTEX_A9_MIDR,
+	.cpu_errata_list = {
+		[0] = {794073, 0x00, 0xFF, ERRATA_A9_794073},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A9_H_INC */
+
+#if CORTEX_A15_H_INC
+{
+	.cpu_partnumber = CORTEX_A15_MIDR,
+	.cpu_errata_list = {
+		[0] = {816470, 0x30, 0xFF, ERRATA_A15_816470},
+		[1] = {827671, 0x30, 0xFF, ERRATA_A15_827671},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A15_H_INC */
+
+#if CORTEX_A17_H_INC
+{
+	.cpu_partnumber = CORTEX_A17_MIDR,
+	.cpu_errata_list = {
+		[0] = {852421, 0x00, 0x12, ERRATA_A17_852421},
+		[1] = {852423, 0x00, 0x12, ERRATA_A17_852423},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A17_H_INC */
+
+#if CORTEX_A35_H_INC
+{
+	.cpu_partnumber = CORTEX_A35_MIDR,
+	.cpu_errata_list = {
+		[0] = {855472, 0x00, 0x00, ERRATA_A35_855472},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A35_H_INC */
+
+#if CORTEX_A53_H_INC
+{
+	.cpu_partnumber = CORTEX_A53_MIDR,
+	.cpu_errata_list = {
+		[0] = {819472, 0x00, 0x01, ERRATA_A53_819472},
+		[1] = {824069, 0x00, 0x02, ERRATA_A53_824069},
+		[2] = {826319, 0x00, 0x02, ERRATA_A53_826319},
+		[3] = {827319, 0x00, 0x02, ERRATA_A53_827319},
+		[4] = {835769, 0x00, 0x04, ERRATA_A53_835769},
+		[5] = {836870, 0x00, 0x03, ERRATA_A53_836870},
+		[6] = {843419, 0x00, 0x04, ERRATA_A53_843419},
+		[7] = {855873, 0x03, 0xFF, ERRATA_A53_855873},
+		[8] = {1530924, 0x00, 0xFF, ERRATA_A53_1530924},
+		[9 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A53_H_INC */
+
+#if CORTEX_A55_H_INC
+{
+	.cpu_partnumber = CORTEX_A55_MIDR,
+	.cpu_errata_list = {
+		[0] = {768277, 0x00, 0x00, ERRATA_A55_768277},
+		[1] = {778703, 0x00, 0x00, ERRATA_A55_778703},
+		[2] = {798797, 0x00, 0x00, ERRATA_A55_798797},
+		[3] = {846532, 0x00, 0x01, ERRATA_A55_846532},
+		[4] = {903758, 0x00, 0x01, ERRATA_A55_903758},
+		[5] = {1221012, 0x00, 0x10, ERRATA_A55_1221012},
+		[6] = {1530923, 0x00, 0xFF, ERRATA_A55_1530923},
+		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A55_H_INC */
+
+#if CORTEX_A57_H_INC
+{
+	.cpu_partnumber = CORTEX_A57_MIDR,
+	.cpu_errata_list = {
+		[0] = {806969, 0x00, 0x00, ERRATA_A57_806969},
+		[1] = {813419, 0x00, 0x00, ERRATA_A57_813419},
+		[2] = {813420, 0x00, 0x00, ERRATA_A57_813420},
+		[3] = {814670, 0x00, 0x00, ERRATA_A57_814670},
+		[4] = {817169, 0x00, 0x01, ERRATA_A57_817169},
+		[5] = {826974, 0x00, 0x11, ERRATA_A57_826974},
+		[6] = {826977, 0x00, 0x11, ERRATA_A57_826977},
+		[7] = {828024, 0x00, 0x11, ERRATA_A57_828024},
+		[8] = {829520, 0x00, 0x12, ERRATA_A57_829520},
+		[9] = {833471, 0x00, 0x12, ERRATA_A57_833471},
+		[10] = {859972, 0x00, 0x13, ERRATA_A57_859972},
+		[11] = {1319537, 0x00, 0xFF, ERRATA_A57_1319537},
+		[12 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A57_H_INC */
+
+#if CORTEX_A72_H_INC
+{
+	.cpu_partnumber = CORTEX_A72_MIDR,
+	.cpu_errata_list = {
+		[0] = {859971, 0x00, 0x03, ERRATA_A72_859971},
+		[1] = {1319367, 0x00, 0xFF, ERRATA_A72_1319367},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A72_H_INC */
+
+#if CORTEX_A73_H_INC
+{
+	.cpu_partnumber = CORTEX_A73_MIDR,
+	.cpu_errata_list = {
+		[0] = {852427, 0x00, 0x00, ERRATA_A73_852427},
+		[1] = {855423, 0x00, 0x01, ERRATA_A73_855423},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A73_H_INC */
+
+#if CORTEX_A75_H_INC
+{
+	.cpu_partnumber = CORTEX_A75_MIDR,
+	.cpu_errata_list = {
+		[0] = {764081, 0x00, 0x00, ERRATA_A75_764081},
+		[1] = {790748, 0x00, 0x00, ERRATA_A75_790748},
+		[2 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A75_H_INC */
+
+#if CORTEX_A76_H_INC
+{
+	.cpu_partnumber = CORTEX_A76_MIDR,
+	.cpu_errata_list = {
+		[0] = {1073348, 0x00, 0x10, ERRATA_A76_1073348},
+		[1] = {1130799, 0x00, 0x20, ERRATA_A76_1130799},
+		[2] = {1165522, 0x00, 0xFF, ERRATA_A76_1165522},
+		[3] = {1220197, 0x00, 0x20, ERRATA_A76_1220197},
+		[4] = {1257314, 0x00, 0x30, ERRATA_A76_1257314},
+		[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,
+	}
+},
+#endif /* CORTEX_A76_H_INC */
+
+#if CORTEX_A77_H_INC
+{
+	.cpu_partnumber = CORTEX_A77_MIDR,
+	.cpu_errata_list = {
+		[0] = {1508412, 0x00, 0x10, ERRATA_A77_1508412},
+		[1] = {1791578, 0x00, 0x11, ERRATA_A77_1791578},
+		[2] = {1800714, 0x00, 0x11, ERRATA_A77_1800714},
+		[3] = {1925769, 0x00, 0x11, ERRATA_A77_1925769},
+		[4] = {1946167, 0x00, 0x11, ERRATA_A77_1946167},
+		[5] = {2356587, 0x00, 0x11, ERRATA_A77_2356587},
+		[6] = {2743100, 0x00, 0x11, ERRATA_A77_2743100},
+		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A77_H_INC */
+
+#if CORTEX_A78_H_INC
+{
+	.cpu_partnumber = CORTEX_A78_MIDR,
+	.cpu_errata_list = {
+		[0] = {1688305, 0x00, 0x10, ERRATA_A78_1688305},
+		[1] = {1821534, 0x00, 0x10, ERRATA_A78_1821534},
+		[2] = {1941498, 0x00, 0x11, ERRATA_A78_1941498},
+		[3] = {1951500, 0x10, 0x11, ERRATA_A78_1951500},
+		[4] = {1952683, 0x00, 0x00, ERRATA_A78_1952683},
+		[5] = {2132060, 0x00, 0x12, ERRATA_A78_2132060},
+		[6] = {2242635, 0x10, 0x12, ERRATA_A78_2242635},
+		[7] = {2376745, 0x00, 0x12, ERRATA_A78_2376745},
+		[8] = {2395406, 0x00, 0x12, ERRATA_A78_2395406},
+		[9] = {2712571, 0x00, 0x12, ERRATA_A78_2712571, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[10] = {2742426, 0x00, 0x12, ERRATA_A78_2742426},
+		[11] = {2772019, 0x00, 0x12, ERRATA_A78_2772019},
+		[12] = {2779479, 0x00, 0x12, ERRATA_A78_2779479},
+		[13 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A78_H_INC */
+
+#if CORTEX_A78_AE_H_INC
+{
+	.cpu_partnumber = CORTEX_A78_AE_MIDR,
+	.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},
+		[3] = {2395408, 0x00, 0x01, ERRATA_A78_AE_2395408},
+		[4] = {2712574, 0x00, 0x02, ERRATA_A78_AE_2712574, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[5 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A78_AE_H_INC */
+
+#if CORTEX_A78C_H_INC
+{
+	.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, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[5] = {2772121, 0x00, 0x02, ERRATA_A78C_2772121},
+		[6] = {2779484, 0x01, 0x02, ERRATA_A78C_2779484},
+		[7 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A78C_H_INC */
+
+#if CORTEX_X1_H_INC
+{
+	.cpu_partnumber = CORTEX_X1_MIDR,
+	.cpu_errata_list = {
+		[0] = {1688305, 0x00, 0x10, ERRATA_X1_1688305},
+		[1] = {1821534, 0x00, 0x10, ERRATA_X1_1821534},
+		[2] = {1827429, 0x00, 0x10, ERRATA_X1_1827429},
+		[3 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_X1_H_INC */
+
+#if NEOVERSE_N1_H_INC
+{
+	.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,
+	}
+},
+#endif /* NEOVERSE_N1_H_INC */
+
+#if NEOVERSE_V1_H_INC
+{
+	.cpu_partnumber = NEOVERSE_V1_MIDR,
+	.cpu_errata_list = {
+		[0] = {1618635, 0x00, 0x0F, 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},
+		[8] = {2139242, 0x00, 0x11, ERRATA_V1_2139242},
+		[9] = {2216392, 0x10, 0x11, ERRATA_V1_2216392},
+		[10] = {2294912, 0x00, 0x11, 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,
+	}
+},
+#endif /* NEOVERSE_V1_H_INC */
+
+#if CORTEX_A710_H_INC
+{
+	.cpu_partnumber = CORTEX_A710_MIDR,
+	.cpu_errata_list = {
+		[0] = {1987031, 0x00, 0x20, ERRATA_A710_1987031},
+		[1] = {2008768, 0x00, 0x20, ERRATA_A710_2008768},
+		[2] = {2017096, 0x00, 0x20, ERRATA_A710_2017096},
+		[3] = {2055002, 0x10, 0x20, ERRATA_A710_2055002},
+		[4] = {2058056, 0x00, 0x10, ERRATA_A710_2058056},
+		[5] = {2081180, 0x00, 0x20, ERRATA_A710_2081180},
+		[6] = {2083908, 0x20, 0x20, ERRATA_A710_2083908},
+		[7] = {2136059, 0x00, 0x20, ERRATA_A710_2136059},
+		[8] = {2147715, 0x20, 0x20, ERRATA_A710_2147715},
+		[9] = {2216384, 0x00, 0x20, ERRATA_A710_2216384},
+		[10] = {2267065, 0x00, 0x20, ERRATA_A710_2267065},
+		[11] = {2282622, 0x00, 0x21, ERRATA_A710_2282622},
+		[12] = {2291219, 0x00, 0x20, ERRATA_A710_2291219},
+		[13] = {2371105, 0x00, 0x20, ERRATA_A710_2371105},
+		[14] = {2701952, 0x00, 0x21, ERRATA_A710_2701952, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[15] = {2768515, 0x00, 0x21, ERRATA_A710_2768515}
+	}
+},
+#endif /* CORTEX_A710_H_INC */
+
+#if NEOVERSE_N2_H_INC
+{
+	.cpu_partnumber = NEOVERSE_N2_MIDR,
+	.cpu_errata_list = {
+		[0] = {2002655, 0x00, 0x00, ERRATA_N2_2002655},
+		[1] = {2025414, 0x00, 0x00, ERRATA_N2_2025414},
+		[2] = {2067956, 0x00, 0x00, ERRATA_N2_2067956},
+		[3] = {2138953, 0x00, 0x00, ERRATA_N2_2138953},
+		[4] = {2138956, 0x00, 0x00, ERRATA_N2_2138956},
+		[5] = {2138958, 0x00, 0x00, ERRATA_N2_2138958},
+		[6] = {2189731, 0x00, 0x00, ERRATA_N2_2189731},
+		[7] = {2242400, 0x00, 0x00, ERRATA_N2_2242400},
+		[8] = {2242415, 0x00, 0x00, ERRATA_N2_2242415},
+		[9] = {2280757, 0x00, 0x00, ERRATA_N2_2280757},
+		[10] = {2326639, 0x00, 0x00, ERRATA_N2_2326639},
+		[11] = {2376738, 0x00, 0x00, ERRATA_N2_2376738},
+		[12] = {2388450, 0x00, 0x00, ERRATA_N2_2388450},
+		[13] = {2728475, 0x00, 0x02, ERRATA_N2_2728475, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[14] = {2743089, 0x00, 0x02, ERRATA_N2_2743089},
+		[15 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* NEOVERSE_N2_H_INC */
+
+#if CORTEX_X2_H_INC
+{
+	.cpu_partnumber = CORTEX_X2_MIDR,
+	.cpu_errata_list = {
+		[0] = {2002765, 0x00, 0x20, ERRATA_X2_2002765},
+		[1] = {2017096, 0x00, 0x20, ERRATA_X2_2017096},
+		[2] = {2058056, 0x00, 0x20, ERRATA_X2_2058056},
+		[3] = {2081180, 0x00, 0x20, ERRATA_X2_2081180},
+		[4] = {2083908, 0x00, 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},
+		[9] = {2701952, 0x00, 0x21, ERRATA_X2_2701952, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[10] = {2768515, 0x00, 0x21, ERRATA_X2_2768515},
+		[11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_X2_H_INC */
+
+#if CORTEX_A510_H_INC
+{
+	.cpu_partnumber = CORTEX_A510_MIDR,
+	.cpu_errata_list = {
+		[0] = {1922240, 0x00, 0x00, ERRATA_A510_1922240},
+		[1] = {2041909, 0x02, 0x02, ERRATA_A510_2041909},
+		[2] = {2042739, 0x00, 0x02, ERRATA_A510_2042739},
+		[3] = {2172148, 0x00, 0x10, ERRATA_A510_2172148},
+		[4] = {2218950, 0x00, 0x10, ERRATA_A510_2218950},
+		[5] = {2250311, 0x00, 0x10, ERRATA_A510_2250311},
+		[6] = {2288014, 0x00, 0x10, ERRATA_A510_2288014},
+		[7] = {2347730, 0x00, 0x11, ERRATA_A510_2347730},
+		[8] = {2371937, 0x00, 0x11, ERRATA_A510_2371937},
+		[9] = {2666669, 0x00, 0x11, ERRATA_A510_2666669},
+		[10] = {2684597, 0x00, 0x12, ERRATA_A510_2684597},
+		[11 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A510_H_INC */
+
+#if NEOVERSE_V2_H_INC
+{
+	.cpu_partnumber = NEOVERSE_V2_MIDR,
+	.cpu_errata_list = {
+		[0] = {2719103, 0x00, 0x01, ERRATA_V2_2719103, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* NEOVERSE_V2_H_INC */
+
+#if CORTEX_A715_H_INC
+{
+	.cpu_partnumber = CORTEX_MAKALU_MIDR,
+	.cpu_errata_list = {
+		[0] = {2701951, 0x00, 0x11, ERRATA_A715_2701951, \
+			ERRATA_NON_ARM_INTERCONNECT},
+		[1 ... ERRATA_LIST_END] = UNDEF_ERRATA,
+	}
+},
+#endif /* CORTEX_A715_H_INC */
+};
+
+/*
+ * Function to do binary search and check for the specific errata ID
+ * in the array of structures specific to the cpu identified.
+ */
+int32_t binary_search(struct em_cpu_list *ptr, uint32_t erratum_id, uint8_t rxpx_val)
+{
+	int low_index = 0U, mid_index = 0U;
+
+	int high_index = MAX_ERRATA_ENTRIES - 1;
+
+	assert(ptr != NULL);
+
+	/*
+	 * Pointer to the errata list of the cpu that matches
+	 * extracted partnumber in the cpu list
+	 */
+	struct em_cpu *erratum_ptr = NULL;
+
+	while (low_index <= high_index) {
+		mid_index = (low_index + high_index) / 2;
+
+		erratum_ptr = &ptr->cpu_errata_list[mid_index];
+		assert(erratum_ptr != NULL);
+
+		if (erratum_id < erratum_ptr->em_errata_id) {
+			high_index = mid_index - 1;
+		} else if (erratum_id > erratum_ptr->em_errata_id) {
+			low_index = mid_index + 1;
+		} else if (erratum_id == erratum_ptr->em_errata_id) {
+			if (RXPX_RANGE(rxpx_val, erratum_ptr->em_rxpx_lo, \
+				erratum_ptr->em_rxpx_hi)) {
+				if ((erratum_ptr->errata_enabled) && \
+				(!(erratum_ptr->non_arm_interconnect))) {
+					return EM_HIGHER_EL_MITIGATION;
+				}
+				return EM_AFFECTED;
+			}
+			return EM_NOT_AFFECTED;
+		}
+	}
+	/* no matching errata ID */
+	return EM_UNKNOWN_ERRATUM;
+}
+
+/* Function to check if the errata exists for the specific CPU and rxpx */
+int32_t verify_errata_implemented(uint32_t errata_id, uint32_t forward_flag)
+{
+	/*
+	 * Read MIDR value and extract the revision, variant and partnumber
+	 */
+	static uint32_t midr_val, cpu_partnum;
+	static uint8_t  cpu_rxpx_val;
+	int32_t ret_val = EM_UNKNOWN_ERRATUM;
+
+	/* Determine the number of cpu listed in the cpu list */
+	uint8_t size_cpulist = ARRAY_SIZE(cpu_list);
+
+	/* Read the midr reg to extract cpu, revision and variant info */
+	midr_val = read_midr();
+
+	/* Extract revision and variant from the MIDR register */
+	cpu_rxpx_val = cpu_get_rev_var();
+
+	/* Extract the cpu partnumber and check if the cpu is in the cpu list */
+	cpu_partnum = EXTRACT_PARTNUM(midr_val);
+
+	for (uint8_t i = 0; i < size_cpulist; i++) {
+		cpu_ptr = &cpu_list[i];
+		uint16_t partnum_extracted = EXTRACT_PARTNUM(cpu_ptr->cpu_partnumber);
+
+		if (partnum_extracted == cpu_partnum) {
+			/*
+			 * If the midr value is in the cpu list, binary search
+			 * for the errata ID and specific revision in the list.
+			 */
+			ret_val = binary_search(cpu_ptr, errata_id, cpu_rxpx_val);
+			break;
+		}
+	}
+	return ret_val;
+}
+
+/* Predicate indicating that a function id is part of EM_ABI */
+bool is_errata_fid(uint32_t smc_fid)
+{
+	return ((smc_fid == ARM_EM_VERSION) ||
+		(smc_fid == ARM_EM_FEATURES) ||
+		(smc_fid == ARM_EM_CPU_ERRATUM_FEATURES));
+
+}
+
+bool validate_spsr_mode(void)
+{
+	/* In AArch64, if the caller is EL1, return true */
+
+	#if __aarch64__
+		if (GET_EL(read_spsr_el3()) == MODE_EL1) {
+			return true;
+		}
+		return false;
+	#else
+
+	/* In AArch32, if in system/svc mode, return true */
+		uint8_t read_el_state = GET_M32(read_spsr());
+
+		if ((read_el_state == (MODE32_svc)) || (read_el_state == MODE32_sys)) {
+			return true;
+		}
+		return false;
+	#endif /* __aarch64__ */
+}
+
+uintptr_t errata_abi_smc_handler(uint32_t smc_fid, u_register_t x1,
+				u_register_t x2, u_register_t x3, u_register_t x4,
+				void *cookie, void *handle, u_register_t flags)
+{
+	int32_t ret_id = EM_UNKNOWN_ERRATUM;
+
+	switch (smc_fid) {
+	case ARM_EM_VERSION:
+		SMC_RET1(handle, MAKE_SMCCC_VERSION(
+			EM_VERSION_MAJOR, EM_VERSION_MINOR
+		));
+		break; /* unreachable */
+	case ARM_EM_FEATURES:
+		if (is_errata_fid((uint32_t)x1)) {
+			SMC_RET1(handle, EM_SUCCESS);
+		}
+
+		SMC_RET1(handle, EM_NOT_SUPPORTED);
+		break; /* unreachable */
+	case ARM_EM_CPU_ERRATUM_FEATURES:
+
+		/*
+		 * If the forward flag is greater than zero and the calling EL
+		 * is EL1 in AArch64 or in system mode or svc mode in case of AArch32,
+		 * return Invalid Parameters.
+		 */
+		if (((uint32_t)x2 != 0) && (validate_spsr_mode())) {
+			SMC_RET1(handle, EM_INVALID_PARAMETERS);
+		}
+		ret_id = verify_errata_implemented((uint32_t)x1, (uint32_t)x2);
+		SMC_RET1(handle, ret_id);
+		break; /* unreachable */
+	default:
+		{
+		   WARN("Unimplemented Errata ABI Service Call: 0x%x\n", smc_fid);
+		   SMC_RET1(handle, EM_UNKNOWN_ERRATUM);
+		   break; /* unreachable */
+		}
+	}
+}
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 2884a3b..e782d09 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <lib/psci/psci.h>
 #include <lib/runtime_instr.h>
 #include <services/drtm_svc.h>
+#include <services/errata_abi_svc.h>
 #include <services/pci_svc.h>
 #include <services/rmmd_svc.h>
 #include <services/sdei.h>
@@ -177,6 +178,13 @@
 	}
 #endif /* TRNG_SUPPORT */
 
+#if ERRATA_ABI_SUPPORT
+	if (is_errata_fid(smc_fid)) {
+		return errata_abi_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+					      handle, flags);
+	}
+#endif /* ERRATA_ABI_SUPPORT */
+
 #if ENABLE_RME
 
 	if (is_rmmd_el3_fid(smc_fid)) {