Merge "build(changelog): add new scope for TI platform" into integration
diff --git a/Makefile b/Makefile
index fb50f0c..f91699c 100644
--- a/Makefile
+++ b/Makefile
@@ -263,24 +263,6 @@
 # Determine if FEAT_SB is supported
 ENABLE_FEAT_SB		=	$(if $(findstring sb,${arch-features}),1,0)
 
-ifeq "8.5" "$(word 1, $(sort 8.5 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_SB		= 	1
-endif
-
-# Determine and enable FEAT_FGT to access HDFGRTR_EL2 register for v8.6 and higher versions.
-ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_FGT		=	1
-endif
-
-# Determine and enable FEAT_ECV to access CNTPOFF_EL2 register for v8.6 and higher versions.
-ifeq "8.6" "$(word 1, $(sort 8.6 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_ECV		=	1
-endif
-
-ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
-ENABLE_FEAT_DIT		= 	1
-endif
-
 ifneq ($(findstring armclang,$(notdir $(CC))),)
 TF_CFLAGS_aarch32	=	-target arm-arm-none-eabi $(march32-directive)
 TF_CFLAGS_aarch64	=	-target aarch64-arm-none-eabi $(march64-directive)
@@ -474,6 +456,7 @@
 ################################################################################
 # Common sources and include directories
 ################################################################################
+include ${MAKE_HELPERS_DIRECTORY}arch_features.mk
 include lib/compiler-rt/compiler-rt.mk
 
 BL_COMMON_SOURCES	+=	common/bl_common.c			\
@@ -776,6 +759,10 @@
     $(info PSA_FWU_SUPPORT is an experimental feature)
 endif
 
+ifeq ($(FEATURE_DETECTION),1)
+    $(info FEATURE_DETECTION is an experimental feature)
+endif
+
 ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
     ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
         $(error "ALLOW_RO_XLAT_TABLES requires translation tables library v2")
@@ -980,10 +967,7 @@
         CREATE_KEYS \
         CTX_INCLUDE_AARCH32_REGS \
         CTX_INCLUDE_FPREGS \
-        CTX_INCLUDE_PAUTH_REGS \
-        CTX_INCLUDE_MTE_REGS \
         CTX_INCLUDE_EL2_REGS \
-        CTX_INCLUDE_NEVE_REGS \
         DEBUG \
         DISABLE_MTPMU \
         DYN_DISABLE_AUTH \
@@ -993,11 +977,9 @@
         ENABLE_AMU_FCONF \
         AMU_RESTRICT_COUNTERS \
         ENABLE_ASSERTIONS \
-        ENABLE_MPAM_FOR_LOWER_ELS \
         ENABLE_PIE \
         ENABLE_PMF \
         ENABLE_PSCI_STAT \
-        ENABLE_RME \
         ENABLE_RUNTIME_INSTRUMENTATION \
         ENABLE_SME_FOR_NS \
         ENABLE_SME_FOR_SWD \
@@ -1017,10 +999,10 @@
         PL011_GENERIC_UART \
         PROGRAMMABLE_RESET_ADDRESS \
         PSCI_EXTENDED_STATE_ID \
-        RAS_EXTENSION \
         RESET_TO_BL31 \
         SAVE_KEYS \
         SEPARATE_CODE_AND_RODATA \
+        SEPARATE_BL2_NOLOAD_REGION \
         SEPARATE_NOBITS_REGION \
         SPIN_ON_BL1_EXIT \
         SPM_MM \
@@ -1045,20 +1027,13 @@
         RAS_TRAP_LOWER_EL_ERR_ACCESS \
         COT_DESC_IN_DTB \
         USE_SP804_TIMER \
-        ENABLE_FEAT_RNG \
-        ENABLE_FEAT_SB \
-        ENABLE_FEAT_DIT \
         PSA_FWU_SUPPORT \
         ENABLE_TRBE_FOR_NS \
         ENABLE_SYS_REG_TRACE_FOR_NS \
-        ENABLE_TRF_FOR_NS \
-        ENABLE_FEAT_HCX \
         ENABLE_MPMM \
         ENABLE_MPMM_FCONF \
-        ENABLE_FEAT_FGT \
-        ENABLE_FEAT_AMUv1 \
-        ENABLE_FEAT_ECV \
         SIMICS_BUILD \
+        FEATURE_DETECTION \
 )))
 
 $(eval $(call assert_numerics,\
@@ -1066,9 +1041,30 @@
         ARM_ARCH_MAJOR \
         ARM_ARCH_MINOR \
         BRANCH_PROTECTION \
+        CTX_INCLUDE_PAUTH_REGS \
+        CTX_INCLUDE_MTE_REGS \
+        CTX_INCLUDE_NEVE_REGS \
+        ENABLE_BTI \
+        ENABLE_PAUTH \
+        ENABLE_FEAT_AMUv1 \
+        ENABLE_FEAT_AMUv1p1 \
+        ENABLE_FEAT_CSV2_2 \
+        ENABLE_FEAT_DIT \
+        ENABLE_FEAT_ECV \
+        ENABLE_FEAT_FGT \
+        ENABLE_FEAT_HCX \
+        ENABLE_FEAT_PAN \
+        ENABLE_FEAT_RNG \
+        ENABLE_FEAT_SB \
+        ENABLE_FEAT_SEL2 \
+        ENABLE_FEAT_VHE \
+        ENABLE_MPAM_FOR_LOWER_ELS \
+        ENABLE_RME \
+        ENABLE_TRF_FOR_NS \
         FW_ENC_STATUS \
         NR_OF_FW_BANKS \
         NR_OF_IMAGES_IN_FW_BANK \
+        RAS_EXTENSION \
 )))
 
 ifdef KEY_SIZE
@@ -1136,6 +1132,7 @@
         RAS_EXTENSION \
         RESET_TO_BL31 \
         SEPARATE_CODE_AND_RODATA \
+        SEPARATE_BL2_NOLOAD_REGION \
         SEPARATE_NOBITS_REGION \
         RECLAIM_INIT_CODE \
         SPD_${SPD} \
@@ -1177,6 +1174,12 @@
         ENABLE_FEAT_AMUv1 \
         ENABLE_FEAT_ECV \
         SIMICS_BUILD \
+        ENABLE_FEAT_AMUv1p1 \
+        ENABLE_FEAT_SEL2 \
+        ENABLE_FEAT_VHE \
+        ENABLE_FEAT_CSV2_2 \
+        ENABLE_FEAT_PAN \
+        FEATURE_DETECTION \
 )))
 
 ifeq (${SANITIZE_UB},trap)
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index bc1794c..6aa7afd 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,11 @@
     RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
 #else
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+#if SEPARATE_BL2_NOLOAD_REGION
+    RAM_NOLOAD (rw!a): ORIGIN = BL2_NOLOAD_START, LENGTH = BL2_NOLOAD_LIMIT - BL2_NOLOAD_START
+#else
+#define RAM_NOLOAD RAM
+#endif
 #endif
 }
 
@@ -106,9 +111,18 @@
     __DATA_RAM_END__ = __DATA_END__;
 
     RELA_SECTION >RAM
-    STACK_SECTION >RAM
-    BSS_SECTION >RAM
-    XLAT_TABLE_SECTION >RAM
+#if SEPARATE_BL2_NOLOAD_REGION
+    SAVED_ADDR = .;
+    . = BL2_NOLOAD_START;
+    __BL2_NOLOAD_START__ = .;
+#endif
+    STACK_SECTION >RAM_NOLOAD
+    BSS_SECTION >RAM_NOLOAD
+    XLAT_TABLE_SECTION >RAM_NOLOAD
+#if SEPARATE_BL2_NOLOAD_REGION
+    __BL2_NOLOAD_END__ = .;
+    . = SAVED_ADDR;
+#endif
 
 #if USE_COHERENT_MEM
     /*
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index e751824..25c7964 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -128,6 +128,10 @@
 				${RMMD_SOURCES}
 endif
 
+ifeq ($(FEATURE_DETECTION),1)
+BL31_SOURCES		+=	common/feat_detect.c
+endif
+
 BL31_LINKERFILE		:=	bl31/bl31.ld.S
 
 # Flag used to indicate if Crash reporting via console should be included
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 9ac10e2..797093e 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,7 @@
 #include <bl31/ehf.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <common/feat_detect.h>
 #include <common/runtime_svc.h>
 #include <drivers/console.h>
 #include <lib/el3_runtime/context_mgmt.h>
@@ -123,6 +124,11 @@
 	NOTICE("BL31: %s\n", version_string);
 	NOTICE("BL31: %s\n", build_message);
 
+#if FEATURE_DETECTION
+	/* Detect if features enabled during compilation are supported by PE. */
+	detect_arch_features();
+#endif /* FEATURE_DETECTION */
+
 #ifdef SUPPORT_UNKNOWN_MPID
 	if (unsupported_mpid_flag == 0) {
 		NOTICE("Unsupported MPID detected!\n");
diff --git a/changelog.yaml b/changelog.yaml
index 53fd113..add81ef 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -349,6 +349,16 @@
                   - title: LS1046AQDS
                     scope: ls1046aqds
 
+              - title: LS1088A
+                scope: ls1088a
+
+                subsections:
+                  - title: LS1088ARDB
+                    scope: ls1088ardb
+
+                  - title: LS1088AQDS
+                    scope: ls1088aqds
+
       - title: QEMU
         scope: qemu
 
@@ -755,6 +765,12 @@
           - title: NXP Crypto
             scope: nxp-crypto
 
+          - title: DDR
+            scope: nxp-ddr
+
+          - title: GIC
+            scope: nxp-gic
+
       - title: Renesas
         scope: renesas-drivers
 
diff --git a/common/feat_detect.c b/common/feat_detect.c
new file mode 100644
index 0000000..ef09b86
--- /dev/null
+++ b/common/feat_detect.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/feat_detect.h>
+
+/*******************************************************************************
+ * This section lists the wrapper modules for each feature to evaluate the
+ * feature states (FEAT_STATE_1 and FEAT_STATE_2) and perform necessary action
+ * as below:
+ *
+ * It verifies whether the FEAT_XXX (eg: FEAT_SB) is supported by the PE or not.
+ * Without this check an exception would occur during context save/restore
+ * routines, if the feature is enabled but not supported by PE.
+ ******************************************************************************/
+
+/******************************************
+ * Feature : FEAT_SB (Speculation Barrier)
+ *****************************************/
+static void read_feat_sb(void)
+{
+#if (ENABLE_FEAT_SB == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_0_feat_sb_present(), "SB");
+#endif
+}
+
+/******************************************************
+ * Feature : FEAT_CSV2_2 (Cache Speculation Variant 2)
+ *****************************************************/
+static void read_feat_csv2_2(void)
+{
+#if (ENABLE_FEAT_CSV2_2 == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_0_feat_csv2_2_present(), "CSV2_2");
+#endif
+}
+
+/***********************************************
+ * Feature : FEAT_PAN (Privileged Access Never)
+ **********************************************/
+static void read_feat_pan(void)
+{
+#if (ENABLE_FEAT_PAN == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_1_pan_present(), "PAN");
+#endif
+}
+
+/******************************************************
+ * Feature : FEAT_VHE (Virtualization Host Extensions)
+ *****************************************************/
+static void read_feat_vhe(void)
+{
+#if (ENABLE_FEAT_VHE == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_1_vhe_present(), "VHE");
+#endif
+}
+
+/*******************************************************************************
+ * Feature : FEAT_RAS (Reliability, Availability, and Serviceability Extension)
+ ******************************************************************************/
+static void read_feat_ras(void)
+{
+#if (RAS_EXTENSION == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_2_feat_ras_present(), "RAS");
+#endif
+}
+
+/************************************************
+ * Feature : FEAT_PAUTH (Pointer Authentication)
+ ***********************************************/
+static void read_feat_pauth(void)
+{
+#if (ENABLE_PAUTH == FEAT_STATE_1) || (CTX_INCLUDE_PAUTH_REGS == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_3_pauth_present(), "PAUTH");
+#endif
+}
+
+/************************************************************
+ * Feature : FEAT_DIT (Data Independent Timing Instructions)
+ ***********************************************************/
+static void read_feat_dit(void)
+{
+#if (ENABLE_FEAT_DIT == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_4_feat_dit_present(), "DIT");
+#endif
+}
+
+/*********************************************************
+ * Feature : FEAT_AMUv1 (Activity Monitors Extensions v1)
+ ********************************************************/
+static void read_feat_amuv1(void)
+{
+#if (ENABLE_FEAT_AMUv1 == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_4_feat_amuv1_present(), "AMUv1");
+#endif
+}
+
+/****************************************************************************
+ * Feature : FEAT_MPAM (Memory Partitioning and Monitoring (MPAM) Extension)
+ ***************************************************************************/
+static void read_feat_mpam(void)
+{
+#if (ENABLE_MPAM_FOR_LOWER_ELS == FEAT_STATE_1)
+	feat_detect_panic(get_mpam_version() != 0U, "MPAM");
+#endif
+}
+
+/**************************************************************
+ * Feature : FEAT_NV2 (Enhanced Nested Virtualization Support)
+ *************************************************************/
+static void read_feat_nv2(void)
+{
+#if (CTX_INCLUDE_NEVE_REGS == FEAT_STATE_1)
+	unsigned int nv = get_armv8_4_feat_nv_support();
+
+	feat_detect_panic((nv == ID_AA64MMFR2_EL1_NV2_SUPPORTED), "NV2");
+#endif
+}
+
+/***********************************
+ * Feature : FEAT_SEL2 (Secure EL2)
+ **********************************/
+static void read_feat_sel2(void)
+{
+#if (ENABLE_FEAT_SEL2 == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_4_sel2_present(), "SEL2");
+#endif
+}
+
+/****************************************************
+ * Feature : FEAT_TRF (Self-hosted Trace Extensions)
+ ***************************************************/
+static void read_feat_trf(void)
+{
+#if (ENABLE_TRF_FOR_NS == FEAT_STATE_1)
+	feat_detect_panic(is_arm8_4_feat_trf_present(), "TRF");
+#endif
+}
+
+/************************************************
+ * Feature : FEAT_MTE (Memory Tagging Extension)
+ ***********************************************/
+static void read_feat_mte(void)
+{
+#if (CTX_INCLUDE_MTE_REGS == FEAT_STATE_1)
+	unsigned int mte = get_armv8_5_mte_support();
+
+	feat_detect_panic((mte != MTE_UNIMPLEMENTED), "MTE");
+#endif
+}
+
+/***********************************************
+ * Feature : FEAT_RNG (Random Number Generator)
+ **********************************************/
+static void read_feat_rng(void)
+{
+#if (ENABLE_FEAT_RNG == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_5_rng_present(), "RNG");
+#endif
+}
+
+/****************************************************
+ * Feature : FEAT_BTI (Branch Target Identification)
+ ***************************************************/
+static void read_feat_bti(void)
+{
+#if (ENABLE_BTI == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_5_bti_present(), "BTI");
+#endif
+}
+
+/****************************************
+ * Feature : FEAT_FGT (Fine Grain Traps)
+ ***************************************/
+static void read_feat_fgt(void)
+{
+#if (ENABLE_FEAT_FGT == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_6_fgt_present(), "FGT");
+#endif
+}
+
+/***********************************************
+ * Feature : FEAT_AMUv1p1 (AMU Extensions v1.1)
+ **********************************************/
+static void read_feat_amuv1p1(void)
+{
+#if (ENABLE_FEAT_AMUv1p1 == FEAT_STATE_1)
+	feat_detect_panic(is_armv8_6_feat_amuv1p1_present(), "AMUv1p1");
+#endif
+}
+
+/*******************************************************
+ * Feature : FEAT_ECV (Enhanced Counter Virtualization)
+ ******************************************************/
+static void read_feat_ecv(void)
+{
+#if (ENABLE_FEAT_ECV == FEAT_STATE_1)
+	unsigned int ecv = get_armv8_6_ecv_support();
+
+	feat_detect_panic(((ecv == ID_AA64MMFR0_EL1_ECV_SUPPORTED) ||
+			(ecv == ID_AA64MMFR0_EL1_ECV_SELF_SYNCH)), "ECV");
+#endif
+}
+
+/******************************************************************
+ * Feature : FEAT_HCX (Extended Hypervisor Configuration Register)
+ *****************************************************************/
+static void read_feat_hcx(void)
+{
+#if (ENABLE_FEAT_HCX == FEAT_STATE_1)
+	feat_detect_panic(is_feat_hcx_present(), "HCX");
+#endif
+}
+
+/**************************************************
+ * Feature : FEAT_RME (Realm Management Extension)
+ *************************************************/
+static void read_feat_rme(void)
+{
+#if (ENABLE_RME == FEAT_STATE_1)
+	feat_detect_panic((get_armv9_2_feat_rme_support() !=
+			ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED), "RME");
+#endif
+}
+
+/***********************************************************************************
+ * TF-A supports many Arm architectural features starting from arch version
+ * (8.0 till 8.7+). These features are mostly enabled through build flags. This
+ * mechanism helps in validating these build flags in the early boot phase
+ * either in BL1 or BL31 depending on the platform and assists in identifying
+ * and notifying the features which are enabled but not supported by the PE.
+ *
+ * It reads all the enabled features ID-registers and ensures the features
+ * are supported by the PE.
+ * In case if they aren't it stops booting at an early phase and logs the error
+ * messages, notifying the platforms about the features that are not supported.
+ *
+ * Further the procedure is implemented with a tri-state approach for each feature:
+ * ENABLE_FEAT_xxx = 0 : The feature is disabled statically at compile time
+ * ENABLE_FEAT_xxx = 1 : The feature is enabled and must be present in hardware.
+ *                       There will be panic if feature is not present at cold boot.
+ * ENABLE_FEAT_xxx = 2 : The feature is enabled but dynamically enabled at runtime
+ *                       depending on hardware capability.
+ *
+ * For better readability, state values are defined with macros namely:
+ * { FEAT_STATE_0, FEAT_STATE_1, FEAT_STATE_2 } taking values as their naming.
+ **********************************************************************************/
+void detect_arch_features(void)
+{
+	/* v8.0 features */
+	read_feat_sb();
+	read_feat_csv2_2();
+
+	/* v8.1 features */
+	read_feat_pan();
+	read_feat_vhe();
+
+	/* v8.2 features */
+	read_feat_ras();
+
+	/* v8.3 features */
+	read_feat_pauth();
+
+	/* v8.4 features */
+	read_feat_dit();
+	read_feat_amuv1();
+	read_feat_mpam();
+	read_feat_nv2();
+	read_feat_sel2();
+	read_feat_trf();
+
+	/* v8.5 features */
+	read_feat_mte();
+	read_feat_rng();
+	read_feat_bti();
+
+	/* v8.6 features */
+	read_feat_amuv1p1();
+	read_feat_fgt();
+	read_feat_ecv();
+
+	/* v8.7 features */
+	read_feat_hcx();
+
+	/* v9.2 features */
+	read_feat_rme();
+}
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index ad125cf..b58ea71 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -480,6 +480,8 @@
 ^^^^^^^^^^^^^^^^^^^^^^^
 :|M|: Rex-BC Chen <rex-bc.chen@mediatek.com>
 :|G|: `mtk-rex-bc-chen`_
+:|M|: Leon Chen <leon.chen@mediatek.com>
+:|G|: `leon-chen-mtk`_
 :|F|: docs/plat/mt\*.rst
 :|F|: plat/mediatek/
 
@@ -571,6 +573,14 @@
 :|F|: plat/nxp/soc-ls1046a/ls1046afrwy
 :|F|: plat/nxp/soc-ls1046a/ls1046aqds
 
+NXP SoC Part LS1088A and its platform port
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+:|M|: Jiafei Pan <jiafei.pan@nxp.com>
+:|G|: `JiafeiPan`_
+:|F|: plat/nxp/soc-ls1088a
+:|F|: plat/nxp/soc-ls1088a/ls1088ardb
+:|F|: plat/nxp/soc-ls1088a/ls1088aqds
+
 QEMU platform port
 ^^^^^^^^^^^^^^^^^^
 :|M|: Jens Wiklander <jens.wiklander@linaro.org>
@@ -805,6 +815,7 @@
 .. _mmind: https://github.com/mmind
 .. _MrVan: https://github.com/MrVan
 .. _mtk-rex-bc-chen: https://github.com/mtk-rex-bc-chen
+.. _leon-chen-mtk: https://github.com/leon-chen-mtk
 .. _niej: https://github.com/niej
 .. _npoushin: https://github.com/npoushin
 .. _prabhakarlad: https://github.com/prabhakarlad
diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst
index a598e5f..af298e3 100644
--- a/docs/components/secure-partition-manager.rst
+++ b/docs/components/secure-partition-manager.rst
@@ -343,6 +343,9 @@
 The SP owner can either be the silicon or the platform provider. The
 corresponding "owner" field value can either take the value of "SiP" or "Plat".
 In absence of "owner" field, it defaults to "SiP" owner.
+The UUID of the partition can be specified as a field in the description file or
+if it does not exist there the UUID is extracted from the DTS partition
+manifest.
 
 .. code:: shell
 
@@ -350,7 +353,8 @@
         "tee1" : {
             "image": "tee1.bin",
              "pm": "tee1.dts",
-             "owner": "SiP"
+             "owner": "SiP",
+             "uuid": "1b1820fe-48f7-4175-8999-d51da00b7c9f"
         },
 
         "tee2" : {
@@ -1284,4 +1288,4 @@
 
 --------------
 
-*Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index b7d1168..af0e769 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -298,13 +298,21 @@
 
 For Cortex-A78 AE, 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. This erratum is
-   still open.
+- ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to
+   Cortex-A78 AE 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
+  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.
 
-- ``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 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
+  erratum is still open.
 
 For Neoverse N1, the following errata build flags are defined :
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index a34bb3c..4dbf5cb 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -174,14 +174,23 @@
    registers to be included when saving and restoring the CPU context. Default
    is 0.
 
--  ``CTX_INCLUDE_NEVE_REGS``: Boolean option that, when set to 1, will cause the
-   Armv8.4-NV registers to be saved/restored when entering/exiting an EL2
-   execution context. Default value is 0.
+-  ``CTX_INCLUDE_MTE_REGS``: Numeric value to include Memory Tagging Extension
+   registers in cpu context. This must be enabled, if the platform wants to use
+   this feature in the Secure world and MTE is enabled at ELX. This flag can
+   take values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+   Default value is 0.
 
--  ``CTX_INCLUDE_PAUTH_REGS``: Boolean option that, when set to 1, enables
-   Pointer Authentication for Secure world. This will cause the ARMv8.3-PAuth
-   registers to be included when saving and restoring the CPU context as
-   part of world switch. Default value is 0.
+-  ``CTX_INCLUDE_NEVE_REGS``: Numeric value, when set will cause the Armv8.4-NV
+   registers to be saved/restored when entering/exiting an EL2 execution
+   context. This flag can take values 0 to 2, to align with the
+   ``FEATURE_DETECTION`` mechanism. Default value is 0.
+
+-  ``CTX_INCLUDE_PAUTH_REGS``: Numeric value to enable the Pointer
+   Authentication for Secure world. This will cause the ARMv8.3-PAuth registers
+   to be included when saving and restoring the CPU context as part of world
+   switch. This flag can take values 0 to 2, to align with ``FEATURE_DETECTION``
+   mechanism. Default value is 0.
+
    Note that Pointer Authentication is enabled for Non-secure world irrespective
    of the value of this flag if the CPU supports it.
 
@@ -246,42 +255,101 @@
    builds, but this behaviour can be overridden in each platform's Makefile or
    in the build command line.
 
--  ``ENABLE_FEAT_AMUv1``: Boolean option to enable access to the HAFGRTR_EL2
+-  ``ENABLE_FEAT_AMUv1``: Numeric value to enable access to the HAFGRTR_EL2
    (Hypervisor Activity Monitors Fine-Grained Read Trap Register) during EL2
-   to EL3 context save/restore operations. It is an optional feature available
-   on v8.4 and onwards and must be set to 1 alongside ``ENABLE_FEAT_FGT``, to
-   access the HAFGRTR_EL2 register. Defaults to ``0``.
+   to EL3 context save/restore operations. This flag can take the values 0 to 2,
+   to align with the ``FEATURE_DETECTION`` mechanism. It is an optional feature
+   available on v8.4 and onwards and must be set to either 1 or 2 alongside
+   ``ENABLE_FEAT_FGT``, to access the HAFGRTR_EL2 register.
+   Default value is ``0``.
+
+-  ``ENABLE_FEAT_AMUv1p1``: Numeric value to enable the ``FEAT_AMUv1p1``
+   extension. ``FEAT_AMUv1p1`` is an optional feature available on Arm v8.6
+   onwards. This flag can take the values 0 to 2, to align with the
+   ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
 
--  ``ENABLE_FEAT_ECV``: Boolean option to enable support for the Enhanced Counter
+-  ``ENABLE_FEAT_CSV2_2``: Numeric value to enable the ``FEAT_CSV2_2``
+   extension. It allows access to the SCXTNUM_EL2 (Software Context Number)
+   register during EL2 context save/restore operations. ``FEAT_CSV2_2`` is an
+   optional feature available on Arm v8.0 onwards. This flag can take values
+   0 to 2, to align with the ``FEATURE_DETECTION`` mechanism.
+   Default value is ``0``.
+
+-  ``ENABLE_FEAT_DIT``: Numeric value to enable ``FEAT_DIT`` (Data Independent
+   Timing) extension. It allows setting the ``DIT`` bit of PSTATE in EL3.
+   ``FEAT_DIT`` is a mandatory  architectural feature and is enabled from v8.4
+   and upwards. This flag can take the values 0 to 2, to align  with the
+   ``FEATURE_DETECTION`` mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_ECV``: Numeric value to enable support for the Enhanced Counter
    Virtualization feature, allowing for access to the CNTPOFF_EL2 (Counter-timer
    Physical Offset register) during EL2 to EL3 context save/restore operations.
-   Its a mandatory architectural feature in Armv8.6 and defaults to ``1`` for
-   v8.6 or later CPUs.
+   Its a mandatory architectural feature and is enabled from v8.6 and upwards.
+   This flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
 
--  ``ENABLE_FEAT_FGT``: Boolean option to enable support for FGT (Fine Grain Traps)
+-  ``ENABLE_FEAT_FGT``: Numeric value to enable support for FGT (Fine Grain Traps)
    feature allowing for access to the HDFGRTR_EL2 (Hypervisor Debug Fine-Grained
-   Read Trap Register)  during EL2 to EL3 context save/restore operations.
-   Its a mandatory architectural feature in Armv8.6 and defaults to ``1`` for
-   v8.6 or later CPUs.
+   Read Trap Register) during EL2 to EL3 context save/restore operations.
+   Its a mandatory architectural feature and is enabled from v8.6 and upwards.
+   This flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
 
--  ``ENABLE_FEAT_HCX``: This option sets the bit SCR_EL3.HXEn in EL3 to allow
-   access to HCRX_EL2 (extended hypervisor control register) from EL2 as well as
-   adding HCRX_EL2 to the EL2 context save/restore operations.
+-  ``ENABLE_FEAT_HCX``: Numeric value to set the bit SCR_EL3.HXEn in EL3 to
+   allow access to HCRX_EL2 (extended hypervisor control register) from EL2 as
+   well as adding HCRX_EL2 to the EL2 context save/restore operations. Its a
+   mandatory architectural feature and is enabled from v8.7 and upwards. This
+   flag can take the values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_PAN``: Numeric value to enable the ``FEAT_PAN`` (Privileged
+   Access Never) extension. ``FEAT_PAN`` adds a bit to PSTATE, generating a
+   permission fault for any privileged data access from EL1/EL2 to virtual
+   memory address, accessible at EL0, provided (HCR_EL2.E2H=1). It is a
+   mandatory architectural feature and is enabled from v8.1 and upwards. This
+   flag can take values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. Default value is ``0``.
+
+-  ``ENABLE_FEAT_RNG``: Numeric value to enable the ``FEAT_RNG`` extension.
+   ``FEAT_RNG`` is an optional feature available on Arm v8.5 onwards. This
+   flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION``
+   mechanism. Default is ``0``.
+
+-  ``ENABLE_FEAT_SB``: Numeric value to enable the ``FEAT_SB`` (Speculation
+   Barrier) extension allowing access to ``sb`` instruction. ``FEAT_SB`` is an
+   optional feature and defaults to ``0`` for pre-Armv8.5 CPUs but are mandatory
+   for Armv8.5 or later CPUs. This flag can take values 0 to 2, to align with
+   ``FEATURE_DETECTION`` mechanism. It is enabled from v8.5 and upwards and if
+   needed could be overidden from platforms explicitly. Default value is ``0``.
+
+-  ``ENABLE_FEAT_SEL2``: Numeric value to enable the ``FEAT_SEL2`` (Secure EL2)
+   extension. ``FEAT_SEL2`` is a mandatory feature available on Arm v8.4.
+   This flag can take values 0 to 2, to align with the ``FEATURE_DETECTION``
+   mechanism. Default is ``0``.
+
+-  ``ENABLE_FEAT_VHE``: Numeric value to enable the ``FEAT_VHE`` (Virtualization
+   Host Extensions) extension. It allows access to CONTEXTIDR_EL2 register
+   during EL2 context save/restore operations.``FEAT_VHE`` is a mandatory
+   architectural feature and is enabled from v8.1 and upwards. It can take
+   values 0 to 2, to align  with the ``FEATURE_DETECTION`` mechanism.
+   Default value is ``0``.
 
 -  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
    support in GCC for TF-A. This option is currently only supported for
    AArch64. Default is 0.
 
--  ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
+-  ``ENABLE_MPAM_FOR_LOWER_ELS``: Numeric value to enable lower ELs to use MPAM
    feature. MPAM is an optional Armv8.4 extension that enables various memory
    system components and resources to define partitions; software running at
    various ELs can assign themselves to desired partition to control their
    performance aspects.
 
-   When this option is set to ``1``, EL3 allows lower ELs to access their own
-   MPAM registers without trapping into EL3. This option doesn't make use of
-   partitioning in EL3, however. Platform initialisation code should configure
-   and use partitions in EL3 as required. This option defaults to ``0``.
+   This flag can take values 0 to 2, to align  with the ``FEATURE_DETECTION``
+   mechanism. When this option is set to ``1`` or ``2``, EL3 allows lower ELs to
+   access their own MPAM registers without trapping into EL3. This option
+   doesn't make use of partitioning in EL3, however. Platform initialisation
+   code should configure and use partitions in EL3 as required. This option
+   defaults to ``0``.
 
 -  ``ENABLE_MPMM``: Boolean option to enable support for the Maximum Power
    Mitigation Mechanism supported by certain Arm cores, which allows the SoC
@@ -307,9 +375,10 @@
    be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in
    software.
 
-- ``ENABLE_RME``: Boolean option to enable support for the ARMv9 Realm
-   Management Extension. Default value is 0. This is currently an experimental
-   feature.
+- ``ENABLE_RME``: Numeric value to enable support for the ARMv9 Realm
+   Management Extension. This flag can take the values 0 to 2, to align with
+   the ``FEATURE_DETECTION`` mechanism. Default value is 0. This is currently
+   an experimental feature.
 
 -  ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime
    instrumentation which injects timestamp collection points into TF-A to
@@ -352,8 +421,8 @@
 
 -  ``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
@@ -399,6 +468,43 @@
    This feature is intended for testing purposes only, and is advisable to keep
    disabled for production images.
 
+-  ``FEATURE_DETECTION``: Boolean option to enable the architectural features
+   detection mechanism. It detects whether the Architectural features enabled
+   through feature specific build flags are supported by the PE or not by
+   validating them either at boot phase or at runtime based on the value
+   possessed by the feature flag (0 to 2) and report error messages at an early
+   stage.
+
+   This prevents and benefits us from EL3 runtime exceptions during context save
+   and restore routines guarded by these build flags. Henceforth validating them
+   before their usage provides more control on the actions taken under them.
+
+   The mechanism permits the build flags to take values 0, 1 or 2 and
+   evaluates them accordingly.
+
+   Lets consider ``ENABLE_FEAT_HCX``, build flag for ``FEAT_HCX`` as an example:
+
+   ::
+
+     ENABLE_FEAT_HCX = 0: Feature disabled statically at compile time.
+     ENABLE_FEAT_HCX = 1: Feature Enabled and the flag is validated at boottime.
+     ENABLE_FEAT_HCX = 2: Feature Enabled and the flag is validated at runtime.
+
+   In the above example, if the feature build flag, ``ENABLE_FEAT_HCX`` set to
+   0, feature is disabled statically during compilation. If it is defined as 1,
+   feature is validated, wherein FEAT_HCX is detected at boot time. In case not
+   implemented by the PE, a hard panic is generated. Finally, if the flag is set
+   to 2, feature is validated at runtime.
+
+   Note that the entire implementation is divided into two phases, wherein as
+   as part of phase-1 we are supporting the values 0,1. Value 2 is currently not
+   supported and is planned to be handled explicilty in phase-2 implementation.
+
+   FEATURE_DETECTION macro is disabled by default, and is currently an
+   experimental procedure. Platforms can explicitly make use of this by
+   mechanism, by enabling it to validate whether they have set their build flags
+   properly at an early phase.
+
 -  ``FIP_NAME``: This is an optional build option which specifies the FIP
    filename for the ``fip`` target. Default is ``fip.bin``.
 
@@ -588,9 +694,10 @@
    enabled on Arm platforms, the option ``ARM_RECOM_STATE_ID_ENC`` needs to be
    set to 1 as well.
 
--  ``RAS_EXTENSION``: When set to ``1``, enable Armv8.2 RAS features. RAS features
+-  ``RAS_EXTENSION``: Numeric value to enable Armv8.2 RAS features. RAS features
    are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
-   or later CPUs.
+   or later CPUs. This flag can take the values 0 to 2, to align with the
+   ``FEATURE_DETECTION`` mechanism.
 
    When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST`` must also be
    set to ``1``.
@@ -647,6 +754,13 @@
    ``BL31_NOBITS_LIMIT``. When the option is ``0`` (the default), NOBITS
    sections are placed in RAM immediately following the loaded firmware image.
 
+-  ``SEPARATE_BL2_NOLOAD_REGION``: Setting this option to ``1`` allows the
+   NOLOAD sections of BL2 (.bss, stacks, page tables) to be allocated in RAM
+   discontiguous from loaded firmware images. When set, the platform need to
+   provide definitions of ``BL2_NOLOAD_START`` and ``BL2_NOLOAD_LIMIT``. This
+   flag is disabled by default and NOLOAD sections are placed in RAM immediately
+   following the loaded firmware image.
+
 -  ``SMC_PCI_SUPPORT``: This option allows platforms to handle PCI configuration
    access requests via a standard SMCCC defined in `DEN0115`_. When combined with
    UEFI+ACPI this can provide a certain amount of OS forward compatibility
@@ -666,7 +780,7 @@
    firmware images have been loaded in memory, and the MMU and caches are
    turned off. Refer to the "Debugging options" section for more details.
 
--  ``SPMD_SPM_AT_SEL2`` : this boolean option is used jointly with the SPM
+-  ``SPMD_SPM_AT_SEL2`` : This boolean option is used jointly with the SPM
    Dispatcher option (``SPD=spmd``). When enabled (1) it indicates the SPMC
    component runs at the S-EL2 execution state provided by the Armv8.4-SecEL2
    extension. This is the default when enabling the SPM Dispatcher. When
@@ -844,9 +958,10 @@
   but unused). This feature is available if trace unit such as ETMv4.x, and
   ETE(extending ETM feature) is implemented. This flag is disabled by default.
 
-- ``ENABLE_TRF_FOR_NS``: Boolean option to enable trace filter control registers
+- ``ENABLE_TRF_FOR_NS``: Numeric value to enable trace filter control registers
   access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused),
-  if FEAT_TRF is implemented. This flag is disabled by default.
+  if FEAT_TRF is implemented. This flag can take the values 0 to 2, to align
+  with the ``FEATURE_DETECTION`` mechanism. This flag is disabled by default.
 
 GICv3 driver options
 --------------------
@@ -961,7 +1076,7 @@
 
 --------------
 
-*Copyright (c) 2019-2021, Arm Limited. All rights reserved.*
+*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
 
 .. _DEN0115: https://developer.arm.com/docs/den0115/latest
 .. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 7f10ca6..3d3b2e3 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -2017,6 +2017,58 @@
 (that was copied during ``bl31_early_platform_setup()``) if the image exists. It
 should return NULL otherwise.
 
+Function : plat_get_cca_attest_token() [mandatory when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uintptr_t, size_t *, uintptr_t, size_t
+    Return   : int
+
+This function returns the Platform attestation token.
+
+The parameters of the function are:
+
+    arg0 - A pointer to the buffer where the Platform token should be copied by
+           this function. The buffer must be big enough to hold the Platform
+           token.
+
+    arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
+           function returns the platform token length in this parameter.
+
+    arg2 - A pointer to the buffer where the challenge object is stored.
+
+    arg3 - The length of the challenge object in bytes. Possible values are 32,
+           48 and 64.
+
+The function returns 0 on success, -EINVAL on failure.
+
+Function : plat_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    Argument : uintptr_t, size_t *, unsigned int
+    Return   : int
+
+This function returns the delegated realm attestation key which will be used to
+sign Realm attestation token. The API currently only supports P-384 ECC curve
+key.
+
+The parameters of the function are:
+
+    arg0 - A pointer to the buffer where the attestation key should be copied
+           by this function. The buffer must be big enough to hold the
+           attestation key.
+
+    arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
+           function returns the attestation key length in this parameter.
+
+    arg2 - The type of the elliptic curve to which the requested attestation key
+           belongs.
+
+The function returns 0 on success, -EINVAL on failure.
+
 Function : bl31_plat_enable_mmu [optional]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -3154,7 +3206,7 @@
 
 --------------
 
-*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.*
 
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
 .. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
diff --git a/docs/plat/nxp/nxp-layerscape.rst b/docs/plat/nxp/nxp-layerscape.rst
index 6cbd7f9..cd5874b 100644
--- a/docs/plat/nxp/nxp-layerscape.rst
+++ b/docs/plat/nxp/nxp-layerscape.rst
@@ -103,7 +103,7 @@
 Arm Cortex-A72 cores with ECC-protected L1 and L2 cache memories for high
 reliability, running up to 1.8 GHz.
 
-Details about LS1043A can be found at `ls1046a`_.
+Details about LS1046A can be found at `ls1046a`_.
 
 - LS1046ARDB Board:
 
@@ -113,7 +113,7 @@
 processor and is optimized to support the DDR4 memory and a full complement
 of high-speed SerDes ports.
 
-Details about LS1043A RDB board can be found at `ls1046ardb`_.
+Details about LS1046A RDB board can be found at `ls1046ardb`_.
 
 - LS1046AFRWY Board:
 
@@ -124,7 +124,28 @@
 Ethernet, USB3.0 and M2_Type_E interfaces for Wi-Fi, FRWY-LS1046A-AC includes
 the Wi-Fi card.
 
-Details about LS1043A RDB board can be found at `ls1046afrwy`_.
+Details about LS1046A FRWY board can be found at `ls1046afrwy`_.
+
+5. LS1088A
+
+- SoC Overview:
+
+The LS1088A family of multicore communications processors combines up to and eight
+Arm Cortex-A53 cores with the advanced, high-performance data path and network
+peripheral interfaces required for wireless access points, networking infrastructure,
+intelligent edge access, including virtual customer premise equipment (vCPE) and
+high-performance industrial applications.
+
+Details about LS1088A can be found at `ls1088a`_.
+
+- LS1088ARDB Board:
+
+The LS1088A reference design board provides a comprehensive platform that
+enables design and evaluation of the product (LS1088A processor). This RDB
+comes pre-loaded with a board support package (BSP) based on a standard
+Linux kernel.
+
+Details about LS1088A RDB board can be found at `ls1088ardb`_.
 
 Table of supported boot-modes by each platform & platform that needs FIP-DDR:
 -----------------------------------------------------------------------------
@@ -144,6 +165,8 @@
 +---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
 |     ls1046afrwy     |  yes  |  yes   |       |       |       |             |              |       no        |
 +---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
+|     ls1088ardb      |  yes  |  yes   |       |       |       |             |              |       no        |
++---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+
 
 
 Boot Sequence
@@ -336,7 +359,7 @@
 
    --  Then reset to alternate bank to boot up ATF.
 
-   Command for lx2160a and ls1028a platforms:
+   Command for lx2160a, ls1088a and ls1028a platforms:
 
    .. code:: shell
 
@@ -370,7 +393,7 @@
 
    --  Then reset to sd/emmc to boot up ATF from sd/emmc as boot-source.
 
-   Command for lx2160A and ls1028a platforms:
+   Command for lx2160A, ls1088a and ls1028a platforms:
 
    .. code:: shell
 
@@ -445,4 +468,6 @@
 .. _ls1046a: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-1046a-and-1026a-processors:LS1046A
 .. _ls1046ardb: https://www.nxp.com/design/qoriq-developer-resources/layerscape-ls1046a-reference-design-board:LS1046A-RDB
 .. _ls1046afrwy: https://www.nxp.com/design/qoriq-developer-resources/ls1046a-freeway-board:FRWY-LS1046A
+.. _ls1088a: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-1088a-and-1048a-processor:LS1088A
+.. _ls1088ardb: https://www.nxp.com/design/qoriq-developer-resources/layerscape-ls1088a-reference-design-board:LS1088A-RDB
 .. _nxp-ls-tbbr.rst: ./nxp-ls-tbbr.rst
diff --git a/drivers/fwu/fwu.c b/drivers/fwu/fwu.c
index 80f870b..ff432be 100644
--- a/drivers/fwu/fwu.c
+++ b/drivers/fwu/fwu.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,7 +25,7 @@
 	crc_32_must_be_first_member_of_structure);
 
 static struct fwu_metadata metadata;
-static bool is_fwu_initialized;
+static bool is_metadata_initialized __unused;
 
 /*******************************************************************************
  * Compute CRC32 of the FWU metadata, and check it against the CRC32 value
@@ -142,7 +142,7 @@
 {
 	bool trial_run = false;
 
-	assert(is_fwu_initialized);
+	assert(is_metadata_initialized);
 
 	for (unsigned int i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
 		struct fwu_image_entry *entry = &metadata.img_entry[i];
@@ -159,7 +159,7 @@
 
 const struct fwu_metadata *fwu_get_metadata(void)
 {
-	assert(is_fwu_initialized);
+	assert(is_metadata_initialized);
 
 	return &metadata;
 }
@@ -188,7 +188,7 @@
 		}
 	}
 
-	plat_fwu_set_images_source(&metadata);
+	is_metadata_initialized = true;
 
-	is_fwu_initialized = true;
+	plat_fwu_set_images_source(&metadata);
 }
diff --git a/drivers/nxp/dcfg/dcfg.c b/drivers/nxp/dcfg/dcfg.c
index a988c5d..e5c4db4 100644
--- a/drivers/nxp/dcfg/dcfg.c
+++ b/drivers/nxp/dcfg/dcfg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2021 NXP
+ * Copyright 2020-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -74,14 +74,11 @@
 
 	reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_DEVDISR5_OFFSET);
 
-#if defined(CONFIG_CHASSIS_3_2)
 	devdisr5_info.ddrc1_present = (reg & DISR5_DDRC1_MASK) ? 0 : 1;
+#if defined(CONFIG_CHASSIS_3_2)
 	devdisr5_info.ddrc2_present = (reg & DISR5_DDRC2_MASK) ? 0 : 1;
-	devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
-#elif defined(CONFIG_CHASSIS_2)
-	devdisr5_info.ddrc1_present = (reg & DISR5_DDRC1_MASK) ? 0 : 1;
-	devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
 #endif
+	devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
 	devdisr5_info.is_populated = true;
 
 	return (const devdisr5_info_t *) &devdisr5_info;
diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.mk b/drivers/nxp/ddr/nxp-ddr/ddr.mk
index 6bdd947..f827a1b 100644
--- a/drivers/nxp/ddr/nxp-ddr/ddr.mk
+++ b/drivers/nxp/ddr/nxp-ddr/ddr.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2021 NXP
+# Copyright 2021-2022 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,6 +19,10 @@
 $(eval $(call add_define,ERRATA_DDR_A050450))
 endif
 
+ifeq (${ERRATA_DDR_A050958}, 1)
+$(eval $(call add_define,ERRATA_DDR_A050958))
+endif
+
 endif
 
 ifeq ($(PLAT_DDR_PHY), PHY_GEN1)
diff --git a/drivers/nxp/ddr/nxp-ddr/dimm.c b/drivers/nxp/ddr/nxp-ddr/dimm.c
index 16efcba..a82db6c 100644
--- a/drivers/nxp/ddr/nxp-ddr/dimm.c
+++ b/drivers/nxp/ddr/nxp-ddr/dimm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -194,7 +194,7 @@
 	case DDR4_SPD_MINI_RDIMM:
 	case DDR4_SPD_72B_SO_RDIMM:
 		pdimm->rdimm = 1;
-		pdimm->rc = spd->mod_section.registered.ref_raw_card & 0x8f;
+		pdimm->rc = spd->mod_section.registered.ref_raw_card & 0x9f;
 		if ((spd->mod_section.registered.reg_map & 0x1) != 0) {
 			pdimm->mirrored_dimm = 1;
 		}
@@ -223,7 +223,7 @@
 	case DDR4_SPD_72B_SO_UDIMM:
 	case DDR4_SPD_16B_SO_DIMM:
 	case DDR4_SPD_32B_SO_DIMM:
-		pdimm->rc = spd->mod_section.unbuffered.ref_raw_card & 0x8f;
+		pdimm->rc = spd->mod_section.unbuffered.ref_raw_card & 0x9f;
 		if ((spd->mod_section.unbuffered.addr_mapping & 0x1) != 0) {
 			pdimm->mirrored_dimm = 1;
 		}
diff --git a/drivers/nxp/ddr/phy-gen2/phy.c b/drivers/nxp/ddr/phy-gen2/phy.c
index 9c84b00..c8245a8 100644
--- a/drivers/nxp/ddr/phy-gen2/phy.c
+++ b/drivers/nxp/ddr/phy-gen2/phy.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
@@ -1673,6 +1673,10 @@
 	int sel_analog_vref = 1;
 	uint32_t addr;
 
+#ifdef ERRATA_DDR_A050958
+	gain_curr_adj_defval = 0x1f;
+#endif
+
 	dq_dqs_rcv_cntrl = gain_curr_adj_defval << csr_gain_curr_adj_lsb |
 			major_mode_dbyte << csr_major_mode_dbyte_lsb	|
 			dfe_ctrl_defval << csr_dfe_ctrl_lsb		|
@@ -2212,10 +2216,14 @@
 
 	size = PHY_GEN2_MAX_IMAGE_SIZE;
 	image_buf = (uintptr_t)phy_gen2_fw_img_buf;
-	mmap_add_dynamic_region(phy_gen2_fw_img_buf,
+	ret = mmap_add_dynamic_region(phy_gen2_fw_img_buf,
 			phy_gen2_fw_img_buf,
 			PHY_GEN2_MAX_IMAGE_SIZE,
 			MT_MEMORY | MT_RW | MT_SECURE);
+	if (ret != 0) {
+		ERROR("Failed to add dynamic memory region.\n");
+		return ret;
+	}
 	ret = img_loadr(imem_id, &image_buf, &size);
 	if (ret != 0) {
 		ERROR("Failed to load %d firmware.\n", imem_id);
diff --git a/drivers/scmi-msg/clock.c b/drivers/scmi-msg/clock.c
index e96cede..85bf7d2 100644
--- a/drivers/scmi-msg/clock.c
+++ b/drivers/scmi-msg/clock.c
@@ -361,7 +361,7 @@
 	[SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set,
 };
 
-static bool message_id_is_supported(size_t message_id)
+static bool message_id_is_supported(unsigned int message_id)
 {
 	return (message_id < ARRAY_SIZE(scmi_clock_handler_table)) &&
 	       (scmi_clock_handler_table[message_id] != NULL);
diff --git a/drivers/scmi-msg/power_domain.c b/drivers/scmi-msg/power_domain.c
index c4e1289..87c41dd 100644
--- a/drivers/scmi-msg/power_domain.c
+++ b/drivers/scmi-msg/power_domain.c
@@ -19,7 +19,7 @@
 #pragma weak plat_scmi_pd_statistics
 #pragma weak plat_scmi_pd_get_attributes
 
-static bool message_id_is_supported(size_t message_id);
+static bool message_id_is_supported(unsigned int message_id);
 
 size_t plat_scmi_pd_count(unsigned int agent_id __unused)
 {
@@ -219,7 +219,7 @@
 	[SCMI_PD_STATE_GET] = scmi_pd_state_get,
 };
 
-static bool message_id_is_supported(size_t message_id)
+static bool message_id_is_supported(unsigned int message_id)
 {
 	return (message_id < ARRAY_SIZE(scmi_pd_handler_table)) &&
 	       (scmi_pd_handler_table[message_id] != NULL);
diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S
index ad2a039..8b6765a 100644
--- a/include/arch/aarch32/el3_common_macros.S
+++ b/include/arch/aarch32/el3_common_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -398,6 +398,12 @@
 		ldr	r1, =__RW_END__
 		sub	r1, r1, r0
 		bl	inv_dcache_range
+#if defined(IMAGE_BL2) && SEPARATE_BL2_NOLOAD_REGION
+		ldr	r0, =__BL2_NOLOAD_START__
+		ldr	r1, =__BL2_NOLOAD_END__
+		sub	r1, r1, r0
+		bl	inv_dcache_range
+#endif
 #endif
 
 		/*
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 29da33c..b4608ae 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -99,7 +99,6 @@
 /*******************************************************************************
  * Definitions for EL2 system registers for save/restore routine
  ******************************************************************************/
-
 #define CNTPOFF_EL2		S3_4_C14_C0_6
 #define HAFGRTR_EL2		S3_4_C3_C1_6
 #define HDFGRTR_EL2		S3_4_C3_C1_4
@@ -155,39 +154,55 @@
 #endif
 
 /* ID_AA64PFR0_EL1 definitions */
-#define ID_AA64PFR0_EL0_SHIFT	U(0)
-#define ID_AA64PFR0_EL1_SHIFT	U(4)
-#define ID_AA64PFR0_EL2_SHIFT	U(8)
-#define ID_AA64PFR0_EL3_SHIFT	U(12)
-#define ID_AA64PFR0_AMU_SHIFT	U(44)
-#define ID_AA64PFR0_AMU_MASK	ULL(0xf)
-#define ID_AA64PFR0_AMU_NOT_SUPPORTED	U(0x0)
-#define ID_AA64PFR0_AMU_V1	U(0x1)
-#define ID_AA64PFR0_AMU_V1P1	U(0x2)
-#define ID_AA64PFR0_ELX_MASK	ULL(0xf)
-#define ID_AA64PFR0_GIC_SHIFT	U(24)
-#define ID_AA64PFR0_GIC_WIDTH	U(4)
-#define ID_AA64PFR0_GIC_MASK	ULL(0xf)
-#define ID_AA64PFR0_SVE_SHIFT	U(32)
-#define ID_AA64PFR0_SVE_MASK	ULL(0xf)
-#define ID_AA64PFR0_SVE_LENGTH	U(4)
-#define ID_AA64PFR0_SEL2_SHIFT	U(36)
-#define ID_AA64PFR0_SEL2_MASK	ULL(0xf)
-#define ID_AA64PFR0_MPAM_SHIFT	U(40)
-#define ID_AA64PFR0_MPAM_MASK	ULL(0xf)
-#define ID_AA64PFR0_DIT_SHIFT	U(48)
-#define ID_AA64PFR0_DIT_MASK	ULL(0xf)
-#define ID_AA64PFR0_DIT_LENGTH	U(4)
-#define ID_AA64PFR0_DIT_SUPPORTED	U(1)
-#define ID_AA64PFR0_CSV2_SHIFT	U(56)
-#define ID_AA64PFR0_CSV2_MASK	ULL(0xf)
-#define ID_AA64PFR0_CSV2_LENGTH	U(4)
+#define ID_AA64PFR0_EL0_SHIFT			U(0)
+#define ID_AA64PFR0_EL1_SHIFT			U(4)
+#define ID_AA64PFR0_EL2_SHIFT			U(8)
+#define ID_AA64PFR0_EL3_SHIFT			U(12)
+
+#define ID_AA64PFR0_AMU_SHIFT			U(44)
+#define ID_AA64PFR0_AMU_MASK			ULL(0xf)
+#define ID_AA64PFR0_AMU_NOT_SUPPORTED		U(0x0)
+#define ID_AA64PFR0_AMU_V1			ULL(0x1)
+#define ID_AA64PFR0_AMU_V1P1			U(0x2)
+
+#define ID_AA64PFR0_ELX_MASK			ULL(0xf)
+
+#define ID_AA64PFR0_GIC_SHIFT			U(24)
+#define ID_AA64PFR0_GIC_WIDTH			U(4)
+#define ID_AA64PFR0_GIC_MASK			ULL(0xf)
+
+#define ID_AA64PFR0_SVE_SHIFT			U(32)
+#define ID_AA64PFR0_SVE_MASK			ULL(0xf)
+#define ID_AA64PFR0_SVE_SUPPORTED		ULL(0x1)
+#define ID_AA64PFR0_SVE_LENGTH			U(4)
+
+#define ID_AA64PFR0_SEL2_SHIFT			U(36)
+#define ID_AA64PFR0_SEL2_MASK			ULL(0xf)
+
+#define ID_AA64PFR0_MPAM_SHIFT			U(40)
+#define ID_AA64PFR0_MPAM_MASK			ULL(0xf)
+
+#define ID_AA64PFR0_DIT_SHIFT			U(48)
+#define ID_AA64PFR0_DIT_MASK			ULL(0xf)
+#define ID_AA64PFR0_DIT_LENGTH			U(4)
+#define ID_AA64PFR0_DIT_SUPPORTED		U(1)
+
+#define ID_AA64PFR0_CSV2_SHIFT			U(56)
+#define ID_AA64PFR0_CSV2_MASK			ULL(0xf)
+#define ID_AA64PFR0_CSV2_LENGTH			U(4)
+#define ID_AA64PFR0_CSV2_2_SUPPORTED		ULL(0x2)
+
 #define ID_AA64PFR0_FEAT_RME_SHIFT		U(52)
 #define ID_AA64PFR0_FEAT_RME_MASK		ULL(0xf)
 #define ID_AA64PFR0_FEAT_RME_LENGTH		U(4)
 #define ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED	U(0)
 #define ID_AA64PFR0_FEAT_RME_V1			U(1)
 
+#define ID_AA64PFR0_RAS_SHIFT			U(28)
+#define ID_AA64PFR0_RAS_MASK			ULL(0xf)
+#define ID_AA64PFR0_RAS_NOT_SUPPORTED		ULL(0x0)
+#define ID_AA64PFR0_RAS_LENGTH			U(4)
+
 /* Exception level handling */
 #define EL_IMPL_NONE		ULL(0)
 #define EL_IMPL_A64ONLY		ULL(1)
@@ -204,8 +219,10 @@
 #define ID_AA64DFR0_TRACEFILT_LENGTH	U(4)
 
 /* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
-#define ID_AA64DFR0_PMS_SHIFT	U(32)
-#define ID_AA64DFR0_PMS_MASK	ULL(0xf)
+#define ID_AA64DFR0_PMS_SHIFT		U(32)
+#define ID_AA64DFR0_PMS_MASK		ULL(0xf)
+#define ID_AA64DFR0_SPE_SUPPORTED	ULL(0x1)
+#define ID_AA64DFR0_SPE_NOT_SUPPORTED   ULL(0x0)
 
 /* ID_AA64DFR0_EL1.TraceBuffer definitions */
 #define ID_AA64DFR0_TRACEBUFFER_SHIFT		U(44)
@@ -222,15 +239,22 @@
 #define ID_AA64ISAR0_RNDR_MASK	ULL(0xf)
 
 /* ID_AA64ISAR1_EL1 definitions */
-#define ID_AA64ISAR1_EL1	S3_0_C0_C6_1
-#define ID_AA64ISAR1_GPI_SHIFT	U(28)
-#define ID_AA64ISAR1_GPI_MASK	ULL(0xf)
-#define ID_AA64ISAR1_GPA_SHIFT	U(24)
-#define ID_AA64ISAR1_GPA_MASK	ULL(0xf)
-#define ID_AA64ISAR1_API_SHIFT	U(8)
-#define ID_AA64ISAR1_API_MASK	ULL(0xf)
-#define ID_AA64ISAR1_APA_SHIFT	U(4)
-#define ID_AA64ISAR1_APA_MASK	ULL(0xf)
+#define ID_AA64ISAR1_EL1		S3_0_C0_C6_1
+
+#define ID_AA64ISAR1_GPI_SHIFT		U(28)
+#define ID_AA64ISAR1_GPI_MASK		ULL(0xf)
+#define ID_AA64ISAR1_GPA_SHIFT		U(24)
+#define ID_AA64ISAR1_GPA_MASK		ULL(0xf)
+
+#define ID_AA64ISAR1_API_SHIFT		U(8)
+#define ID_AA64ISAR1_API_MASK		ULL(0xf)
+#define ID_AA64ISAR1_APA_SHIFT		U(4)
+#define ID_AA64ISAR1_APA_MASK		ULL(0xf)
+
+#define ID_AA64ISAR1_SB_SHIFT		U(36)
+#define ID_AA64ISAR1_SB_MASK		ULL(0xf)
+#define ID_AA64ISAR1_SB_SUPPORTED	ULL(0x1)
+#define ID_AA64ISAR1_SB_NOT_SUPPORTED	ULL(0x0)
 
 /* ID_AA64MMFR0_EL1 definitions */
 #define ID_AA64MMFR0_EL1_PARANGE_SHIFT	U(0)
@@ -292,17 +316,23 @@
 #define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED	ULL(0x0)
 
 /* ID_AA64MMFR2_EL1 definitions */
-#define ID_AA64MMFR2_EL1		S3_0_C0_C7_2
+#define ID_AA64MMFR2_EL1			S3_0_C0_C7_2
 
-#define ID_AA64MMFR2_EL1_ST_SHIFT	U(28)
-#define ID_AA64MMFR2_EL1_ST_MASK	ULL(0xf)
+#define ID_AA64MMFR2_EL1_ST_SHIFT		U(28)
+#define ID_AA64MMFR2_EL1_ST_MASK		ULL(0xf)
 
-#define ID_AA64MMFR2_EL1_CCIDX_SHIFT	U(20)
-#define ID_AA64MMFR2_EL1_CCIDX_MASK	ULL(0xf)
-#define ID_AA64MMFR2_EL1_CCIDX_LENGTH	U(4)
+#define ID_AA64MMFR2_EL1_CCIDX_SHIFT		U(20)
+#define ID_AA64MMFR2_EL1_CCIDX_MASK		ULL(0xf)
+#define ID_AA64MMFR2_EL1_CCIDX_LENGTH		U(4)
+
+#define ID_AA64MMFR2_EL1_CNP_SHIFT		U(0)
+#define ID_AA64MMFR2_EL1_CNP_MASK		ULL(0xf)
 
-#define ID_AA64MMFR2_EL1_CNP_SHIFT	U(0)
-#define ID_AA64MMFR2_EL1_CNP_MASK	ULL(0xf)
+#define ID_AA64MMFR2_EL1_NV_SHIFT		U(24)
+#define ID_AA64MMFR2_EL1_NV_MASK		ULL(0xf)
+#define ID_AA64MMFR2_EL1_NV_NOT_SUPPORTED	ULL(0x0)
+#define ID_AA64MMFR2_EL1_NV_SUPPORTED		ULL(0x1)
+#define ID_AA64MMFR2_EL1_NV2_SUPPORTED		ULL(0x2)
 
 /* ID_AA64PFR1_EL1 definitions */
 #define ID_AA64PFR1_EL1_SSBS_SHIFT	U(4)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
index a260f03..29710e7 100644
--- a/include/arch/aarch64/arch_features.h
+++ b/include/arch/aarch64/arch_features.h
@@ -140,4 +140,88 @@
 		ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK;
 }
 
+/*********************************************************************************
+ * Function to identify the presence of FEAT_SB (Speculation Barrier Instruction)
+ ********************************************************************************/
+static inline bool is_armv8_0_feat_sb_present(void)
+{
+	return (((read_id_aa64isar1_el1() >> ID_AA64ISAR1_SB_SHIFT) &
+		ID_AA64ISAR1_SB_MASK) == ID_AA64ISAR1_SB_SUPPORTED);
+}
+
+/*********************************************************************************
+ * Function to identify the presence of FEAT_CSV2_2 (Cache Speculation Variant 2)
+ ********************************************************************************/
+static inline bool is_armv8_0_feat_csv2_2_present(void)
+{
+	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_CSV2_SHIFT) &
+		ID_AA64PFR0_CSV2_MASK) == ID_AA64PFR0_CSV2_2_SUPPORTED);
+}
+
+/**********************************************************************************
+ * Function to identify the presence of FEAT_SPE (Statistical Profiling Extension)
+ *********************************************************************************/
+static inline bool is_armv8_2_feat_spe_present(void)
+{
+	return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT) &
+		ID_AA64DFR0_PMS_MASK) != ID_AA64DFR0_SPE_NOT_SUPPORTED);
+}
+
+/*******************************************************************************
+ * Function to identify the presence of FEAT_SVE (Scalable Vector Extension)
+ ******************************************************************************/
+static inline bool is_armv8_2_feat_sve_present(void)
+{
+	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT) &
+		ID_AA64PFR0_SVE_MASK) == ID_AA64PFR0_SVE_SUPPORTED);
+}
+
+/*******************************************************************************
+ * Function to identify the presence of FEAT_RAS (Reliability,Availability,
+ * and Serviceability Extension)
+ ******************************************************************************/
+static inline bool is_armv8_2_feat_ras_present(void)
+{
+	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_RAS_SHIFT) &
+		ID_AA64PFR0_RAS_MASK) != ID_AA64PFR0_RAS_NOT_SUPPORTED);
+}
+
+/**************************************************************************
+ * Function to identify the presence of FEAT_DIT (Data Independent Timing)
+ *************************************************************************/
+static inline bool is_armv8_4_feat_dit_present(void)
+{
+	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_DIT_SHIFT) &
+		ID_AA64PFR0_DIT_MASK) == ID_AA64PFR0_DIT_SUPPORTED);
+}
+
+/*************************************************************************
+ * Function to identify the presence of FEAT_TRF (TraceLift)
+ ************************************************************************/
+static inline bool is_arm8_4_feat_trf_present(void)
+{
+	return (((read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT) &
+		ID_AA64DFR0_TRACEFILT_MASK) == ID_AA64DFR0_TRACEFILT_SUPPORTED);
+}
+
+/*******************************************************************************
+ * Function to identify the presence of FEAT_AMUv1 (Activity Monitors-
+ * Extension v1)
+ ******************************************************************************/
+static inline bool is_armv8_4_feat_amuv1_present(void)
+{
+	return (((read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) &
+		ID_AA64PFR0_AMU_MASK) >= ID_AA64PFR0_AMU_V1);
+}
+
+/********************************************************************************
+ * Function to identify the presence of FEAT_NV2 (Enhanced Nested Virtualization
+ * Support)
+ *******************************************************************************/
+static inline unsigned int get_armv8_4_feat_nv_support(void)
+{
+	return (((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_NV_SHIFT) &
+		ID_AA64MMFR2_EL1_NV_MASK));
+}
+
 #endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index d47244e..de2b931 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -469,6 +469,14 @@
 		sub	x1, x1, x0
 		bl	inv_dcache_range
 #endif
+#if defined(IMAGE_BL2) && SEPARATE_BL2_NOLOAD_REGION
+		adrp	x0, __BL2_NOLOAD_START__
+		add	x0, x0, :lo12:__BL2_NOLOAD_START__
+		adrp	x1, __BL2_NOLOAD_END__
+		add	x1, x1, :lo12:__BL2_NOLOAD_END__
+		sub	x1, x1, x0
+		bl	inv_dcache_range
+#endif
 #endif
 		adrp	x0, __BSS_START__
 		add	x0, x0, :lo12:__BSS_START__
diff --git a/include/common/bl_common.ld.h b/include/common/bl_common.ld.h
index 5147e37..9888a3c 100644
--- a/include/common/bl_common.ld.h
+++ b/include/common/bl_common.ld.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -70,7 +70,9 @@
  */
 #define BASE_XLAT_TABLE					\
 	. = ALIGN(16);					\
-	*(base_xlat_table)
+	__BASE_XLAT_TABLE_START__ = .;			\
+	*(base_xlat_table)				\
+	__BASE_XLAT_TABLE_END__ = .;
 
 #if PLAT_RO_XLAT_TABLES
 #define BASE_XLAT_TABLE_RO		BASE_XLAT_TABLE
@@ -210,7 +212,9 @@
  */
 #define XLAT_TABLE_SECTION				\
 	xlat_table (NOLOAD) : {				\
+		__XLAT_TABLE_START__ = .;		\
 		*(xlat_table)				\
+		__XLAT_TABLE_END__ = .;			\
 	}
 
 #endif /* BL_COMMON_LD_H */
diff --git a/include/common/feat_detect.h b/include/common/feat_detect.h
new file mode 100644
index 0000000..0f0f105
--- /dev/null
+++ b/include/common/feat_detect.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FEAT_DETECT_H
+#define FEAT_DETECT_H
+
+#include <arch_features.h>
+#include <common/debug.h>
+
+/* Function Prototypes */
+void detect_arch_features(void);
+
+/* Macro Definitions */
+#define FEAT_STATE_1	1
+#define FEAT_STATE_2	2
+#define feat_detect_panic(a, b)		((a) ? (void)0 : feature_panic(b))
+
+/*******************************************************************************
+ * Function : feature_panic
+ * Customised panic module with error logging mechanism to list the feature
+ * not supported by the PE.
+ ******************************************************************************/
+static inline void feature_panic(char *feat_name)
+{
+	ERROR("FEAT_%s not supported by the PE\n", feat_name);
+	panic();
+}
+
+#endif /* FEAT_DETECT_H */
diff --git a/include/drivers/nxp/crypto/caam/caam.h b/include/drivers/nxp/crypto/caam/caam.h
index 4984b54..6cc1f3d 100644
--- a/include/drivers/nxp/crypto/caam/caam.h
+++ b/include/drivers/nxp/crypto/caam/caam.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-2021 NXP
+ * Copyright 2017-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -15,7 +15,7 @@
 /* Job ring 3 is reserved for usage by sec firmware */
 #define DEFAULT_JR	3
 
-#if defined(CONFIG_CHASSIS_3_2) || defined(CONFIG_CHASSIS_2)
+#if defined(CONFIG_CHASSIS_3_2) || defined(CONFIG_CHASSIS_3) || defined(CONFIG_CHASSIS_2)
 #define CAAM_JR0_OFFSET			0x10000
 #define CAAM_JR1_OFFSET			0x20000
 #define CAAM_JR2_OFFSET			0x30000
diff --git a/include/drivers/nxp/dcfg/dcfg.h b/include/drivers/nxp/dcfg/dcfg.h
index 524450a..cf29b12 100644
--- a/include/drivers/nxp/dcfg/dcfg.h
+++ b/include/drivers/nxp/dcfg/dcfg.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2021 NXP
+ * Copyright 2018-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -12,7 +12,7 @@
 
 #if defined(CONFIG_CHASSIS_2)
 #include <dcfg_lsch2.h>
-#elif defined(CONFIG_CHASSIS_3_2)
+#elif defined(CONFIG_CHASSIS_3_2) || defined(CONFIG_CHASSIS_3)
 #include <dcfg_lsch3.h>
 #endif
 
diff --git a/include/drivers/nxp/gic/gicv3/plat_gic.h b/include/drivers/nxp/gic/gicv3/plat_gic.h
index f4e12de..0c0d0fc 100644
--- a/include/drivers/nxp/gic/gicv3/plat_gic.h
+++ b/include/drivers/nxp/gic/gicv3/plat_gic.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -21,8 +21,12 @@
 #define GICD_CTLR_OFFSET        0x0
 #define GICD_CLR_SPI_SR         0x58
 #define GICD_IGROUPR_2          0x88
+#define GICD_ISENABLER_1        0x104
+#define GICD_ICENABLER_1        0x184
 #define GICD_ISENABLER_2        0x108
 #define GICD_ICENABLER_2        0x188
+#define GICD_ISENABLER_3        0x10c
+#define GICD_ICENABLER_3        0x18c
 #define GICD_ICPENDR_2          0x288
 #define GICD_ICACTIVER_2        0x388
 #define GICD_IPRIORITYR_22      0x458
@@ -69,6 +73,9 @@
 #define GIC_IRM_SPI89           0x80000000
 
 #define GICD_IROUTER_VALUE      0x100
+#define GICD_ISENABLER_1_VALUE  0x10000000
+#define GICD_ISENABLER_2_VALUE  0x100
+#define GICD_ISENABLER_3_VALUE  0x20100
 #define GICR_WAKER_SLEEP_BIT    0x2
 #define GICR_WAKER_ASLEEP       (1 << 2 | 1 << 1)
 
diff --git a/include/lib/cpus/aarch64/cortex_a76ae.h b/include/lib/cpus/aarch64/cortex_a76ae.h
index 9e34efb..0d30f70 100644
--- a/include/lib/cpus/aarch64/cortex_a76ae.h
+++ b/include/lib/cpus/aarch64/cortex_a76ae.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,6 +12,9 @@
 /* Cortex-A76AE MIDR for revision 0 */
 #define CORTEX_A76AE_MIDR		U(0x410FD0E0)
 
+/* Cortex-A76 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A76AE_BHB_LOOP_COUNT	U(24)
+
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
  ******************************************************************************/
diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h
index f3cb39f..31da99e 100644
--- a/include/lib/cpus/aarch64/cortex_a78.h
+++ b/include/lib/cpus/aarch64/cortex_a78.h
@@ -35,8 +35,10 @@
 #define CORTEX_A78_ACTLR_TAM_BIT			(ULL(1) << 30)
 
 #define CORTEX_A78_ACTLR2_EL1				S3_0_C15_C1_1
+#define CORTEX_A78_ACTLR2_EL1_BIT_0			(ULL(1) << 0)
 #define CORTEX_A78_ACTLR2_EL1_BIT_1			(ULL(1) << 1)
 #define CORTEX_A78_ACTLR2_EL1_BIT_2			(ULL(1) << 2)
+#define CORTEX_A78_ACTLR2_EL1_BIT_40			(ULL(1) << 40)
 
 /*******************************************************************************
  * CPU Activity Monitor Unit register specific definitions.
diff --git a/include/lib/cpus/aarch64/cortex_a78_ae.h b/include/lib/cpus/aarch64/cortex_a78_ae.h
index 0c8adcf..b68ec1e 100644
--- a/include/lib/cpus/aarch64/cortex_a78_ae.h
+++ b/include/lib/cpus/aarch64/cortex_a78_ae.h
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
- * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +10,10 @@
 
 #include <cortex_a78.h>
 
-#define CORTEX_A78_AE_MIDR U(0x410FD420)
+#define CORTEX_A78_AE_MIDR 				U(0x410FD420)
+
+/* Cortex-A78AE loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A78_AE_BHB_LOOP_COUNT			U(32)
 
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
@@ -18,4 +21,11 @@
 #define CORTEX_A78_AE_CPUECTLR_EL1			CORTEX_A78_CPUECTLR_EL1
 #define CORTEX_A78_AE_CPUECTLR_EL1_BIT_8		CORTEX_A78_CPUECTLR_EL1_BIT_8
 
+/*******************************************************************************
+ * CPU Auxiliary Control register 2 specific definitions.
+ ******************************************************************************/
+#define CORTEX_A78_AE_ACTLR2_EL1			CORTEX_A78_ACTLR2_EL1
+#define CORTEX_A78_AE_ACTLR2_EL1_BIT_0			CORTEX_A78_ACTLR2_EL1_BIT_0
+#define CORTEX_A78_AE_ACTLR2_EL1_BIT_40			CORTEX_A78_ACTLR2_EL1_BIT_40
+
 #endif /* CORTEX_A78_AE_H */
diff --git a/include/lib/cpus/aarch64/cortex_a78c.h b/include/lib/cpus/aarch64/cortex_a78c.h
index adb13bc..b1945ed 100644
--- a/include/lib/cpus/aarch64/cortex_a78c.h
+++ b/include/lib/cpus/aarch64/cortex_a78c.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,9 @@
 
 #define CORTEX_A78C_MIDR			        U(0x410FD4B1)
 
+/* Cortex-A76 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A78C_BHB_LOOP_COUNT			U(32)
+
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
  ******************************************************************************/
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index 512d196..d2d12e5 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -217,13 +217,13 @@
 
 // Starting with Armv8.4
 #define CTX_CONTEXTIDR_EL2	U(0x198)
-#define CTX_SDER32_EL2		U(0x1a0)
-#define CTX_TTBR1_EL2		U(0x1a8)
-#define CTX_VDISR_EL2		U(0x1b0)
-#define CTX_VNCR_EL2		U(0x1b8)
-#define CTX_VSESR_EL2		U(0x1c0)
-#define CTX_VSTCR_EL2		U(0x1c8)
-#define CTX_VSTTBR_EL2		U(0x1d0)
+#define CTX_TTBR1_EL2		U(0x1a0)
+#define CTX_VDISR_EL2		U(0x1a8)
+#define CTX_VSESR_EL2		U(0x1b0)
+#define CTX_VSTCR_EL2		U(0x1b8)
+#define CTX_VSTTBR_EL2		U(0x1c0)
+#define CTX_SDER32_EL2		U(0x1c8)
+#define CTX_VNCR_EL2		U(0x1d0)
 #define CTX_TRFCR_EL2		U(0x1d8)
 
 // Starting with Armv8.5
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 509fd58..7664509 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -303,6 +303,14 @@
 			unsigned int ncpu);
 
 /*******************************************************************************
+ * Mandatory BL31 functions when ENABLE_RME=1
+ ******************************************************************************/
+int plat_get_cca_attest_token(uintptr_t buf, size_t *len,
+			       uintptr_t hash, size_t hash_size);
+int plat_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
+				   unsigned int type);
+
+/*******************************************************************************
  * Optional BL31 functions (may be overridden)
  ******************************************************************************/
 void bl31_plat_enable_mmu(uint32_t flags);
diff --git a/include/services/gtsi_svc.h b/include/services/gtsi_svc.h
deleted file mode 100644
index ef4289f..0000000
--- a/include/services/gtsi_svc.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef GTSI_SVC_H
-#define GTSI_SVC_H
-
-/* GTSI error codes. */
-#define GTSI_SUCCESS			0
-#define GTSI_ERROR_NOT_SUPPORTED	-1
-#define GTSI_ERROR_INVALID_ADDRESS	-2
-#define GTSI_ERROR_INVALID_PAS		-3
-
-/* The macros below are used to identify GTSI calls from the SMC function ID */
-#define GTSI_FNUM_MIN_VALUE	U(0x1B0)
-#define GTSI_FNUM_MAX_VALUE	U(0x1B1)
-#define is_gtsi_fid(fid) __extension__ ({		\
-	__typeof__(fid) _fid = (fid);			\
-	((GET_SMC_NUM(_fid) >= GTSI_FNUM_MIN_VALUE) &&	\
-	(GET_SMC_NUM(_fid) <= GTSI_FNUM_MAX_VALUE)  &&	\
-	(GET_SMC_TYPE(_fid) == SMC_TYPE_FAST)	    &&	\
-	(GET_SMC_CC(_fid) == SMC_64)                &&	\
-	(GET_SMC_OEN(_fid) == OEN_STD_START)        &&	\
-	((_fid & 0x00FE0000) == 0U)); })
-
-/* Get GTSI fastcall std FID from function number */
-#define GTSI_FID(smc_cc, func_num)			\
-	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)	|	\
-	 ((smc_cc) << FUNCID_CC_SHIFT)		|	\
-	 (OEN_STD_START << FUNCID_OEN_SHIFT)	|	\
-	 ((func_num) << FUNCID_NUM_SHIFT))
-
-#define GRAN_TRANS_TO_REALM_FNUM	U(0x1B0)
-#define GRAN_TRANS_TO_NS_FNUM		U(0x1B1)
-
-#define SMC_ASC_MARK_REALM	GTSI_FID(SMC_64, GRAN_TRANS_TO_REALM_FNUM)
-#define SMC_ASC_MARK_NONSECURE	GTSI_FID(SMC_64, GRAN_TRANS_TO_NS_FNUM)
-
-#define GRAN_TRANS_RET_BAD_ADDR		-2
-#define GRAN_TRANS_RET_BAD_PAS		-3
-
-#endif /* GTSI_SVC_H */
diff --git a/include/services/rmi_svc.h b/include/services/rmi_svc.h
deleted file mode 100644
index 46fd510..0000000
--- a/include/services/rmi_svc.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef RMI_SVC_H
-#define RMI_SVC_H
-
-#include <lib/smccc.h>
-#include <lib/utils_def.h>
-
-/* RMI error codes. */
-#define RMI_SUCCESS			0
-#define RMI_ERROR_NOT_SUPPORTED		-1
-#define RMI_ERROR_INVALID_ADDRESS	-2
-#define RMI_ERROR_INVALID_PAS		-3
-
-/* The macros below are used to identify RMI calls from the SMC function ID */
-#define RMI_FNUM_MIN_VALUE	U(0x150)
-#define RMI_FNUM_MAX_VALUE	U(0x18F)
-#define is_rmi_fid(fid) __extension__ ({		\
-	__typeof__(fid) _fid = (fid);			\
-	((GET_SMC_NUM(_fid) >= RMI_FNUM_MIN_VALUE) &&	\
-	 (GET_SMC_NUM(_fid) <= RMI_FNUM_MAX_VALUE) &&	\
-	 (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST)	   &&	\
-	 (GET_SMC_CC(_fid) == SMC_64)              &&	\
-	 (GET_SMC_OEN(_fid) == OEN_STD_START)      &&	\
-	 ((_fid & 0x00FE0000) == 0U)); })
-
-/* Get RMI fastcall std FID from function number */
-#define RMI_FID(smc_cc, func_num)			\
-	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)	|	\
-	((smc_cc) << FUNCID_CC_SHIFT)		|	\
-	(OEN_STD_START << FUNCID_OEN_SHIFT)	|	\
-	((func_num) << FUNCID_NUM_SHIFT))
-
-/*
- * SMC_RMM_INIT_COMPLETE is the only function in the RMI that originates from
- * the Realm world and is handled by the RMMD. The remaining functions are
- * always invoked by the Normal world, forwarded by RMMD and handled by the
- * RMM
- */
-#define RMI_FNUM_REQ_COMPLETE		U(0x18F)
-#define RMI_FNUM_VERSION_REQ		U(0x150)
-
-#define RMI_FNUM_GRANULE_DELEGATE	U(0x151)
-#define RMI_FNUM_GRANULE_UNDELEGATE	U(0x152)
-
-/* RMI SMC64 FIDs handled by the RMMD */
-#define RMI_RMM_REQ_COMPLETE		RMI_FID(SMC_64, RMI_FNUM_REQ_COMPLETE)
-#define RMI_RMM_REQ_VERSION		RMI_FID(SMC_64, RMI_FNUM_VERSION_REQ)
-
-#define RMI_RMM_GRANULE_DELEGATE	RMI_FID(SMC_64, \
-						RMI_FNUM_GRANULE_DELEGATE)
-#define RMI_RMM_GRANULE_UNDELEGATE	RMI_FID(SMC_64, \
-						RMI_FNUM_GRANULE_UNDELEGATE)
-
-#define RMI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16)
-#define RMI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF)
-
-/* Reserve a special value for MBZ parameters. */
-#define RMI_PARAM_MBZ			U(0x0)
-
-#endif /* RMI_SVC_H */
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index 132973b..2fbdddd 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,115 @@
 #ifndef RMMD_SVC_H
 #define RMMD_SVC_H
 
+#include <lib/smccc.h>
+#include <lib/utils_def.h>
+
+/* Construct RMM fastcall std FID from function number */
+#define RMM_FID(smc_cc, func_num)			\
+	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)	|	\
+	((smc_cc) << FUNCID_CC_SHIFT)		|	\
+	(OEN_STD_START << FUNCID_OEN_SHIFT)	|	\
+	((func_num) << FUNCID_NUM_SHIFT))
+
+/* The macros below are used to identify RMI calls from the SMC function ID */
+#define RMI_FNUM_MIN_VALUE	U(0x150)
+#define RMI_FNUM_MAX_VALUE	U(0x18F)
+
+#define is_rmi_fid(fid) __extension__ ({		\
+	__typeof__(fid) _fid = (fid);			\
+	((GET_SMC_NUM(_fid) >= RMI_FNUM_MIN_VALUE) &&	\
+	 (GET_SMC_NUM(_fid) <= RMI_FNUM_MAX_VALUE) &&	\
+	 (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST)	   &&	\
+	 (GET_SMC_CC(_fid) == SMC_64)              &&	\
+	 (GET_SMC_OEN(_fid) == OEN_STD_START)      &&	\
+	 ((_fid & 0x00FE0000) == 0U)); })
+
+/*
+ * RMI_FNUM_REQ_COMPLETE is the only function in the RMI rnage that originates
+ * from the Realm world and is handled by the RMMD. The RMI functions are
+ * always invoked by the Normal world, forwarded by RMMD and handled by the
+ * RMM
+ */
+#define RMI_FNUM_REQ_COMPLETE		U(0x18F)
+#define RMMD_RMI_REQ_COMPLETE		RMM_FID(SMC_64, RMI_FNUM_REQ_COMPLETE)
+
+/* The SMC in the range 0x8400 0190 - 0x8400 01AF are reserved for RSIs.*/
+
+/*
+ * EL3 - RMM SMCs used for requesting RMMD services. These SMCs originate in Realm
+ * world and return to Realm world.
+ *
+ * These are allocated from 0x8400 01B0 - 0x8400 01CF in the RMM Service range.
+ */
+#define RMMD_EL3_FNUM_MIN_VALUE		U(0x1B0)
+#define RMMD_EL3_FNUM_MAX_VALUE		U(0x1CF)
+
+/* The macros below are used to identify GTSI calls from the SMC function ID */
+#define is_rmmd_el3_fid(fid) __extension__ ({		\
+	__typeof__(fid) _fid = (fid);			\
+	((GET_SMC_NUM(_fid) >= RMMD_EL3_FNUM_MIN_VALUE) &&\
+	(GET_SMC_NUM(_fid) <= RMMD_EL3_FNUM_MAX_VALUE)  &&\
+	(GET_SMC_TYPE(_fid) == SMC_TYPE_FAST)	    &&	\
+	(GET_SMC_CC(_fid) == SMC_64)                &&	\
+	(GET_SMC_OEN(_fid) == OEN_STD_START)        &&	\
+	((_fid & 0x00FE0000) == 0U)); })
+
+/* RMMD Service Function NUmbers */
+#define GTSI_DELEGATE			U(0x1B0)
+#define GTSI_UNDELEGATE			U(0x1B1)
+#define ATTEST_GET_REALM_KEY		U(0x1B2)
+#define ATTEST_GET_PLAT_TOKEN		U(0x1B3)
+
+#define RMMD_GTSI_DELEGATE		RMM_FID(SMC_64, GTSI_DELEGATE)
+#define RMMD_GTSI_UNDELEGATE		RMM_FID(SMC_64, GTSI_UNDELEGATE)
+
+/* Return error codes from RMM-EL3 SMCs */
+#define RMMD_OK				0
+#define RMMD_ERR_BAD_ADDR		-2
+#define RMMD_ERR_BAD_PAS		-3
+#define RMMD_ERR_NOMEM			-4
+#define RMMD_ERR_INVAL			-5
+#define RMMD_ERR_UNK			-6
+
+/*
+ * Retrieve Platform token from EL3.
+ * The arguments to this SMC are :
+ *    arg0 - Function ID.
+ *    arg1 - Platform attestation token buffer Physical address. (The challenge
+ *           object is passed in this buffer.)
+ *    arg2 - Platform attestation token buffer size (in bytes).
+ *    arg3 - Challenge object size (in bytes). It has be one of the defined SHA hash
+ *           sizes.
+ * The return arguments are :
+ *    ret0 - Status / error.
+ *    ret1 - Size of the platform token if successful.
+ */
+#define RMMD_ATTEST_GET_PLAT_TOKEN	RMM_FID(SMC_64, ATTEST_GET_PLAT_TOKEN)
+
+/* Acceptable SHA sizes for Challenge object */
+#define SHA256_DIGEST_SIZE	32U
+#define SHA384_DIGEST_SIZE	48U
+#define SHA512_DIGEST_SIZE	64U
+
+/*
+ * Retrieve Realm attestation key from EL3. Only P-384 ECC curve key is
+ * supported. The arguments to this SMC are :
+ *    arg0 - Function ID.
+ *    arg1 - Realm attestation key buffer Physical address.
+ *    arg2 - Realm attestation key buffer size (in bytes).
+ *    arg3 - The type of the elliptic curve to which the requested
+ *           attestation key belongs to. The value should be one of the
+ *           defined curve types.
+ * The return arguments are :
+ *    ret0 - Status / error.
+ *    ret1 - Size of the realm attestation key if successful.
+ */
+#define RMMD_ATTEST_GET_REALM_KEY	RMM_FID(SMC_64, ATTEST_GET_REALM_KEY)
+
+/* ECC Curve types for attest key generation */
+#define ATTEST_KEY_CURVE_ECC_SECP384R1		0
+
+
 #ifndef __ASSEMBLER__
 #include <stdint.h>
 
@@ -20,7 +129,7 @@
 		void *handle,
 		uint64_t flags);
 
-uint64_t rmmd_gtsi_handler(uint32_t smc_fid,
+uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid,
 		uint64_t x1,
 		uint64_t x2,
 		uint64_t x3,
@@ -30,5 +139,4 @@
 		uint64_t flags);
 
 #endif /* __ASSEMBLER__ */
-
 #endif /* RMMD_SVC_H */
diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S
index 888f98b..5c19548 100644
--- a/lib/cpus/aarch64/cortex_a76ae.S
+++ b/lib/cpus/aarch64/cortex_a76ae.S
@@ -1,12 +1,15 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arch.h>
 #include <asm_macros.S>
+#include <common/bl_common.h>
 #include <cortex_a76ae.h>
 #include <cpu_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
@@ -18,14 +21,46 @@
 #error "Cortex-A76AE supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-	/* ---------------------------------------------
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table CORTEX_A76AE_BHB_LOOP_COUNT, cortex_a76ae
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif /* WORKAROUND_CVE_2022_23960 */
+	ret
+endfunc check_errata_cve_2022_23960
+
+	/* --------------------------------------------
+	 * The CPU Ops reset function for Cortex-A76AE.
+	 * Shall clobber: x0-x19
+	 * --------------------------------------------
+	 */
+func cortex_a76ae_reset_func
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Cortex-A76ae generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_cortex_a76ae
+	msr	vbar_el3, x0
+	isb
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+
+	ret
+endfunc cortex_a76ae_reset_func
+
+	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
-	 * ---------------------------------------------
+	 * ----------------------------------------------------
 	 */
 func cortex_a76ae_core_pwr_dwn
-	/* ---------------------------------------------
+	/* ---------------------------------------------------
 	 * Enable CPU power down bit in power control register
-	 * ---------------------------------------------
+	 * ---------------------------------------------------
 	 */
 	mrs	x0, CORTEX_A76AE_CPUPWRCTLR_EL1
 	orr	x0, x0, #CORTEX_A76AE_CORE_PWRDN_EN_MASK
@@ -39,6 +74,18 @@
  * Errata printing function for Cortex-A76AE. Must follow AAPCS.
  */
 func cortex_a76ae_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata WORKAROUND_CVE_2022_23960, cortex_a76ae, cve_2022_23960
+
+	ldp	x8, x30, [sp], #16
 	ret
 endfunc cortex_a76ae_errata_report
 #endif	/* REPORT_ERRATA */
@@ -62,5 +109,5 @@
 	ret
 endfunc cortex_a76ae_cpu_reg_dump
 
-declare_cpu_ops cortex_a76ae, CORTEX_A76AE_MIDR, CPU_NO_RESET_FUNC, \
+declare_cpu_ops cortex_a76ae, CORTEX_A76AE_MIDR, cortex_a76ae_reset_func, \
 	cortex_a76ae_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a78_ae.S b/lib/cpus/aarch64/cortex_a78_ae.S
index 421c174..27adc38 100644
--- a/lib/cpus/aarch64/cortex_a78_ae.S
+++ b/lib/cpus/aarch64/cortex_a78_ae.S
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
- * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2019-2022, ARM Limited. All rights reserved.
+ * Copyright (c) 2021-2022, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,12 +11,17 @@
 #include <cortex_a78_ae.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
 #error "cortex_a78_ae must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table CORTEX_A78_AE_BHB_LOOP_COUNT, cortex_a78_ae
+#endif /* WORKAROUND_CVE_2022_23960 */
+
 /* --------------------------------------------------
  * Errata Workaround for A78 AE Erratum 1941500.
  * This applies to revisions r0p0 and r0p1 of A78 AE.
@@ -99,6 +104,87 @@
 	b	cpu_rev_var_range
 endfunc check_errata_1951502
 
+/* --------------------------------------------------
+ * Errata Workaround for A78 AE Erratum 2376748.
+ * This applies to revisions r0p0 and r0p1 of A78 AE.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_ae_2376748_wa
+	/* Compare x0 against revisions r0p0 - r0p1 */
+	mov	x17, x30
+	bl	check_errata_2376748
+	cbz	x0, 1f
+
+	/* -------------------------------------------------------
+	 * Set CPUACTLR2_EL1[0] to 1 to force PLDW/PFRM ST to
+	 * behave like PLD/PRFM LD and not cause invalidations to
+	 * other PE caches. There might be a small performance
+	 * degradation to this workaround for certain workloads
+	 * that share data.
+	 * -------------------------------------------------------
+	 */
+	mrs	x0, CORTEX_A78_AE_ACTLR2_EL1
+	orr	x0, x0, #CORTEX_A78_AE_ACTLR2_EL1_BIT_0
+	msr	CORTEX_A78_AE_ACTLR2_EL1, x0
+	isb
+1:
+	ret	x17
+endfunc errata_a78_ae_2376748_wa
+
+func check_errata_2376748
+	/* Applies to revisions r0p0 and r0p1. */
+	mov	x1, #CPU_REV(0, 0)
+	mov	x2, #CPU_REV(0, 1)
+	b	cpu_rev_var_range
+endfunc check_errata_2376748
+
+/* --------------------------------------------------
+ * Errata Workaround for A78 AE Erratum 2395408.
+ * This applies to revisions r0p0 and r0p1 of A78 AE.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a78_ae_2395408_wa
+	/* Compare x0 against revisions r0p0 - r0p1 */
+	mov	x17, x30
+	bl	check_errata_2395408
+	cbz	x0, 1f
+
+	/* --------------------------------------------------------
+	 * Disable folding of demand requests into older prefetches
+	 * with L2 miss requests outstanding by setting the
+	 * CPUACTLR2_EL1[40] to 1.
+	 * --------------------------------------------------------
+	 */
+	mrs	x0, CORTEX_A78_AE_ACTLR2_EL1
+	orr	x0, x0, #CORTEX_A78_AE_ACTLR2_EL1_BIT_40
+	msr	CORTEX_A78_AE_ACTLR2_EL1, x0
+	isb
+1:
+	ret	x17
+endfunc errata_a78_ae_2395408_wa
+
+func check_errata_2395408
+	/* Applies to revisions r0p0 and r0p1. */
+	mov	x1, #CPU_REV(0, 0)
+	mov	x2, #CPU_REV(0, 1)
+	b	cpu_rev_var_range
+endfunc check_errata_2395408
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_cve_2022_23960
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A78-AE
 	 * -------------------------------------------------
@@ -118,6 +204,16 @@
 	bl	errata_a78_ae_1951502_wa
 #endif
 
+#if ERRATA_A78_AE_2376748
+	mov	x0, x18
+	bl	errata_a78_ae_2376748_wa
+#endif
+
+#if ERRATA_A78_AE_2395408
+	mov	x0, x18
+	bl	errata_a78_ae_2395408_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
@@ -138,8 +234,16 @@
 	msr	CPUAMCNTENSET1_EL0, x0
 #endif
 
-	isb
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Cortex-A78AE generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_cortex_a78_ae
+	msr	vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
 
+	isb
 	ret	x19
 endfunc cortex_a78_ae_reset_func
 
@@ -175,6 +279,9 @@
 	 */
 	report_errata ERRATA_A78_AE_1941500, cortex_a78_ae, 1941500
 	report_errata ERRATA_A78_AE_1951502, cortex_a78_ae, 1951502
+	report_errata ERRATA_A78_AE_2376748, cortex_a78_ae, 2376748
+	report_errata ERRATA_A78_AE_2395408, cortex_a78_ae, 2395408
+	report_errata WORKAROUND_CVE_2022_23960, cortex_a78_ae, cve_2022_23960
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/aarch64/cortex_a78c.S b/lib/cpus/aarch64/cortex_a78c.S
index 1b170fe..0712109 100644
--- a/lib/cpus/aarch64/cortex_a78c.S
+++ b/lib/cpus/aarch64/cortex_a78c.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,12 +10,43 @@
 #include <cortex_a78c.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
+#include "wa_cve_2022_23960_bhb_vector.S"
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
 #error "cortex_a78c must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
+#if WORKAROUND_CVE_2022_23960
+	wa_cve_2022_23960_bhb_vector_table CORTEX_A78C_BHB_LOOP_COUNT, cortex_a78c
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+	mov	x0, #ERRATA_APPLIES
+#else
+	mov	x0, #ERRATA_MISSING
+#endif
+	ret
+endfunc check_errata_cve_2022_23960
+
+	/* -------------------------------------------------
+	 * The CPU Ops reset function for Cortex-A78C
+	 * -------------------------------------------------
+	 */
+func cortex_a78c_reset_func
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+	/*
+	 * The Cortex-A78c generic vectors are overridden to apply errata
+	 * mitigation on exception entry from lower ELs.
+	 */
+	adr	x0, wa_cve_vbar_cortex_a78c
+	msr	vbar_el3, x0
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+	isb
+	ret
+endfunc cortex_a78c_reset_func
+
 	/* ----------------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ----------------------------------------------------
@@ -37,6 +68,18 @@
  * Errata printing function for Cortex A78C. Must follow AAPCS.
  */
 func cortex_a78c_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata WORKAROUND_CVE_2022_23960, cortex_a78c, cve_2022_23960
+
+	ldp	x8, x30, [sp], #16
         ret
 endfunc cortex_a78c_errata_report
 #endif
@@ -61,5 +104,5 @@
 endfunc cortex_a78c_cpu_reg_dump
 
 declare_cpu_ops cortex_a78c, CORTEX_A78C_MIDR, \
-	CPU_NO_RESET_FUNC, \
+	cortex_a78c_reset_func, \
 	cortex_a78c_core_pwr_dwn
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index c7630fb..8840f8e 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -1,6 +1,6 @@
 #
 # Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
-# Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
+# Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -341,6 +341,14 @@
 # to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
 ERRATA_A78_AE_1951502	?=0
 
+# 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.
+ERRATA_A78_AE_2376748	?=0
+
+# Flag to apply erratum 2395408 workaround during reset. This erratum applies
+# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open.
+ERRATA_A78_AE_2395408	?=0
+
 # Flag to apply T32 CLREX workaround during reset. This erratum applies
 # only to r0p0 and r1p0 of the Neoverse N1 cpu.
 ERRATA_N1_1043202	?=0
@@ -838,6 +846,14 @@
 $(eval $(call assert_boolean,ERRATA_A78_AE_1951502))
 $(eval $(call add_define,ERRATA_A78_AE_1951502))
 
+# Process ERRATA_A78_AE_2376748 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_2376748))
+$(eval $(call add_define,ERRATA_A78_AE_2376748))
+
+# Process ERRATA_A78_AE_2395408 flag
+$(eval $(call assert_boolean,ERRATA_A78_AE_2395408))
+$(eval $(call add_define,ERRATA_A78_AE_2395408))
+
 # Process ERRATA_N1_1043202 flag
 $(eval $(call assert_boolean,ERRATA_N1_1043202))
 $(eval $(call add_define,ERRATA_N1_1043202))
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index c1c0612..0432d96 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,14 +13,14 @@
 #if CTX_INCLUDE_EL2_REGS
 	.global	el2_sysregs_context_save
 	.global	el2_sysregs_context_restore
-#endif
+#endif /* CTX_INCLUDE_EL2_REGS */
 
 	.global	el1_sysregs_context_save
 	.global	el1_sysregs_context_restore
 #if CTX_INCLUDE_FPREGS
 	.global	fpregs_context_save
 	.global	fpregs_context_restore
-#endif
+#endif /* CTX_INCLUDE_FPREGS */
 	.global	prepare_el3_entry
 	.global	restore_gp_pmcr_pauth_regs
 	.global save_and_update_ptw_el1_sys_regs
@@ -62,7 +62,7 @@
 #if CTX_INCLUDE_AARCH32_REGS
 	mrs	x16, dbgvcr32_el2
 	str	x16, [x0, #CTX_DBGVCR32_EL2]
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
 
 	mrs	x9, elr_el2
 	mrs	x10, esr_el2
@@ -91,7 +91,8 @@
 #if ENABLE_SPE_FOR_LOWER_ELS
 	mrs	x13, PMSCR_EL2
 	str	x13, [x0, #CTX_PMSCR_EL2]
-#endif
+#endif /* ENABLE_SPE_FOR_LOWER_ELS */
+
 	mrs	x14, sctlr_el2
 	str	x14, [x0, #CTX_SCTLR_EL2]
 
@@ -118,7 +119,7 @@
 #if CTX_INCLUDE_MTE_REGS
 	mrs	x9, TFSR_EL2
 	str	x9, [x0, #CTX_TFSR_EL2]
-#endif
+#endif /* CTX_INCLUDE_MTE_REGS */
 
 #if ENABLE_MPAM_FOR_LOWER_ELS
 	mrs	x10, MPAM2_EL2
@@ -143,7 +144,7 @@
 	mrs	x11, MPAMVPM7_EL2
 	mrs	x12, MPAMVPMV_EL2
 	stp	x11, x12, [x0, #CTX_MPAMVPM7_EL2]
-#endif
+#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
 
 #if ENABLE_FEAT_FGT
 	mrs	x13, HDFGRTR_EL2
@@ -152,7 +153,7 @@
    	stp	x13, x14, [x0, #CTX_HDFGRTR_EL2]
 #else
    	str	x13, [x0, #CTX_HDFGRTR_EL2]
-#endif
+#endif /* ENABLE_FEAT_AMUv1 */
 	mrs	x15, HDFGWTR_EL2
 	mrs	x16, HFGITR_EL2
 	stp	x15, x16, [x0, #CTX_HDFGWTR_EL2]
@@ -160,48 +161,80 @@
 	mrs	x9, HFGRTR_EL2
 	mrs	x10, HFGWTR_EL2
 	stp	x9, x10, [x0, #CTX_HFGRTR_EL2]
-#endif
+#endif /* ENABLE_FEAT_FGT */
 
 #if ENABLE_FEAT_ECV
 	mrs	x11, CNTPOFF_EL2
 	str	x11, [x0, #CTX_CNTPOFF_EL2]
-#endif
+#endif /* ENABLE_FEAT_ECV */
 
-#if ARM_ARCH_AT_LEAST(8, 4)
-	mrs	x12, contextidr_el2
-	str	x12, [x0, #CTX_CONTEXTIDR_EL2]
+#if ENABLE_FEAT_VHE
+	/*
+	 * CONTEXTIDR_EL2 register is saved only when FEAT_VHE or
+	 * FEAT_Debugv8p2 (currently not in TF-A) is supported.
+	 */
+	mrs	x9, contextidr_el2
+	mrs	x10, ttbr1_el2
+	stp	x9, x10, [x0, #CTX_CONTEXTIDR_EL2]
+#endif /* ENABLE_FEAT_VHE */
 
-#if CTX_INCLUDE_AARCH32_REGS
-	mrs	x13, sder32_el2
-	str	x13, [x0, #CTX_SDER32_EL2]
-#endif
-	mrs	x14, ttbr1_el2
-	mrs	x15, vdisr_el2
-	stp	x14, x15, [x0, #CTX_TTBR1_EL2]
+#if RAS_EXTENSION
+	/*
+	 * VDISR_EL2 and VSESR_EL2 registers are saved only when
+	 * FEAT_RAS is supported.
+	 */
+	mrs	x11, vdisr_el2
+	mrs	x12, vsesr_el2
+	stp	x11, x12, [x0, #CTX_VDISR_EL2]
+#endif /* RAS_EXTENSION */
+
+#if ENABLE_FEAT_SEL2
+	/*
+	 * VSTCR_EL2 and VSTTBR_EL2 registers are saved only
+	 * when FEAT_SEL2 is supported.
+	 */
+	mrs	x13, vstcr_el2
+	mrs	x14, vsttbr_el2
+	stp	x13, x14, [x0, #CTX_VSTCR_EL2]
+#endif /* ENABLE_FEAT_SEL2 */
+
+#if CTX_INCLUDE_AARCH32_REGS && ENABLE_FEAT_SEL2
+	/*
+	 * SDER32_EL2 register is saved only when EL2 and EL1
+	 * capable of using Aarch32 and FEAT_SEL2 is supported.
+	 */
+	mrs	x15, sder32_el2
+	str	x15, [x0, #CTX_SDER32_EL2]
+#endif /* CTX_INCLUDE_AARCH32_REGS && ENABLE_FEAT_SEL2 */
 
 #if CTX_INCLUDE_NEVE_REGS
+	/*
+	 * VNCR_EL2 register is saved only when FEAT_NV2 is supported.
+	 */
 	mrs	x16, vncr_el2
 	str	x16, [x0, #CTX_VNCR_EL2]
-#endif
+#endif /* CTX_INCLUDE_NEVE_REGS */
 
-	mrs	x9, vsesr_el2
-	mrs	x10, vstcr_el2
-	stp	x9, x10, [x0, #CTX_VSESR_EL2]
-
-	mrs	x11, vsttbr_el2
+#if ENABLE_TRF_FOR_NS
+	/*
+	 * TRFCR_EL2 register is saved only when FEAT_TRF is supported.
+	 */
 	mrs	x12, TRFCR_EL2
-	stp	x11, x12, [x0, #CTX_VSTTBR_EL2]
-#endif
+	str	x12, [x0, #CTX_TRFCR_EL2]
+#endif /* ENABLE_TRF_FOR_NS */
 
-#if ARM_ARCH_AT_LEAST(8, 5)
+#if ENABLE_FEAT_CSV2_2
+	/*
+	 * SCXTNUM_EL2 register is saved only when FEAT_CSV2_2 is supported.
+	 */
 	mrs	x13, scxtnum_el2
 	str	x13, [x0, #CTX_SCXTNUM_EL2]
-#endif
+#endif /* ENABLE_FEAT_CSV2_2 */
 
 #if ENABLE_FEAT_HCX
 	mrs	x14, hcrx_el2
 	str	x14, [x0, #CTX_HCRX_EL2]
-#endif
+#endif /* ENABLE_FEAT_HCX */
 
 	ret
 endfunc el2_sysregs_context_save
@@ -241,7 +274,7 @@
 #if CTX_INCLUDE_AARCH32_REGS
 	ldr	x16, [x0, #CTX_DBGVCR32_EL2]
 	msr	dbgvcr32_el2, x16
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
 
 	ldp	x9, x10, [x0, #CTX_ELR_EL2]
 	msr	elr_el2, x9
@@ -270,7 +303,8 @@
 #if ENABLE_SPE_FOR_LOWER_ELS
 	ldr	x13, [x0, #CTX_PMSCR_EL2]
 	msr	PMSCR_EL2, x13
-#endif
+#endif /* ENABLE_SPE_FOR_LOWER_ELS */
+
 	ldr	x14, [x0, #CTX_SCTLR_EL2]
 	msr	sctlr_el2, x14
 
@@ -297,7 +331,7 @@
 #if CTX_INCLUDE_MTE_REGS
 	ldr	x9, [x0, #CTX_TFSR_EL2]
 	msr	TFSR_EL2, x9
-#endif
+#endif /* CTX_INCLUDE_MTE_REGS */
 
 #if ENABLE_MPAM_FOR_LOWER_ELS
 	ldr	x10, [x0, #CTX_MPAM2_EL2]
@@ -322,7 +356,7 @@
 	ldp	x11, x12, [x0, #CTX_MPAMVPM7_EL2]
 	msr	MPAMVPM7_EL2, x11
 	msr	MPAMVPMV_EL2, x12
-#endif
+#endif /* ENABLE_MPAM_FOR_LOWER_ELS */
 
 #if ENABLE_FEAT_FGT
 #if ENABLE_FEAT_AMUv1
@@ -330,7 +364,7 @@
 	msr	HAFGRTR_EL2, x14
 #else
 	ldr	x13, [x0, #CTX_HDFGRTR_EL2]
-#endif
+#endif /* ENABLE_FEAT_AMUv1 */
 	msr	HDFGRTR_EL2, x13
 
 	ldp	x15, x16, [x0, #CTX_HDFGWTR_EL2]
@@ -340,48 +374,80 @@
 	ldp	x9, x10, [x0, #CTX_HFGRTR_EL2]
 	msr	HFGRTR_EL2, x9
 	msr	HFGWTR_EL2, x10
-#endif
+#endif /* ENABLE_FEAT_FGT */
 
 #if ENABLE_FEAT_ECV
 	ldr	x11, [x0, #CTX_CNTPOFF_EL2]
 	msr	CNTPOFF_EL2, x11
-#endif
+#endif /* ENABLE_FEAT_ECV */
+
+#if ENABLE_FEAT_VHE
+	/*
+	 * CONTEXTIDR_EL2 register is restored only when FEAT_VHE or
+	 * FEAT_Debugv8p2 (currently not in TF-A) is supported.
+	 */
+	ldp	x9, x10, [x0, #CTX_CONTEXTIDR_EL2]
+	msr	contextidr_el2, x9
+	msr	ttbr1_el2, x10
+#endif /* ENABLE_FEAT_VHE */
 
-#if ARM_ARCH_AT_LEAST(8, 4)
-	ldr	x12, [x0, #CTX_CONTEXTIDR_EL2]
-	msr	contextidr_el2, x12
+#if RAS_EXTENSION
+	/*
+	 * VDISR_EL2 and VSESR_EL2 registers are restored only when FEAT_RAS
+	 * is supported.
+	 */
+	ldp	x11, x12, [x0, #CTX_VDISR_EL2]
+	msr	vdisr_el2, x11
+	msr	vsesr_el2, x12
+#endif /* RAS_EXTENSION */
 
-#if CTX_INCLUDE_AARCH32_REGS
-	ldr	x13, [x0, #CTX_SDER32_EL2]
-	msr	sder32_el2, x13
-#endif
-	ldp	x14, x15, [x0, #CTX_TTBR1_EL2]
-	msr	ttbr1_el2, x14
-	msr	vdisr_el2, x15
+#if ENABLE_FEAT_SEL2
+	/*
+	 * VSTCR_EL2 and VSTTBR_EL2 registers are restored only when FEAT_SEL2
+	 * is supported.
+	 */
+	ldp	x13, x14, [x0, #CTX_VSTCR_EL2]
+	msr	vstcr_el2, x13
+	msr	vsttbr_el2, x14
+#endif /* ENABLE_FEAT_SEL2 */
+
+#if CTX_INCLUDE_AARCH32_REGS && ENABLE_FEAT_SEL2
+	/*
+	 * SDER32_EL2 register is restored only when EL2 and EL1 capable of using
+	 * Aarch32 and FEAT_SEL2 is supported.
+	 */
+	ldr	x15, [x0, #CTX_SDER32_EL2]
+	msr	sder32_el2, x15
+#endif /* CTX_INCLUDE_AARCH32_REGS && ENABLE_FEAT_SEL2 */
 
 #if CTX_INCLUDE_NEVE_REGS
+	/*
+	 * VNCR_EL2 register is restored only when FEAT_NV2 is supported.
+	 */
 	ldr	x16, [x0, #CTX_VNCR_EL2]
 	msr	vncr_el2, x16
-#endif
-
-	ldp	x9, x10, [x0, #CTX_VSESR_EL2]
-	msr	vsesr_el2, x9
-	msr	vstcr_el2, x10
+#endif /* CTX_INCLUDE_NEVE_REGS */
 
-	ldp	x11, x12, [x0, #CTX_VSTTBR_EL2]
-	msr	vsttbr_el2, x11
+#if ENABLE_TRF_FOR_NS
+	/*
+	 * TRFCR_EL2 register is restored only when FEAT_TRF is supported.
+	 */
+	ldr	x12, [x0, #CTX_TRFCR_EL2]
 	msr	TRFCR_EL2, x12
-#endif
+#endif /* ENABLE_TRF_FOR_NS */
 
-#if ARM_ARCH_AT_LEAST(8, 5)
+#if ENABLE_FEAT_CSV2_2
+	/*
+	 * SCXTNUM_EL2 register is restored only when FEAT_CSV2_2 is supported.
+	 */
 	ldr	x13, [x0, #CTX_SCXTNUM_EL2]
 	msr	scxtnum_el2, x13
-#endif
+#endif /* ENABLE_FEAT_CSV2_2 */
 
 #if ENABLE_FEAT_HCX
 	ldr	x14, [x0, #CTX_HCRX_EL2]
 	msr	hcrx_el2, x14
-#endif
+#endif /* ENABLE_FEAT_HCX */
 
 	ret
 endfunc el2_sysregs_context_restore
@@ -405,7 +471,7 @@
 	mrs	x15, sctlr_el1
 	mrs	x16, tcr_el1
 	stp	x15, x16, [x0, #CTX_SCTLR_EL1]
-#endif
+#endif /* ERRATA_SPECULATIVE_AT */
 
 	mrs	x17, cpacr_el1
 	mrs	x9, csselr_el1
@@ -456,7 +522,7 @@
 	mrs	x15, dacr32_el2
 	mrs	x16, ifsr32_el2
 	stp	x15, x16, [x0, #CTX_DACR32_EL2]
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
 
 	/* Save NS timer registers if the build has instructed so */
 #if NS_TIMER_SWITCH
@@ -470,7 +536,7 @@
 
 	mrs	x14, cntkctl_el1
 	str	x14, [x0, #CTX_CNTKCTL_EL1]
-#endif
+#endif /* NS_TIMER_SWITCH */
 
 	/* Save MTE system registers if the build has instructed so */
 #if CTX_INCLUDE_MTE_REGS
@@ -481,7 +547,7 @@
 	mrs	x9, RGSR_EL1
 	mrs	x10, GCR_EL1
 	stp	x9, x10, [x0, #CTX_RGSR_EL1]
-#endif
+#endif /* CTX_INCLUDE_MTE_REGS */
 
 	ret
 endfunc el1_sysregs_context_save
@@ -504,7 +570,7 @@
 	ldp	x15, x16, [x0, #CTX_SCTLR_EL1]
 	msr	sctlr_el1, x15
 	msr	tcr_el1, x16
-#endif
+#endif /* ERRATA_SPECULATIVE_AT */
 
 	ldp	x17, x9, [x0, #CTX_CPACR_EL1]
 	msr	cpacr_el1, x17
@@ -555,7 +621,8 @@
 	ldp	x15, x16, [x0, #CTX_DACR32_EL2]
 	msr	dacr32_el2, x15
 	msr	ifsr32_el2, x16
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
+
 	/* Restore NS timer registers if the build has instructed so */
 #if NS_TIMER_SWITCH
 	ldp	x10, x11, [x0, #CTX_CNTP_CTL_EL0]
@@ -568,7 +635,8 @@
 
 	ldr	x14, [x0, #CTX_CNTKCTL_EL1]
 	msr	cntkctl_el1, x14
-#endif
+#endif /* NS_TIMER_SWITCH */
+
 	/* Restore MTE system registers if the build has instructed so */
 #if CTX_INCLUDE_MTE_REGS
 	ldp	x11, x12, [x0, #CTX_TFSRE0_EL1]
@@ -578,7 +646,7 @@
 	ldp	x13, x14, [x0, #CTX_RGSR_EL1]
 	msr	RGSR_EL1, x13
 	msr	GCR_EL1, x14
-#endif
+#endif /* CTX_INCLUDE_MTE_REGS */
 
 	/* No explict ISB required here as ERET covers it */
 	ret
@@ -626,7 +694,7 @@
 #if CTX_INCLUDE_AARCH32_REGS
 	mrs	x11, fpexc32_el2
 	str	x11, [x0, #CTX_FP_FPEXC32_EL2]
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
 	ret
 endfunc fpregs_context_save
 
@@ -671,7 +739,8 @@
 #if CTX_INCLUDE_AARCH32_REGS
 	ldr	x11, [x0, #CTX_FP_FPEXC32_EL2]
 	msr	fpexc32_el2, x11
-#endif
+#endif /* CTX_INCLUDE_AARCH32_REGS */
+
 	/*
 	 * No explict ISB required here as ERET to
 	 * switch to secure EL1 or non-secure world
@@ -688,13 +757,13 @@
 	 * in ARM DDI 0487F.c page J1-7635 to a default value.
 	 */
 	.macro set_unset_pstate_bits
-        /*
-         * If Data Independent Timing (DIT) functionality is implemented,
-         * always enable DIT in EL3
-         */
+	/*
+	 * If Data Independent Timing (DIT) functionality is implemented,
+	 * always enable DIT in EL3
+	 */
 #if ENABLE_FEAT_DIT
-        mov     x8, #DIT_BIT
-        msr     DIT, x8
+	mov     x8, #DIT_BIT
+	msr     DIT, x8
 #endif /* ENABLE_FEAT_DIT */
 	.endm /* set_unset_pstate_bits */
 
@@ -933,7 +1002,7 @@
 	mrs	x17, spsel
 	cmp	x17, #MODE_SP_EL0
 	ASM_ASSERT(eq)
-#endif
+#endif /* ENABLE_ASSERTIONS */
 
 	/* ----------------------------------------------------------
 	 * Save the current SP_EL0 i.e. the EL3 runtime stack which
@@ -971,7 +1040,7 @@
 	isb
 	msr	S3_6_C1_C2_0, x20 /* zcr_el3 */
 sve_not_enabled:
-#endif
+#endif /* IMAGE_BL31 */
 
 #if IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639
 	/* ----------------------------------------------------------
@@ -982,7 +1051,8 @@
 	cbz	x17, 1f
 	blr	x17
 1:
-#endif
+#endif /* IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 */
+
 	restore_ptw_el1_sys_regs
 
 	/* ----------------------------------------------------------
@@ -1005,10 +1075,12 @@
 	esb
 #else
 	dsb	sy
-#endif
+#endif /* IMAGE_BL31 && RAS_EXTENSION */
+
 #ifdef IMAGE_BL31
 	str	xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_IS_IN_EL3]
-#endif
+#endif /* IMAGE_BL31 */
+
 	exception_return
 
 endfunc el3_exit
diff --git a/make_helpers/arch_features.mk b/make_helpers/arch_features.mk
new file mode 100644
index 0000000..01e3e09
--- /dev/null
+++ b/make_helpers/arch_features.mk
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# This file lists all the checks related to the Architectural Feature
+# Enablement flags, based on the Architectural version.
+
+# 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.4 and upwards.
+ifeq "8.4" "$(word 1, $(sort 8.4 $(ARM_ARCH_MAJOR).$(ARM_ARCH_MINOR)))"
+ENABLE_FEAT_DIT		=	1
+ENABLE_FEAT_SEL2	=	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_SB		=	1
+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_FGT		=	1
+ENABLE_FEAT_ECV		=	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
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index b39dcf4..99f44a4 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -133,12 +133,18 @@
 # Use BRANCH_PROTECTION to enable PAUTH.
 ENABLE_PAUTH			:= 0
 
-# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
-ENABLE_FEAT_HCX			:= 0
-
 # Flag to enable access to the HAFGRTR_EL2 register
 ENABLE_FEAT_AMUv1		:= 0
 
+# Flag to enable AMUv1p1 extension.
+ENABLE_FEAT_AMUv1p1		:= 0
+
+# Flag to enable CSV2_2 extension.
+ENABLE_FEAT_CSV2_2 		:= 0
+
+# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn.
+ENABLE_FEAT_HCX			:= 0
+
 # Flag to enable access to the HDFGRTR_EL2 register
 ENABLE_FEAT_FGT			:= 0
 
@@ -148,6 +154,21 @@
 # Flag to enable use of the DIT feature.
 ENABLE_FEAT_DIT			:= 0
 
+# Flag to enable access to Privileged Access Never bit of PSTATE.
+ENABLE_FEAT_PAN			:= 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
+
+# Flag to enable Secure EL-2 feature.
+ENABLE_FEAT_SEL2		:= 0
+
+# Flag to enable Virtualization Host Extensions
+ENABLE_FEAT_VHE 		:= 0
+
 # By default BL31 encryption disabled
 ENCRYPT_BL31			:= 0
 
@@ -166,6 +187,9 @@
 # Fault injection support
 FAULT_INJECTION_SUPPORT		:= 0
 
+# Flag to enable architectural features detection mechanism
+FEATURE_DETECTION		:= 0
+
 # Byte alignment that each component in FIP is aligned to
 FIP_ALIGN			:= 0
 
@@ -250,6 +274,10 @@
 # separate memory region, which may be discontiguous from the rest of BL31.
 SEPARATE_NOBITS_REGION		:= 0
 
+# Put BL2 NOLOAD sections (.bss, stacks, page tables) in a separate memory
+# region, platform Makefile is free to override this value.
+SEPARATE_BL2_NOLOAD_REGION	:= 0
+
 # If the BL31 image initialisation code is recalimed after use for the secondary
 # cores stack
 RECLAIM_INIT_CODE		:= 0
diff --git a/plat/arm/board/fvp/fvp_plat_attest_token.c b/plat/arm/board/fvp/fvp_plat_attest_token.c
new file mode 100644
index 0000000..5463f33
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_plat_attest_token.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+
+/* Using hardcoded token values for AEM FVP */
+static uint8_t platform_token[] = {
+	0xD2, 0x84, 0x40, 0xA0, 0x59, 0x08, 0xB1, 0xD9,
+	0x61, 0xA8, 0xA9, 0x0A, 0x58, 0x40, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x3A, 0x00,
+	0x01, 0x24, 0xFA, 0x58, 0x40, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
+	0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x3A, 0x00, 0x01,
+	0x25, 0x00, 0x58, 0x41, 0x01, 0x0B, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
+	0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x12, 0x78, 0x1C,
+	0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61,
+	0x72, 0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x43,
+	0x43, 0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F, 0x31,
+	0x2E, 0x30, 0x2E, 0x30, 0x0B, 0x58, 0x19, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0x3A, 0x00, 0x01, 0x24, 0xF7, 0x78, 0x1C, 0x68,
+	0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x61, 0x72,
+	0x6D, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x43, 0x43,
+	0x41, 0x2D, 0x53, 0x53, 0x44, 0x2F, 0x31, 0x2E,
+	0x30, 0x2E, 0x30, 0x3A, 0x00, 0x01, 0x25, 0x01,
+	0x78, 0x18, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A,
+	0x2F, 0x2F, 0x63, 0x63, 0x61, 0x5F, 0x76, 0x65,
+	0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x2E, 0x6F,
+	0x72, 0x67, 0x3A, 0x00, 0x01, 0x24, 0xF9, 0x19,
+	0x30, 0x00, 0x3A, 0x00, 0x01, 0x24, 0xFD, 0x8D,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0xA4, 0x02, 0x58, 0x40, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+	0xCC, 0xCC, 0xCC, 0xCC, 0x05, 0x58, 0x40, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
+	0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04,
+	0x65, 0x31, 0x2E, 0x30, 0x2E, 0x30, 0x06, 0x08,
+	0x58, 0x40, 0xD3, 0x8A, 0x41, 0xA6, 0xC1, 0x29,
+	0x98, 0x18, 0xB5, 0x16, 0x9C, 0x21, 0x78, 0xB7,
+	0x92, 0xF8, 0x26, 0x82, 0x76, 0x2F, 0x26, 0x45,
+	0x21, 0x6D, 0x0C, 0x21, 0x06, 0xF4, 0xB5, 0xE3,
+	0xA8, 0x07, 0xD1, 0xD6, 0x8C, 0x73, 0xA5, 0xC8,
+	0x16, 0xD8, 0x30, 0x68, 0xC0, 0xA4, 0x77, 0xE2,
+	0x1E, 0xD2, 0x17, 0x86, 0xC3, 0x68, 0x82, 0xDD,
+	0x21, 0x1B, 0xA3, 0xE2, 0xC7, 0xF7, 0x06, 0x33,
+	0xB0, 0x3A
+};
+
+int plat_get_cca_attest_token(uintptr_t buf, size_t *len,
+			       uintptr_t hash, size_t hash_size)
+{
+	(void)hash;
+	(void)hash_size;
+
+	if (*len < sizeof(platform_token)) {
+		return -EINVAL;
+	}
+
+	(void)memcpy((void *)buf, platform_token, sizeof(platform_token));
+	*len = sizeof(platform_token);
+
+	return 0;
+}
diff --git a/plat/arm/board/fvp/fvp_realm_attest_key.c b/plat/arm/board/fvp/fvp_realm_attest_key.c
new file mode 100644
index 0000000..b32f557
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_realm_attest_key.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <services/rmmd_svc.h>
+
+static uint8_t sample_attest_priv_key[] = {
+	0x20, 0x11, 0xC7, 0xF0, 0x3C, 0xEE, 0x43, 0x25, 0x17, 0x6E,
+	0x52, 0x4F, 0x03, 0x3C, 0x0C, 0xE1, 0xE2, 0x1A, 0x76, 0xE6,
+	0xC1, 0xA4, 0xF0, 0xB8, 0x39, 0xAA, 0x1D, 0xF6, 0x1E, 0x0E,
+	0x8A, 0x5C, 0x8A, 0x05, 0x74, 0x0F, 0x9B, 0x69, 0xEF, 0xA7,
+	0xEB, 0x1A, 0x41, 0x85, 0xBD, 0x11, 0x7F, 0x68
+};
+
+int plat_get_cca_realm_attest_key(uintptr_t buf, size_t *len, unsigned int type)
+{
+	assert(type == ATTEST_KEY_CURVE_ECC_SECP384R1);
+
+	if (*len < sizeof(sample_attest_priv_key)) {
+		return -EINVAL;
+	}
+
+	(void)memcpy((void *)buf, sample_attest_priv_key,
+		     sizeof(sample_attest_priv_key));
+	*len = sizeof(sample_attest_priv_key);
+
+	return 0;
+}
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 77df610..5e5ddce 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -103,7 +103,7 @@
 # if SPM_MM
 #  define PLAT_ARM_MMAP_ENTRIES		10
 #  if ENABLE_RME
-#   define MAX_XLAT_TABLES		10
+#   define MAX_XLAT_TABLES		11
 #  else
 #   define MAX_XLAT_TABLES		9
 # endif
@@ -113,13 +113,13 @@
 #  define PLAT_ARM_MMAP_ENTRIES		9
 #  if USE_DEBUGFS
 #   if ENABLE_RME
-#    define MAX_XLAT_TABLES		9
+#    define MAX_XLAT_TABLES		10
 #   else
 #    define MAX_XLAT_TABLES		8
 #   endif
 #  else
 #   if ENABLE_RME
-#    define MAX_XLAT_TABLES		8
+#    define MAX_XLAT_TABLES		9
 #   else
 #    define MAX_XLAT_TABLES		7
 #   endif
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index acac886..c9f5551 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -193,6 +193,8 @@
 
 ifeq (${ENABLE_RME},1)
 BL2_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S
+BL31_SOURCES		+=	plat/arm/board/fvp/fvp_plat_attest_token.c	\
+				plat/arm/board/fvp/fvp_realm_attest_key.c
 endif
 
 ifeq (${BL2_AT_EL3},1)
@@ -344,6 +346,10 @@
     endif
 endif
 
+ifeq (${ENABLE_RME},1)
+    BL31_CPPFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC
+endif
+
 ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
     ifeq (${ARCH},aarch32)
         BL32_CPPFLAGS	+=	-DPLAT_RO_XLAT_TABLES
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
index dbd6272..02f6158 100644
--- a/plat/nvidia/tegra/soc/t194/plat_ras.c
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -152,12 +152,6 @@
 
 			/* enable specified errors, or set to 0 if no supported error */
 			write_erxctlr_el1(err_ctrl);
-
-			/*
-			 * Check if all the bit settings have been enabled to detect
-			 * uncorrected/corrected errors, if not assert.
-			 */
-			assert(read_erxctlr_el1() == err_ctrl);
 		}
 	}
 }
diff --git a/plat/nxp/common/img_loadr/load_img.c b/plat/nxp/common/img_loadr/load_img.c
index c185c36..51011e4 100644
--- a/plat/nxp/common/img_loadr/load_img.c
+++ b/plat/nxp/common/img_loadr/load_img.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -49,10 +49,14 @@
 	/* Create MMU entry for the CSF header */
 #if PLAT_XLAT_TABLES_DYNAMIC
 #ifdef CSF_HEADER_PREPENDED
-	mmap_add_dynamic_region(img_info.image_info.image_base,
+	err = mmap_add_dynamic_region(img_info.image_info.image_base,
 			img_info.image_info.image_base,
 			CSF_HDR_SZ,
 			MT_MEMORY | MT_RW | MT_SECURE);
+	if (err != 0) {
+		ERROR("Failed to add dynamic memory region.\n");
+		return err;
+	}
 #endif
 #endif
 
diff --git a/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h b/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h
index e8a7645..8d64f04 100644
--- a/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h
+++ b/plat/nxp/common/include/default/ch_3/soc_default_base_addr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -15,12 +15,13 @@
 #define NXP_DCSR_ADDR			0x700000000
 #define NXP_DCSR_SIZE			0x40000000
 
-/* Flex-SPI controller address */
-#define NXP_FLEXSPI_ADDR		0x020C0000
-/* Flex-SPI Flash Start address */
-#define NXP_FLEXSPI_FLASH_ADDR		0x20000000
+/* Quad SPI Region #1 base address */
+#define NXP_QSPI_FLASH_ADDR		0x20000000
 
-/* MMU 500 soc.c*/
+/* IFC Region #1 base address */
+#define NXP_NOR_FLASH_ADDR		0x30000000
+
+/* MMU 500 */
 #define NXP_SMMU_ADDR			0x05000000
 
 #define NXP_SNVS_ADDR			0x01E90000
@@ -34,8 +35,12 @@
 #define NXP_I2C_ADDR			0x02000000
 #define NXP_ESDHC_ADDR			0x02140000
 #define NXP_ESDHC2_ADDR			0x02150000
-#define NXP_UART_ADDR			0x021C0000
-#define NXP_UART1_ADDR			0x021D0000
+#ifndef NXP_UART_ADDR
+#define NXP_UART_ADDR			0x021C0500
+#endif
+#ifndef NXP_UART1_ADDR
+#define NXP_UART1_ADDR			0x021C0600
+#endif
 
 #define NXP_GPIO1_ADDR			0x02300000
 #define NXP_GPIO2_ADDR			0x02310000
@@ -50,8 +55,8 @@
 #define NXP_TIMER_STATUS_ADDR		0x023F0000
 
 #define NXP_GICD_ADDR			0x06000000
-#define NXP_GICR_ADDR			0x06200000
-#define NXP_GICR_SGI_ADDR		0x06210000
+#define NXP_GICR_ADDR			0x06100000
+#define NXP_GICR_SGI_ADDR		0x06110000
 
 #define NXP_CAAM_ADDR			0x08000000
 
@@ -61,4 +66,35 @@
 
 #define NXP_RESET_ADDR			0x01E60000
 #define NXP_SEC_REGFILE_ADDR		0x01E88000
-#endif	/*	SOC_DEFAULT_BASE_ADDR_H		*/
+
+#define NXP_RST_ADDR			0x01E88000
+
+/* DDR memory Map */
+#define NXP_DDR_ADDR			0x01080000
+#define NXP_DDR2_ADDR			0x01090000
+#define NXP_DDR3_ADDR			0x08210000
+
+/* QuadSPI base address */
+#define NXP_QSPI_ADDR			0x020C0000
+/* IFC base address */
+#define NXP_IFC_ADDR			0x02240000
+
+/* CCI400 base address */
+#define NXP_CCI_ADDR			0x04090000
+
+/* Global Generic Reference Timer base address */
+#define NXP_TIMER_ADDR			0x023E0000
+
+/* OCRAM TZPC base address */
+#define NXP_OCRAM_TZPC_ADDR		0x02200000
+
+#define NXP_EPU_ADDR			0x700060000
+
+#define NXP_CCN_ADDR			0x04000000
+#define NXP_CCN_HNI_ADDR		0x04080000
+#define NXP_CCN_HN_F_0_ADDR		0x04200000
+#define NXP_CCN_HN_F_1_ADDR		0x04210000
+
+#define TPMWAKEMR0_ADDR			0x700123c50
+
+#endif	/* SOC_DEFAULT_BASE_ADDR_H */
diff --git a/plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h b/plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h
new file mode 100644
index 0000000..8e68367
--- /dev/null
+++ b/plat/nxp/common/include/default/ch_3/soc_default_helper_macros.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef SOC_DEFAULT_HELPER_MACROS_H
+#define SOC_DEFAULT_HELPER_MACROS_H
+
+#ifdef NXP_OCRAM_TZPC_ADDR
+#define TZPC_BLOCK_SIZE			0x1000
+#endif
+
+/* Reset block register offsets */
+#ifdef NXP_RESET_ADDR
+
+/* Register Offset */
+#define RST_RSTCR_OFFSET		0x0
+#define RST_RSTRQMR1_OFFSET		0x10
+#define RST_RSTRQSR1_OFFSET		0x18
+#define BRR_OFFSET			0x60
+
+/* helper macros */
+#define RSTRQMR_RPTOE_MASK		(1 << 19)
+#endif /* NXP_RESET_ADDR */
+
+#define PCIeRC_RN_I_NODE_ID_OFFSET	0x8
+#define PoS_CONTROL_REG_OFFSET		0x0
+#define POS_EARLY_WR_COMP_EN		0x20
+#define HNI_POS_EN			0x01
+#define POS_TERMINATE_BARRIERS		0x10
+#define SERIALIZE_DEV_nGnRnE_WRITES	0x200
+#define ENABLE_ERR_SIGNAL_TO_MN		0x4
+#define ENABLE_RESERVE_BIT53		0x400
+#define ENABLE_WUO			0x10
+
+#define PORT_S0_CTRL_REG_RNI		0x010
+#define PORT_S1_CTRL_REG_RNI		0x110
+#define PORT_S2_CTRL_REG_RNI		0x210
+#define ENABLE_FORCE_RD_QUO		0x20
+#define QOS_SETTING			0x00FF000C
+
+/* epu register offsets and values */
+#define EPU_EPGCR_OFFSET		0x0
+#define EPU_EPIMCR10_OFFSET		0x128
+#define EPU_EPCTR10_OFFSET		0xa28
+#define EPU_EPCCR10_OFFSET		0x828
+#ifndef EPU_EPCCR10_VAL
+#define EPU_EPCCR10_VAL			0xb2800000
+#endif
+#define EPU_EPIMCR10_VAL		0xba000000
+#define EPU_EPCTR10_VAL			0x0
+#define EPU_EPGCR_VAL			(1 << 31)
+
+#ifdef NXP_CCN_ADDR
+#define NXP_CCN_HN_F_1_ADDR		0x04210000
+
+#define CCN_HN_F_SAM_NODEID_MASK	0x7f
+#define CCN_HN_F_SNP_DMN_CTL_OFFSET	0x200
+#define CCN_HN_F_SNP_DMN_CTL_SET_OFFSET	0x210
+#define CCN_HN_F_SNP_DMN_CTL_CLR_OFFSET	0x220
+#define CCN_HN_F_SNP_DMN_CTL_MASK	0x80a00
+#define CCN_HNF_NODE_COUNT              8
+#define CCN_HNF_OFFSET                  0x10000
+
+#define SA_AUX_CTRL_REG_OFFSET		0x500
+#define NUM_HNI_NODE			2
+#define CCN_HNI_MEMORY_MAP_SIZE		0x10000
+
+#define PCIeRC_RN_I_NODE_ID_OFFSET	0x8
+#define PoS_CONTROL_REG_OFFSET		0x0
+#define POS_EARLY_WR_COMP_EN		0x20
+#define HNI_POS_EN			0x01
+#define POS_TERMINATE_BARRIERS		0x10
+#define SERIALIZE_DEV_nGnRnE_WRITES	0x200
+#define ENABLE_ERR_SIGNAL_TO_MN		0x4
+#define ENABLE_RESERVE_BIT53		0x400
+#define ENABLE_WUO			0x10
+#endif
+
+/* reset register bit */
+#define RSTRQMR_RPTOE_MASK		(1 << 19)
+
+/* secmon register offsets and bitfields */
+#define SECMON_HPCOMR_OFFSET		0x4
+#define SECMON_HPCOMR_NPSWAEN		0x80000000
+
+/* Secure-Register-File register offsets and bit masks */
+#ifdef NXP_RST_ADDR
+/* Register Offset */
+#define CORE_HOLD_OFFSET		0x140
+#endif
+
+#define DCFG_SBEESR2_ADDR		0x00100534
+#define DCFG_MBEESR2_ADDR		0x00100544
+/* SBEESR and MBEESR bit mask */
+#define OCRAM_EESR_MASK			0x00000008
+
+#endif /* SOC_DEFAULT_HELPER_MACROS_H */
diff --git a/plat/nxp/common/plat_make_helper/soc_common_def.mk b/plat/nxp/common/plat_make_helper/soc_common_def.mk
index 22cd39a..52f2867 100644
--- a/plat/nxp/common/plat_make_helper/soc_common_def.mk
+++ b/plat/nxp/common/plat_make_helper/soc_common_def.mk
@@ -1,4 +1,4 @@
-# Copyright 2020-2021 NXP
+# Copyright 2020-2022 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -11,14 +11,12 @@
 $(eval $(call add_define_val,CACHE_WRITEBACK_GRANULE,$(CACHE_WRITEBACK_GRANULE)))
 endif
 
-ifeq (${INTERCONNECT}, "CCI400")
+ifneq (${INTERCONNECT},)
 $(eval $(call add_define,NXP_HAS_${INTERCONNECT}))
+ifeq (${INTERCONNECT}, CCI400)
 ICNNCT_ID := 0x420
 $(eval $(call add_define,ICNNCT_ID))
 endif
-
-ifeq (${INTERCONNECT}, "CCN508")
-$(eval $(call add_define,NXP_HAS_CCN508))
 endif
 
 ifneq (${CHASSIS},)
diff --git a/plat/nxp/common/setup/ls_bl2_el3_setup.c b/plat/nxp/common/setup/ls_bl2_el3_setup.c
index 5b5144d..a4cbaef 100644
--- a/plat/nxp/common/setup/ls_bl2_el3_setup.c
+++ b/plat/nxp/common/setup/ls_bl2_el3_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2020 NXP
+ * Copyright 2018-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -182,7 +182,7 @@
 	unsigned int flags = 0U;
 	/* Initialise the IO layer and register platform IO devices */
 	ls_setup_page_tables(
-#if SEPARATE_RW_AND_NOLOAD
+#if SEPARATE_BL2_NOLOAD_REGION
 			      BL2_START,
 			      BL2_LIMIT - BL2_START,
 #else
@@ -289,8 +289,9 @@
 	if ((dram_regions_info.region[0].addr == 0)
 		&& (dram_regions_info.total_dram_size > 0)) {
 		populate_dram_regions_info();
-
+#ifdef PLAT_XLAT_TABLES_DYNAMIC
 		mmap_add_ddr_region_dynamically();
+#endif
 	}
 
 	/* setup the memory region access permissions */
diff --git a/plat/nxp/common/setup/ls_common.c b/plat/nxp/common/setup/ls_common.c
index e7ae060..28d6b72 100644
--- a/plat/nxp/common/setup/ls_common.c
+++ b/plat/nxp/common/setup/ls_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2021 NXP
+ * Copyright 2018-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -113,7 +113,8 @@
 #if defined(PLAT_XLAT_TABLES_DYNAMIC)
 void mmap_add_ddr_region_dynamically(void)
 {
-	int i = 0;
+	int ret, i = 0;
+
 	dram_regions_info_t *info_dram_regions = get_dram_regions_info();
 	/* MMU map for Non-Secure DRAM Regions */
 	VERBOSE("DRAM Region %d: %p - %p\n", i,
@@ -121,10 +122,14 @@
 			(void *) (info_dram_regions->region[i].addr
 				+ info_dram_regions->region[i].size
 				- 1));
-	mmap_add_dynamic_region(info_dram_regions->region[i].addr,
+	ret = mmap_add_dynamic_region(info_dram_regions->region[i].addr,
 			info_dram_regions->region[i].addr,
 			info_dram_regions->region[i].size,
 			MT_MEMORY | MT_RW | MT_NS);
+	if (ret != 0) {
+		ERROR("Failed to add dynamic memory region\n");
+		panic();
+	}
 
 	/* MMU map for Secure DDR Region on DRAM-0 */
 	if (info_dram_regions->region[i].size >
@@ -137,12 +142,16 @@
 				+ NXP_SECURE_DRAM_SIZE
 				+ NXP_SP_SHRD_DRAM_SIZE
 				- 1));
-		mmap_add_dynamic_region((info_dram_regions->region[i].addr
+		ret = mmap_add_dynamic_region((info_dram_regions->region[i].addr
 				+ info_dram_regions->region[i].size),
 				(info_dram_regions->region[i].addr
 				+ info_dram_regions->region[i].size),
 				(NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE),
 				MT_MEMORY | MT_RW | MT_SECURE);
+		if (ret != 0) {
+			ERROR("Failed to add dynamic memory region\n");
+			panic();
+		}
 	}
 
 #ifdef IMAGE_BL31
@@ -155,10 +164,14 @@
 			(void *) (info_dram_regions->region[i].addr
 				+ info_dram_regions->region[i].size
 				- 1));
-		mmap_add_dynamic_region(info_dram_regions->region[i].addr,
+		ret = mmap_add_dynamic_region(info_dram_regions->region[i].addr,
 				info_dram_regions->region[i].addr,
 				info_dram_regions->region[i].size,
 				MT_MEMORY | MT_RW | MT_NS);
+		if (ret != 0) {
+			ERROR("Failed to add dynamic memory region\n");
+			panic();
+		}
 	}
 #endif
 }
diff --git a/plat/nxp/common/soc_errata/errata.c b/plat/nxp/common/soc_errata/errata.c
index a117c91..55ef604 100644
--- a/plat/nxp/common/soc_errata/errata.c
+++ b/plat/nxp/common/soc_errata/errata.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -19,6 +19,15 @@
 	INFO("SoC workaround for Errata A008850 Early-Phase was applied\n");
 	erratum_a008850_early();
 #endif
+#if ERRATA_SOC_A009660
+	INFO("SoC workaround for Errata A009660 was applied\n");
+	erratum_a009660();
+#endif
+#if ERRATA_SOC_A010539
+	INFO("SoC workaround for Errata A010539 was applied\n");
+	erratum_a010539();
+#endif
+
 	/*
 	 * The following DDR Erratas workaround are implemented in DDR driver,
 	 * but print information here.
@@ -29,4 +38,22 @@
 #if ERRATA_DDR_A050450
 	INFO("SoC workaround for DDR Errata A050450 was applied\n");
 #endif
+#if ERRATA_DDR_A050958
+	INFO("SoC workaround for DDR Errata A050958 was applied\n");
+#endif
+#if ERRATA_DDR_A008511
+	INFO("SoC workaround for DDR Errata A008511 was applied\n");
+#endif
+#if ERRATA_DDR_A009803
+	INFO("SoC workaround for DDR Errata A009803 was applied\n");
+#endif
+#if ERRATA_DDR_A009942
+	INFO("SoC workaround for DDR Errata A009942 was applied\n");
+#endif
+#if ERRATA_DDR_A010165
+	INFO("SoC workaround for DDR Errata A010165 was applied\n");
+#endif
+#if ERRATA_DDR_A009663
+	INFO("SoC workaround for DDR Errata A009663 was applied\n");
+#endif
 }
diff --git a/plat/nxp/common/soc_errata/errata.mk b/plat/nxp/common/soc_errata/errata.mk
index d2511bb..3deef3d 100644
--- a/plat/nxp/common/soc_errata/errata.mk
+++ b/plat/nxp/common/soc_errata/errata.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2021 NXP
+# Copyright 2021-2022 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,7 +9,9 @@
 
 ERRATA := \
   ERRATA_SOC_A050426 \
-  ERRATA_SOC_A008850
+  ERRATA_SOC_A008850 \
+  ERRATA_SOC_A009660 \
+  ERRATA_SOC_A010539
 
 define enable_errata
   $(1) ?= 0
diff --git a/plat/nxp/common/soc_errata/errata_a009660.c b/plat/nxp/common/soc_errata/errata_a009660.c
new file mode 100644
index 0000000..d31a4d7
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_a009660.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <mmio.h>
+#include <soc_default_base_addr.h>
+
+void erratum_a009660(void)
+{
+	mmio_write_32(NXP_SCFG_ADDR + 0x20c, 0x63b20042);
+}
diff --git a/plat/nxp/common/soc_errata/errata_a010539.c b/plat/nxp/common/soc_errata/errata_a010539.c
new file mode 100644
index 0000000..3dcbdc8
--- /dev/null
+++ b/plat/nxp/common/soc_errata/errata_a010539.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <mmio.h>
+
+#include <plat_common.h>
+
+void erratum_a010539(void)
+{
+	if (get_boot_dev() == BOOT_DEVICE_QSPI) {
+		unsigned int *porsr1 = (void *)(NXP_DCFG_ADDR +
+				DCFG_PORSR1_OFFSET);
+		uint32_t val;
+
+		val = (gur_in32(porsr1) & ~PORSR1_RCW_MASK);
+		mmio_write_32((uint32_t)(NXP_DCSR_DCFG_ADDR +
+				DCFG_DCSR_PORCR1_OFFSET), htobe32(val));
+		/* Erratum need to set '1' to all bits for reserved SCFG register 0x1a8 */
+		mmio_write_32((uint32_t)(NXP_SCFG_ADDR + 0x1a8),
+				htobe32(0xffffffff));
+	}
+}
diff --git a/plat/nxp/common/soc_errata/errata_list.h b/plat/nxp/common/soc_errata/errata_list.h
index ae95fa2..f6741e2 100644
--- a/plat/nxp/common/soc_errata/errata_list.h
+++ b/plat/nxp/common/soc_errata/errata_list.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -17,4 +17,12 @@
 void erratum_a008850_post(void);
 #endif
 
+#ifdef ERRATA_SOC_A009660
+void erratum_a009660(void);
+#endif
+
+#ifdef ERRATA_SOC_A010539
+void erratum_a010539(void);
+#endif
+
 #endif /* ERRATA_LIST_H */
diff --git a/plat/nxp/common/tbbr/tbbr.mk b/plat/nxp/common/tbbr/tbbr.mk
index 25852ba..7edcfbc 100644
--- a/plat/nxp/common/tbbr/tbbr.mk
+++ b/plat/nxp/common/tbbr/tbbr.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2020 NXP
+# Copyright 2020-2022 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -13,6 +13,12 @@
 CSF_FILE		:=	input_blx_ch${CHASSIS}
 BL2_CSF_FILE		:=	input_bl2_ch${CHASSIS}
 else
+ifeq ($(CHASSIS), 3)
+CSF_FILE		:=	input_blx_ch${CHASSIS}
+BL2_CSF_FILE		:=	input_bl2_ch${CHASSIS}
+PBI_CSF_FILE		:=	input_pbi_ch${CHASSIS}
+$(eval $(call add_define, CSF_HDR_CH3))
+else
 ifeq ($(CHASSIS), 3_2)
 CSF_FILE		:=	input_blx_ch3
 BL2_CSF_FILE		:=	input_bl2_ch${CHASSIS}
@@ -22,6 +28,7 @@
     $(error -> CHASSIS not set!)
 endif
 endif
+endif
 
 PLAT_AUTH_PATH		:=  $(PLAT_DRIVERS_PATH)/auth
 
diff --git a/plat/nxp/soc-ls1088a/aarch64/ls1088a.S b/plat/nxp/soc-ls1088a/aarch64/ls1088a.S
new file mode 100644
index 0000000..0c6b7ea
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/aarch64/ls1088a.S
@@ -0,0 +1,1817 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+.section .text, "ax"
+
+#include <asm_macros.S>
+#include <lib/psci/psci.h>
+#include <nxp_timer.h>
+#include <plat_gic.h>
+
+#include "bl31_data.h"
+#include "plat_psci.h"
+#include "platform_def.h"
+
+/*
+ * the BASE address for these offsets is AUX_01_DATA in the
+ * bootcore's psci data region
+ */
+#define DEVDISR2_MASK_OFFSET	0x0    /* references AUX_01_DATA */
+#define DEVDISR5_MASK_OFFSET	0x8    /* references AUX_02_DATA */
+
+/*
+ * the BASE address for these offsets is AUX_04_DATA in the
+ * bootcore's psci data region
+ */
+#define GICD_BASE_ADDR_OFFSET	0x0    /* references AUX_04_DATA */
+#define GICC_BASE_ADDR_OFFSET	0x8    /* references AUX_05_DATA */
+
+#define IPSTPACK_RETRY_CNT	0x10000
+#define DDR_SLEEP_RETRY_CNT	0x10000
+#define CPUACTLR_EL1		S3_1_C15_C2_0
+#define DDR_SDRAM_CFG_2_FRCSR	0x80000000
+#define DDR_SDRAM_CFG_2_OFFSET	0x114
+#define DDR_TIMING_CFG_4_OFFSET	0x160
+#define DDR_CNTRL_BASE_ADDR	0x01080000
+
+#define DLL_LOCK_MASK		0x3
+#define DLL_LOCK_VALUE		0x2
+
+#define ERROR_DDR_SLEEP		-1
+#define ERROR_DDR_WAKE		-2
+#define ERROR_NO_QUIESCE	-3
+
+#define CORE_RESTARTABLE	0
+#define CORE_NOT_RESTARTABLE	1
+
+.global soc_init_lowlevel
+.global soc_init_percpu
+
+.global _soc_core_release
+.global _soc_core_restart
+.global _soc_ck_disabled
+.global _soc_sys_reset
+.global _soc_sys_off
+
+.global _soc_core_prep_off
+.global _soc_core_entr_off
+.global _soc_core_exit_off
+
+.global _soc_core_prep_stdby
+.global _soc_core_entr_stdby
+.global _soc_core_exit_stdby
+.global _soc_core_prep_pwrdn
+.global _soc_core_entr_pwrdn
+.global _soc_core_exit_pwrdn
+.global _soc_clstr_prep_stdby
+.global _soc_clstr_exit_stdby
+.global _soc_clstr_prep_pwrdn
+.global _soc_clstr_exit_pwrdn
+.global _soc_sys_prep_stdby
+.global _soc_sys_exit_stdby
+.global _soc_sys_prep_pwrdn
+.global _soc_sys_pwrdn_wfi
+.global _soc_sys_exit_pwrdn
+
+.global _set_platform_security
+.global _soc_set_start_addr
+
+.equ TZPCDECPROT_0_SET_BASE, 0x02200804
+.equ TZPCDECPROT_1_SET_BASE, 0x02200810
+.equ TZPCDECPROT_2_SET_BASE, 0x0220081C
+
+.equ TZASC_REGION_ATTRIBUTES_0_0, 0x01100110
+
+.equ MPIDR_AFFINITY0_MASK, 0x00FF
+.equ MPIDR_AFFINITY1_MASK, 0xFF00
+.equ CPUECTLR_DISABLE_TWALK_PREFETCH, 0x4000000000
+.equ CPUECTLR_INS_PREFETCH_MASK, 0x1800000000
+.equ CPUECTLR_DAT_PREFETCH_MASK, 0x0300000000
+.equ OSDLR_EL1_DLK_LOCK, 0x1
+.equ CNTP_CTL_EL0_EN, 0x1
+.equ CNTP_CTL_EL0_IMASK, 0x2
+/* shifted value for incrementing cluster count in mpidr */
+.equ MPIDR_CLUSTER, 0x100
+
+/*
+ * This function initialize the soc,
+ * in: none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11
+ */
+func soc_init_lowlevel
+	/*
+	 * called from C, so save the non-volatile regs
+	 * save these as pairs of registers to maintain the
+	 * required 16-byte alignment on the stack
+	 */
+	stp	x4, x5, [sp, #-16]!
+	stp	x6, x7, [sp, #-16]!
+	stp	x8, x9, [sp, #-16]!
+	stp	x10, x11, [sp, #-16]!
+	stp	x12, x13, [sp, #-16]!
+	stp	x18, x30, [sp, #-16]!
+
+	/*
+	 * make sure the personality has been established by releasing cores
+	 * that are marked "to-be-disabled" from reset
+	 */
+	bl	release_disabled
+
+	/* set SCRATCHRW7 to 0x0 */
+	ldr	x0, =DCFG_SCRATCHRW7_OFFSET
+	mov	x1, xzr
+	bl	_write_reg_dcfg
+
+	/* restore the aarch32/64 non-volatile registers */
+	ldp	x18, x30, [sp], #16
+	ldp	x12, x13, [sp], #16
+	ldp	x10, x11, [sp], #16
+	ldp	x8, x9, [sp], #16
+	ldp	x6, x7, [sp], #16
+	ldp	x4, x5, [sp], #16
+	ret
+endfunc soc_init_lowlevel
+
+/*
+ * void soc_init_percpu(void)
+ * this function performs any soc-specific initialization that is needed on
+ * a per-core basis
+ * in:  none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+func soc_init_percpu
+	stp	x4, x30, [sp, #-16]!
+
+	bl	plat_my_core_mask
+	mov	x2, x0
+
+	/* x2 = core mask */
+
+	/* see if this core is marked for prefetch disable */
+	mov	x0, #PREFETCH_DIS_OFFSET
+	bl	_get_global_data
+	tst	x0, x2
+	b.eq	1f
+	bl	_disable_ldstr_pfetch_A53
+1:
+	mov	x0, #NXP_PMU_ADDR
+	bl	enable_timer_base_to_cluster
+	ldp	x4, x30, [sp], #16
+	ret
+endfunc soc_init_percpu
+
+/*
+ * this function sets the security mechanisms in the SoC to implement the
+ * Platform Security Policy
+ */
+func _set_platform_security
+	mov	x3, x30
+
+#if (!SUPPRESS_TZC)
+	/* initialize the tzpc */
+	bl	init_tzpc
+#endif
+
+#if (!SUPPRESS_SEC)
+	/* initialize secmon */
+	bl	initSecMon
+#endif
+	mov	x30, x3
+	ret
+endfunc _set_platform_security
+
+/*
+ * this function writes a 64-bit address to bootlocptrh/l
+ * in:  x0, 64-bit address to write to BOOTLOCPTRL/H
+ * out: none
+ * uses x0, x1, x2
+ */
+func _soc_set_start_addr
+	/* get the 64-bit base address of the dcfg block */
+	ldr	x2, =NXP_DCFG_ADDR
+
+	/* write the 32-bit BOOTLOCPTRL register */
+	mov	x1, x0
+	str	w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET]
+
+	/* write the 32-bit BOOTLOCPTRH register */
+	lsr	x1, x0, #32
+	str	w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET]
+	ret
+endfunc _soc_set_start_addr
+
+/*
+ * part of CPU_ON
+ * this function releases a secondary core from reset
+ * in: x0 = core_mask_lsb
+ * out: none
+ * uses: x0, x1, x2, x3
+ */
+_soc_core_release:
+	mov	x3, x30
+
+	/* x0 = core mask */
+
+	ldr	x1, =NXP_SEC_REGFILE_ADDR
+	/*
+	 * write to CORE_HOLD to tell the bootrom that we want this core
+	 * to run
+	 */
+	str	w0, [x1, #CORE_HOLD_OFFSET]
+
+	/* x0 = core mask */
+
+	/* read-modify-write BRRL to release core */
+	mov	x1, #NXP_RESET_ADDR
+	ldr	w2, [x1, #BRR_OFFSET]
+	orr	w2, w2, w0
+	str	w2, [x1, #BRR_OFFSET]
+	dsb	sy
+	isb
+
+	/* send event */
+	sev
+	isb
+
+	mov	x30, x3
+	ret
+
+/*
+ * this function determines if a core is disabled via COREDISABLEDSR
+ * in:  w0  = core_mask_lsb
+ * out: w0  = 0, core not disabled
+ *      w0 != 0, core disabled
+ * uses x0, x1
+ */
+_soc_ck_disabled:
+	/* get base addr of dcfg block */
+	ldr	x1, =NXP_DCFG_ADDR
+
+	/* read COREDISABLEDSR */
+	ldr	w1, [x1, #DCFG_COREDISABLEDSR_OFFSET]
+
+	/* test core bit */
+	and	w0, w1, w0
+
+	ret
+
+/*
+ * part of CPU_ON
+ * this function restarts a core shutdown via _soc_core_entr_off
+ * in:  x0 = core mask lsb (of the target cpu)
+ * out: x0 == 0, on success
+ *      x0 != 0, on failure
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_core_restart:
+	mov	x6, x30
+	mov	x4, x0
+
+	/* x4 = core mask lsb */
+
+	/* pgm GICD_CTLR - enable secure grp0  */
+	mov	x5, #NXP_GICD_ADDR
+	ldr	w2, [x5, #GICD_CTLR_OFFSET]
+	orr	w2, w2, #GICD_CTLR_EN_GRP_0
+	str	w2, [x5, #GICD_CTLR_OFFSET]
+	dsb	sy
+	isb
+	/* poll on RWP til write completes */
+4:
+	ldr	w2, [x5, #GICD_CTLR_OFFSET]
+	tst	w2, #GICD_CTLR_RWP
+	b.ne	4b
+
+	/*
+	 * x4 = core mask lsb
+	 * x5 = gicd base addr
+	 */
+
+	mov	x0, x4
+	bl	get_mpidr_value
+
+	/*
+	 * x0 = mpidr of target core
+	 * x4 = core mask lsb of target core
+	 * x5 = gicd base addr
+	 */
+
+	/* generate target list bit */
+	and	x1, x0, #MPIDR_AFFINITY0_MASK
+	mov	x2, #1
+	lsl	x2, x2, x1
+	/* get the affinity1 field */
+	and	x1, x0, #MPIDR_AFFINITY1_MASK
+	lsl	x1, x1, #8
+	orr	x2, x2, x1
+	/* insert the INTID for SGI15 */
+	orr	x2, x2, #ICC_SGI0R_EL1_INTID
+	/* fire the SGI */
+	msr	ICC_SGI0R_EL1, x2
+	dsb	sy
+	isb
+
+	/* load '0' on success */
+	mov	x0, xzr
+
+	mov	x30, x6
+	ret
+
+/*
+ * part of CPU_OFF
+ * this function programs SoC & GIC registers in preparation for shutting down
+ * the core
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7
+ */
+_soc_core_prep_off:
+	mov	x8, x30
+	mov	x7, x0
+
+	/* x7 = core mask lsb */
+
+	mrs	x1, CPUECTLR_EL1
+	/* set smp and disable L2 snoops in cpuectlr */
+	orr	x1, x1, #CPUECTLR_SMPEN_EN
+	orr	x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH
+	bic	x1, x1, #CPUECTLR_INS_PREFETCH_MASK
+	bic	x1, x1, #CPUECTLR_DAT_PREFETCH_MASK
+	/* set retention control in cpuectlr */
+	bic	x1, x1, #CPUECTLR_TIMER_MASK
+	orr	x1, x1, #CPUECTLR_TIMER_8TICKS
+	msr	CPUECTLR_EL1, x1
+
+	/* get redistributor rd base addr for this core */
+	mov	x0, x7
+	bl	get_gic_rd_base
+	mov	x6, x0
+
+	/* get redistributor sgi base addr for this core */
+	mov	x0, x7
+	bl	get_gic_sgi_base
+	mov	x5, x0
+
+	/* x5 = gicr sgi base addr
+	 * x6 = gicr rd  base addr
+	 * x7 = core mask lsb
+	 */
+
+	/* disable SGI 15 at redistributor - GICR_ICENABLER0 */
+	mov	w3, #GICR_ICENABLER0_SGI15
+	str	w3, [x5, #GICR_ICENABLER0_OFFSET]
+2:
+	/* poll on rwp bit in GICR_CTLR */
+	ldr	w4, [x6, #GICR_CTLR_OFFSET]
+	tst	w4, #GICR_CTLR_RWP
+	b.ne	2b
+
+	/* disable GRP1 interrupts at cpu interface */
+	msr	ICC_IGRPEN1_EL3, xzr
+
+	/* disable GRP0 ints at cpu interface */
+	msr	ICC_IGRPEN0_EL1, xzr
+
+	/* program the redistributor - poll on GICR_CTLR.RWP as needed */
+
+	/* define SGI 15 as Grp0 - GICR_IGROUPR0 */
+	ldr	w4, [x5, #GICR_IGROUPR0_OFFSET]
+	bic	w4, w4, #GICR_IGROUPR0_SGI15
+	str	w4, [x5, #GICR_IGROUPR0_OFFSET]
+
+	/* define SGI 15 as Grp0 - GICR_IGRPMODR0 */
+	ldr	w3, [x5, #GICR_IGRPMODR0_OFFSET]
+	bic	w3, w3, #GICR_IGRPMODR0_SGI15
+	str	w3, [x5, #GICR_IGRPMODR0_OFFSET]
+
+	/* set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */
+	ldr	w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+	bic	w4, w4, #GICR_IPRIORITYR3_SGI15_MASK
+	str	w4, [x5, #GICR_IPRIORITYR3_OFFSET]
+
+	/* enable SGI 15 at redistributor - GICR_ISENABLER0 */
+	mov	w3, #GICR_ISENABLER0_SGI15
+	str	w3, [x5, #GICR_ISENABLER0_OFFSET]
+	dsb	sy
+	isb
+3:
+	/* poll on rwp bit in GICR_CTLR */
+	ldr	w4, [x6, #GICR_CTLR_OFFSET]
+	tst	w4, #GICR_CTLR_RWP
+	b.ne	3b
+
+	/* quiesce the debug interfaces */
+	mrs	x3, osdlr_el1
+	orr	x3, x3, #OSDLR_EL1_DLK_LOCK
+	msr	osdlr_el1, x3
+	isb
+
+	/* enable grp0 ints */
+	mov	x3, #ICC_IGRPEN0_EL1_EN
+	msr	ICC_IGRPEN0_EL1, x3
+
+	/*
+	 * x5 = gicr sgi base addr
+	 * x6 = gicr rd  base addr
+	 * x7 = core mask lsb
+	 */
+
+	/* clear any pending interrupts */
+	mvn	w1, wzr
+	str	w1, [x5, #GICR_ICPENDR0_OFFSET]
+
+	/* make sure system counter is enabled */
+	ldr	x3, =NXP_TIMER_ADDR
+	ldr	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+	tst	w0, #SYS_COUNTER_CNTCR_EN
+	b.ne	4f
+	orr	w0, w0, #SYS_COUNTER_CNTCR_EN
+	str	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+4:
+	/* enable the core timer and mask timer interrupt */
+	mov	x1, #CNTP_CTL_EL0_EN
+	orr	x1, x1, #CNTP_CTL_EL0_IMASK
+	msr	cntp_ctl_el0, x1
+
+	mov	x30, x8
+	ret
+
+/*
+ * part of CPU_OFF
+ * this function performs the final steps to shutdown the core
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5
+ */
+_soc_core_entr_off:
+	mov	x5, x30
+	mov	x4, x0
+
+	/* x4 = core mask */
+1:
+	/* enter low-power state by executing wfi */
+	wfi
+
+	/* see if SGI15 woke us up */
+	mrs	x2, ICC_IAR0_EL1
+	mov	x3, #ICC_IAR0_EL1_SGI15
+	cmp	x2, x3
+	b.ne	2f
+
+	/* deactivate the int */
+	msr	ICC_EOIR0_EL1, x2
+
+	/* x4 = core mask */
+2:
+	/* check if core has been turned on */
+	mov	x0, x4
+	bl	_getCoreState
+
+	/* x0 = core state */
+
+	cmp	x0, #CORE_WAKEUP
+	b.ne	1b
+
+	/* if we get here, then we have exited the wfi */
+
+	mov	x30, x5
+	ret
+
+/*
+ * part of CPU_OFF
+ * this function starts the process of starting a core back up
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_core_exit_off:
+	mov	x6, x30
+	mov	x5, x0
+
+	/* disable forwarding of GRP0 ints at cpu interface */
+	msr	ICC_IGRPEN0_EL1, xzr
+
+	/* get redistributor sgi base addr for this core */
+	mov	x0, x5
+	bl	get_gic_sgi_base
+	mov	x4, x0
+
+	/*
+	 * x4 = gicr sgi base addr
+	 * x5 = core mask
+	 */
+
+	/* disable SGI 15 at redistributor - GICR_ICENABLER0 */
+	mov	w1, #GICR_ICENABLER0_SGI15
+	str	w1, [x4, #GICR_ICENABLER0_OFFSET]
+
+	/* get redistributor rd base addr for this core */
+	mov	x0, x5
+	bl	get_gic_rd_base
+	mov	x4, x0
+
+	/* x4 = gicr rd  base addr */
+2:
+	/* poll on rwp bit in GICR_CTLR */
+	ldr	w2, [x4, #GICR_CTLR_OFFSET]
+	tst	w2, #GICR_CTLR_RWP
+	b.ne	2b
+
+	/* x4 = gicr rd  base addr */
+
+	/* unlock the debug interfaces */
+	mrs	x3, osdlr_el1
+	bic	x3, x3, #OSDLR_EL1_DLK_LOCK
+	msr	osdlr_el1, x3
+	isb
+
+	dsb	sy
+	isb
+	mov	x30, x6
+	ret
+
+/*
+ * this function requests a reset of the entire SOC
+ * in:  none
+ * out: none
+ * uses: x0, x1, x2, x3, x4, x5, x6
+ */
+_soc_sys_reset:
+	mov	x3, x30
+
+	/* make sure the mask is cleared in the reset request mask register */
+	mov	x0, #RST_RSTRQMR1_OFFSET
+	mov	w1, wzr
+	bl	_write_reg_reset
+
+	/* set the reset request */
+	mov	x4, #RST_RSTCR_OFFSET
+	mov	x0, x4
+	mov	w1, #RSTCR_RESET_REQ
+	bl	_write_reg_reset
+
+	/* x4 = RST_RSTCR_OFFSET */
+
+	/*
+	 * just in case this address range is mapped as cacheable,
+	 * flush the write out of the dcaches
+	 */
+	mov	x2, #NXP_RESET_ADDR
+	add	x2, x2, x4
+	dc	cvac, x2
+	dsb	st
+	isb
+
+	/* this function does not return */
+	b	.
+
+/*
+ * this function turns off the SoC
+ * Note: this function is not intended to return, and the only allowable
+ *       recovery is POR
+ * in:  none
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_sys_off:
+	/*
+	 * A-009810: LPM20 entry sequence might cause
+	 * spurious timeout reset request
+	 * workaround: MASK RESET REQ RPTOE
+	 */
+	ldr	x0, =NXP_RESET_ADDR
+	ldr	w1, [x0, #RST_RSTRQMR1_OFFSET]
+	orr	w1, w1, #RSTRQMR_RPTOE_MASK
+	str	w1, [x0, #RST_RSTRQMR1_OFFSET]
+
+	/* disable SEC, QBman spi and qspi */
+	ldr	x2, =NXP_DCFG_ADDR
+	ldr	x0, =DCFG_DEVDISR1_OFFSET
+	ldr	w1, =DCFG_DEVDISR1_SEC
+	str	w1, [x2, x0]
+	ldr	x0, =DCFG_DEVDISR3_OFFSET
+	ldr	w1, =DCFG_DEVDISR3_QBMAIN
+	str	w1, [x2, x0]
+	ldr	x0, =DCFG_DEVDISR4_OFFSET
+	ldr	w1, =DCFG_DEVDISR4_SPI_QSPI
+	str	w1, [x2, x0]
+
+	/* set TPMWAKEMR0 */
+	ldr	x0, =TPMWAKEMR0_ADDR
+	mov	w1, #0x1
+	str	w1, [x0]
+
+	/* disable icache, dcache, mmu @ EL1 */
+	mov	x1, #SCTLR_I_C_M_MASK
+	mrs	x0, sctlr_el1
+	bic	x0, x0, x1
+	msr	sctlr_el1, x0
+
+	/* disable L2 prefetches */
+	mrs	x0, CPUECTLR_EL1
+	orr	x0, x0, #CPUECTLR_SMPEN_EN
+	orr	x0, x0, #CPUECTLR_TIMER_8TICKS
+	msr	CPUECTLR_EL1, x0
+	dsb	sy
+	isb
+
+	/* disable CCN snoop domain */
+	ldr	x0, =NXP_CCI_ADDR
+	mov	w1, #0x1
+	str	w1, [x0]
+
+	mov	x2, #DAIF_SET_MASK
+
+	mrs	x1, spsr_el1
+	orr	x1, x1, x2
+	msr	spsr_el1, x1
+
+	mrs	x1, spsr_el2
+	orr	x1, x1, x2
+	msr	spsr_el2, x1
+
+	bl	get_pmu_idle_cluster_mask
+	mov	x3, #NXP_PMU_ADDR
+
+	/* x3 = pmu base addr */
+
+	/* idle the ACP interfaces */
+	str	w0, [x3, #PMU_CLAINACTSETR_OFFSET]
+
+	/* force the debug interface to be quiescent */
+	mrs	x0, osdlr_el1
+	orr	x0, x0, #0x1
+	msr	osdlr_el1, x0
+
+	bl	get_pmu_flush_cluster_mask
+	/* x3 = pmu base addr */
+	mov	x3, #NXP_PMU_ADDR
+
+	/* clear flush request and status */
+	ldr	x2, =PMU_CLSL2FLUSHCLRR_OFFSET
+	str	w0, [x3, x2]
+
+	/* close the Skyros master port */
+	ldr	x2, =PMU_CLSINACTSETR_OFFSET
+	str	w0, [x3, x2]
+
+	/* request lpm20 */
+	ldr	x0, =PMU_POWMGTCSR_OFFSET
+	ldr	w1, =PMU_POWMGTCSR_VAL
+	str	w1, [x3, x0]
+
+	/* this function does not return */
+1:
+	wfi
+	b	1b
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_core_prep_stdby:
+	/* clear CPUECTLR_EL1[2:0] */
+	mrs	x1, CPUECTLR_EL1
+	bic	x1, x1, #CPUECTLR_TIMER_MASK
+	msr	CPUECTLR_EL1, x1
+
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core into standby state
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_stdby:
+	/* X0 = core mask lsb */
+	dsb	sy
+	isb
+	wfi
+
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_core_exit_stdby:
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_core_prep_pwrdn:
+	/* make sure system counter is enabled */
+	ldr	x3, =NXP_TIMER_ADDR
+	ldr	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+	tst	w0, #SYS_COUNTER_CNTCR_EN
+	b.ne	1f
+	orr	w0, w0, #SYS_COUNTER_CNTCR_EN
+	str	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+	/*
+	 * enable dynamic retention control (CPUECTLR[2:0])
+	 * set the SMPEN bit (CPUECTLR[6])
+	 */
+	mrs	x1, CPUECTLR_EL1
+	bic	x1, x1, #CPUECTLR_RET_MASK
+	orr	x1, x1, #CPUECTLR_TIMER_8TICKS
+	orr	x1, x1, #CPUECTLR_SMPEN_EN
+	msr	CPUECTLR_EL1, x1
+
+	isb
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core into a power-down state
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_core_entr_pwrdn:
+	/* X0 = core mask lsb */
+	dsb	sy
+	isb
+	wfi
+
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function cleans up after a core exits power-down
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses
+ */
+_soc_core_exit_pwrdn:
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_clstr_prep_stdby:
+	/* clear CPUECTLR_EL1[2:0] */
+	mrs	x1, CPUECTLR_EL1
+	bic	x1, x1, #CPUECTLR_TIMER_MASK
+	msr	CPUECTLR_EL1, x1
+
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_clstr_exit_stdby:
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to power-down
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0, x1, x2, x3
+ */
+_soc_clstr_prep_pwrdn:
+	/* make sure system counter is enabled */
+	ldr	x3, =NXP_TIMER_ADDR
+	ldr	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+	tst	w0, #SYS_COUNTER_CNTCR_EN
+	b.ne	1f
+	orr	w0, w0, #SYS_COUNTER_CNTCR_EN
+	str	w0, [x3, #SYS_COUNTER_CNTCR_OFFSET]
+1:
+	/*
+	 * enable dynamic retention control (CPUECTLR[2:0])
+	 * set the SMPEN bit (CPUECTLR[6])
+	 */
+	mrs	x1, CPUECTLR_EL1
+	bic	x1, x1, #CPUECTLR_RET_MASK
+	orr	x1, x1, #CPUECTLR_TIMER_8TICKS
+	orr	x1, x1, #CPUECTLR_SMPEN_EN
+	msr	CPUECTLR_EL1, x1
+
+	isb
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function cleans up after a core exits power-down
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses
+ */
+_soc_clstr_exit_pwrdn:
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to standby
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_prep_stdby:
+	/* clear CPUECTLR_EL1[2:0] */
+	mrs	x1, CPUECTLR_EL1
+	bic	x1, x1, #CPUECTLR_TIMER_MASK
+	msr	CPUECTLR_EL1, x1
+
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after standby state
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses none
+ */
+_soc_sys_exit_stdby:
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs SoC-specific programming prior to
+ * suspend-to-power-down
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0
+ */
+_soc_sys_prep_pwrdn:
+	/* set retention control */
+	mrs	x0, CPUECTLR_EL1
+	bic	x0, x0, #CPUECTLR_TIMER_MASK
+	orr	x0, x0, #CPUECTLR_TIMER_8TICKS
+	orr	x0, x0, #CPUECTLR_SMPEN_EN
+	msr	CPUECTLR_EL1, x0
+	dsb	sy
+	isb
+
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function puts the calling core, and potentially the soc, into a
+ * low-power state
+ * in:  x0 = core mask lsb
+ * out: x0 = 0, success
+ *      x0 < 0, failure
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
+ */
+_soc_sys_pwrdn_wfi:
+	/* Save LR to stack */
+	stp	x18, x30, [sp, #-16]!
+
+	/* Poll PCPW20SR for all secondary cores to be placed in PW20 */
+	bl	get_tot_num_cores
+	mov	x3, #0x1
+	lsl	x3, x3, x0
+	sub	x3, x3, #2
+1:
+	mov	x0, #NXP_PMU_ADDR
+	ldr	w1, [x0, #PMU_PCPW20SR_OFFSET]
+	cmp	w1, w3
+	b.ne	1b
+
+	/* backup EPU registers to stack */
+	mov	x3, #NXP_PMU_ADDR
+	ldr	x2, =NXP_EPU_ADDR
+	ldr	w4, [x2, #EPU_EPIMCR10_OFFSET]
+	ldr	w5, [x2, #EPU_EPCCR10_OFFSET]
+	ldr	w6, [x2, #EPU_EPCTR10_OFFSET]
+	ldr	w7, [x2, #EPU_EPGCR_OFFSET]
+	stp	x4, x5, [sp, #-16]!
+	stp	x6, x7, [sp, #-16]!
+
+	/*
+	 * x2 = epu base addr
+	 * x3 = pmu base addr
+	 */
+
+	/* set up EPU event to receive the wake signal from PMU */
+	mov	w4, #EPU_EPIMCR10_VAL
+	mov	w5, #EPU_EPCCR10_VAL
+	mov	w6, #EPU_EPCTR10_VAL
+	mov	w7, #EPU_EPGCR_VAL
+	str	w4, [x2, #EPU_EPIMCR10_OFFSET]
+	str	w5, [x2, #EPU_EPCCR10_OFFSET]
+	str	w6, [x2, #EPU_EPCTR10_OFFSET]
+	str	w7, [x2, #EPU_EPGCR_OFFSET]
+
+	/*
+	 * A-010194: There is logic problem
+	 * in the path of GIC-to-PMU to issue
+	 * wake request to core0
+	 * Workaround: Re-target the wakeup interrupts
+	 * to a core other than the last active core0
+	 */
+	ldr	x2, =NXP_GICD_ADDR
+
+	/* backup flextimer/mmc/usb interrupt router */
+	ldr	x0, =GICD_IROUTER60_OFFSET
+	ldr	x1, =GICD_IROUTER76_OFFSET
+	ldr	w4, [x2, x0]
+	ldr	w5, [x2, x1]
+	ldr	x0, =GICD_IROUTER112_OFFSET
+	ldr	x1, =GICD_IROUTER113_OFFSET
+	ldr	w6, [x2, x0]
+	ldr	w7, [x2, x1]
+	stp	x4, x5, [sp, #-16]!
+	stp	x6,  x7,  [sp, #-16]!
+
+	/*
+	 * x2 = gicd base addr
+	 * x0 = GICD_IROUTER112_OFFSET
+	 * x1 = GICD_IROUTER113_OFFSET
+	 */
+
+	/* re-route interrupt to cluster 1 */
+	ldr	w4, =GICD_IROUTER_VALUE
+	str	w4, [x2, x0]
+	str	w4, [x2, x1]
+	ldr	x0, =GICD_IROUTER60_OFFSET
+	ldr	x1, =GICD_IROUTER76_OFFSET
+	str	w4, [x2, x0]
+	str	w4, [x2, x1]
+	dsb	sy
+	isb
+
+	/* backup flextimer/mmc/usb interrupt enabler */
+	ldr	x0, =GICD_ISENABLER_1
+	ldr	w4, [x2, x0]
+	ldr	x1, =GICD_ISENABLER_2
+	ldr	w5, [x2, x1]
+	stp	x4, x5, [sp, #-16]!
+
+	ldr	x0, =GICD_ISENABLER_3
+	ldr	w4, [x2, x0]
+	ldr	x1, =GICD_ICENABLER_1
+	ldr	w5, [x2, x1]
+	stp	x4, x5, [sp, #-16]!
+
+	ldr	x0, =GICD_ICENABLER_2
+	ldr	w4, [x2, x0]
+	ldr	x1, =GICD_ICENABLER_3
+	ldr	w5, [x2, x1]
+	stp	x4, x5, [sp, #-16]!
+
+	/* enable related interrupt routing */
+	ldr	w4, =GICD_ISENABLER_1_VALUE
+	ldr	x0, =GICD_ISENABLER_1
+	str	w4, [x2, x0]
+	dsb	sy
+	isb
+
+	ldr	w4, =GICD_ISENABLER_2_VALUE
+	ldr	x0, =GICD_ISENABLER_2
+	str	w4, [x2, x0]
+	dsb	sy
+	isb
+
+	ldr	w4, =GICD_ISENABLER_3_VALUE
+	ldr	x0, =GICD_ISENABLER_3
+	str	w4, [x2, x0]
+	dsb	sy
+	isb
+
+	/* set POWMGTDCR [STP_PV_EN] = 1 */
+	ldr	x2, =NXP_POWMGTDCR
+	ldr	w4, =0x01
+	str	w4, [x2]
+
+	/* program IPSTPCR for override stop request (except DDR) */
+	mov	x3, #NXP_PMU_ADDR
+
+	/* build an override mask for IPSTPCR4/IPSTPACK4/DEVDISR5 */
+	ldr	x2, =PMU_IPPDEXPCR4_OFFSET
+	ldr	w7, [x3, x2]
+
+	mov	x5, xzr
+	ldr	x6, =IPPDEXPCR4_MASK
+	and	x6, x6, x7
+	cbz	x6, 1f
+
+	/*
+	 * x5 = override mask
+	 * x6 = IPPDEXPCR bits for DEVDISR5
+	 * x7 = IPPDEXPCR
+	 */
+
+	/* get the overrides */
+	orr	x4, x5, #DEVDISR5_FLX_TMR
+	tst	x6, #IPPDEXPCR_FLX_TMR
+	csel	x5, x5, x4, EQ
+1:
+	/* store the DEVDISR5 override mask */
+	ldr	x2, =BC_PSCI_BASE
+	add	x2, x2, #AUX_01_DATA
+	str	w5, [x2, #DEVDISR5_MASK_OFFSET]
+
+	mov	x3, #NXP_PMU_ADDR
+
+	/* write IPSTPCR0 - no overrides */
+	ldr	x2, =PMU_IPSTPCR0_OFFSET
+	ldr	w5, =IPSTPCR0_VALUE
+	str	w5, [x3, x2]
+
+	/* write IPSTPCR1 - no overrides */
+	ldr	x2, =PMU_IPSTPCR1_OFFSET
+	ldr	w5, =IPSTPCR1_VALUE
+	str	w5, [x3, x2]
+
+	/* write IPSTPCR2 - no overrides */
+	ldr	x2, =PMU_IPSTPCR2_OFFSET
+	ldr	w5, =IPSTPCR2_VALUE
+	str	w5, [x3, x2]
+
+	/* write IPSTPCR3 - no overrides */
+	ldr	x2, =PMU_IPSTPCR3_OFFSET
+	ldr	w5, =IPSTPCR3_VALUE
+	str	w5, [x3, x2]
+
+	/* write IPSTPCR4 - overrides possible */
+	ldr	x2, =BC_PSCI_BASE
+	add	x2, x2, #AUX_01_DATA
+	ldr	w6, [x2, #DEVDISR5_MASK_OFFSET]
+	ldr	x2, =PMU_IPSTPCR4_OFFSET
+	ldr	w5, =IPSTPCR4_VALUE
+	bic	x5, x5, x6
+	str	w5, [x3, x2]
+
+	/* write IPSTPCR5 - no overrides */
+	ldr	x2, =PMU_IPSTPCR5_OFFSET
+	ldr	w5, =IPSTPCR5_VALUE
+	str	w5, [x3, x2]
+
+	/* write IPSTPCR6 - no overrides */
+	ldr	x2, =PMU_IPSTPCR6_OFFSET
+	ldr	w5, =IPSTPCR6_VALUE
+	str	w5, [x3, x2]
+
+	/* poll IPSTPACK for IP stop acknowledgment (except DDR) */
+	mov	x3, #NXP_PMU_ADDR
+
+	/* poll on IPSTPACK0 */
+	ldr	x2, =PMU_IPSTPACK0_OFFSET
+	ldr	x4, =IPSTPCR0_VALUE
+	ldr	x7, =IPSTPACK_RETRY_CNT
+3:
+	ldr	w0, [x3, x2]
+	cmp	x0, x4
+	b.eq	14f
+	sub	x7, x7, #1
+	cbnz	x7, 3b
+
+14:
+	/* poll on IPSTPACK1 */
+	ldr	x2, =PMU_IPSTPACK1_OFFSET
+	ldr	x4, =IPSTPCR1_VALUE
+	ldr	x7, =IPSTPACK_RETRY_CNT
+4:
+	ldr	w0, [x3, x2]
+	cmp	x0, x4
+	b.eq	15f
+	sub	x7, x7, #1
+	cbnz	x7, 4b
+
+15:
+	/* poll on IPSTPACK2 */
+	ldr	x2, =PMU_IPSTPACK2_OFFSET
+	ldr	x4, =IPSTPCR2_VALUE
+	ldr	x7, =IPSTPACK_RETRY_CNT
+5:
+	ldr	w0, [x3, x2]
+	cmp	x0, x4
+	b.eq	16f
+	sub	x7, x7, #1
+	cbnz	x7, 5b
+
+16:
+	/* poll on IPSTPACK3 */
+	ldr	x2, =PMU_IPSTPACK3_OFFSET
+	ldr	x4, =IPSTPCR3_VALUE
+	ldr	x7, =IPSTPACK_RETRY_CNT
+6:
+	ldr	w0, [x3, x2]
+	cmp	x0, x4
+	b.eq	17f
+	sub	x7, x7, #1
+	cbnz	x7, 6b
+
+17:
+	/* poll on IPSTPACK4 */
+	ldr	x2, =PMU_IPSTPACK4_OFFSET
+	ldr	x4, =IPSTPCR4_VALUE
+	ldr	x7, =IPSTPACK_RETRY_CNT
+7:
+	ldr	w0, [x3, x2]
+	cmp	x0, x4
+	b.eq	18f
+	sub	x7, x7, #1
+	cbnz	x7, 7b
+
+18:
+	/* poll on IPSTPACK5 */
+	ldr	x2, =PMU_IPSTPACK5_OFFSET
+	ldr	x4, =IPSTPCR5_VALUE
+	ldr	x7, =IPSTPACK_RETRY_CNT
+8:
+	ldr	w0, [x3, x2]
+	cmp	x0, x4
+	b.eq	19f
+	sub	x7, x7, #1
+	cbnz	x7, 8b
+
+19:
+	/* poll on IPSTPACK6 */
+	ldr	x2, =PMU_IPSTPACK6_OFFSET
+	ldr	x4, =IPSTPCR6_VALUE
+	ldr	x7, =IPSTPACK_RETRY_CNT
+9:
+	ldr	w0, [x3, x2]
+	cmp	x0, x4
+	b.eq	20f
+	sub	x7, x7, #1
+	cbnz	x7, 9b
+
+20:
+	/* save current DEVDISR states to DDR. */
+	ldr	x2, =NXP_DCFG_ADDR
+
+	/* save DEVDISR1 and load new value */
+	ldr	x0, =DCFG_DEVDISR1_OFFSET
+	ldr	w1, [x2, x0]
+	mov	w13, w1
+	ldr	x1, =DEVDISR1_VALUE
+	str	w1, [x2, x0]
+	/* save DEVDISR2 and load new value */
+	ldr	x0, =DCFG_DEVDISR2_OFFSET
+	ldr	w1, [x2, x0]
+	mov	w14, w1
+	ldr	x1, =DEVDISR2_VALUE
+	str	w1, [x2, x0]
+
+	/* x6 = DEVDISR5 override mask */
+
+	/* save DEVDISR3 and load new value */
+	ldr	x0, =DCFG_DEVDISR3_OFFSET
+	ldr	w1, [x2, x0]
+	mov	w15, w1
+	ldr	x1, =DEVDISR3_VALUE
+	str	w1, [x2, x0]
+
+	/* save DEVDISR4 and load new value */
+	ldr	x0, =DCFG_DEVDISR4_OFFSET
+	ldr	w1, [x2, x0]
+	mov	w16, w1
+	/* not stop uart print */
+	ldr	x1, =0x0000332
+	str	w1, [x2, x0]
+
+	/* save DEVDISR5 and load new value */
+	ldr	x0, =DCFG_DEVDISR5_OFFSET
+	ldr	w1, [x2, x0]
+	mov	w17, w1
+	/* Enable this wakeup will fail, should enable OCRAM */
+	ldr	x1, =0x00102300
+	str	w1, [x2, x0]
+
+	/* save DEVDISR6 and load new value */
+	ldr	x0, =DCFG_DEVDISR6_OFFSET
+	ldr	w1, [x2, x0]
+	mov	w18, w1
+	ldr	x1, =DEVDISR6_VALUE
+	str	w1, [x2, x0]
+
+	/*
+	 * w13 = DEVDISR1 saved value
+	 * w14 = DEVDISR2 saved value
+	 * w15 = DEVDISR3 saved value
+	 * w16 = DEVDISR4 saved value
+	 * w17 = DEVDISR5 saved value
+	 * w18 = DEVDISR6 saved value
+	 */
+	/*
+	 * A-009810: LPM20 entry sequence might cause
+	 * spurious timeout reset request
+	 * workaround: MASK RESET REQ RPTOE
+	 */
+	ldr	x0, =NXP_RESET_ADDR
+	ldr	w1, =RSTRQMR_RPTOE_MASK
+	str	w1, [x0, #RST_RSTRQMR1_OFFSET]
+
+	/* disable SEC, QBman spi and qspi */
+	ldr	x2, =NXP_DCFG_ADDR
+	ldr	x0, =DCFG_DEVDISR1_OFFSET
+	ldr	w1, =DCFG_DEVDISR1_SEC
+	str	w1, [x2, x0]
+	ldr	x0, =DCFG_DEVDISR3_OFFSET
+	ldr	w1, =DCFG_DEVDISR3_QBMAIN
+	str	w1, [x2, x0]
+	ldr	x0, =DCFG_DEVDISR4_OFFSET
+	ldr	w1, =DCFG_DEVDISR4_SPI_QSPI
+	str	w1, [x2, x0]
+
+	/*
+	 * write the GICR_WAKER.ProcessorSleep bits to 1
+	 * enable the WakeRequest signal
+	 * x3 is cpu mask starting from cpu7
+	 */
+	bl	get_tot_num_cores
+	sub	x0, x0, #1
+	mov	x3, #0x1
+	lsl	x3, x3, x0
+2:
+	mov	x0, x3
+	bl	get_gic_rd_base
+	ldr	w1, [x0, #GICR_WAKER_OFFSET]
+	orr	w1, w1, #GICR_WAKER_SLEEP_BIT
+	str	w1, [x0, #GICR_WAKER_OFFSET]
+1:
+	ldr	w1, [x0, #GICR_WAKER_OFFSET]
+	cmp	w1, #GICR_WAKER_ASLEEP
+	b.ne	1b
+
+	lsr	x3, x3, #1
+	cbnz	x3, 2b
+
+	/* x3 = pmu base addr */
+
+	/* perform Icache Warming Sequence */
+	ldr	x5, =IPSTPCR4_VALUE
+	mov	x6, DDR_CNTRL_BASE_ADDR
+	mov	x7, #NXP_PMU_ADDR
+	mov	x8, #NXP_DCFG_ADDR
+	mov	x10, #PMU_IPSTPCR4_OFFSET
+	mov	x11, #PMU_IPSTPACK4_OFFSET
+	mov	x12, #PMU_IPSTPCR3_OFFSET
+	mov	x18, #PMU_IPSTPCR2_OFFSET
+	mov	x19, #PMU_IPSTPCR1_OFFSET
+	mov	x21, #PMU_IPSTPCR0_OFFSET
+	ldr	x22, =DCFG_DEVDISR5_OFFSET
+	ldr	x23, =NXP_EPU_ADDR
+	mov	x9, #CORE_RESTARTABLE
+	bl	final_pwrdown
+
+	/*
+	 * disable the WakeRequest signal on cpu 0-7
+	 * x3 is cpu mask starting from cpu7
+	 */
+	bl	get_tot_num_cores
+	sub	x0, x0, #1
+	mov	x3, #0x1
+	lsl	x3, x3, x0
+2:
+	mov	x0, x3
+	bl	get_gic_rd_base
+	ldr	w1, [x0, #GICR_WAKER_OFFSET]
+	bic	w1, w1, #GICR_WAKER_SLEEP_BIT
+	str	w1, [x0, #GICR_WAKER_OFFSET]
+1:
+	ldr	w1, [x0, #GICR_WAKER_OFFSET]
+	cbnz	w1, 1b
+
+	lsr	x3, x3, #1
+	cbnz	x3, 2b
+
+	/* set SGI for secondary core wakeup */
+	ldr	x0, =0x1000002
+	msr	S3_0_C12_C11_7, x0
+	isb
+	ldr	x0, =0x2000004
+	msr	S3_0_C12_C11_7, x0
+	isb
+	ldr	x0, =0x3000008
+	msr	S3_0_C12_C11_7, x0
+	isb
+	ldr	x0, =0x4010001
+	msr	S3_0_C12_C11_7, x0
+	isb
+	ldr	x0, =0x5010002
+	msr	S3_0_C12_C11_7, x0
+	isb
+	ldr	x0, =0x6010004
+	msr	S3_0_C12_C11_7, x0
+	isb
+	ldr	x0, =0x7010008
+	msr	S3_0_C12_C11_7, x0
+
+	/* enable SEC, QBman spi and qspi */
+	ldr	x2, =NXP_DCFG_ADDR
+	str	wzr, [x2, #DCFG_DEVDISR1_OFFSET]
+	str	wzr, [x2, #DCFG_DEVDISR3_OFFSET]
+	str	wzr, [x2, #DCFG_DEVDISR4_OFFSET]
+
+	/* clear POWMGTDCR [STP_PV_EN] */
+	ldr	x2, =NXP_POWMGTDCR
+	ldr	w4, [x2]
+	bic	w4, w4, #0x01
+	str	w4, [x2]
+
+	/* restore flextimer/mmc/usb interrupt enabler */
+	ldr	x3, =NXP_GICD_ADDR
+	ldp	x0, x2, [sp], #16
+	ldr	x1, =GICD_ICENABLER_2
+	mvn	w0, w0
+	str	w0, [x3, x1]
+	ldr	x1, =GICD_ICENABLER_3
+	mvn	w2, w2
+	str	w2, [x3, x1]
+
+	ldp	x0, x2, [sp], #16
+	ldr	x1, =GICD_ISENABLER_3
+	str	w0, [x3, x1]
+	ldr	x1, =GICD_ICENABLER_1
+	mvn	w2, w2
+	str	w0, [x3, x1]
+
+	ldp	x0, x2, [sp], #16
+	ldr	x1, =GICD_ISENABLER_1
+	str	w0, [x3, x1]
+	ldr	x1, =GICD_ISENABLER_2
+	str	w0, [x3, x1]
+
+	/* restore flextimer/mmc/usb interrupt router */
+	ldr	x3, =NXP_GICD_ADDR
+	ldp	x0, x2, [sp], #16
+	ldr	x1, =GICD_IROUTER113_OFFSET
+	str	w2, [x3, x1]
+	ldr	x1, =GICD_IROUTER112_OFFSET
+	str	w0, [x3, x1]
+	ldp	x0, x2, [sp], #16
+	ldr	x1, =GICD_IROUTER76_OFFSET
+	str	w2, [x3, x1]
+	ldr	x1, =GICD_IROUTER60_OFFSET
+	str	w0, [x3, x1]
+
+	/* restore EPU registers */
+	ldr	x3, =NXP_EPU_ADDR
+	ldp	x0, x2, [sp], #16
+	str	w2, [x3, #EPU_EPGCR_OFFSET]
+	str	w0, [x3, #EPU_EPCTR10_OFFSET]
+	ldp	x2, x1, [sp], #16
+	str	w1, [x3, #EPU_EPCCR10_OFFSET]
+	str	w2, [x3, #EPU_EPIMCR10_OFFSET]
+
+	isb
+	/* Restor LR */
+	ldp	x18, x30, [sp], #16
+	ret
+
+/*
+ * part of CPU_SUSPEND
+ * this function performs any SoC-specific cleanup after power-down
+ * in:  x0 = core mask lsb
+ * out: none
+ * uses x0, x1
+ */
+_soc_sys_exit_pwrdn:
+	mrs	x1, SCTLR_EL1
+	orr	x1, x1, #SCTLR_I_MASK
+	msr	SCTLR_EL1, x1
+	isb
+	ret
+
+/*
+ * this function checks to see if cores which are to be disabled have been
+ * released from reset - if not, it releases them
+ * in:  none
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8
+ */
+release_disabled:
+	mov	x8, x30
+
+	/* read COREDISABLESR */
+	mov	x0, #NXP_DCFG_ADDR
+	ldr	w4, [x0, #DCFG_COREDISABLEDSR_OFFSET]
+
+	/* get the number of cpus on this device */
+	mov	x6, #PLATFORM_CORE_COUNT
+
+	mov	x0, #NXP_RESET_ADDR
+	ldr	w5, [x0, #BRR_OFFSET]
+
+	/* load the core mask for the first core */
+	mov	x7, #1
+
+	/*
+	 * x4 = COREDISABLESR
+	 * x5 = BRR
+	 * x6 = loop count
+	 * x7 = core mask bit
+	 */
+2:
+	/* check if the core is to be disabled */
+	tst	x4, x7
+	b.eq	1f
+
+	/* see if disabled cores have already been released from reset */
+	tst	x5, x7
+	b.ne	1f
+
+	/* if core has not been released, then release it (0-3) */
+	mov	x0, x7
+	bl	_soc_core_release
+
+	/* record the core state in the data area (0-3) */
+	mov	x0, x7
+	mov	x1, #CORE_DISABLED
+	bl	_setCoreState
+
+1:
+	/* decrement the counter */
+	subs	x6, x6, #1
+	b.le	3f
+
+	/* shift the core mask to the next core */
+	lsl	x7, x7, #1
+	/* continue */
+	b	2b
+3:
+	mov	x30, x8
+	ret
+
+/*
+ * write a register in the DCFG block
+ * in:  x0 = offset
+ * in:  w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_dcfg:
+	ldr	x2, =NXP_DCFG_ADDR
+	str	w1, [x2, x0]
+	ret
+
+/*
+ * read a register in the DCFG block
+ * in:  x0 = offset
+ * out: w0 = value read
+ * uses x0, x1
+ */
+_read_reg_dcfg:
+	ldr	x1, =NXP_DCFG_ADDR
+	ldr	w0, [x1, x0]
+	ret
+
+/*
+ * this function sets up the TrustZone Address Space Controller (TZASC)
+ * in:  none
+ * out: none
+ * uses x0, x1
+ */
+init_tzpc:
+	/*
+	 * set Non Secure access for all devices protected via TZPC
+	 * decode Protection-0 Set Reg
+	 */
+	ldr	x1, =TZPCDECPROT_0_SET_BASE
+	/* set decode region to NS, Bits[7:0] */
+	mov	w0, #0xFF
+	str	w0, [x1]
+
+	/* decode Protection-1 Set Reg */
+	ldr	x1, =TZPCDECPROT_1_SET_BASE
+	/* set decode region to NS, Bits[7:0] */
+	mov	w0, #0xFF
+	str	w0, [x1]
+
+	/* decode Protection-2 Set Reg */
+	ldr	x1, =TZPCDECPROT_2_SET_BASE
+	/* set decode region to NS, Bits[7:0] */
+	mov	w0, #0xFF
+	str	w0, [x1]
+
+	/*
+	 * entire SRAM as NS
+	 * secure RAM region size Reg
+	 */
+	ldr	x1, =NXP_OCRAM_TZPC_ADDR
+	/* 0x00000000 = no secure region */
+	mov	w0, #0x00000000
+	str	w0, [x1]
+
+	ret
+
+/* this function performs initialization on SecMon for boot services */
+initSecMon:
+	/* read the register hpcomr */
+	ldr	x1, =NXP_SNVS_ADDR
+	ldr	w0, [x1, #SECMON_HPCOMR_OFFSET]
+	/* turn off secure access for the privileged registers */
+	orr	w0, w0, #SECMON_HPCOMR_NPSWAEN
+	/* write back */
+	str	w0, [x1, #SECMON_HPCOMR_OFFSET]
+
+	ret
+
+/*
+ * this function returns the redistributor base address for the core specified
+ * in x1
+ * in:  x0 - core mask lsb of specified core
+ * out: x0 = redistributor rd base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_rd_base:
+	/* get the 0-based core number */
+	clz	w1, w0
+	mov	w2, #0x20
+	sub	w2, w2, w1
+	sub	w2, w2, #1
+
+	/* x2 = core number / loop counter */
+
+	ldr	x0, =NXP_GICR_ADDR
+	mov	x1, #GIC_RD_OFFSET
+2:
+	cbz	x2, 1f
+	add	x0, x0, x1
+	sub	x2, x2, #1
+	b	2b
+1:
+	ret
+
+/*
+ * this function returns the redistributor base address for the core specified
+ * in x1
+ * in:  x0 - core mask lsb of specified core
+ * out: x0 = redistributor sgi base address for specified core
+ * uses x0, x1, x2
+ */
+get_gic_sgi_base:
+	/* get the 0-based core number */
+	clz	w1, w0
+	mov	w2, #0x20
+	sub	w2, w2, w1
+	sub	w2, w2, #1
+
+	/* x2 = core number / loop counter */
+
+	ldr	x0, =NXP_GICR_SGI_ADDR
+	mov	x1, #GIC_SGI_OFFSET
+2:
+	cbz	x2, 1f
+	add	x0, x0, x1
+	sub	x2, x2, #1
+	b	2b
+1:
+	ret
+
+/*
+ * this function returns an mpidr value for a core, given a core_mask_lsb
+ * in:  x0 = core mask lsb
+ * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits
+ * uses x0, x1
+ */
+get_mpidr_value:
+	/* convert a core mask to an SoC core number */
+	clz	w0, w0
+	mov	w1, #31
+	sub	w0, w1, w0
+
+	/* w0 = SoC core number */
+
+	mov	w1, wzr
+2:
+	cmp	w0, #CORES_PER_CLUSTER
+	b.lt	1f
+	sub	w0, w0, #CORES_PER_CLUSTER
+	add	w1, w1, #MPIDR_CLUSTER
+	b	2b
+
+	/* insert the mpidr core number */
+1:
+	orr	w0, w1, w0
+	ret
+
+/*
+ * write a register in the RESET block
+ * in:  x0 = offset
+ * in:  w1 = value to write
+ * uses x0, x1, x2
+ */
+_write_reg_reset:
+	ldr	x2, =NXP_RESET_ADDR
+	str	w1, [x2, x0]
+	ret
+
+/*
+ * read a register in the RESET block
+ * in:  x0 = offset
+ * out: w0 = value read
+ * uses x0, x1
+ */
+_read_reg_reset:
+	ldr	x1, =NXP_RESET_ADDR
+	ldr	w0, [x1, x0]
+	ret
+
+/*
+ * this function will pwrdown ddr and the final core - it will do this
+ * by loading itself into the icache and then executing from there
+ * in:  x5  = ipstpcr4 (IPSTPCR4_VALUE bic DEVDISR5_MASK)
+ *      x6  = DDR_CNTRL_BASE_ADDR
+ *      x7  = NXP_PMU_ADDR
+ *      x8  = NXP_DCFG_ADDR
+ *      x9  = 0, restartable
+ *          = 1, non-restartable
+ *      x10 = PMU_IPSTPCR4_OFFSET
+ *      x11 = PMU_IPSTPACK4_OFFSET
+ *      x12 = PMU_IPSTPCR3_OFFSET
+ *      x18 = PMU_IPSTPCR2_OFFSET
+ *      x19 = PMU_IPSTPCR1_OFFSET
+ *      x21 = PMU_IPSTPCR0_OFFSET
+ *      w13 = DEVDISR1 saved value
+ *      w14 = DEVDISR2 saved value
+ *      w15 = DEVDISR3 saved value
+ *      w16 = DEVDISR4 saved value
+ *      w17 = DEVDISR5 saved value
+ *      x22 = DCFG_DEVDISR5_OFFSET
+ *      x23 = NXP_EPU_ADDR
+ * out: none
+ * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x13, x14, x15, x16, x17
+ * x10, x11, x12, x18, x19, x21, x22, x23
+ */
+
+final_pwrdown:
+	/* delay */
+	mov	w4, #0xffffff
+554:
+	sub	w4, w4, #1
+	cmp	w4, #0
+	b.ge	554b
+
+	mov	x0, xzr
+	b	touch_line_0
+
+/* 4Kb aligned */
+.align 12
+start_line_0:
+	mov	x0, #1
+	/* put ddr in self refresh - start */
+	mov	x2, #DDR_SDRAM_CFG_2_FRCSR
+	ldr	w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+	orr	w3, w3, w2
+	/* put ddr in self refresh - end */
+	str	w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+	nop
+	nop
+touch_line_0:
+	cbz	x0, touch_line_1
+
+start_line_1:
+	/* quiesce ddr clocks - start */
+	orr	w3, w5, #DCFG_DEVDISR5_MEM
+	mov	w4, w3
+	/* quiesce ddr clocks - end */
+	str	w4, [x7, x10]
+	mov	w3, #DCFG_DEVDISR5_MEM
+	/* poll on ipstpack4 - start */
+	mov	x2, #DDR_SLEEP_RETRY_CNT
+	nop
+	nop
+touch_line_1:
+	cbz	x0, touch_line_2
+
+start_line_2:
+	/* x11 = PMU_IPSTPACK4_OFFSET */
+	ldr	w1, [x7, x11]
+	tst	w1, w3
+	b.ne	5f
+	subs	x2, x2, #1
+	/* poll on ipstpack4 - end */
+	b.gt	start_line_2
+
+	/* if we get here, we have a timeout err */
+	mov	w4, w5
+	/* x10 = PMU_IPSTPCR4_OFFSET re-enable ddr clks interface */
+	str	w4, [x7, x10]
+touch_line_2:
+	cbz	x0, touch_line_3
+
+start_line_3:
+	/* load error code */
+	mov	x0, #ERROR_DDR_SLEEP
+	b	2f
+5:
+	wfe
+	ldr	w1, [x23, #EPU_EPCTR10_OFFSET]
+	cbz	w1, 5b
+
+	mov	w4, w5
+touch_line_3:
+	cbz	x0, touch_line_4
+
+start_line_4:
+	/* re-enable ddr in devdisr5 */
+	str	w4, [x8, x22]
+	/* re-enable ddr clk in ipstpcr4 */
+	str	w4, [x7, x10]
+13:
+	/* poll on ipstpack4 - start */
+	ldr	w1, [x7, x11]
+	tst	w1, w3
+	b.eq	2f
+	nop
+	b	13b
+	/* poll on ipstpack4 - end */
+2:
+touch_line_4:
+	cbz	x0, touch_line_5
+
+start_line_5:
+	/* take ddr out-of self refresh - start */
+	mov	x2, #DDR_SDRAM_CFG_2_FRCSR
+	ldr	w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+	mov	w4, w3
+	bic	w4, w4, w2
+	mov	w3, w4
+	/* wait for ddr cntrlr clock- start */
+	mov	x1, #DDR_SLEEP_RETRY_CNT
+3:
+	subs	x1, x1, #1
+touch_line_5:
+	cbz	x0, touch_line_6
+
+start_line_6:
+	/* wait for ddr cntrlr clock - end */
+	b.gt	3b
+	/* take ddr out-of self refresh - end */
+	str	w3, [x6, #DDR_SDRAM_CFG_2_OFFSET]
+	mov	w1, w17
+	/* reset devdisr5 */
+	str	w1, [x8, #DCFG_DEVDISR5_OFFSET]
+	mov	w1, w16
+	/* reset devdisr4 */
+	str	w1, [x8, #DCFG_DEVDISR4_OFFSET]
+	mov	w1, w15
+touch_line_6:
+	cbz	x0, touch_line_7
+
+start_line_7:
+	/* reset devdisr3 */
+	str	w1, [x8, #DCFG_DEVDISR3_OFFSET]
+	mov	w1, w14
+	/* reset devdisr2 */
+	str	w1, [x8, #DCFG_DEVDISR2_OFFSET]
+	mov	w1, w13
+	/* reset devdisr1 */
+	str	w1, [x8, #DCFG_DEVDISR1_OFFSET]
+	/* reset ipstpcr4 */
+	str	wzr, [x7, x10]
+	/* reset ipstpcr3 */
+	str	wzr, [x7, x12]
+touch_line_7:
+	cbz	x0, touch_line_8
+
+start_line_8:
+	/* reset ipstpcr2 */
+	str	wzr, [x7, x18]
+	/* reset ipstpcr1 */
+	str	wzr, [x7, x19]
+	/* reset ipstpcr0 */
+	str	wzr, [x7, x21]
+
+touch_line_8:
+	cbz	x0, touch_line_9
+
+start_line_9:
+	b	continue_restart
+touch_line_9:
+	cbz	x0, start_line_0
+
+/* execute here after ddr is back up */
+continue_restart:
+	/*
+	 * if x0 = 1, all is well
+	 * if x0 < 1, we had an error
+	 */
+	cmp	x0, #1
+	b.ne	4f
+	mov	x0, #0
+4:
+	ret
diff --git a/plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S b/plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S
new file mode 100644
index 0000000..890cf81
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/aarch64/ls1088a_helpers.S
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+	.globl	plat_secondary_cold_boot_setup
+	.globl	plat_is_my_cpu_primary
+	.globl	plat_reset_handler
+	.globl  platform_mem_init
+
+func platform_mem1_init
+	ret
+endfunc platform_mem1_init
+
+func platform_mem_init
+	ret
+endfunc	platform_mem_init
+
+func apply_platform_errata
+	ret
+endfunc apply_platform_errata
+
+func plat_reset_handler
+	mov	x29, x30
+	bl	apply_platform_errata
+
+#if defined(IMAGE_BL31)
+	ldr	x0, =POLICY_SMMU_PAGESZ_64K
+	cbz	x0, 1f
+	/* Set the SMMU page size in the sACR register */
+	bl	_set_smmu_pagesz_64
+#endif
+1:
+	mov	x30, x29
+	ret
+endfunc plat_reset_handler
+
+	/*
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * This function performs any platform specific actions
+	 * needed for a secondary cpu after a cold reset e.g
+	 * mark the cpu's presence, mechanism to place it in a
+	 * holding pen etc.
+	 */
+func plat_secondary_cold_boot_setup
+	/* ls1088a does not do cold boot for secondary CPU */
+cb_panic:
+	b	cb_panic
+endfunc plat_secondary_cold_boot_setup
+
+	/*
+	 * unsigned int plat_is_my_cpu_primary (void);
+	 *
+	 * Find out whether the current cpu is the primary
+	 * cpu.
+	 */
+func plat_is_my_cpu_primary
+	mrs	x0, mpidr_el1
+	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+	cmp	x0, 0x0
+	cset	w0, eq
+	ret
+endfunc plat_is_my_cpu_primary
diff --git a/plat/nxp/soc-ls1088a/include/soc.h b/plat/nxp/soc-ls1088a/include/soc.h
new file mode 100644
index 0000000..eb36c2e
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/include/soc.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOC_H
+#define	SOC_H
+
+/* Chassis specific defines - common across SoC's of a particular platform */
+#include "dcfg_lsch3.h"
+#include "soc_default_base_addr.h"
+#include "soc_default_helper_macros.h"
+
+/*
+ * SVR Definition of LS1088A
+ * A: without security
+ * AE: with security
+ * (not include major and minor rev)
+ */
+#define SVR_LS1044A			0x870323
+#define SVR_LS1044AE			0x870322
+#define SVR_LS1048A			0x870321
+#define SVR_LS1048AE			0x870320
+#define SVR_LS1084A			0x870303
+#define SVR_LS1084AE			0x870302
+#define SVR_LS1088A			0x870301
+#define SVR_LS1088AE			0x870300
+
+#define SVR_WO_E			0xFFFFFE
+
+/* Number of cores in platform */
+#define NUMBER_OF_CLUSTERS		2
+#define CORES_PER_CLUSTER		4
+#define PLATFORM_CORE_COUNT		(NUMBER_OF_CLUSTERS * CORES_PER_CLUSTER)
+
+/* set to 0 if the clusters are not symmetrical */
+#define SYMMETRICAL_CLUSTERS		1
+
+
+#define NUM_DRAM_REGIONS		2
+#define	NXP_DRAM0_ADDR			0x80000000
+#define NXP_DRAM0_MAX_SIZE		0x80000000	/*  2 GB  */
+
+#define NXP_DRAM1_ADDR			0x8080000000
+#define NXP_DRAM1_MAX_SIZE		0x7F80000000	/* 510 G */
+
+/* DRAM0 Size defined in platform_def.h */
+#define	NXP_DRAM0_SIZE			PLAT_DEF_DRAM0_SIZE
+
+#define NXP_POWMGTDCR			0x700123C20
+
+/* epu register offsets and values */
+#define EPU_EPGCR_OFFSET		0x0
+#define EPU_EPIMCR10_OFFSET		0x128
+#define EPU_EPCTR10_OFFSET		0xa28
+#define EPU_EPCCR10_OFFSET		0x828
+
+#ifdef EPU_EPCCR10_VAL
+#undef EPU_EPCCR10_VAL
+#endif
+#define EPU_EPCCR10_VAL			0xf2800000
+
+#define EPU_EPIMCR10_VAL		0xba000000
+#define EPU_EPCTR10_VAL			0x0
+#define EPU_EPGCR_VAL			(1 << 31)
+
+/* pmu register offsets and values */
+#define PMU_PCPW20SR_OFFSET		0x830
+#define PMU_CLAINACTSETR_OFFSET		0x1100
+#define PMU_CLAINACTCLRR_OFFSET		0x1104
+#define PMU_CLSINACTSETR_OFFSET		0x1108
+#define PMU_CLSINACTCLRR_OFFSET		0x110C
+#define PMU_CLL2FLUSHSETR_OFFSET	0x1110
+#define PMU_CLSL2FLUSHCLRR_OFFSET	0x1114
+#define PMU_CLL2FLUSHSR_OFFSET		0x1118
+#define PMU_POWMGTCSR_OFFSET		0x4000
+#define PMU_IPPDEXPCR0_OFFSET		0x4040
+#define PMU_IPPDEXPCR1_OFFSET		0x4044
+#define PMU_IPPDEXPCR2_OFFSET		0x4048
+#define PMU_IPPDEXPCR3_OFFSET		0x404C
+#define PMU_IPPDEXPCR4_OFFSET		0x4050
+#define PMU_IPPDEXPCR5_OFFSET		0x4054
+#define PMU_IPSTPCR0_OFFSET		0x4120
+#define PMU_IPSTPCR1_OFFSET		0x4124
+#define PMU_IPSTPCR2_OFFSET		0x4128
+#define PMU_IPSTPCR3_OFFSET		0x412C
+#define PMU_IPSTPCR4_OFFSET		0x4130
+#define PMU_IPSTPCR5_OFFSET		0x4134
+#define PMU_IPSTPCR6_OFFSET		0x4138
+#define PMU_IPSTPACK0_OFFSET		0x4140
+#define PMU_IPSTPACK1_OFFSET		0x4144
+#define PMU_IPSTPACK2_OFFSET		0x4148
+#define PMU_IPSTPACK3_OFFSET		0x414C
+#define PMU_IPSTPACK4_OFFSET		0x4150
+#define PMU_IPSTPACK5_OFFSET		0x4154
+#define PMU_IPSTPACK6_OFFSET		0x4158
+#define PMU_POWMGTCSR_VAL		(1 << 20)
+
+#define IPPDEXPCR0_MASK			0xFFFFFFFF
+#define IPPDEXPCR1_MASK			0xFFFFFFFF
+#define IPPDEXPCR2_MASK			0xFFFFFFFF
+#define IPPDEXPCR3_MASK			0xFFFFFFFF
+#define IPPDEXPCR4_MASK			0xFFFFFFFF
+#define IPPDEXPCR5_MASK			0xFFFFFFFF
+
+/* DEVDISR5_FLX_TMR */
+#define IPPDEXPCR_FLX_TMR		0x00004000
+#define DEVDISR5_FLX_TMR		0x00004000
+
+#define IPSTPCR0_VALUE			0x0041310C
+#define IPSTPCR1_VALUE			0x000003FF
+#define IPSTPCR2_VALUE			0x00013006
+
+/* Dont' stop UART */
+#define IPSTPCR3_VALUE			0x0000033A
+
+#define IPSTPCR4_VALUE			0x00103300
+#define IPSTPCR5_VALUE			0x00000001
+#define IPSTPCR6_VALUE			0x00000000
+
+
+#define TZPC_BLOCK_SIZE			0x1000
+
+/* PORSR1 */
+#define PORSR1_RCW_MASK			0xFF800000
+#define PORSR1_RCW_SHIFT		23
+
+/* CFG_RCW_SRC[6:0] */
+#define RCW_SRC_TYPE_MASK		0x70
+
+/* RCW SRC NOR */
+#define	NOR_16B_VAL			0x20
+
+/*
+ * RCW SRC Serial Flash
+ * 1. SERAIL NOR (QSPI)
+ * 2. OTHERS (SD/MMC, SPI, I2C1)
+ */
+#define RCW_SRC_SERIAL_MASK		0x7F
+#define QSPI_VAL			0x62
+#define SDHC_VAL			0x40
+#define EMMC_VAL			0x41
+
+/*
+ * Required LS standard platform porting definitions
+ * for CCN-504 - Read from RN-F node ID register
+ */
+#define PLAT_CLUSTER_TO_CCN_ID_MAP 1, 9, 11, 19
+
+/* Defines required for using XLAT tables from ARM common code */
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 40)
+
+/*
+ * Clock Divisors
+ */
+#define NXP_PLATFORM_CLK_DIVIDER	1
+#define NXP_UART_CLK_DIVIDER		2
+
+/* dcfg register offsets and values */
+#define DCFG_DEVDISR1_OFFSET		0x70
+#define DCFG_DEVDISR2_OFFSET		0x74
+#define DCFG_DEVDISR3_OFFSET		0x78
+#define DCFG_DEVDISR5_OFFSET		0x80
+#define DCFG_DEVDISR6_OFFSET		0x84
+
+#define DCFG_DEVDISR1_SEC		(1 << 22)
+#define DCFG_DEVDISR3_QBMAIN		(1 << 12)
+#define DCFG_DEVDISR4_SPI_QSPI		(1 << 4 | 1 << 5)
+#define DCFG_DEVDISR5_MEM		(1 << 0)
+
+#define DEVDISR1_VALUE			0x0041310c
+#define DEVDISR2_VALUE			0x000003ff
+#define DEVDISR3_VALUE			0x00013006
+#define DEVDISR4_VALUE			0x0000033e
+#define DEVDISR5_VALUE			0x00103300
+#define DEVDISR6_VALUE			0x00000001
+
+/*
+ * pwr mgmt features supported in the soc-specific code:
+ * value == 0x0, the soc code does not support this feature
+ * value != 0x0, the soc code supports this feature
+ */
+#define SOC_CORE_RELEASE		0x1
+#define SOC_CORE_RESTART		0x1
+#define SOC_CORE_OFF			0x1
+#define SOC_CORE_STANDBY		0x1
+#define SOC_CORE_PWR_DWN		0x1
+#define SOC_CLUSTER_STANDBY		0x1
+#define SOC_CLUSTER_PWR_DWN		0x1
+#define SOC_SYSTEM_STANDBY		0x1
+#define SOC_SYSTEM_PWR_DWN		0x1
+#define SOC_SYSTEM_OFF			0x1
+#define SOC_SYSTEM_RESET		0x1
+
+#define SYSTEM_PWR_DOMAINS		1
+#define PLAT_NUM_PWR_DOMAINS	(PLATFORM_CORE_COUNT + \
+				NUMBER_OF_CLUSTERS  + \
+				SYSTEM_PWR_DOMAINS)
+
+/* Power state coordination occurs at the system level */
+#define PLAT_PD_COORD_LVL MPIDR_AFFLVL2
+#define PLAT_MAX_PWR_LVL  PLAT_PD_COORD_LVL
+
+/* Local power state for power domains in Run state */
+#define LS_LOCAL_STATE_RUN  PSCI_LOCAL_STATE_RUN
+
+/* define retention state */
+#define PLAT_MAX_RET_STATE  (PSCI_LOCAL_STATE_RUN + 1)
+#define LS_LOCAL_STATE_RET  PLAT_MAX_RET_STATE
+
+/* define power-down state */
+#define PLAT_MAX_OFF_STATE  (PLAT_MAX_RET_STATE + 1)
+#define LS_LOCAL_STATE_OFF  PLAT_MAX_OFF_STATE
+
+#ifndef __ASSEMBLER__
+/* CCI slave interfaces */
+static const int cci_map[] = {
+	3,
+	4,
+};
+void soc_init_lowlevel(void);
+void soc_init_percpu(void);
+void _soc_set_start_addr(unsigned long addr);
+void _set_platform_security(void);
+#endif
+
+#endif /* SOC_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c b/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c
new file mode 100644
index 0000000..b7397ba
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/ddr_init.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <utils.h>
+
+#include <errata.h>
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+#error No static value defined
+#endif
+
+static const struct rc_timing rce[] = {
+	{U(1600), U(8), U(8)},
+	{U(1867), U(8), U(8)},
+	{U(2134), U(8), U(9)},
+	{}
+};
+
+static const struct board_timing udimm[] = {
+	{U(0x04), rce, U(0x01020307), U(0x08090b06)},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+	int ret;
+	struct memctl_opt *popts = &priv->opt;
+
+	if (popts->rdimm != 0) {
+		debug("RDIMM parameters not set.\n");
+		return -EINVAL;
+	}
+
+	ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
+	if (ret != 0) {
+		return ret;
+	}
+
+	popts->addr_hash = 1;
+	popts->cpo_sample = U(0x7b);
+	popts->ddr_cdr1 = DDR_CDR1_DHC_EN	|
+			  DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+	popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm)	|
+			  DDR_CDR2_VREF_TRAIN_EN		|
+			  DDR_CDR2_VREF_RANGE_2;
+
+	return 0;
+}
+
+long long init_ddr(void)
+{
+	int spd_addr[] = { NXP_SPD_EEPROM0 };
+	struct ddr_info info;
+	struct sysinfo sys;
+	long long dram_size;
+
+	zeromem(&sys, sizeof(sys));
+	get_clocks(&sys);
+	debug("platform clock %lu\n", sys.freq_platform);
+	debug("DDR PLL %lu\n", sys.freq_ddr_pll0);
+
+	zeromem(&info, sizeof(struct ddr_info));
+	info.num_ctlrs = NUM_OF_DDRC;
+	info.dimm_on_ctlr = DDRC_NUM_DIMM;
+	info.clk = get_ddr_freq(&sys, 0);
+	info.spd_addr = spd_addr;
+	info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+	dram_size = dram_init(&info);
+	if (dram_size < 0) {
+		ERROR("DDR init failed.\n");
+	}
+
+	erratum_a008850_post();
+
+	return dram_size;
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h b/plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h
new file mode 100644
index 0000000..ebd3a26
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/plat_def.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0		0x51
+
+#define NXP_SYSCLK_FREQ		100000000
+#define NXP_DDRCLK_FREQ		100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR	NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE	115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE	0x2000
+#else
+#define PLATFORM_STACK_SIZE	0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE	0x1000
+#endif
+
+#define BL2_START		NXP_OCRAM_ADDR
+#define BL2_LIMIT		(NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#define BL2_NOLOAD_START	NXP_OCRAM_ADDR
+#define BL2_NOLOAD_LIMIT	BL2_BASE
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES		4
+#define MAX_IO_BLOCK_DEVICES	1
+#define MAX_IO_HANDLES		4
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES		2
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES		1
+#endif
+
+#define BL32_IRQ_SEC_PHY_TIMER	29
+#define BL31_WDOG_SEC		89
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define PLAT_LS_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define PLAT_LS_G0_IRQ_PROPS(grp)	\
+	INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(15, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
+
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/platform.c b/plat/nxp/soc-ls1088a/ls1088aqds/platform.c
new file mode 100644
index 0000000..8b3eada
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+	return true;
+#else
+	return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+	return true;
+#else
+	return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/platform.mk b/plat/nxp/soc-ls1088a/ls1088aqds/platform.mk
new file mode 100644
index 0000000..97ccf26
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/platform.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+BOOT_MODE	?= 	qspi
+BOARD		:=	ls1088aqds
+
+# DDR Compilation Configs
+NUM_OF_DDRC	:=	1
+DDRC_NUM_DIMM	:=      1
+DDR_ECC_EN	:=      yes
+
+# On-Board Flash Details
+QSPI_FLASH_SZ	:=      0x4000000
+NOR_FLASH_SZ	:=	0x20000000
+
+BL2_SOURCES	+=	${BOARD_PATH}/ddr_init.c \
+			${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE	:=	qspi	\
+				sd	\
+				nor
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1088a/soc.mk
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h b/plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h
new file mode 100644
index 0000000..7daf1c0
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088aqds/policy.h b/plat/nxp/soc-ls1088a/ls1088aqds/policy.h
new file mode 100644
index 0000000..0eaafae
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088aqds/policy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POLICY_H
+#define	POLICY_H
+
+/*
+ * Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c b/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c
new file mode 100644
index 0000000..c88583f
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/ddr_init.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <ddr.h>
+#include <utils.h>
+
+#include <errata.h>
+#include <platform_def.h>
+
+#ifdef CONFIG_STATIC_DDR
+#error No static value defined
+#endif
+
+static const struct rc_timing rce[] = {
+	{U(1600), U(8), U(8)},
+	{U(1867), U(8), U(8)},
+	{U(2134), U(8), U(9)},
+	{}
+};
+
+static const struct board_timing udimm[] = {
+	{U(0x04), rce, U(0x01030508), U(0x090b0d06)},
+	{U(0x1f), rce, U(0x01030508), U(0x090b0d06)},
+};
+
+int ddr_board_options(struct ddr_info *priv)
+{
+	int ret;
+	struct memctl_opt *popts = &priv->opt;
+
+	if (popts->rdimm != 0) {
+		debug("RDIMM parameters not set.\n");
+		return -EINVAL;
+	}
+
+	ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm));
+	if (ret != 0) {
+		return ret;
+	}
+
+	popts->addr_hash = 1;
+	popts->cpo_sample = U(0x7b);
+	popts->ddr_cdr1 = DDR_CDR1_DHC_EN	|
+			  DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+	popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm)	|
+			  DDR_CDR2_VREF_TRAIN_EN		|
+			  DDR_CDR2_VREF_RANGE_2;
+
+	return 0;
+}
+
+long long init_ddr(void)
+{
+	int spd_addr[] = { NXP_SPD_EEPROM0 };
+	struct ddr_info info;
+	struct sysinfo sys;
+	long long dram_size;
+
+	zeromem(&sys, sizeof(sys));
+	get_clocks(&sys);
+	debug("platform clock %lu\n", sys.freq_platform);
+	debug("DDR PLL %lu\n", sys.freq_ddr_pll0);
+
+	zeromem(&info, sizeof(struct ddr_info));
+	info.num_ctlrs = NUM_OF_DDRC;
+	info.dimm_on_ctlr = DDRC_NUM_DIMM;
+	info.clk = get_ddr_freq(&sys, 0);
+	info.spd_addr = spd_addr;
+	info.ddr[0] = (void *)NXP_DDR_ADDR;
+
+	dram_size = dram_init(&info);
+
+	if (dram_size < 0) {
+		ERROR("DDR init failed.\n");
+	}
+
+	erratum_a008850_post();
+
+	return dram_size;
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h b/plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h
new file mode 100644
index 0000000..a6b14fe
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/plat_def.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DEF_H
+#define PLAT_DEF_H
+
+#include <arch.h>
+/*
+ * Required without TBBR.
+ * To include the defines for DDR PHY
+ * Images.
+ */
+#include <tbbr_img_def.h>
+
+#include <policy.h>
+#include <soc.h>
+
+#define NXP_SPD_EEPROM0		0x51
+
+#define NXP_SYSCLK_FREQ		100000000
+#define NXP_DDRCLK_FREQ		100000000
+
+/* UART related definition */
+#define NXP_CONSOLE_ADDR	NXP_UART_ADDR
+#define NXP_CONSOLE_BAUDRATE	115200
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL2)
+#if defined(TRUSTED_BOARD_BOOT)
+#define PLATFORM_STACK_SIZE	0x2000
+#else
+#define PLATFORM_STACK_SIZE	0x1000
+#endif
+#elif defined(IMAGE_BL31)
+#define PLATFORM_STACK_SIZE	0x1000
+#endif
+
+#define BL2_START		NXP_OCRAM_ADDR
+#define BL2_LIMIT		(NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
+#define BL2_NOLOAD_START	NXP_OCRAM_ADDR
+#define BL2_NOLOAD_LIMIT	BL2_BASE
+
+/* IO defines as needed by IO driver framework */
+#define MAX_IO_DEVICES		4
+#define MAX_IO_BLOCK_DEVICES	1
+#define MAX_IO_HANDLES		4
+
+/*
+ * FIP image defines - Offset at which FIP Image would be present
+ * Image would include Bl31 , Bl33 and Bl32 (optional)
+ */
+#ifdef POLICY_FUSE_PROVISION
+#define MAX_FIP_DEVICES		2
+#endif
+
+#ifndef MAX_FIP_DEVICES
+#define MAX_FIP_DEVICES		1
+#endif
+
+#define BL32_IRQ_SEC_PHY_TIMER	29
+#define BL31_WDOG_SEC		89
+
+/*
+ * ID of the secure physical generic timer interrupt used by the BL32.
+ */
+#define PLAT_LS_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
+/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
+#define PLAT_LS_G0_IRQ_PROPS(grp)	\
+	INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(15, GIC_HIGHEST_SEC_PRIORITY, grp, \
+			GIC_INTR_CFG_LEVEL)
+
+#endif /* PLAT_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/platform.c b/plat/nxp/soc-ls1088a/ls1088ardb/platform.c
new file mode 100644
index 0000000..8b3eada
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/platform.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_common.h>
+
+#pragma weak board_enable_povdd
+#pragma weak board_disable_povdd
+
+bool board_enable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+	return true;
+#else
+	return false;
+#endif
+}
+
+bool board_disable_povdd(void)
+{
+#ifdef CONFIG_POVDD_ENABLE
+	return true;
+#else
+	return false;
+#endif
+}
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/platform.mk b/plat/nxp/soc-ls1088a/ls1088ardb/platform.mk
new file mode 100644
index 0000000..6884faf
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/platform.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# board-specific build parameters
+BOOT_MODE	?= 	qspi
+BOARD		:=	ls1088ardb
+
+# DDR Compilation Configs
+NUM_OF_DDRC	:=	1
+DDRC_NUM_DIMM	:=      1
+DDR_ECC_EN	:=      yes
+
+# On-Board Flash Details
+QSPI_FLASH_SZ	:=      0x4000000
+
+# Adding Platform files build files
+BL2_SOURCES	+=	${BOARD_PATH}/ddr_init.c \
+			${BOARD_PATH}/platform.c
+
+SUPPORTED_BOOT_MODE	:=	qspi	\
+				sd
+
+# Adding platform board build info
+include plat/nxp/common/plat_make_helper/plat_common_def.mk
+
+# Adding SoC build info
+include plat/nxp/soc-ls1088a/soc.mk
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h b/plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h
new file mode 100644
index 0000000..7daf1c0
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/platform_def.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <plat_def.h>
+#include <plat_default_def.h>
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/nxp/soc-ls1088a/ls1088ardb/policy.h b/plat/nxp/soc-ls1088a/ls1088ardb/policy.h
new file mode 100644
index 0000000..af206f9
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/ls1088ardb/policy.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef POLICY_H
+#define POLICY_H
+
+/* Set this to 0x0 to leave the default SMMU page size in sACR
+ * Set this to 0x1 to change the SMMU page size to 64K
+ */
+#define POLICY_SMMU_PAGESZ_64K 0x1
+
+#endif /* POLICY_H */
diff --git a/plat/nxp/soc-ls1088a/soc.c b/plat/nxp/soc-ls1088a/soc.c
new file mode 100644
index 0000000..5f9f313
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/soc.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright 2022 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch.h>
+#include <caam.h>
+#include <cci.h>
+#include <common/debug.h>
+#include <dcfg.h>
+#ifdef I2C_INIT
+#include <i2c.h>
+#endif
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <ls_interconnect.h>
+#if TRUSTED_BOARD_BOOT
+#include <nxp_smmu.h>
+#endif
+#include <nxp_timer.h>
+#include <plat_console.h>
+#include <plat_gic.h>
+#include <plat_tzc400.h>
+#include <pmu.h>
+#if defined(NXP_SFP_ENABLED)
+#include <sfp.h>
+#endif
+
+#include <errata.h>
+#ifdef CONFIG_OCRAM_ECC_EN
+#include <ocram.h>
+#endif
+#include <plat_common.h>
+#include <platform_def.h>
+#include <soc.h>
+
+static unsigned char _power_domain_tree_desc[NUMBER_OF_CLUSTERS + 2];
+static struct soc_type soc_list[] =  {
+	SOC_ENTRY(LS1044A, LS1044A, 1, 4),
+	SOC_ENTRY(LS1044AE, LS1044AE, 1, 4),
+	SOC_ENTRY(LS1048A, LS1048A, 1, 4),
+	SOC_ENTRY(LS1048AE, LS1048AE, 1, 4),
+	SOC_ENTRY(LS1084A, LS1084A, 2, 4),
+	SOC_ENTRY(LS1084AE, LS1084AE, 2, 4),
+	SOC_ENTRY(LS1088A, LS1088A, 2, 4),
+	SOC_ENTRY(LS1088AE, LS1088AE, 2, 4),
+};
+
+static dcfg_init_info_t dcfg_init_data = {
+	.g_nxp_dcfg_addr = NXP_DCFG_ADDR,
+	.nxp_sysclk_freq = NXP_SYSCLK_FREQ,
+	.nxp_ddrclk_freq = NXP_DDRCLK_FREQ,
+	.nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER,
+};
+
+/*
+ * This function dynamically constructs the topology according to
+ *  SoC Flavor and returns it.
+ */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	unsigned int i;
+	uint8_t num_clusters, cores_per_cluster;
+
+	get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+	/*
+	 * The highest level is the system level. The next level is constituted
+	 * by clusters and then cores in clusters.
+	 */
+	_power_domain_tree_desc[0] = 1;
+	_power_domain_tree_desc[1] = num_clusters;
+
+	for (i = 0; i < _power_domain_tree_desc[1]; i++) {
+		_power_domain_tree_desc[i + 2] = cores_per_cluster;
+	}
+
+
+	return _power_domain_tree_desc;
+}
+
+CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256,
+		assert_invalid_ls1088a_cluster_count);
+
+/*
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ */
+unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr)
+{
+	return CORES_PER_CLUSTER;
+}
+
+/*
+ * This function returns the total number of cores in the SoC
+ */
+unsigned int get_tot_num_cores(void)
+{
+	uint8_t num_clusters, cores_per_cluster;
+
+	get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+	return (num_clusters * cores_per_cluster);
+}
+
+/*
+ * This function returns the PMU IDLE Cluster mask.
+ */
+unsigned int get_pmu_idle_cluster_mask(void)
+{
+	uint8_t num_clusters, cores_per_cluster;
+
+	get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+	return ((1 << num_clusters) - 2);
+}
+
+/*
+ * This function returns the PMU Flush Cluster mask.
+ */
+unsigned int get_pmu_flush_cluster_mask(void)
+{
+	uint8_t num_clusters, cores_per_cluster;
+
+	get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+
+	return ((1 << num_clusters) - 2);
+}
+
+/*
+ * This function returns the PMU IDLE Core mask.
+ */
+unsigned int get_pmu_idle_core_mask(void)
+{
+	return ((1 << get_tot_num_cores()) - 2);
+}
+
+#ifdef IMAGE_BL2
+
+void soc_bl2_prepare_exit(void)
+{
+#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE)
+	set_sfp_wr_disable();
+#endif
+}
+
+void soc_preload_setup(void)
+{
+
+}
+
+/*
+ * This function returns the boot device based on RCW_SRC
+ */
+enum boot_device get_boot_dev(void)
+{
+	enum boot_device src = BOOT_DEVICE_NONE;
+	uint32_t porsr1;
+	uint32_t rcw_src, val;
+
+	porsr1 = read_reg_porsr1();
+
+	rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT;
+
+	/* RCW SRC NOR */
+	val = rcw_src & RCW_SRC_TYPE_MASK;
+	if (val == NOR_16B_VAL) {
+		src = BOOT_DEVICE_IFC_NOR;
+		INFO("RCW BOOT SRC is IFC NOR\n");
+	} else {
+		val = rcw_src & RCW_SRC_SERIAL_MASK;
+		switch (val) {
+		case QSPI_VAL:
+			src = BOOT_DEVICE_QSPI;
+			INFO("RCW BOOT SRC is QSPI\n");
+			break;
+		case SDHC_VAL:
+			src = BOOT_DEVICE_EMMC;
+			INFO("RCW BOOT SRC is SD/EMMC\n");
+			break;
+		case EMMC_VAL:
+			src = BOOT_DEVICE_EMMC;
+			INFO("RCW BOOT SRC is SD/EMMC\n");
+			break;
+		default:
+			src = BOOT_DEVICE_NONE;
+		}
+	}
+
+	return src;
+}
+
+/*
+ * This function sets up access permissions on memory regions
+ */
+void soc_mem_access(void)
+{
+	dram_regions_info_t *info_dram_regions = get_dram_regions_info();
+	int i = 0;
+	struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION];
+	int dram_idx, index = 1;
+
+	for (dram_idx = 0; dram_idx < info_dram_regions->num_dram_regions;
+	     dram_idx++) {
+		if (info_dram_regions->region[i].size == 0) {
+			ERROR("DDR init failure, or");
+			ERROR("DRAM regions not populated correctly.\n");
+			break;
+		}
+
+		index = populate_tzc400_reg_list(tzc400_reg_list,
+				dram_idx, index,
+				info_dram_regions->region[dram_idx].addr,
+				info_dram_regions->region[dram_idx].size,
+				NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE);
+	}
+
+	mem_access_setup(NXP_TZC_ADDR, index,
+			 tzc400_reg_list);
+}
+
+/*
+ * This function implements soc specific erratum
+ * This is called before DDR is initialized or MMU is enabled
+ */
+void soc_early_init(void)
+{
+	enum boot_device dev;
+	dram_regions_info_t *dram_regions_info = get_dram_regions_info();
+
+#ifdef CONFIG_OCRAM_ECC_EN
+	ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE);
+#endif
+	dcfg_init(&dcfg_init_data);
+#if LOG_LEVEL > 0
+	/* Initialize the console to provide early debug support */
+	plat_console_init(NXP_CONSOLE_ADDR,
+			  NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+	enable_timer_base_to_cluster(NXP_PMU_ADDR);
+	enable_core_tb(NXP_PMU_ADDR);
+
+	/*
+	 * Use the region(NXP_SD_BLOCK_BUF_ADDR + NXP_SD_BLOCK_BUF_SIZE)
+	 * as dma of sd
+	 */
+	dev = get_boot_dev();
+	if (dev == BOOT_DEVICE_EMMC) {
+		mmap_add_region(NXP_SD_BLOCK_BUF_ADDR, NXP_SD_BLOCK_BUF_ADDR,
+				NXP_SD_BLOCK_BUF_SIZE,
+				MT_DEVICE | MT_RW | MT_NS);
+	}
+
+#if TRUSTED_BOARD_BOOT
+	uint32_t mode;
+
+	sfp_init(NXP_SFP_ADDR);
+	/*
+	 * For secure boot disable SMMU.
+	 * Later when platform security policy comes in picture,
+	 * this might get modified based on the policy
+	 */
+	if (check_boot_mode_secure(&mode) == true) {
+		bypass_smmu(NXP_SMMU_ADDR);
+	}
+
+	/*
+	 * For Mbedtls currently crypto is not supported via CAAM
+	 * enable it when that support is there. In tbbr.mk
+	 * the CAAM_INTEG is set as 0.
+	 */
+#ifndef MBEDTLS_X509
+	/* Initialize the crypto accelerator if enabled */
+	if (is_sec_enabled() == false) {
+		INFO("SEC is disabled.\n");
+	} else {
+		sec_init(NXP_CAAM_ADDR);
+	}
+#endif
+#endif
+
+	soc_errata();
+
+	delay_timer_init(NXP_TIMER_ADDR);
+	i2c_init(NXP_I2C_ADDR);
+	dram_regions_info->total_dram_size = init_ddr();
+}
+#else /* !IMAGE_BL2 */
+
+void soc_early_platform_setup2(void)
+{
+	dcfg_init(&dcfg_init_data);
+	/*
+	 * Initialize system level generic timer for Socs
+	 */
+	delay_timer_init(NXP_TIMER_ADDR);
+
+#if LOG_LEVEL > 0
+	/* Initialize the console to provide early debug support */
+	plat_console_init(NXP_CONSOLE_ADDR,
+			  NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE);
+#endif
+}
+
+void soc_platform_setup(void)
+{
+	/* Initialize the GIC driver, cpu and distributor interfaces */
+	static uintptr_t target_mask_array[PLATFORM_CORE_COUNT];
+	static interrupt_prop_t ls_interrupt_props[] = {
+		PLAT_LS_G1S_IRQ_PROPS(INTR_GROUP1S),
+		PLAT_LS_G0_IRQ_PROPS(INTR_GROUP0)
+	};
+
+	plat_ls_gic_driver_init(NXP_GICD_ADDR, NXP_GICR_ADDR,
+				PLATFORM_CORE_COUNT,
+				ls_interrupt_props,
+				ARRAY_SIZE(ls_interrupt_props),
+				target_mask_array,
+				plat_core_pos);
+
+	plat_ls_gic_init();
+	enable_init_timer();
+}
+
+/*
+ * This function initializes the soc from the BL31 module
+ */
+void soc_init(void)
+{
+	uint8_t num_clusters, cores_per_cluster;
+
+	/* low-level init of the soc */
+	soc_init_lowlevel();
+	_init_global_data();
+	soc_init_percpu();
+	_initialize_psci();
+
+	/*
+	 * Initialize Interconnect for this cluster during cold boot.
+	 * No need for locks as no other CPU is active.
+	 */
+	cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map));
+
+	/*
+	 * Enable Interconnect coherency for the primary CPU's cluster.
+	 */
+	get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster);
+	plat_ls_interconnect_enter_coherency(num_clusters);
+
+	/* set platform security policies */
+	_set_platform_security();
+
+	/* Initialize the crypto accelerator if enabled */
+	if (is_sec_enabled() == false) {
+		INFO("SEC is disabled.\n");
+	} else {
+		sec_init(NXP_CAAM_ADDR);
+	}
+}
+
+void soc_runtime_setup(void)
+{
+
+}
+#endif /* IMAGE_BL2 */
+
+/*
+ * Function to return the SoC SYS CLK
+ */
+unsigned int get_sys_clk(void)
+{
+	return NXP_SYSCLK_FREQ;
+}
+
+/*
+ * Function returns the base counter frequency
+ * after reading the first entry at CNTFID0 (0x20 offset).
+ *
+ * Function is used by:
+ *   1. ARM common code for PSCI management.
+ *   2. ARM Generic Timer init.
+ */
+unsigned int plat_get_syscnt_freq2(void)
+{
+	unsigned int counter_base_frequency;
+	/*
+	 * Below register specifies the base frequency of the system counter.
+	 * As per NXP Board Manuals:
+	 * The system counter always works with SYS_REF_CLK/4 frequency clock.
+	 */
+	counter_base_frequency = mmio_read_32(NXP_TIMER_ADDR + CNTFID_OFF);
+
+	return counter_base_frequency;
+}
diff --git a/plat/nxp/soc-ls1088a/soc.def b/plat/nxp/soc-ls1088a/soc.def
new file mode 100644
index 0000000..25d0847
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/soc.def
@@ -0,0 +1,87 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#
+#------------------------------------------------------------------------------
+#
+# This file contains the basic architecture definitions that drive the build
+#
+# -----------------------------------------------------------------------------
+
+CORE_TYPE		:=	a53
+
+CACHE_LINE		:=	6
+
+# Set to GIC400 or GIC500
+GIC			:=	GIC500
+
+# Set to CCI400 or CCN504 or CCN508
+INTERCONNECT		:=	CCI400
+
+# Select the DDR PHY generation to be used
+PLAT_DDR_PHY		:=	PHY_GEN1
+
+PHYS_SYS		:=	64
+
+# Indicate layerscape chassis level - set to 3=LSCH3 or 2=LSCH2
+CHASSIS			:=	3
+
+# TZC IP Details TZC used is TZC380 or TZC400
+TZC_ID			:=	TZC400
+
+# CONSOLE Details available is NS16550 or PL011
+CONSOLE			:=	NS16550
+
+NXP_SFP_VER		:=	3_4
+
+# In IMAGE_BL2, compile time flag for handling Cache coherency
+# with CAAM for BL2 running from OCRAM
+SEC_MEM_NON_COHERENT	:=	yes
+
+
+# OCRAM MAP for BL2
+# Before BL2
+# 0x18000000 - 0x18009fff -> Used by ROM code, (TBD - can it be used for xlat tables)
+# 0x1800a000 - 0x1801Cfff -> Reserved for BL2 binary (76 KB)
+# 0x1801D000 - 0x1801ffff -> CSF header for BL2 (12 KB)
+OCRAM_START_ADDR	:=	0x18000000
+OCRAM_SIZE		:=	0x20000
+
+CSF_HDR_SZ		:=	0x3000
+
+# Area of OCRAM reserved by ROM code
+NXP_ROM_RSVD		:=	0xa000
+
+# Input to CST create_hdr_isbc tool
+BL2_HDR_LOC		:=	0x1801D000
+
+# Location of BL2 on OCRAM
+# BL2_BASE=OCRAM_START_ADDR+NXP_ROM_RSVD
+BL2_BASE		:=	0x1800a000
+
+# SoC ERRATUM to be enabled
+ERRATA_SOC_A008850	:=	1
+
+# ARM Erratum
+ERRATA_A53_855873	:=	1
+
+# DDR Erratum
+ERRATA_DDR_A008511	:=	1
+ERRATA_DDR_A009803	:=	1
+ERRATA_DDR_A009942	:=	1
+ERRATA_DDR_A010165	:=	1
+
+# Define Endianness of each module
+NXP_ESDHC_ENDIANNESS	:=	LE
+NXP_SFP_ENDIANNESS	:=	LE
+NXP_GPIO_ENDIANNESS	:=	LE
+NXP_SNVS_ENDIANNESS	:=	LE
+NXP_GUR_ENDIANNESS	:=	LE
+NXP_SEC_ENDIANNESS	:=	LE
+NXP_DDR_ENDIANNESS	:=	LE
+NXP_QSPI_ENDIANNESS	:=	LE
+
+# OCRAM ECC Enabled
+OCRAM_ECC_EN		:=	yes
diff --git a/plat/nxp/soc-ls1088a/soc.mk b/plat/nxp/soc-ls1088a/soc.mk
new file mode 100644
index 0000000..83ac9d0
--- /dev/null
+++ b/plat/nxp/soc-ls1088a/soc.mk
@@ -0,0 +1,110 @@
+#
+# Copyright 2022 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# SoC-specific build parameters
+SOC		:=	ls1088a
+PLAT_PATH	:=	plat/nxp
+PLAT_COMMON_PATH:=	plat/nxp/common
+PLAT_DRIVERS_PATH:=	drivers/nxp
+PLAT_SOC_PATH	:=	${PLAT_PATH}/soc-${SOC}
+BOARD_PATH	:=	${PLAT_SOC_PATH}/${BOARD}
+
+# Separate BL2 NOLOAD region (.bss, stack, page tables). need to
+# define BL2_NOLOAD_START and BL2_NOLOAD_LIMIT
+SEPARATE_BL2_NOLOAD_REGION	:= 1
+
+# get SoC-specific defnitions
+include ${PLAT_SOC_PATH}/soc.def
+include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk
+include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk
+
+# For Security Features
+DISABLE_FUSE_WRITE	:= 1
+ifeq (${TRUSTED_BOARD_BOOT}, 1)
+ifeq (${GENERATE_COT},1)
+# Save Keys to be used by DDR FIP image
+SAVE_KEYS=1
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2))
+# Used by create_pbl tool to
+# create bl2_<boot_mode>_sec.pbl image
+SECURE_BOOT	:= yes
+endif
+$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM))
+
+# Selecting Drivers for SoC
+$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM))
+$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2))
+$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
+
+# Selecting PSCI & SIP_SVC support
+$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31))
+$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31))
+
+
+# Adding SoC specific files
+include ${PLAT_COMMON_PATH}/soc_errata/errata.mk
+
+PLAT_INCLUDES	+=	-I${PLAT_COMMON_PATH}/include/default\
+			-I${BOARD_PATH}\
+			-I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\
+			-I${PLAT_COMMON_PATH}/soc_errata\
+			-I${PLAT_COMMON_PATH}/include\
+			-I${PLAT_SOC_PATH}/include
+
+ifeq (${SECURE_BOOT},yes)
+include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk
+endif
+
+ifeq (${PSCI_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/psci/psci.mk
+endif
+
+ifeq (${SIPSVC_NEEDED}, yes)
+include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk
+endif
+
+# for fuse-fip & fuse-programming
+ifeq (${FUSE_PROG}, 1)
+include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk
+endif
+
+ifeq (${IMG_LOADR_NEEDED},yes)
+include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk
+endif
+
+# Adding source files for the above selected drivers.
+include ${PLAT_DRIVERS_PATH}/drivers.mk
+
+PLAT_BL_COMMON_SOURCES	+=	${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\
+				${PLAT_SOC_PATH}/${ARCH}/${SOC}_helpers.S\
+				${PLAT_SOC_PATH}/soc.c
+
+BL31_SOURCES	+=	${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\
+			${PSCI_SOURCES}\
+			${SIPSVC_SOURCES}\
+			${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S
+
+ifeq (${TEST_BL31}, 1)
+BL31_SOURCES	+=	${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S  \
+			${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S
+endif
+
+BL2_SOURCES		+=	${DDR_CNTLR_SOURCES}\
+				${TBBR_SOURCES}\
+				${FUSE_SOURCES}
+
+# Adding TFA setup files
+include ${PLAT_PATH}/common/setup/common.mk
diff --git a/plat/nxp/soc-lx2160a/soc.def b/plat/nxp/soc-lx2160a/soc.def
index 24d1d13..81d6744 100644
--- a/plat/nxp/soc-lx2160a/soc.def
+++ b/plat/nxp/soc-lx2160a/soc.def
@@ -1,6 +1,6 @@
 #
 # Copyright (c) 2015, 2016 Freescale Semiconductor, Inc.
-# Copyright 2017-2020 NXP Semiconductors
+# Copyright 2017-2022 NXP Semiconductors
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -107,5 +107,10 @@
 # SoC Errata
 ERRATA_SOC_A050426	:= 1
 
+# DDR Errata
+ERRATA_DDR_A011396	:= 1
+ERRATA_DDR_A050450	:= 1
+ERRATA_DDR_A050958	:= 1
+
 # enable dynamic memory mapping
 PLAT_XLAT_TABLES_DYNAMIC :=	1
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 9e732d6..a890534 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -146,7 +146,7 @@
 endif
 
 $(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
-$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g")))
+$(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g" | grep -o [0-9]*)))
 DTC_CPPFLAGS		+=	${INCLUDES}
 DTC_FLAGS		+=	-Wno-unit_address_vs_reg
 ifeq ($(shell test $(DTC_VERSION) -ge 10601; echo $$?),0)
diff --git a/services/std_svc/rmmd/rmmd.mk b/services/std_svc/rmmd/rmmd.mk
index bac0a9f..bcf54e1 100644
--- a/services/std_svc/rmmd/rmmd.mk
+++ b/services/std_svc/rmmd/rmmd.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,7 +12,8 @@
 
 RMMD_SOURCES	+=	$(addprefix services/std_svc/rmmd/,	\
 			${ARCH}/rmmd_helpers.S			\
-			rmmd_main.c)
+			rmmd_main.c				\
+			rmmd_attest.c)
 
 # Let the top-level Makefile know that we intend to include RMM image
 NEED_RMM	:=	yes
diff --git a/services/std_svc/rmmd/rmmd_attest.c b/services/std_svc/rmmd/rmmd_attest.c
new file mode 100644
index 0000000..0432ec3
--- /dev/null
+++ b/services/std_svc/rmmd/rmmd_attest.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdint.h>
+#include <string.h>
+#include <common/debug.h>
+#include <lib/spinlock.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include "rmmd_private.h"
+#include <services/rmmd_svc.h>
+
+static spinlock_t lock;
+
+/* For printing Realm attestation token hash */
+#define DIGITS_PER_BYTE				2UL
+#define LENGTH_OF_TERMINATING_ZERO_IN_BYTES	1UL
+#define BYTES_PER_LINE_BASE			4UL
+
+static void print_challenge(uint8_t *hash, size_t hash_size)
+{
+	size_t leftover;
+	/*
+	 * bytes_per_line is always a power of two, so it can be used to
+	 * construct mask with it when it is necessary to count remainder.
+	 *
+	 */
+	const size_t bytes_per_line = 1 << BYTES_PER_LINE_BASE;
+	char hash_text[(1 << BYTES_PER_LINE_BASE) * DIGITS_PER_BYTE +
+		LENGTH_OF_TERMINATING_ZERO_IN_BYTES];
+	const char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+				  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+	unsigned int i;
+
+	for (i = 0U; i < hash_size; ++i) {
+		hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE] =
+			hex_chars[hash[i] >> 4];
+		hash_text[(i & (bytes_per_line - 1)) * DIGITS_PER_BYTE + 1] =
+			hex_chars[hash[i] & 0x0f];
+		if (((i + 1) & (bytes_per_line - 1)) == 0U) {
+			hash_text[bytes_per_line * DIGITS_PER_BYTE] = '\0';
+			VERBOSE("hash part %u = %s\n",
+				(i >> BYTES_PER_LINE_BASE) + 1, hash_text);
+		}
+	}
+
+	leftover = (size_t)i & (bytes_per_line - 1);
+
+	if (leftover != 0UL) {
+		hash_text[leftover * DIGITS_PER_BYTE] = '\0';
+		VERBOSE("hash part %u = %s\n", (i >> BYTES_PER_LINE_BASE) + 1,
+			hash_text);
+	}
+}
+
+/*
+ * TODO: Have different error codes for different errors so that the caller can
+ * differentiate various error cases.
+ */
+int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_len, uint64_t challenge_hash_len)
+{
+	int err;
+	uintptr_t va;
+	uint8_t temp_buf[SHA512_DIGEST_SIZE];
+
+	/*
+	 * TODO: Currently we don't validate incoming buf_pa. This is a
+	 * prototype and we will need to allocate static buffer for EL3-RMM
+	 * communication.
+	 */
+
+	/* We need a page of buffer to pass data */
+	if (*buf_len != PAGE_SIZE) {
+		ERROR("Invalid buffer length\n");
+		return RMMD_ERR_INVAL;
+	}
+
+	if ((challenge_hash_len != SHA256_DIGEST_SIZE) &&
+	    (challenge_hash_len != SHA384_DIGEST_SIZE) &&
+	    (challenge_hash_len != SHA512_DIGEST_SIZE)) {
+		ERROR("Invalid hash size: %lu\n", challenge_hash_len);
+		return RMMD_ERR_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Map the buffer that was provided by the RMM. */
+	err = mmap_add_dynamic_region_alloc_va(buf_pa, &va, PAGE_SIZE,
+					       MT_RW_DATA | MT_REALM);
+	if (err != 0) {
+		ERROR("mmap_add_dynamic_region_alloc_va failed: %d (%p).\n"
+		      , err, (void *)buf_pa);
+		spin_unlock(&lock);
+		return RMMD_ERR_NOMEM;
+	}
+
+	(void)memcpy(temp_buf, (void *)va, challenge_hash_len);
+
+	print_challenge((uint8_t *)temp_buf, challenge_hash_len);
+
+	/* Get the platform token. */
+	err = plat_get_cca_attest_token(va,
+		buf_len, (uintptr_t)temp_buf, challenge_hash_len);
+
+	if (err != 0) {
+		ERROR("Failed to get platform token: %d.\n", err);
+		err = RMMD_ERR_UNK;
+	}
+
+	/* Unmap RMM memory. */
+	(void)mmap_remove_dynamic_region(va, PAGE_SIZE);
+	spin_unlock(&lock);
+
+	return err;
+}
+
+int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_len,
+				uint64_t ecc_curve)
+{
+	int err;
+	uintptr_t va;
+
+	/*
+	 * TODO: Currently we don't validate incoming buf_pa. This is a
+	 * prototype and we will need to allocate static buffer for EL3-RMM
+	 * communication.
+	 */
+
+	/* We need a page of buffer to pass data */
+	if (*buf_len != PAGE_SIZE) {
+		ERROR("Invalid buffer length\n");
+		return RMMD_ERR_INVAL;
+	}
+
+	if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
+		ERROR("Invalid ECC curve specified\n");
+		return RMMD_ERR_INVAL;
+	}
+
+	spin_lock(&lock);
+
+	/* Map the buffer that was provided by the RMM. */
+	err = mmap_add_dynamic_region_alloc_va(buf_pa, &va, PAGE_SIZE,
+					       MT_RW_DATA | MT_REALM);
+	if (err != 0) {
+		ERROR("mmap_add_dynamic_region_alloc_va failed: %d (%p).\n"
+		      , err, (void *)buf_pa);
+		spin_unlock(&lock);
+		return RMMD_ERR_NOMEM;
+	}
+
+	/* Get the Realm attestation key. */
+	err = plat_get_cca_realm_attest_key(va, buf_len, (unsigned int)ecc_curve);
+	if (err != 0) {
+		ERROR("Failed to get attestation key: %d.\n", err);
+		err =  RMMD_ERR_UNK;
+	}
+
+	/* Unmap RMM memory. */
+	(void)mmap_remove_dynamic_region(va, PAGE_SIZE);
+	spin_unlock(&lock);
+
+	return err;
+}
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index 28d0b01..cf5ff7b 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,8 +26,6 @@
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
-#include <services/gtsi_svc.h>
-#include <services/rmi_svc.h>
 #include <services/rmmd_svc.h>
 #include <smccc_helpers.h>
 #include <lib/extensions/sve.h>
@@ -257,7 +255,7 @@
 
 	/* RMI must not be invoked by the Secure world */
 	if (src_sec_state == SMC_FROM_SECURE) {
-		WARN("RMM: RMI invoked by secure world.\n");
+		WARN("RMMD: RMI invoked by secure world.\n");
 		SMC_RET1(handle, SMC_UNK);
 	}
 
@@ -266,17 +264,19 @@
 	 * is.
 	 */
 	if (src_sec_state == SMC_FROM_NON_SECURE) {
-		VERBOSE("RMM: RMI call from non-secure world.\n");
+		VERBOSE("RMMD: RMI call from non-secure world.\n");
 		return rmmd_smc_forward(NON_SECURE, REALM, smc_fid,
 					x1, x2, x3, x4, handle);
 	}
 
-	assert(src_sec_state == SMC_FROM_REALM);
+	if (src_sec_state != SMC_FROM_REALM) {
+		SMC_RET1(handle, SMC_UNK);
+	}
 
 	switch (smc_fid) {
-	case RMI_RMM_REQ_COMPLETE:
+	case RMMD_RMI_REQ_COMPLETE:
 		if (ctx->state == RMM_STATE_RESET) {
-			VERBOSE("RMM: running rmmd_rmm_sync_exit\n");
+			VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
 			rmmd_rmm_sync_exit(x1);
 		}
 
@@ -284,7 +284,7 @@
 					x2, x3, x4, 0, handle);
 
 	default:
-		WARN("RMM: Unsupported RMM call 0x%08x\n", smc_fid);
+		WARN("RMMD: Unsupported RMM call 0x%08x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
 }
@@ -325,10 +325,32 @@
 /* Subscribe to PSCI CPU on to initialize RMM on secondary */
 SUBSCRIBE_TO_EVENT(psci_cpu_on_finish, rmmd_cpu_on_finish_handler);
 
+/* Convert GPT lib error to RMMD GTS error */
+static int gpt_to_gts_error(int error, uint32_t smc_fid, uint64_t address)
+{
+	int ret;
+
+	if (error == 0) {
+		return RMMD_OK;
+	}
+
+	if (error == -EINVAL) {
+		ret = RMMD_ERR_BAD_ADDR;
+	} else {
+		/* This is the only other error code we expect */
+		assert(error == -EPERM);
+		ret = RMMD_ERR_BAD_PAS;
+	}
+
+	ERROR("RMMD: PAS Transition failed. GPT ret = %d, PA: 0x%"PRIx64 ", FID = 0x%x\n",
+				error, address, smc_fid);
+	return ret;
+}
+
 /*******************************************************************************
- * This function handles all SMCs in the range reserved for GTF.
+ * This function handles RMM-EL3 interface SMCs
  ******************************************************************************/
-uint64_t rmmd_gtsi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
+uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
 				uint64_t x3, uint64_t x4, void *cookie,
 				void *handle, uint64_t flags)
 {
@@ -339,33 +361,25 @@
 	src_sec_state = caller_sec_state(flags);
 
 	if (src_sec_state != SMC_FROM_REALM) {
-		WARN("RMM: GTF call originated from secure or normal world\n");
+		WARN("RMMD: RMM-EL3 call originated from secure or normal world\n");
 		SMC_RET1(handle, SMC_UNK);
 	}
 
 	switch (smc_fid) {
-	case SMC_ASC_MARK_REALM:
+	case RMMD_GTSI_DELEGATE:
 		ret = gpt_delegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
-		break;
-	case SMC_ASC_MARK_NONSECURE:
+		SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
+	case RMMD_GTSI_UNDELEGATE:
 		ret = gpt_undelegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
-		break;
+		SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
+	case RMMD_ATTEST_GET_PLAT_TOKEN:
+		ret = rmmd_attest_get_platform_token(x1, &x2, x3);
+		SMC_RET2(handle, ret, x2);
+	case RMMD_ATTEST_GET_REALM_KEY:
+		ret = rmmd_attest_get_signing_key(x1, &x2, x3);
+		SMC_RET2(handle, ret, x2);
 	default:
-		WARN("RMM: Unsupported GTF call 0x%08x\n", smc_fid);
+		WARN("RMMD: Unsupported RMM-EL3 call 0x%08x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
 	}
-
-	if (ret == -EINVAL) {
-		ERROR("[GTSI] Transition failed: invalid %s\n", "address");
-		ERROR("       PA: 0x%"PRIx64 ", SRC: %d, PAS: %d\n", x1,
-		      SMC_FROM_REALM, smc_fid);
-		ret = GRAN_TRANS_RET_BAD_ADDR;
-	} else if (ret == -EPERM) {
-		ERROR("[GTSI] Transition failed: invalid %s\n", "caller/PAS");
-		ERROR("       PA: 0x%"PRIx64 ", SRC: %d, PAS: %d\n", x1,
-		      SMC_FROM_REALM, smc_fid);
-		ret = GRAN_TRANS_RET_BAD_PAS;
-	}
-
-	SMC_RET1(handle, ret);
 }
diff --git a/services/std_svc/rmmd/rmmd_private.h b/services/std_svc/rmmd/rmmd_private.h
index d170bcd..73df2b8 100644
--- a/services/std_svc/rmmd/rmmd_private.h
+++ b/services/std_svc/rmmd/rmmd_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,7 +31,6 @@
 
 #ifndef __ASSEMBLER__
 #include <stdint.h>
-#include <services/rmi_svc.h>
 
 typedef enum rmm_state {
 	RMM_STATE_RESET = 0,
@@ -52,6 +51,12 @@
 uint64_t rmmd_rmm_sync_entry(rmmd_rmm_context_t *ctx);
 __dead2 void rmmd_rmm_sync_exit(uint64_t rc);
 
+/* Functions implementing attestation utilities for RMM */
+int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_len,
+				   uint64_t challenge_hash_len);
+int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_len,
+				   uint64_t ecc_curve);
+
 /* Assembly helpers */
 uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);
 void __dead2 rmmd_rmm_exit(uint64_t c_rt_ctx, uint64_t ret);
diff --git a/services/std_svc/rmmd/trp/trp_entry.S b/services/std_svc/rmmd/trp/trp_entry.S
index 5826d75..1b03c9f 100644
--- a/services/std_svc/rmmd/trp/trp_entry.S
+++ b/services/std_svc/rmmd/trp/trp_entry.S
@@ -1,12 +1,11 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <asm_macros.S>
-#include <services/gtsi_svc.h>
-#include <services/rmi_svc.h>
+#include <services/rmmd_svc.h>
 #include "trp_private.h"
 
 .global trp_head
@@ -59,7 +58,7 @@
 
 	bl	trp_main
 warm_boot:
-	mov_imm	x0, RMI_RMM_REQ_COMPLETE
+	mov_imm	x0, RMMD_RMI_REQ_COMPLETE
 	mov	x1, xzr
 	smc	#0
 	b	trp_handler
diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c
index 2ab9ecc..2e3f076 100644
--- a/services/std_svc/rmmd/trp/trp_main.c
+++ b/services/std_svc/rmmd/trp/trp_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,7 @@
 
 #include <common/debug.h>
 #include <plat/common/platform.h>
-#include <services/gtsi_svc.h>
-#include <services/rmi_svc.h>
+#include <services/rmmd_svc.h>
 #include <services/trp/platform_trp.h>
 
 #include <platform_def.h>
@@ -79,7 +78,7 @@
 {
 	VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
 					  RMI_ABI_VERSION_MINOR);
-	return set_smc_args(RMI_RMM_REQ_COMPLETE, RMI_ABI_VERSION,
+	return set_smc_args(RMMD_RMI_REQ_COMPLETE, RMI_ABI_VERSION,
 			    0, 0, 0, 0, 0, 0);
 }
 
@@ -91,13 +90,13 @@
 	unsigned long long ret;
 
 	VERBOSE("Delegating granule 0x%llx\n", x1);
-	ret = trp_smc(set_smc_args(SMC_ASC_MARK_REALM, x1, 0, 0, 0, 0, 0, 0));
+	ret = trp_smc(set_smc_args(RMMD_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0));
 
 	if (ret != 0ULL) {
 		ERROR("Granule transition from NON-SECURE type to REALM type "
 			"failed 0x%llx\n", ret);
 	}
-	return set_smc_args(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
+	return set_smc_args(RMMD_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
 }
 
 /*******************************************************************************
@@ -108,13 +107,13 @@
 	unsigned long long ret;
 
 	VERBOSE("Undelegating granule 0x%llx\n", x1);
-	ret = trp_smc(set_smc_args(SMC_ASC_MARK_NONSECURE, x1, 0, 0, 0, 0, 0, 0));
+	ret = trp_smc(set_smc_args(RMMD_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0));
 
 	if (ret != 0ULL) {
 		ERROR("Granule transition from REALM type to NON-SECURE type "
 			"failed 0x%llx\n", ret);
 	}
-	return set_smc_args(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
+	return set_smc_args(RMMD_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
 }
 
 /*******************************************************************************
diff --git a/services/std_svc/rmmd/trp/trp_private.h b/services/std_svc/rmmd/trp/trp_private.h
index 9231390..43a4a4b 100644
--- a/services/std_svc/rmmd/trp/trp_private.h
+++ b/services/std_svc/rmmd/trp/trp_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,6 +31,19 @@
 #define write_trp_arg(args, offset, val) (((args)->regs[offset >> 3])	\
 					 = val)
 
+/* RMI handled by TRP */
+#define RMI_FNUM_VERSION_REQ		U(0x150)
+
+#define RMI_FNUM_GRANULE_DELEGATE	U(0x151)
+#define RMI_FNUM_GRANULE_UNDELEGATE	U(0x152)
+
+#define RMI_RMM_REQ_VERSION		RMM_FID(SMC_64, RMI_FNUM_VERSION_REQ)
+
+#define RMI_RMM_GRANULE_DELEGATE	RMM_FID(SMC_64, \
+						RMI_FNUM_GRANULE_DELEGATE)
+#define RMI_RMM_GRANULE_UNDELEGATE	RMM_FID(SMC_64, \
+						RMI_FNUM_GRANULE_UNDELEGATE)
+
 /* Definitions for RMI VERSION */
 #define RMI_ABI_VERSION_MAJOR		U(0x0)
 #define RMI_ABI_VERSION_MINOR		U(0x0)
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index eea7e14..bfe26ca 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2022, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,9 +13,7 @@
 #include <lib/pmf/pmf.h>
 #include <lib/psci/psci.h>
 #include <lib/runtime_instr.h>
-#include <services/gtsi_svc.h>
 #include <services/pci_svc.h>
-#include <services/rmi_svc.h>
 #include <services/rmmd_svc.h>
 #include <services/sdei.h>
 #include <services/spm_mm_svc.h>
@@ -168,13 +166,10 @@
 	}
 #endif
 #if ENABLE_RME
-	/*
-	 * Granule transition service interface functions (GTSI) are allocated
-	 * from the Std service range. Call the RMM dispatcher to handle calls.
-	 */
-	if (is_gtsi_fid(smc_fid)) {
-		return rmmd_gtsi_handler(smc_fid, x1, x2, x3, x4, cookie,
-						handle, flags);
+
+	if (is_rmmd_el3_fid(smc_fid)) {
+		return rmmd_rmm_el3_handler(smc_fid, x1, x2, x3, x4, cookie,
+					    handle, flags);
 	}
 
 	if (is_rmi_fid(smc_fid)) {
diff --git a/tools/memory/print_memory_map.py b/tools/memory/print_memory_map.py
index 8a84018..ef53f7e 100755
--- a/tools/memory/print_memory_map.py
+++ b/tools/memory/print_memory_map.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python3
 #
-# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -17,12 +17,24 @@
 blx_symbols = ['__BL1_RAM_START__', '__BL1_RAM_END__',
                 '__BL2_END__',
                 '__BL31_END__',
+                '__RO_START__', '__RO_END_UNALIGNED__', '__RO_END__',
                 '__TEXT_START__', '__TEXT_END__',
+                '__TEXT_RESIDENT_START__', '__TEXT_RESIDENT_END__',
                 '__RODATA_START__', '__RODATA_END__',
                 '__DATA_START__', '__DATA_END__',
                 '__STACKS_START__', '__STACKS_END__',
-                '__BSS_END',
+                '__BSS_START__', '__BSS_END__',
                 '__COHERENT_RAM_START__', '__COHERENT_RAM_END__',
+                '__CPU_OPS_START__', '__CPU_OPS_END__',
+                '__FCONF_POPULATOR_START__', '__FCONF_POPULATOR_END__',
+                '__GOT_START__', '__GOT_END__',
+                '__PARSER_LIB_DESCS_START__', '__PARSER_LIB_DESCS_END__',
+                '__PMF_TIMESTAMP_START__', '__PMF_TIMESTAMP_END__',
+                '__PMF_SVC_DESCS_START__', '__PMF_SVC_DESCS_END__',
+                '__RELA_START__', '__RELA_END__',
+                '__RT_SVC_DESCS_START__', '__RT_SVC_DESCS_END__',
+                '__BASE_XLAT_TABLE_START__', '__BASE_XLAT_TABLE_END__',
+                '__XLAT_TABLE_START__', '__XLAT_TABLE_END__',
                ]
 
 # Regex to extract address from map file
@@ -40,6 +52,10 @@
 else:
     build_dir = 'build/fvp/debug'
 
+max_len = max(len(word) for word in blx_symbols) + 2
+if (max_len % 2) != 0:
+    max_len += 1
+
 # Extract all the required symbols from the map files
 for image in bl_images:
     file_path = os.path.join(build_dir, image, '{}.map'.format(image))
@@ -47,6 +63,7 @@
         with open (file_path, 'rt') as mapfile:
             for line in mapfile:
                 for symbol in blx_symbols:
+                    skip_symbol = 0
                     # Regex to find symbol definition
                     line_pattern = re.compile(r"\b0x\w*\s*" + symbol + "\s= .")
                     match = line_pattern.search(line)
@@ -54,7 +71,13 @@
                         # Extract address from line
                         match = address_pattern.search(line)
                         if match:
-                            address_list.append([match.group(0), symbol, image])
+                            if '_END__' in symbol:
+                                sym_start = symbol.replace('_END__', '_START__')
+                                if [match.group(0), sym_start, image] in address_list:
+                                    address_list.remove([match.group(0), sym_start, image])
+                                    skip_symbol = 1
+                            if skip_symbol == 0:
+                                address_list.append([match.group(0), symbol, image])
 
 # Sort by address
 address_list.sort(key=operator.itemgetter(0))
@@ -64,16 +87,16 @@
     address_list = reversed(address_list)
 
 # Generate memory view
-print('{:-^93}'.format('Memory Map from: ' + build_dir))
+print(('{:-^%d}' % (max_len * 3 + 20 + 7)).format('Memory Map from: ' + build_dir))
 for address in address_list:
     if "bl1" in address[2]:
-        print(address[0], '+{:-^22}+ |{:^22}| |{:^22}|'.format(address[1], '', ''))
+        print(address[0], ('+{:-^%d}+ |{:^%d}| |{:^%d}|' % (max_len, max_len, max_len)).format(address[1], '', ''))
     elif "bl2" in address[2]:
-        print(address[0], '|{:^22}| +{:-^22}+ |{:^22}|'.format('', address[1], ''))
+        print(address[0], ('|{:^%d}| +{:-^%d}+ |{:^%d}|' % (max_len, max_len, max_len)).format('', address[1], ''))
     elif "bl31" in address[2]:
-        print(address[0], '|{:^22}| |{:^22}| +{:-^22}+'.format('', '', address[1]))
+        print(address[0], ('|{:^%d}| |{:^%d}| +{:-^%d}+' % (max_len, max_len, max_len)).format('', '', address[1]))
     else:
-        print(address[0], '|{:^22}| |{:^22}| +{:-^22}+'.format('', '', address[1]))
+        print(address[0], ('|{:^%d}| |{:^%d}| +{:-^%d}+' % (max_len, max_len, max_len)).format('', '', address[1]))
 
-print('{:^20}{:_^22}   {:_^22}   {:_^22}'.format('', '', '', ''))
-print('{:^20}{:^22}   {:^22}   {:^22}'.format('address', 'bl1', 'bl2', 'bl31'))
+print(('{:^20}{:_^%d}   {:_^%d}   {:_^%d}' % (max_len, max_len, max_len)).format('', '', '', ''))
+print(('{:^20}{:^%d}   {:^%d}   {:^%d}' % (max_len, max_len, max_len)).format('address', 'bl1', 'bl2', 'bl31'))
diff --git a/tools/nxp/create_pbl/create_pbl.c b/tools/nxp/create_pbl/create_pbl.c
index 244b0fb..9457a00 100644
--- a/tools/nxp/create_pbl/create_pbl.c
+++ b/tools/nxp/create_pbl/create_pbl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 NXP
+ * Copyright 2021-2022 NXP
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -507,7 +507,9 @@
 		}
 	}
 
-	printf("\nBoot Location Pointer= %x\n", BYTE_SWAP_32(pblimg.ep));
+	printf("\nBoot Location Pointer= 0x%x\n",
+	       pblimg.chassis == CHASSIS_2 ? BYTE_SWAP_32(pblimg.ep) :
+	       pblimg.ep);
 	ret = SUCCESS;
 
 bootptr_err:
diff --git a/tools/nxp/create_pbl/pbl_ch3.mk b/tools/nxp/create_pbl/pbl_ch3.mk
index e9dbfb0..9283474 100644
--- a/tools/nxp/create_pbl/pbl_ch3.mk
+++ b/tools/nxp/create_pbl/pbl_ch3.mk
@@ -1,5 +1,5 @@
 #
-# Copyright 2018-2020 NXP
+# Copyright 2018-2022 NXP
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -63,7 +63,7 @@
 	-o ${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl -f ${BL2_SRC_OFFSET};
 
 	# Append the bl2.bin to the RCW image
-	@echo "bl2_loc is ${bl2_offset}"
+	@echo "bl2_loc is ${bl2_loc} KB"
 	dd if=${BUILD_PLAT}/bl2.bin of=${BUILD_PLAT}/bl2_${BOOT_MODE}.pbl bs=1K seek=${bl2_loc}
 
 	cd ${CREATE_PBL_TOOL_PATH}; ${MAKE} clean ; cd -;
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index 6b1f204..82d5c1b 100755
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -13,8 +13,9 @@
 This script parses the layout file and generates a make file which updates
 FDT_SOURCES, FIP_ARGS, CRT_ARGS and SPTOOL_ARGS which are used in later build
 steps.
-This script also gets SP "uuid" from parsing its PM and converting it to a
-standard format.
+If the SP entry in the layout file has a "uuid" field the scripts gets the UUID
+from there, otherwise it parses the associated partition manifest and extracts
+the UUID from there.
 
 param1: Generated mk file "sp_gen.mk"
 param2: "SP_LAYOUT_FILE", json file containing platform provided information
@@ -37,7 +38,8 @@
 
         "SP2" : {
                 "image": "sp2.bin",
-                "pm": "test/sp2.dts"
+                "pm": "test/sp2.dts",
+                "uuid": "1b1820fe-48f7-4175-8999-d51da00b7c9f"
         }
 
         ...
@@ -106,35 +108,41 @@
         src = [ json_dir + "/" + data[key]['image'] , dtb  ]
         out_file.write("SPTOOL_ARGS += -i " + ":".join(src) + " -o " + dst + "\n")
 
-        """
-        Extract uuid from partition manifest
-        """
-        pm_file = open(dts)
-        for line in pm_file:
-            if "uuid" in line:
-                # re.findall returns a list of string tuples.
-                # uuid_hex is the first item in this list representing the four
-                # uuid hex integers from the manifest uuid field. The heading
-                # '0x' of the hexadecimal representation is stripped out.
-                # e.g. uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
-                # uuid_hex = ('1e67b5b4', 'e14f904a', '13fb1fb8', 'cbdae1da')
-                uuid_hex = re.findall(r'0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+)', line)[0];
+        if "uuid" in data[key]:
+            """
+            Extract the UUID from the JSON file if the SP entry has a 'uuid' field
+            """
+            uuid_std = uuid.UUID(data[key]['uuid'])
+        else:
+            """
+            Extract uuid from partition manifest
+            """
+            pm_file = open(dts)
+            for line in pm_file:
+                if "uuid" in line:
+                    # re.findall returns a list of string tuples.
+                    # uuid_hex is the first item in this list representing the four
+                    # uuid hex integers from the manifest uuid field. The heading
+                    # '0x' of the hexadecimal representation is stripped out.
+                    # e.g. uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
+                    # uuid_hex = ('1e67b5b4', 'e14f904a', '13fb1fb8', 'cbdae1da')
+                    uuid_hex = re.findall(r'0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+)', line)[0];
 
-        # uuid_hex is a list of four hex string values
-        if len(uuid_hex) != 4:
-            print("ERROR: malformed UUID")
-            exit(-1)
+            # uuid_hex is a list of four hex string values
+            if len(uuid_hex) != 4:
+                print("ERROR: malformed UUID")
+                exit(-1)
 
-        # The uuid field in SP manifest is the little endian representation
-        # mapped to arguments as described in SMCCC section 5.3.
-        # Convert each unsigned integer value to a big endian representation
-        # required by fiptool.
-        y=list(map(bytearray.fromhex, uuid_hex))
-        z=(int.from_bytes(y[0], byteorder='little', signed=False),
-        int.from_bytes(y[1], byteorder='little', signed=False),
-        int.from_bytes(y[2], byteorder='little', signed=False),
-        int.from_bytes(y[3], byteorder='little', signed=False))
-        uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
+            # The uuid field in SP manifest is the little endian representation
+            # mapped to arguments as described in SMCCC section 5.3.
+            # Convert each unsigned integer value to a big endian representation
+            # required by fiptool.
+            y=list(map(bytearray.fromhex, uuid_hex))
+            z=(int.from_bytes(y[0], byteorder='little', signed=False),
+            int.from_bytes(y[1], byteorder='little', signed=False),
+            int.from_bytes(y[2], byteorder='little', signed=False),
+            int.from_bytes(y[3], byteorder='little', signed=False))
+            uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
 
         """
         Append FIP_ARGS