Merge changes I80316689,I23cac4fb,If911e7de,I169ff358,I4e040cd5, ... into integration

* changes:
  ddr: a80x0: add DDR 32-bit ECC mode support
  ble: ap807: improve PLL configuration sequence
  ble: ap807: clean-up PLL configuration sequence
  ddr: a80x0: add DDR 32-bit mode support
  plat: marvell: mci: perform mci link tuning for all mci interfaces
  plat: marvell: mci: use more meaningful name for mci link tuning
  plat: marvell: a8k: remove wrong or unnecessary comments
  plat: marvell: ap807: enable snoop filter for ap807
  plat: marvell: ap807: update configuration space of each CP
  plat: marvell: ap807: use correct address for MCIx4 register
  plat: marvell: add support for PLL 2.2GHz mode
  plat: marvell: armada: make a8k_common.mk and mss_common.mk more generic
  marvell: armada: add extra level in marvell platform hierarchy
diff --git a/Makefile b/Makefile
index 2f53cdf..bc5604b 100644
--- a/Makefile
+++ b/Makefile
@@ -889,6 +889,7 @@
 $(eval $(call assert_boolean,USE_DEBUGFS))
 $(eval $(call assert_boolean,ARM_IO_IN_DTB))
 $(eval $(call assert_boolean,SDEI_IN_FCONF))
+$(eval $(call assert_boolean,SEC_INT_DESC_IN_FCONF))
 $(eval $(call assert_boolean,USE_ROMLIB))
 $(eval $(call assert_boolean,USE_TBBR_DEFS))
 $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -899,6 +900,7 @@
 $(eval $(call assert_boolean,ENCRYPT_BL31))
 $(eval $(call assert_boolean,ENCRYPT_BL32))
 $(eval $(call assert_boolean,ERRATA_SPECULATIVE_AT))
+$(eval $(call assert_boolean,RAS_TRAP_LOWER_EL_ERR_ACCESS))
 
 $(eval $(call assert_numeric,ARM_ARCH_MAJOR))
 $(eval $(call assert_numeric,ARM_ARCH_MINOR))
@@ -969,6 +971,7 @@
 $(eval $(call add_define,USE_DEBUGFS))
 $(eval $(call add_define,ARM_IO_IN_DTB))
 $(eval $(call add_define,SDEI_IN_FCONF))
+$(eval $(call add_define,SEC_INT_DESC_IN_FCONF))
 $(eval $(call add_define,USE_ROMLIB))
 $(eval $(call add_define,USE_TBBR_DEFS))
 $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -977,6 +980,7 @@
 $(eval $(call add_define,BL2_INV_DCACHE))
 $(eval $(call add_define,USE_SPINLOCK_CAS))
 $(eval $(call add_define,ERRATA_SPECULATIVE_AT))
+$(eval $(call add_define,RAS_TRAP_LOWER_EL_ERR_ACCESS))
 
 ifeq (${SANITIZE_UB},trap)
         $(eval $(call add_define,MONITOR_TRAPS))
@@ -1010,6 +1014,7 @@
         endif
         -include $(BUILD_PLAT)/sp_gen.mk
         FIP_DEPS += sp
+        CRT_DEPS += sp
         NEED_SP_PKG := yes
 else
         ifeq (${SPMD_SPM_AT_SEL2},1)
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 9d298d0..bf29186 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -43,6 +43,8 @@
 :G: `laurenw-arm`_
 :M: Madhukar Pappireddy <Madhukar.Pappireddy@arm.com>
 :G: `madhukar-Arm`_
+:M: Raghu Krishnamurthy <raghu.ncstate@icloud.com>
+:G: `raghuncstate`_
 
 
 .. _code owners:
@@ -610,6 +612,7 @@
 .. _J-Alves: https://github.com/J-Alves
 .. _madhukar-Arm: https://github.com/madhukar-Arm
 .. _john-powell-arm: https://github.com/john-powell-arm
+.. _raghuncstate: https://github.com/raghuncstate
 
 
 .. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
diff --git a/docs/components/ras.rst b/docs/components/ras.rst
index 3d81f17..86529d7 100644
--- a/docs/components/ras.rst
+++ b/docs/components/ras.rst
@@ -32,7 +32,8 @@
 
 The build option ``RAS_EXTENSION`` when set to ``1`` includes the RAS in run
 time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST`` must also
-be set ``1``.
+be set ``1``. ``RAS_TRAP_LOWER_EL_ERR_ACCESS`` controls the access to the RAS
+error record registers from lower ELs.
 
 .. _ras-figure:
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index c863079..f207886 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -651,6 +651,12 @@
    than static C structures at compile time. This is currently an experimental
    feature and is only supported if SDEI_SUPPORT build flag is enabled.
 
+-  ``SEC_INT_DESC_IN_FCONF``: This flag determines whether to configure Group 0
+   and Group1 secure interrupts using the firmware configuration framework. The
+   platform specific secure interrupt property descriptor is retrieved from
+   device tree in runtime rather than depending on static C structure at compile
+   time. This is currently an experimental feature.
+
 -  ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
    This feature creates a library of functions to be placed in ROM and thus
    reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default
@@ -701,6 +707,10 @@
    | 1530924 |  Cortex-A53  |
    +---------+--------------+
 
+- ``RAS_TRAP_LOWER_EL_ERR_ACCESS``: This flag enables/disables the SCR_EL3.TERR
+  bit, to trap access to the RAS ERR and RAS ERX registers from lower ELs.
+  This flag is disabled by default.
+
 GICv3 driver options
 --------------------
 
@@ -711,8 +721,10 @@
 The driver can be configured with the following options set in the platform
 makefile:
 
--  ``GICV3_IMPL``: Selects between GIC-500 and GIC-600 variants of GICv3.
-   This option can take values GIC500 and GIC600 with default set to GIC500.
+-  ``GICV3_SUPPORT_GIC600``: Add support for the GIC-600 variants of GICv3.
+   Enabling this option will add runtime detection support for the
+   GIC-600, so is safe to select even for a GIC500 implementation.
+   This option defaults to 0.
 
 -  ``GICV3_IMPL_GIC600_MULTICHIP``: Selects GIC-600 variant with multichip
    functionality. This option defaults to 0
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index eb7eb00..f23ec28 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -116,7 +116,6 @@
 
 -  ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
 
-   -  ``FVP_GIC600`` : The GIC600 implementation of GICv3 is selected
    -  ``FVP_GICV2`` : The GICv2 only driver is selected
    -  ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
 
diff --git a/drivers/arm/gic/v3/gic600.c b/drivers/arm/gic/v3/gic-x00.c
similarity index 76%
rename from drivers/arm/gic/v3/gic600.c
rename to drivers/arm/gic/v3/gic-x00.c
index 59652da..c1a9f0d 100644
--- a/drivers/arm/gic/v3/gic600.c
+++ b/drivers/arm/gic/v3/gic-x00.c
@@ -5,8 +5,9 @@
  */
 
 /*
- * Driver for GIC-600 specific features. This driver only overrides
- * APIs that are different to those generic ones in GICv3 driver.
+ * Driver for GIC-500 and GIC-600 specific features. This driver only
+ * overrides APIs that are different to those generic ones in GICv3
+ * driver.
  *
  * GIC-600 supports independently power-gating redistributor interface.
  */
@@ -19,7 +20,8 @@
 #include "gicv3_private.h"
 
 /* GIC-600 specific register offsets */
-#define GICR_PWRR	0x24
+#define GICR_PWRR		0x24
+#define IIDR_MODEL_ARM_GIC_600	0x0200043b
 
 /* GICR_PWRR fields */
 #define PWRR_RDPD_SHIFT		0
@@ -39,6 +41,8 @@
 #define PWRR_ON		(0 << PWRR_RDPD_SHIFT)
 #define PWRR_OFF	(1 << PWRR_RDPD_SHIFT)
 
+#if GICV3_SUPPORT_GIC600
+
 /* GIC-600 specific accessor functions */
 static void gicr_write_pwrr(uintptr_t base, unsigned int val)
 {
@@ -93,6 +97,29 @@
 	}
 }
 
+static uintptr_t get_gicr_base(unsigned int proc_num)
+{
+	uintptr_t gicr_base;
+
+	assert(gicv3_driver_data);
+	assert(proc_num < gicv3_driver_data->rdistif_num);
+	assert(gicv3_driver_data->rdistif_base_addrs);
+
+	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+	assert(gicr_base);
+
+	return gicr_base;
+}
+
+static bool gicv3_is_gic600(uintptr_t gicr_base)
+{
+	uint32_t reg = mmio_read_32(gicr_base + GICR_IIDR);
+
+	return (reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600;
+}
+
+#endif
+
 void gicv3_distif_pre_save(unsigned int proc_num)
 {
 	arm_gicv3_distif_pre_save(proc_num);
@@ -103,38 +130,33 @@
 	arm_gicv3_distif_post_restore(proc_num);
 }
 
+
 /*
- * Power off GIC-600 redistributor
+ * Power off GIC-600 redistributor (if configured and detected)
  */
 void gicv3_rdistif_off(unsigned int proc_num)
 {
-	uintptr_t gicr_base;
-
-	assert(gicv3_driver_data);
-	assert(proc_num < gicv3_driver_data->rdistif_num);
-	assert(gicv3_driver_data->rdistif_base_addrs);
-
-	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
-	assert(gicr_base);
+#if GICV3_SUPPORT_GIC600
+	uintptr_t gicr_base = get_gicr_base(proc_num);
 
 	/* Attempt to power redistributor off */
-	gic600_pwr_off(gicr_base);
+	if (gicv3_is_gic600(gicr_base)) {
+		gic600_pwr_off(gicr_base);
+	}
+#endif
 }
 
 /*
- * Power on GIC-600 redistributor
+ * Power on GIC-600 redistributor (if configured and detected)
  */
 void gicv3_rdistif_on(unsigned int proc_num)
 {
-	uintptr_t gicr_base;
-
-	assert(gicv3_driver_data);
-	assert(proc_num < gicv3_driver_data->rdistif_num);
-	assert(gicv3_driver_data->rdistif_base_addrs);
-
-	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
-	assert(gicr_base);
+#if GICV3_SUPPORT_GIC600
+	uintptr_t gicr_base = get_gicr_base(proc_num);
 
 	/* Power redistributor on */
-	gic600_pwr_on(gicr_base);
+	if (gicv3_is_gic600(gicr_base)) {
+		gic600_pwr_on(gicr_base);
+	}
+#endif
 }
diff --git a/drivers/arm/gic/v3/gic500.c b/drivers/arm/gic/v3/gic500.c
deleted file mode 100644
index f03e33f..0000000
--- a/drivers/arm/gic/v3/gic500.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/*
- * Driver for GIC500-specific features. This driver only overrides APIs that are
- * different to those generic ones in GICv3 driver.
- */
-#include "gicv3_private.h"
-
-void gicv3_distif_pre_save(unsigned int proc_num)
-{
-	arm_gicv3_distif_pre_save(proc_num);
-}
-
-void gicv3_distif_post_restore(unsigned int proc_num)
-{
-	arm_gicv3_distif_post_restore(proc_num);
-}
-
diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk
index 0f40103..a2fc16f 100644
--- a/drivers/arm/gic/v3/gicv3.mk
+++ b/drivers/arm/gic/v3/gicv3.mk
@@ -5,7 +5,7 @@
 #
 
 # Default configuration values
-GICV3_IMPL			?=	GIC500
+GICV3_SUPPORT_GIC600		?=	0
 GICV3_IMPL_GIC600_MULTICHIP	?=	0
 GICV3_OVERRIDE_DISTIF_PWR_OPS	?=	0
 GIC_ENABLE_V4_EXTN		?=	0
@@ -20,19 +20,14 @@
 GICV3_SOURCES	+=	drivers/arm/gic/v3/arm_gicv3_common.c
 endif
 
-# Either GIC-600 or GIC-500 can be selected at one time
-ifeq (${GICV3_IMPL}, GIC600)
-# GIC-600 sources
-GICV3_SOURCES	+=	drivers/arm/gic/v3/gic600.c
+GICV3_SOURCES	+=	drivers/arm/gic/v3/gic-x00.c
 ifeq (${GICV3_IMPL_GIC600_MULTICHIP}, 1)
 GICV3_SOURCES	+=	drivers/arm/gic/v3/gic600_multichip.c
 endif
-else ifeq (${GICV3_IMPL}, GIC500)
-# GIC-500 sources
-GICV3_SOURCES	+=	drivers/arm/gic/v3/gic500.c
-else
-$(error "Incorrect GICV3_IMPL value ${GICV3_IMPL}")
-endif
+
+# Set GIC-600 support
+$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600))
+$(eval $(call add_define,GICV3_SUPPORT_GIC600))
 
 # Set GICv4 extension
 $(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN))
diff --git a/drivers/auth/dualroot/cot.c b/drivers/auth/dualroot/cot.c
index 8aca2be..f28ddaa 100644
--- a/drivers/auth/dualroot/cot.c
+++ b/drivers/auth/dualroot/cot.c
@@ -30,6 +30,9 @@
 static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
+#if defined(SPD_spmd)
+static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
+#endif /* SPD_spmd */
 
 static unsigned char trusted_world_pk_buf[PK_DER_LEN];
 static unsigned char content_pk_buf[PK_DER_LEN];
@@ -97,6 +100,24 @@
 		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
 static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
+#if defined(SPD_spmd)
+static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
+static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
+static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
+static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
+static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
+static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
+static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
+static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
+#endif /* SPD_spmd */
 #endif /* IMAGE_BL2 */
 
 
@@ -642,6 +663,102 @@
 	}
 };
 
+/*
+ * Secure Partitions
+ */
+#if defined(SPD_spmd)
+static const auth_img_desc_t sp_content_cert = {
+	.img_id = SP_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &sp_pkg1_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[0],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &sp_pkg2_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[1],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &sp_pkg3_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[2],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[3] = {
+			.type_desc = &sp_pkg4_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[3],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[4] = {
+			.type_desc = &sp_pkg5_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[4],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[5] = {
+			.type_desc = &sp_pkg6_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[5],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[6] = {
+			.type_desc = &sp_pkg7_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[6],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[7] = {
+			.type_desc = &sp_pkg8_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[7],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+DEFINE_SP_PKG(1);
+DEFINE_SP_PKG(2);
+DEFINE_SP_PKG(3);
+DEFINE_SP_PKG(4);
+DEFINE_SP_PKG(5);
+DEFINE_SP_PKG(6);
+DEFINE_SP_PKG(7);
+DEFINE_SP_PKG(8);
+#endif /* SPD_spmd */
+
 #else  /* IMAGE_BL2 */
 
 /* FWU auth descriptor */
@@ -769,6 +886,17 @@
 	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
 	[BL33_IMAGE_ID]				=	&bl33_image,
 	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
+#if defined(SPD_spmd)
+	[SP_CONTENT_CERT_ID]			=	&sp_content_cert,
+	[SP_CONTENT_CERT_ID + 1]		=	&sp_pkg1,
+	[SP_CONTENT_CERT_ID + 2]		=	&sp_pkg2,
+	[SP_CONTENT_CERT_ID + 3]		=	&sp_pkg3,
+	[SP_CONTENT_CERT_ID + 4]		=	&sp_pkg4,
+	[SP_CONTENT_CERT_ID + 5]		=	&sp_pkg5,
+	[SP_CONTENT_CERT_ID + 6]		=	&sp_pkg6,
+	[SP_CONTENT_CERT_ID + 7]		=	&sp_pkg7,
+	[SP_CONTENT_CERT_ID + 8]		=       &sp_pkg8,
+#endif
 };
 #endif
 
diff --git a/drivers/auth/tbbr/tbbr_cot_bl2.c b/drivers/auth/tbbr/tbbr_cot_bl2.c
index c47bf1a..63c18fa 100644
--- a/drivers/auth/tbbr/tbbr_cot_bl2.c
+++ b/drivers/auth/tbbr/tbbr_cot_bl2.c
@@ -27,6 +27,9 @@
 static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
 static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
+#if defined(SPD_spmd)
+static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
+#endif /* SPD_spmd */
 
 static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
@@ -60,6 +63,24 @@
 		AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
 static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
+#if defined(SPD_spmd)
+static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
+static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
+static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
+static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
+static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
+static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
+static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
+static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
+#endif /* SPD_spmd */
 
 /*
  * Trusted key certificate
@@ -535,6 +556,99 @@
 		}
 	}
 };
+/* Secure Partitions */
+#if defined(SPD_spmd)
+static const auth_img_desc_t sp_content_cert = {
+	.img_id = SP_CONTENT_CERT_ID,
+	.img_type = IMG_CERT,
+	.parent = &trusted_key_cert,
+	.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+		[0] = {
+			.type = AUTH_METHOD_SIG,
+			.param.sig = {
+				.pk = &trusted_world_pk,
+				.sig = &sig,
+				.alg = &sig_alg,
+				.data = &raw_data
+			}
+		},
+		[1] = {
+			.type = AUTH_METHOD_NV_CTR,
+			.param.nv_ctr = {
+				.cert_nv_ctr = &trusted_nv_ctr,
+				.plat_nv_ctr = &trusted_nv_ctr
+			}
+		}
+	},
+	.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+		[0] = {
+			.type_desc = &sp_pkg1_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[0],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[1] = {
+			.type_desc = &sp_pkg2_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[1],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[2] = {
+			.type_desc = &sp_pkg3_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[2],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[3] = {
+			.type_desc = &sp_pkg4_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[3],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[4] = {
+			.type_desc = &sp_pkg5_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[4],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[5] = {
+			.type_desc = &sp_pkg6_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[5],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[6] = {
+			.type_desc = &sp_pkg7_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[6],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		},
+		[7] = {
+			.type_desc = &sp_pkg8_hash,
+			.data = {
+				.ptr = (void *)sp_pkg_hash_buf[7],
+				.len = (unsigned int)HASH_DER_LEN
+			}
+		}
+	}
+};
+
+DEFINE_SP_PKG(1);
+DEFINE_SP_PKG(2);
+DEFINE_SP_PKG(3);
+DEFINE_SP_PKG(4);
+DEFINE_SP_PKG(5);
+DEFINE_SP_PKG(6);
+DEFINE_SP_PKG(7);
+DEFINE_SP_PKG(8);
+#endif /* SPD_spmd */
 
 static const auth_img_desc_t * const cot_desc[] = {
 	[TRUSTED_BOOT_FW_CERT_ID]		=	&trusted_boot_fw_cert,
@@ -557,6 +671,17 @@
 	[NON_TRUSTED_FW_CONTENT_CERT_ID]	=	&non_trusted_fw_content_cert,
 	[BL33_IMAGE_ID]				=	&bl33_image,
 	[NT_FW_CONFIG_ID]			=	&nt_fw_config,
+#if defined(SPD_spmd)
+	[SP_CONTENT_CERT_ID]			=	&sp_content_cert,
+	[SP_CONTENT_CERT_ID + 1]		=	&sp_pkg1,
+	[SP_CONTENT_CERT_ID + 2]		=	&sp_pkg2,
+	[SP_CONTENT_CERT_ID + 3]		=	&sp_pkg3,
+	[SP_CONTENT_CERT_ID + 4]		=	&sp_pkg4,
+	[SP_CONTENT_CERT_ID + 5]		=	&sp_pkg5,
+	[SP_CONTENT_CERT_ID + 6]		=	&sp_pkg6,
+	[SP_CONTENT_CERT_ID + 7]		=	&sp_pkg7,
+	[SP_CONTENT_CERT_ID + 8]		=       &sp_pkg8,
+#endif
 };
 
 /* Register the CoT in the authentication module */
diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi
index 0deb8a2..192f574 100644
--- a/fdts/fvp-base-gicv3-psci-common.dtsi
+++ b/fdts/fvp-base-gicv3-psci-common.dtsi
@@ -6,6 +6,11 @@
 
 #include <services/sdei_flags.h>
 
+#define LEVEL	0
+#define EDGE	2
+#define SDEI_NORMAL	0x70
+#define HIGHEST_SEC	0
+
 /memreserve/ 0x80000000 0x00010000;
 
 / {
@@ -38,8 +43,9 @@
 		max-pwr-lvl = <2>;
 	};
 
-#if SDEI_IN_FCONF
+#if SDEI_IN_FCONF || SEC_INT_DESC_IN_FCONF
 	firmware {
+#if SDEI_IN_FCONF
 		sdei {
 			compatible = "arm,sdei-1.0";
 			method = "smc";
@@ -59,9 +65,38 @@
 						<2001 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>,
 						<2002 SDEI_DYN_IRQ SDEI_MAPF_DYNAMIC>;
 		};
-	};
 #endif /* SDEI_IN_FCONF */
 
+#if SEC_INT_DESC_IN_FCONF
+		sec_interrupts {
+			compatible = "arm,secure_interrupt_desc";
+			/* Number of G0 and G1 secure interrupts defined by the platform */
+			g0_intr_cnt = <2>;
+			g1s_intr_cnt = <9>;
+			/*
+			 * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+			 * terminology. Each interrupt property descriptor has 3 fields:
+			 * 1. Interrupt number
+			 * 2. Interrupt priority
+			 * 3. Type of interrupt (Edge or Level configured)
+			 */
+			g0_intr_desc =	< 8 SDEI_NORMAL EDGE>,
+					<14 HIGHEST_SEC EDGE>;
+
+			g1s_intr_desc =	< 9 HIGHEST_SEC EDGE>,
+					<10 HIGHEST_SEC EDGE>,
+					<11 HIGHEST_SEC EDGE>,
+					<12 HIGHEST_SEC EDGE>,
+					<13 HIGHEST_SEC EDGE>,
+					<15 HIGHEST_SEC EDGE>,
+					<29 HIGHEST_SEC LEVEL>,
+					<56 HIGHEST_SEC LEVEL>,
+					<57 HIGHEST_SEC LEVEL>;
+		};
+#endif /* SEC_INT_DESC_IN_FCONF */
+	};
+#endif /* SDEI_IN_FCONF || SEC_INT_DESC_IN_FCONF */
+
 	cpus {
 		#address-cells = <2>;
 		#size-cells = <0>;
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 10fe926..90569c3 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -342,6 +342,7 @@
 #define SCR_EEL2_BIT		(U(1) << 18)
 #define SCR_API_BIT		(U(1) << 17)
 #define SCR_APK_BIT		(U(1) << 16)
+#define SCR_TERR_BIT		(U(1) << 15)
 #define SCR_TWE_BIT		(U(1) << 13)
 #define SCR_TWI_BIT		(U(1) << 12)
 #define SCR_ST_BIT		(U(1) << 11)
diff --git a/include/common/tbbr/cot_def.h b/include/common/tbbr/cot_def.h
index c411146..6ce7f80 100644
--- a/include/common/tbbr/cot_def.h
+++ b/include/common/tbbr/cot_def.h
@@ -8,8 +8,11 @@
 #define COT_DEF_H
 
 /* TBBR CoT definitions */
-
+#if defined(SPD_spmd)
+#define COT_MAX_VERIFIED_PARAMS		8
+#else
 #define COT_MAX_VERIFIED_PARAMS		4
+#endif
 
 /*
  * Maximum key and hash sizes (in DER format).
diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h
index 1701995..1f9aab1 100644
--- a/include/common/tbbr/tbbr_img_def.h
+++ b/include/common/tbbr/tbbr_img_def.h
@@ -9,4 +9,12 @@
 
 #include <export/common/tbbr/tbbr_img_def_exp.h>
 
+#if defined(SPD_spmd)
+#define SP_CONTENT_CERT_ID		MAX_IMAGE_IDS
+#define MAX_SP_IDS			U(8)
+#define MAX_NUMBER_IDS			(MAX_IMAGE_IDS + MAX_SP_IDS + U(1))
+#else
+#define MAX_NUMBER_IDS			MAX_IMAGE_IDS
+#endif
+
 #endif /* TBBR_IMG_DEF_H */
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 03596b9..77dc350 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -222,6 +222,14 @@
 #define TYPER_PPI_NUM_SHIFT	U(27)
 #define TYPER_PPI_NUM_MASK	U(0x1f)
 
+/* GICR_IIDR bit definitions */
+#define IIDR_PRODUCT_ID_MASK	0xff000000
+#define IIDR_VARIANT_MASK	0x000f0000
+#define IIDR_REVISION_MASK	0x0000f000
+#define IIDR_IMPLEMENTER_MASK	0x00000fff
+#define IIDR_MODEL_MASK		(IIDR_PRODUCT_ID_MASK | \
+				 IIDR_IMPLEMENTER_MASK)
+
 /*******************************************************************************
  * GICv3 and 3.1 CPU interface registers & constants
  ******************************************************************************/
diff --git a/include/drivers/auth/auth_mod.h b/include/drivers/auth/auth_mod.h
index 1dc9ff4..01d144d 100644
--- a/include/drivers/auth/auth_mod.h
+++ b/include/drivers/auth/auth_mod.h
@@ -50,6 +50,24 @@
 extern const size_t cot_desc_size;
 extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
 
+#if defined(SPD_spmd)
+#define DEFINE_SP_PKG(n) \
+	static const auth_img_desc_t sp_pkg##n = { \
+		.img_id = SP_CONTENT_CERT_ID + (n), \
+		.img_type = IMG_RAW, \
+		.parent = &sp_content_cert, \
+		.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { \
+			[0] = { \
+				.type = AUTH_METHOD_HASH, \
+				.param.hash = { \
+					.data = &raw_data, \
+					.hash = &sp_pkg##n##_hash \
+				} \
+			} \
+		} \
+	}
+#endif
+
 #endif /* TRUSTED_BOARD_BOOT */
 
 #endif /* AUTH_MOD_H */
diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h
index 89dbc58..a98c1b4 100644
--- a/include/export/common/tbbr/tbbr_img_def_exp.h
+++ b/include/export/common/tbbr/tbbr_img_def_exp.h
@@ -88,12 +88,7 @@
 /* Encrypted image identifier */
 #define ENC_IMAGE_ID			U(30)
 
-/* Define size of the array */
-#if defined(SPD_spmd)
-#define MAX_SP_IDS			U(8)
-#define MAX_NUMBER_IDS			MAX_SP_IDS + U(31)
-#else
-#define MAX_NUMBER_IDS			U(31)
-#endif
+/* Max Images */
+#define MAX_IMAGE_IDS			U(31)
 
 #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */
diff --git a/include/lib/extensions/ras.h b/include/lib/extensions/ras.h
index 4fc8f04..793ab9f 100644
--- a/include/lib/extensions/ras.h
+++ b/include/lib/extensions/ras.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -192,6 +193,7 @@
 			probe_data);
 }
 
+const char *ras_serr_to_str(unsigned int serr);
 int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
 		void *handle, uint64_t flags);
 void ras_init(void);
diff --git a/include/lib/extensions/ras_arch.h b/include/lib/extensions/ras_arch.h
index 0c98c4a..55760b0 100644
--- a/include/lib/extensions/ras_arch.h
+++ b/include/lib/extensions/ras_arch.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -151,6 +152,9 @@
 #define ERROR_STATUS_SET_UC	0x2     /* Uncontainable */
 #define ERROR_STATUS_SET_CE	0x3     /* Corrected */
 
+/* Number of architecturally-defined primary error codes */
+#define ERROR_STATUS_NUM_SERR	U(22)
+
 /* Implementation Defined Syndrome bit in ESR */
 #define SERROR_IDS_BIT		U(24)
 
diff --git a/include/plat/arm/common/fconf_sec_intr_config.h b/include/plat/arm/common/fconf_sec_intr_config.h
new file mode 100644
index 0000000..5d6b594
--- /dev/null
+++ b/include/plat/arm/common/fconf_sec_intr_config.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FCONF_SEC_INTR_CONFIG_H
+#define FCONF_SEC_INTR_CONFIG_H
+
+#include <lib/fconf/fconf.h>
+
+#include <platform_def.h>
+
+#define hw_config__sec_intr_prop_getter(id)	sec_intr_prop.id
+
+#define SEC_INT_COUNT_MAX U(15)
+
+struct sec_intr_prop_t {
+	interrupt_prop_t descriptor[SEC_INT_COUNT_MAX];
+	uint32_t count;
+};
+
+int fconf_populate_sec_intr_config(uintptr_t config);
+
+extern struct sec_intr_prop_t sec_intr_prop;
+
+#endif /* FCONF_SEC_INTR_CONFIG_H */
diff --git a/include/tools_share/firmware_image_package.h b/include/tools_share/firmware_image_package.h
index 598d5c2..75f3cc6 100644
--- a/include/tools_share/firmware_image_package.h
+++ b/include/tools_share/firmware_image_package.h
@@ -64,6 +64,8 @@
 	{{0xa4,  0x9f, 0x44, 0x11}, {0x5e, 0x63}, {0xe4, 0x11}, 0x87, 0x28, {0x3f, 0x05, 0x72, 0x2a, 0xf3, 0x3d} }
 #define UUID_NON_TRUSTED_FW_CONTENT_CERT \
 	{{0x8e,  0xc4, 0xc1, 0xf3}, {0x5d, 0x63}, {0xe4, 0x11}, 0xa7, 0xa9, {0x87, 0xee, 0x40, 0xb2, 0x3f, 0xa7} }
+#define UUID_SIP_SECURE_PARTITION_CONTENT_CERT \
+	{{0x77,  0x6d, 0xfd, 0x44}, {0x86, 0x97}, {0x4c, 0x3b}, 0x91, 0xeb, {0xc1, 0x3e, 0x02, 0x5a, 0x2a, 0x6f} }
 /* Dynamic configs */
 #define UUID_HW_CONFIG \
 	{{0x08,  0xb8, 0xf1, 0xd9}, {0xc9, 0xcf}, {0x93, 0x49}, 0xa9, 0x62, {0x6f, 0xbc, 0x6b, 0x72, 0x65, 0xcc} }
diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h
index 6bccfdd..24a8f39 100644
--- a/include/tools_share/tbbr_oid.h
+++ b/include/tools_share/tbbr_oid.h
@@ -145,4 +145,16 @@
 /* NonTrustedFirmwareConfigHash - NT_FW_CONFIG */
 #define NON_TRUSTED_FW_CONFIG_HASH_OID		"1.3.6.1.4.1.4128.2100.1202"
 
+/*
+ * Secure Partitions Content Certificate
+ */
+#define SP_PKG1_HASH_OID			"1.3.6.1.4.1.4128.2100.1301"
+#define SP_PKG2_HASH_OID			"1.3.6.1.4.1.4128.2100.1302"
+#define SP_PKG3_HASH_OID			"1.3.6.1.4.1.4128.2100.1303"
+#define SP_PKG4_HASH_OID			"1.3.6.1.4.1.4128.2100.1304"
+#define SP_PKG5_HASH_OID			"1.3.6.1.4.1.4128.2100.1305"
+#define SP_PKG6_HASH_OID			"1.3.6.1.4.1.4128.2100.1306"
+#define SP_PKG7_HASH_OID			"1.3.6.1.4.1.4128.2100.1307"
+#define SP_PKG8_HASH_OID			"1.3.6.1.4.1.4128.2100.1308"
+
 #endif /* TBBR_OID_H */
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index e260f8d..c050b02 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,6 +34,12 @@
 	.macro	apply_workaround
 	stp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
 
+	/* Disable cycle counter when event counting is prohibited */
+	mrs	x1, pmcr_el0
+	orr	x0, x1, #PMCR_EL0_DP_BIT
+	msr	pmcr_el0, x0
+	isb
+
 	/* -------------------------------------------------
 	 * A new write-only system register where a write of
 	 * 1 to bit 0 will cause the indirect branch predictor
diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c
index fc14e70..70ac3bc 100644
--- a/lib/debugfs/devfip.c
+++ b/lib/debugfs/devfip.c
@@ -74,7 +74,8 @@
 	{"tos-fw.cfg",		UUID_TOS_FW_CONFIG},
 	{"nt-fw.cfg",		UUID_NT_FW_CONFIG},
 	{"rot-k.crt",		UUID_ROT_KEY_CERT},
-	{"nt-k.crt",		UUID_NON_TRUSTED_WORLD_KEY_CERT}
+	{"nt-k.crt",		UUID_NON_TRUSTED_WORLD_KEY_CERT},
+	{"sip-sp.crt",		UUID_SIP_SECURE_PARTITION_CONTENT_CERT}
 };
 
 /*******************************************************************************
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 53b4ea3..f4a34bf 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -108,6 +108,14 @@
 	if (EP_GET_ST(ep->h.attr) != 0U)
 		scr_el3 |= SCR_ST_BIT;
 
+#if RAS_TRAP_LOWER_EL_ERR_ACCESS
+	/*
+	 * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR
+	 * and RAS ERX registers from EL1 and EL2 are trapped to EL3.
+	 */
+	scr_el3 |= SCR_TERR_BIT;
+#endif
+
 #if !HANDLE_EA_EL3_FIRST
 	/*
 	 * SCR_EL3.EA: Do not route External Abort and SError Interrupt External
diff --git a/lib/extensions/ras/ras_common.c b/lib/extensions/ras/ras_common.c
index 64a4852..36f9a95 100644
--- a/lib/extensions/ras/ras_common.c
+++ b/lib/extensions/ras/ras_common.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,6 +19,47 @@
 # error Platform must define RAS priority value
 #endif
 
+/*
+ * Function to convert architecturally-defined primary error code SERR,
+ * bits[7:0] from ERR<n>STATUS to its corresponding error string.
+ */
+const char *ras_serr_to_str(unsigned int serr)
+{
+	const char *str[ERROR_STATUS_NUM_SERR] = {
+		"No error",
+		"IMPLEMENTATION DEFINED error",
+		"Data value from (non-associative) internal memory",
+		"IMPLEMENTATION DEFINED pin",
+		"Assertion failure",
+		"Error detected on internal data path",
+		"Data value from associative memory",
+		"Address/control value from associative memory",
+		"Data value from a TLB",
+		"Address/control value from a TLB",
+		"Data value from producer",
+		"Address/control value from producer",
+		"Data value from (non-associative) external memory",
+		"Illegal address (software fault)",
+		"Illegal access (software fault)",
+		"Illegal state (software fault)",
+		"Internal data register",
+		"Internal control register",
+		"Error response from slave",
+		"External timeout",
+		"Internal timeout",
+		"Deferred error from slave not supported at master"
+	};
+
+	/*
+	 * All other values are reserved. Reserved values might be defined
+	 * in a future version of the architecture
+	 */
+	if (serr >= ERROR_STATUS_NUM_SERR)
+		return "unknown SERR";
+
+	return str[serr];
+}
+
 /* Handler that receives External Aborts on RAS-capable systems */
 int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
 		void *handle, uint64_t flags)
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index e5880d2..6db228f 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -226,7 +226,10 @@
 ARM_IO_IN_DTB			:= 0
 
 # Build option to support SDEI through fconf
-SDEI_IN_FCONF			:=0
+SDEI_IN_FCONF			:= 0
+
+# Build option to support Secure Interrupt descriptors through fconf
+SEC_INT_DESC_IN_FCONF		:= 0
 
 # Build option to choose whether Trusted Firmware uses library at ROM
 USE_ROMLIB			:= 0
@@ -299,3 +302,6 @@
 
 # Select workaround for AT speculative behaviour.
 ERRATA_SPECULATIVE_AT           := 0
+
+# Trap RAS error record access from lower EL
+RAS_TRAP_LOWER_EL_ERR_ACCESS	:= 0
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index f0adfe1..9520934 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -99,3 +99,8 @@
     $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/nt_fw_key.crt,--nt-fw-key-cert))
 endif
 endif
+
+# Add SiP owned Secure Partitions CoT (image cert)
+ifneq (${SP_LAYOUT_FILE},)
+    $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/sip_sp_content.crt,--sip-sp-cert))
+endif
diff --git a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
index ff079ab..b9d9053 100644
--- a/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
+++ b/plat/arm/board/a5ds/fdts/a5ds_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 7039a6d..34e50ea 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -70,8 +70,8 @@
 				lib/cpus/aarch64/cortex_a75.S
 endif
 
-# GIC-600 configuration
-GICV3_IMPL		:=	GIC600
+# Allow detection of GIC-600
+GICV3_SUPPORT_GIC600	:=	1
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
index 7c11108..5f89284 100644
--- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts
+++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
@@ -111,6 +111,7 @@
 			soc_fw_content_cert_uuid = <0x200cb2e2 0x11e4635e 0xccabe89c 0x66b62bf9>;
 			tos_fw_content_cert_uuid = <0x11449fa4 0x11e4635e 0x53f2887 0x3df32a72>;
 			nt_fw_content_cert_uuid = <0xf3c1c48e 0x11e4635d 0xee87a9a7 0xa73fb240>;
+			sp_content_cert_uuid = <0x44fd6d77 0x3b4c9786 0x3ec1eb91 0x6f2a5a02>;
 		};
 	};
 #endif /* ARM_IO_IN_DTB */
diff --git a/plat/arm/board/fvp/fvp_gicv3.c b/plat/arm/board/fvp/fvp_gicv3.c
index a3ee8ef..3e04d6b 100644
--- a/plat/arm/board/fvp/fvp_gicv3.c
+++ b/plat/arm/board/fvp/fvp_gicv3.c
@@ -12,6 +12,7 @@
 #include <fconf_hw_config_getter.h>
 #include <lib/utils.h>
 #include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/fconf_sec_intr_config.h>
 #include <plat/common/platform.h>
 
 /* The GICv3 driver only needs to be initialized in EL3 */
@@ -23,10 +24,13 @@
 /* List of zero terminated GICR frame addresses which CPUs will probe */
 static uint64_t *fvp_gicr_frames = fvp_gicr_base_addrs;
 
+#if  !(SEC_INT_DESC_IN_FCONF && ((!defined(__aarch64__) && defined(IMAGE_BL32)) || \
+	(defined(__aarch64__) && defined(IMAGE_BL31))))
 static const interrupt_prop_t fvp_interrupt_props[] = {
 	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
 	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
 };
+#endif
 
 /*
  * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
@@ -52,8 +56,6 @@
 
 
 static gicv3_driver_data_t fvp_gic_data = {
-	.interrupt_props = fvp_interrupt_props,
-	.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props),
 	.rdistif_num = PLATFORM_CORE_COUNT,
 	.rdistif_base_addrs = fvp_rdistif_base_addrs,
 	.mpidr_to_core_pos = fvp_gicv3_mpidr_hash
@@ -61,7 +63,10 @@
 
 void plat_arm_gic_driver_init(void)
 {
-	/* Get GICD and GICR base addressed through FCONF APIs */
+	/*
+	 * Get GICD and GICR base addressed through FCONF APIs.
+	 * FCONF is not supported in BL32 for FVP.
+	 */
 #if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \
 	(defined(__aarch64__) && defined(IMAGE_BL31))
 	fvp_gic_data.gicd_base = (uintptr_t)FCONF_GET_PROPERTY(hw_config,
@@ -69,9 +74,20 @@
 							       gicd_base);
 	fvp_gicr_base_addrs[0] = FCONF_GET_PROPERTY(hw_config, gicv3_config,
 						    gicr_base);
+#if SEC_INT_DESC_IN_FCONF
+	fvp_gic_data.interrupt_props = FCONF_GET_PROPERTY(hw_config,
+					sec_intr_prop, descriptor);
+	fvp_gic_data.interrupt_props_num = FCONF_GET_PROPERTY(hw_config,
+					sec_intr_prop, count);
+#else
+	fvp_gic_data.interrupt_props = fvp_interrupt_props;
+	fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props);
+#endif
 #else
 	fvp_gic_data.gicd_base = PLAT_ARM_GICD_BASE;
 	fvp_gicr_base_addrs[0] = PLAT_ARM_GICR_BASE;
+	fvp_gic_data.interrupt_props = fvp_interrupt_props;
+	fvp_gic_data.interrupt_props_num = ARRAY_SIZE(fvp_interrupt_props);
 #endif
 
 	/*
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 024e682..7d670ac 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -49,13 +49,10 @@
 $(eval $(call add_define,FVP_INTERCONNECT_DRIVER))
 
 # Choose the GIC sources depending upon the how the FVP will be invoked
-ifeq (${FVP_USE_GIC_DRIVER},$(filter ${FVP_USE_GIC_DRIVER},FVP_GICV3 FVP_GIC600))
+ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3)
 
-	# GIC500 is the default option in case GICV3_IMPL is not set
-	ifeq (${FVP_USE_GIC_DRIVER}, FVP_GIC600)
-		GICV3_IMPL	:=	GIC600
-	endif
-
+# The GIC model (GIC-600 or GIC-500) will be detected at runtime
+GICV3_SUPPORT_GIC600		:=	1
 GICV3_OVERRIDE_DISTIF_PWR_OPS	:=	1
 
 # Include GICv3 driver files
@@ -221,6 +218,11 @@
 BL31_SOURCES		+=	common/fdt_wrappers.c				\
 				lib/fconf/fconf.c				\
 				plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+
+ifeq (${SEC_INT_DESC_IN_FCONF},1)
+BL31_SOURCES		+=	plat/arm/common/fconf/fconf_sec_intr_config.c
+endif
+
 endif
 
 ifeq (${FVP_USE_SP804_TIMER},1)
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index ba6ceec..64cb7ad 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -25,6 +25,11 @@
 BL32_SOURCES		+=	common/fdt_wrappers.c				\
 				lib/fconf/fconf.c				\
 				plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+
+ifeq (${SEC_INT_DESC_IN_FCONF},1)
+BL32_SOURCES		+=	plat/arm/common/fconf/fconf_sec_intr_config.c
+endif
+
 endif
 
 include plat/arm/common/sp_min/arm_sp_min.mk
diff --git a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
index 1727e2e..d4f98d9 100644
--- a/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
+++ b/plat/arm/board/fvp_ve/fdts/fvp_ve_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
diff --git a/plat/arm/board/juno/fdts/juno_fw_config.dts b/plat/arm/board/juno/fdts/juno_fw_config.dts
index 4e460aa..60ca60d 100644
--- a/plat/arm/board/juno/fdts/juno_fw_config.dts
+++ b/plat/arm/board/juno/fdts/juno_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 44f7b8a..0bd3a21 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -15,7 +15,7 @@
 N1SDP_CPU_SOURCES	:=	lib/cpus/aarch64/neoverse_n1.S
 
 # GIC-600 configuration
-GICV3_IMPL			:=	GIC600
+GICV3_SUPPORT_GIC600		:=	1
 GICV3_IMPL_GIC600_MULTICHIP	:=	1
 
 # Include GICv3 driver files
diff --git a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts
index bb544a4..b9265ad 100644
--- a/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts
+++ b/plat/arm/board/rddaniel/fdts/rddaniel_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
diff --git a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts
index bb544a4..b9265ad 100644
--- a/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts
+++ b/plat/arm/board/rddanielxlr/fdts/rddanielxlr_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
diff --git a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
index a5b4a58..09b9867 100644
--- a/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
+++ b/plat/arm/board/rde1edge/fdts/rde1edge_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
diff --git a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
index 1f460f1..c9dee60 100644
--- a/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
+++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 / {
@@ -13,7 +13,7 @@
 
 		/* tb_fw_config is temporarily contained on this dtb */
 		tb_fw-config {
-			load-address = <0x0 0x80001010>;
+			load-address = <0x0 0x4001010>;
 			max-size = <0x200>;
 			id = <TB_FW_CONFIG_ID>;
 		};
diff --git a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
index da933e5..94d0e39 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
+++ b/plat/arm/board/sgi575/fdts/sgi575_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
diff --git a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
index 306bd89..c92c1d0 100644
--- a/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
+++ b/plat/arm/board/sgm775/fdts/sgm775_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
diff --git a/plat/arm/board/tc0/fdts/tc0_fw_config.dts b/plat/arm/board/tc0/fdts/tc0_fw_config.dts
index 8d7faf8..8458e08 100644
--- a/plat/arm/board/tc0/fdts/tc0_fw_config.dts
+++ b/plat/arm/board/tc0/fdts/tc0_fw_config.dts
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <export/common/tbbr/tbbr_img_def_exp.h>
+#include <common/tbbr/tbbr_img_def.h>
 
 /dts-v1/;
 
@@ -14,7 +14,7 @@
 
 		/* tb_fw_config is temporarily contained in this dtb */
 		tb_fw-config {
-			load-address = <0x0 0x2001010>;
+			load-address = <0x0 0x4001010>;
 			max-size = <0x200>;
 			id = <TB_FW_CONFIG_ID>;
 		};
diff --git a/plat/arm/board/tc0/platform.mk b/plat/arm/board/tc0/platform.mk
index 265826f..7f514cc 100644
--- a/plat/arm/board/tc0/platform.mk
+++ b/plat/arm/board/tc0/platform.mk
@@ -25,7 +25,8 @@
 GIC_ENABLE_V4_EXTN	:=      1
 
 # GIC-600 configuration
-GICV3_IMPL		:=	GIC600
+GICV3_SUPPORT_GIC600	:=	1
+
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c
index 26e51b2..68cd9fb 100644
--- a/plat/arm/common/fconf/arm_fconf_io.c
+++ b/plat/arm/common/fconf/arm_fconf_io.c
@@ -49,6 +49,9 @@
 	[SOC_FW_CONTENT_CERT_ID] = {UUID_SOC_FW_CONTENT_CERT},
 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {UUID_TRUSTED_OS_FW_CONTENT_CERT},
 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT},
+#if defined(SPD_spmd)
+	[SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT},
+#endif
 #endif /* ARM_IO_IN_DTB */
 #endif /* TRUSTED_BOARD_BOOT */
 };
@@ -174,6 +177,13 @@
 		(uintptr_t)&arm_uuid_spec[NON_TRUSTED_FW_CONTENT_CERT_ID],
 		open_fip
 	},
+#if defined(SPD_spmd)
+	[SP_CONTENT_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&arm_uuid_spec[SP_CONTENT_CERT_ID],
+		open_fip
+	},
+#endif
 #endif /* ARM_IO_IN_DTB */
 #endif /* TRUSTED_BOARD_BOOT */
 };
@@ -181,7 +191,7 @@
 #ifdef IMAGE_BL2
 
 #if TRUSTED_BOARD_BOOT
-#define FCONF_ARM_IO_UUID_NUMBER	U(19)
+#define FCONF_ARM_IO_UUID_NUMBER	U(20)
 #else
 #define FCONF_ARM_IO_UUID_NUMBER	U(10)
 #endif
@@ -216,6 +226,9 @@
 	{SOC_FW_CONTENT_CERT_ID, "soc_fw_content_cert_uuid"},
 	{TRUSTED_OS_FW_CONTENT_CERT_ID, "tos_fw_content_cert_uuid"},
 	{NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"},
+#if defined(SPD_spmd)
+	{SP_CONTENT_CERT_ID, "sp_content_cert_uuid"},
+#endif
 #endif /* TRUSTED_BOARD_BOOT */
 };
 
diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c
index 1b09bc8..64e873e 100644
--- a/plat/arm/common/fconf/arm_fconf_sp.c
+++ b/plat/arm/common/fconf/arm_fconf_sp.c
@@ -30,7 +30,7 @@
 	union uuid_helper_t uuid_helper;
 	unsigned int index = 0;
 	uint32_t val32;
-	const unsigned int sp_start_index = MAX_NUMBER_IDS - MAX_SP_IDS;
+	const unsigned int sp_start_index = SP_CONTENT_CERT_ID + 1;
 
 	/* As libfdt use void *, we can't avoid this cast */
 	const void *dtb = (void *)config;
diff --git a/plat/arm/common/fconf/fconf_sec_intr_config.c b/plat/arm/common/fconf/fconf_sec_intr_config.c
new file mode 100644
index 0000000..f28be24
--- /dev/null
+++ b/plat/arm/common/fconf/fconf_sec_intr_config.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+
+#include <common/debug.h>
+#include <common/fdt_wrappers.h>
+#include <libfdt.h>
+#include <plat/arm/common/fconf_sec_intr_config.h>
+
+#define G0_INTR_NUM(i)		g0_intr_prop[3U * (i)]
+#define G0_INTR_PRIORITY(i)	g0_intr_prop[3U * (i) + 1]
+#define G0_INTR_CONFIG(i)	g0_intr_prop[3U * (i) + 2]
+
+#define G1S_INTR_NUM(i)		g1s_intr_prop[3U * (i)]
+#define G1S_INTR_PRIORITY(i)	g1s_intr_prop[3U * (i) + 1]
+#define G1S_INTR_CONFIG(i)	g1s_intr_prop[3U * (i) + 2]
+
+struct sec_intr_prop_t sec_intr_prop;
+
+static void print_intr_prop(interrupt_prop_t prop)
+{
+	VERBOSE("FCONF: Secure Interrupt NUM: %d, PRI: %d, TYPE: %d\n",
+		prop.intr_num, prop.intr_pri, prop.intr_cfg);
+}
+
+int fconf_populate_sec_intr_config(uintptr_t config)
+{
+	int node, err;
+	uint32_t g0_intr_count, g1s_intr_count;
+	uint32_t g0_intr_prop[SEC_INT_COUNT_MAX * 3];
+	uint32_t g1s_intr_prop[SEC_INT_COUNT_MAX * 3];
+
+	/* Necessary to work with libfdt APIs */
+	const void *hw_config_dtb = (const void *)config;
+
+	node = fdt_node_offset_by_compatible(hw_config_dtb, -1,
+						"arm,secure_interrupt_desc");
+	if (node < 0) {
+		ERROR("FCONF: Unable to locate node with %s compatible property\n",
+						"arm,secure_interrupt_desc");
+		return node;
+	}
+
+	/* Read number of Group 0 interrupts specified by platform */
+	err = fdt_read_uint32(hw_config_dtb, node, "g0_intr_cnt", &g0_intr_count);
+	if (err < 0) {
+		ERROR("FCONF: Could not locate g0s_intr_cnt property\n");
+		return err;
+	}
+
+	/* At least 1 Group 0 interrupt description has to be provided*/
+	if (g0_intr_count < 1U) {
+		ERROR("FCONF: Invalid number of Group 0 interrupts count specified\n");
+		return -1;
+	}
+
+	/* Read number of Group 1 secure interrupts specified by platform */
+	err = fdt_read_uint32(hw_config_dtb, node, "g1s_intr_cnt",
+				&g1s_intr_count);
+	if (err < 0) {
+		ERROR("FCONF: Could not locate g1s_intr_cnt property\n");
+		return err;
+	}
+
+	/* At least one Group 1 interrupt description has to be provided*/
+	if (g1s_intr_count < 1U) {
+		ERROR("FCONF: Invalid number of Group 1 secure interrupts count specified\n");
+		return -1;
+	}
+
+	/*
+	 * Check if the total number of secure interrupts described are within
+	 * the limit defined statically by the platform.
+	 */
+	if ((g0_intr_count + g1s_intr_count) > SEC_INT_COUNT_MAX) {
+		ERROR("FCONF: Total number of secure interrupts exceed limit the of %d\n",
+				SEC_INT_COUNT_MAX);
+		return -1;
+	}
+
+	sec_intr_prop.count = g0_intr_count + g1s_intr_count;
+
+	/* Read the Group 0 interrupt descriptors */
+	err = fdt_read_uint32_array(hw_config_dtb, node, "g0_intr_desc",
+				g0_intr_count * 3, g0_intr_prop);
+	if (err < 0) {
+		ERROR("FCONF: Read cell failed for 'g0s_intr_desc': %d\n", err);
+		return err;
+	}
+
+	/* Read the Group 1 secure interrupt descriptors */
+	err = fdt_read_uint32_array(hw_config_dtb, node, "g1s_intr_desc",
+				g1s_intr_count * 3, g1s_intr_prop);
+	if (err < 0) {
+		ERROR("FCONF: Read cell failed for 'g1s_intr_desc': %d\n", err);
+		return err;
+	}
+
+	/* Populate Group 0 interrupt descriptors into fconf based C struct */
+	for (uint32_t i = 0; i < g0_intr_count; i++) {
+		interrupt_prop_t sec_intr_property;
+
+		/* Secure Interrupt Group: INTR_GROUP0 i.e., 0x1 */
+		sec_intr_property.intr_grp = 1;
+		sec_intr_property.intr_num = G0_INTR_NUM(i);
+		sec_intr_property.intr_pri = G0_INTR_PRIORITY(i);
+		sec_intr_property.intr_cfg = G0_INTR_CONFIG(i);
+		sec_intr_prop.descriptor[i] = sec_intr_property;
+		print_intr_prop(sec_intr_property);
+	}
+
+	/* Populate G1 secure interrupt descriptors into fconf based C struct */
+	for (uint32_t i = 0; i < g1s_intr_count; i++) {
+		interrupt_prop_t sec_intr_property;
+
+		/* Secure Interrupt Group: INTR_GROUP1S i.e., 0x0 */
+		sec_intr_property.intr_grp = 0;
+		sec_intr_property.intr_num = G1S_INTR_NUM(i);
+		sec_intr_property.intr_pri = G1S_INTR_PRIORITY(i);
+		sec_intr_property.intr_cfg = G1S_INTR_CONFIG(i);
+		sec_intr_prop.descriptor[i + g0_intr_count] = sec_intr_property;
+		print_intr_prop(sec_intr_property);
+	}
+
+	return 0;
+}
+
+FCONF_REGISTER_POPULATOR(HW_CONFIG, sec_intr_prop, fconf_populate_sec_intr_config);
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 2504581..6b9e0cd 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -23,7 +23,7 @@
 PLAT_INCLUDES		+=	-I${CSS_ENT_BASE}/include
 
 # GIC-600 configuration
-GICV3_IMPL			:=	GIC600
+GICV3_SUPPORT_GIC600	:=	1
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
index 60e9fb2..5b954f8 100644
--- a/plat/arm/css/sgm/sgm-common.mk
+++ b/plat/arm/css/sgm/sgm-common.mk
@@ -23,7 +23,7 @@
 INTERCONNECT_SOURCES	:=	${CSS_SGM_BASE}/sgm_interconnect.c
 
 # GIC-600 configuration
-GICV3_IMPL		:=	GIC600
+GICV3_SUPPORT_GIC600	:=	1
 
 # Include GICv3 driver files
 include drivers/arm/gic/v3/gicv3.mk
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index a87dea8..f002947 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -15,6 +15,7 @@
 #include <drivers/ti/uart/uart_16550.h>
 #include <lib/xlat_tables/xlat_tables.h>
 
+#include "agilex_mmc.h"
 #include "agilex_clock_manager.h"
 #include "agilex_memory_controller.h"
 #include "agilex_pinmux.h"
@@ -76,6 +77,7 @@
 	socfpga_emac_init();
 	init_hard_memory_controller();
 	mailbox_init();
+	agx_mmc_init();
 
 	if (!intel_mailbox_is_fpga_not_ready())
 		socfpga_bridges_enable();
diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h
index 8af6a60..20667f0 100644
--- a/plat/intel/soc/agilex/include/agilex_clock_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h
@@ -89,6 +89,7 @@
 
 /* Peripheral PLL Macros */
 #define CLKMGR_PERPLL_EN_RESET			0x00000fff
+#define CLKMGR_PERPLL_EN_SDMMCCLK		BIT(5)
 #define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x)	(((x) << 0) & 0x0000ffff)
 
 /* Altera Macros */
diff --git a/plat/intel/soc/agilex/include/agilex_mmc.h b/plat/intel/soc/agilex/include/agilex_mmc.h
new file mode 100644
index 0000000..00f4ca5
--- /dev/null
+++ b/plat/intel/soc/agilex/include/agilex_mmc.h
@@ -0,0 +1,7 @@
+/*
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+void agx_mmc_init(void);
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 0a91c23..8f857d1 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -37,6 +37,7 @@
 		plat/intel/soc/agilex/bl2_plat_setup.c			\
 		plat/intel/soc/agilex/soc/agilex_clock_manager.c	\
 		plat/intel/soc/agilex/soc/agilex_memory_controller.c	\
+		plat/intel/soc/agilex/soc/agilex_mmc.c			\
 		plat/intel/soc/agilex/soc/agilex_pinmux.c		\
                 plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_delay_timer.c		\
diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
index c6c48ba..4efd713 100644
--- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
@@ -47,14 +47,14 @@
 	return 0;
 }
 
-uint32_t pll_source_sync_config(uint32_t pll_mem_offset)
+uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data)
 {
 	uint32_t val = 0;
 	uint32_t count = 0;
 	uint32_t req_status = 0;
 
 	val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ |
-		CLKMGR_MEM_WDAT << CLKMGR_MEM_WDAT_OFFSET | CLKMGR_MEM_ADDR);
+		(data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR);
 	mmio_write_32(pll_mem_offset, val);
 
 	do {
@@ -89,14 +89,17 @@
 	rdata = mmio_read_32(pll_mem_offset + 0x4);
 	INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata);
 
-	return 0;
+	return rdata;
 }
 
 void config_clkmgr_handoff(handoff *hoff_ptr)
 {
 	uint32_t mdiv, mscnt, hscnt;
-	uint32_t arefclk_div, drefclk_div;
+	uint32_t drefclk_div, refclk_div, rdata;
 
+	/* Set clock maanger into boot mode before running configuration */
+	mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_CTRL,
+		CLKMGR_CTRL_BOOTMODE_SET_MSK);
 	/* Bypass all mainpllgrp's clocks */
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0x7);
 	wait_fsm();
@@ -116,26 +119,24 @@
 	/* Setup main PLL dividers */
 	mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->main_pll_pllm);
 
-	arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV(
-			hoff_ptr->main_pll_pllglob);
 	drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV(
 			hoff_ptr->main_pll_pllglob);
+	refclk_div = CLKMGR_PLLGLOB_REFCLKDIV(
+			hoff_ptr->main_pll_pllglob);
 
-	mscnt = 100 / (mdiv / BIT(drefclk_div));
+	mscnt = 100 / (mdiv * BIT(drefclk_div));
 	if (!mscnt)
 		mscnt = 1;
-	hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4;
+	hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4;
 
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB,
-			CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
-			CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
-
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV,
-			hoff_ptr->main_pll_nocdiv);
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
-			hoff_ptr->main_pll_pllglob);
+			hoff_ptr->main_pll_pllglob &
+			~CLKMGR_PLLGLOB_RST_SET_MSK);
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_FDBCK,
 			hoff_ptr->main_pll_fdbck);
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB,
+			CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
+			CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC0,
 			hoff_ptr->main_pll_pllc0);
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC1,
@@ -150,33 +151,33 @@
 			hoff_ptr->main_pll_mpuclk);
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCCLK,
 			hoff_ptr->main_pll_nocclk);
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV,
+			hoff_ptr->main_pll_nocdiv);
 
 	/* Setup peripheral PLL dividers */
 	mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->per_pll_pllm);
 
-	arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV(
-			hoff_ptr->per_pll_pllglob);
 	drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV(
 			hoff_ptr->per_pll_pllglob);
+	refclk_div = CLKMGR_PLLGLOB_REFCLKDIV(
+			hoff_ptr->per_pll_pllglob);
 
-	mscnt = 100 / (mdiv / BIT(drefclk_div));
+
+	mscnt = 100 / (mdiv * BIT(drefclk_div));
 	if (!mscnt)
 		mscnt = 1;
-	hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4;
+	hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4;
+
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
+			hoff_ptr->per_pll_pllglob &
+			~CLKMGR_PLLGLOB_RST_SET_MSK);
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK,
+			hoff_ptr->per_pll_fdbck);
 
 	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_VCOCALIB,
 			CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
 			CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
 
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL,
-			hoff_ptr->per_pll_emacctl);
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV,
-			CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(
-			hoff_ptr->per_pll_gpiodiv));
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
-			hoff_ptr->per_pll_pllglob);
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK,
-			hoff_ptr->per_pll_fdbck);
 	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC0,
 			hoff_ptr->per_pll_pllc0);
 	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC1,
@@ -187,6 +188,10 @@
 			hoff_ptr->per_pll_pllc3);
 	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLM,
 			hoff_ptr->per_pll_pllm);
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL,
+			hoff_ptr->per_pll_emacctl);
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV,
+			hoff_ptr->per_pll_gpiodiv);
 
 	/* Take both PLL out of reset and power up */
 	mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
@@ -196,13 +201,16 @@
 			CLKMGR_PLLGLOB_PD_SET_MSK |
 			CLKMGR_PLLGLOB_RST_SET_MSK);
 
-	wait_pll_lock();
+	rdata = pll_source_sync_read(CLKMGR_MAINPLL +
+		CLKMGR_MAINPLL_MEM);
+	pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM,
+		rdata | 0x80);
 
-	pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM);
-	pll_source_sync_read(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM);
+	rdata = pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM);
+	pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM,
+		rdata | 0x80);
 
-	pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM);
-	pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM);
+	wait_pll_lock();
 
 	/*Configure Ping Pong counters in altera group */
 	mmio_write_32(CLKMGR_ALTERA + CLKMGR_ALTERA_EMACACTR,
@@ -241,7 +249,7 @@
 
 	/* Clear loss lock  interrupt status register that */
 	/* might be set during configuration */
-	mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR,
+	mmio_clrbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR,
 			CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK |
 			CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK);
 
diff --git a/plat/intel/soc/agilex/soc/agilex_mmc.c b/plat/intel/soc/agilex/soc/agilex_mmc.c
new file mode 100644
index 0000000..e05d92a
--- /dev/null
+++ b/plat/intel/soc/agilex/soc/agilex_mmc.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <lib/mmio.h>
+
+#include "socfpga_system_manager.h"
+#include "agilex_clock_manager.h"
+
+void agx_mmc_init(void)
+{
+	mmio_clrbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+		CLKMGR_PERPLL_EN_SDMMCCLK);
+	mmio_write_32(SOCFPGA_SYSMGR(SDMMC),
+		SYSMGR_SDMMC_SMPLSEL(0) | SYSMGR_SDMMC_DRVSEL(3));
+	mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
+		CLKMGR_PERPLL_EN_SDMMCCLK);
+}
diff --git a/plat/intel/soc/agilex/soc/agilex_pinmux.c b/plat/intel/soc/agilex/soc/agilex_pinmux.c
index eff1947..0b908cf 100644
--- a/plat/intel/soc/agilex/soc/agilex_pinmux.c
+++ b/plat/intel/soc/agilex/soc/agilex_pinmux.c
@@ -7,6 +7,7 @@
 #include <lib/mmio.h>
 
 #include "agilex_pinmux.h"
+#include "socfpga_system_manager.h"
 
 const uint32_t sysmgr_pinmux_array_sel[] = {
 	0x00000000, 0x00000001, /* usb */
@@ -185,6 +186,12 @@
 	0x0000011c, 0x00000000
 };
 
+void config_fpgaintf_mod(void)
+{
+	mmio_write_32(SOCFPGA_SYSMGR(FPGAINTF_EN_2), 1<<8);
+}
+
+
 void config_pinmux(handoff *hoff_ptr)
 {
 	unsigned int i;
@@ -213,5 +220,6 @@
 			hoff_ptr->pinmux_iodelay_array[i+1]);
 	}
 
+	config_fpgaintf_mod();
 }
 
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index fce816b..b4fce7b 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -35,14 +35,12 @@
 	uint32_t dir, sf, ret;
 
 	for (dir = 0; dir < subsystem_id.num_directory; dir++) {
-
-		dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR);
-		dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER);
-
 		for (sf = 0; sf < subsystem_id.num_snoop_filter; sf++) {
+			dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR);
+			dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER);
 
 			/* Initialize All Entries */
-			mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(sf));
+			mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(dir));
 
 			/* Poll Active Bit */
 			ret = poll_active_bit(dir);
@@ -52,7 +50,7 @@
 			}
 
 			/* Snoope Filter Enable */
-			mmio_write_32(dir_sf_en, BIT(sf));
+			mmio_setbits_32(dir_sf_en, BIT(sf));
 		}
 	}
 
@@ -64,11 +62,8 @@
 	uint32_t dir, ca, ca_id, ca_type, ca_snoop_en;
 
 	for (dir = 0; dir < subsystem_id.num_directory; dir++) {
-
-		ca_snoop_en = DIRECTORY_UNIT(dir, NCORE_DIRUCASER0);
-
 		for (ca = 0; ca < subsystem_id.num_coh_agent; ca++) {
-
+			ca_snoop_en = DIRECTORY_UNIT(ca, NCORE_DIRUCASER0);
 			ca_id = mmio_read_32(COH_AGENT_UNIT(ca, NCORE_CAIUIDR));
 
 			/* Coh Agent Snoop Enable */
diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h
index 76565bc..8b42d47 100644
--- a/plat/intel/soc/common/include/socfpga_system_manager.h
+++ b/plat/intel/soc/common/include/socfpga_system_manager.h
@@ -13,6 +13,8 @@
 
 #define SOCFPGA_SYSMGR_SDMMC				0x28
 
+#define SOCFPGA_SYSMGR_FPGAINTF_EN_2			0x6c
+
 #define SOCFPGA_SYSMGR_EMAC_0				0x44
 #define SOCFPGA_SYSMGR_EMAC_1				0x48
 #define SOCFPGA_SYSMGR_EMAC_2				0x4c
@@ -32,6 +34,7 @@
 /* Field Masking */
 
 #define SYSMGR_SDMMC_DRVSEL(x)			(((x) & 0x7) << 0)
+#define SYSMGR_SDMMC_SMPLSEL(x)			(((x) & 0x7) << 4)
 
 #define IDLE_DATA_LWSOC2FPGA				BIT(0)
 #define IDLE_DATA_SOC2FPGA				BIT(4)
diff --git a/plat/intel/soc/common/socfpga_delay_timer.c b/plat/intel/soc/common/socfpga_delay_timer.c
index ff8a556..c55cc9d 100644
--- a/plat/intel/soc/common/socfpga_delay_timer.c
+++ b/plat/intel/soc/common/socfpga_delay_timer.c
@@ -36,4 +36,8 @@
 {
 	timer_init(&plat_timer_ops);
 	mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN);
+
+	asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN));
+	asm volatile("msr cntp_tval_el0, %0" : : "r" (~0));
+
 }
diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h
index 678b15c..2331869 100644
--- a/plat/nvidia/tegra/include/platform_def.h
+++ b/plat/nvidia/tegra/include/platform_def.h
@@ -95,6 +95,7 @@
  * Platform macros to support exception handling framework
  ******************************************************************************/
 #define PLAT_PRI_BITS			U(3)
+#define PLAT_RAS_PRI			U(0x10)
 #define PLAT_SDEI_CRITICAL_PRI		U(0x20)
 #define PLAT_SDEI_NORMAL_PRI		U(0x30)
 #define PLAT_TEGRA_WDT_PRIO		U(0x40)
diff --git a/plat/nvidia/tegra/include/t194/tegra194_ras_private.h b/plat/nvidia/tegra/include/t194/tegra194_ras_private.h
new file mode 100644
index 0000000..336461a
--- /dev/null
+++ b/plat/nvidia/tegra/include/t194/tegra194_ras_private.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA194_RAS_PRIVATE
+#define TEGRA194_RAS_PRIVATE
+
+#include <stdint.h>
+
+/* Implementation defined RAS error and corresponding error message */
+struct ras_error {
+	const char *error_msg;
+	/* IERR(bits[15:8]) from ERR<n>STATUS */
+	uint8_t error_code;
+};
+
+/* RAS error node-specific auxiliary data */
+struct ras_aux_data {
+	/* name for current RAS node. */
+	const char *name;
+	/* point to null-terminated ras_error array to convert error code to msg. */
+	const struct ras_error *error_records;
+	/*
+	 * function to return an value which needs to be programmed into ERXCTLR_EL1
+	 * to enable all specified RAS errors for current node.
+	 */
+	uint64_t (*err_ctrl)(void);
+};
+
+/* IFU Uncorrectable RAS ERROR */
+#define IFU_UNCORR_RAS_ERROR_LIST(X)
+
+/* JSR_RET Uncorrectable RAS ERROR */
+#define JSR_RET_UNCORR_RAS_ERROR_LIST(X)					\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(JSR_RET, 35, 0x13, "Floating Point Register File Parity Error")	\
+	X(JSR_RET, 34, 0x12, "Integer Register File Parity Error")		\
+	X(JSR_RET, 33, 0x11, "Garbage Bundle")					\
+	X(JSR_RET, 32, 0x10, "Bundle Completion Timeout")
+
+/* JSR_MTS Uncorrectable RAS ERROR */
+#define JSR_MTS_UNCORR_RAS_ERROR_LIST(X)					\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(JSR_MTS, 40, 0x28, "CoreSight Access Error")				\
+	X(JSR_MTS, 39, 0x27, "Dual Execution Uncorrectable Error")		\
+	X(JSR_MTS, 37, 0x25, "CTU MMIO Region")					\
+	X(JSR_MTS, 36, 0x24, "MTS MMCRAB Region Access")			\
+	X(JSR_MTS, 35, 0x23, "MTS_CARVEOUT Access from ARM SW")			\
+	X(JSR_MTS, 34, 0x22, "NAFLL PLL Failure to Lock")			\
+	X(JSR_MTS, 32, 0x20, "Internal Uncorrectable  MTS Error")
+
+/* LSD_STQ Uncorrectable RAS ERROR */
+#define LSD_STQ_UNCORR_RAS_ERROR_LIST(X)					\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(LSD_STQ, 41, 0x39, "Coherent Cache Data Store Multi-Line ECC Error")	\
+	X(LSD_STQ, 40, 0x38, "Coherent Cache Data Store Uncorrectable ECC Error") \
+	X(LSD_STQ, 38, 0x36, "Coherent Cache Data Load Uncorrectable ECC Error") \
+	X(LSD_STQ, 33, 0x31, "Coherent Cache Tag Store Parity Error")		\
+	X(LSD_STQ, 32, 0x30, "Coherent Cache Tag Load Parity Error")
+
+/* LSD_DCC Uncorrectable RAS ERROR */
+#define LSD_DCC_UNCORR_RAS_ERROR_LIST(X)					\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(LSD_DCC, 41, 0x49, "BTU Copy Mini-Cache PPN Multi-Hit Error")		\
+	X(LSD_DCC, 39, 0x47, "Coherent Cache Data Uncorrectable ECC Error")	\
+	X(LSD_DCC, 37, 0x45, "Version Cache Byte-Enable Parity Error")		\
+	X(LSD_DCC, 36, 0x44, "Version Cache Data Uncorrectable ECC Error")	\
+	X(LSD_DCC, 33, 0x41, "BTU Copy Coherent Cache PPN Parity Error")	\
+	X(LSD_DCC, 32, 0x40, "BTU Copy Coherent Cache VPN Parity Error")
+
+/* LSD_L1HPF Uncorrectable RAS ERROR */
+#define LSD_L1HPF_UNCORR_RAS_ERROR_LIST(X)
+
+/* L2 Uncorrectable RAS ERROR */
+#define L2_UNCORR_RAS_ERROR_LIST(X)						\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(L2, 56, 0x68, "URT Timeout")						\
+	X(L2, 55, 0x67, "L2 Protocol Violation")				\
+	X(L2, 54, 0x66, "SCF to L2 Slave Error Read")				\
+	X(L2, 53, 0x65, "SCF to L2 Slave Error Write")				\
+	X(L2, 52, 0x64, "SCF to L2 Decode Error Read")				\
+	X(L2, 51, 0x63, "SCF to L2 Decode Error Write")				\
+	X(L2, 50, 0x62, "SCF to L2 Request Response Interface Parity Errors")	\
+	X(L2, 49, 0x61, "SCF to L2 Advance notice interface parity errors")	\
+	X(L2, 48, 0x60, "SCF to L2 Filldata Parity Errors")			\
+	X(L2, 47, 0x5F, "SCF to L2 UnCorrectable ECC Data Error on interface")	\
+	X(L2, 45, 0x5D, "Core 1 to L2 Parity Error")				\
+	X(L2, 44, 0x5C, "Core 0 to L2 Parity Error")				\
+	X(L2, 43, 0x5B, "L2 Multi-Hit")						\
+	X(L2, 42, 0x5A, "L2 URT Tag Parity Error")				\
+	X(L2, 41, 0x59, "L2 NTT Tag Parity Error")				\
+	X(L2, 40, 0x58, "L2 MLT Tag Parity Error")				\
+	X(L2, 39, 0x57, "L2 URD Data")						\
+	X(L2, 38, 0x56, "L2 NTP Data")						\
+	X(L2, 36, 0x54, "L2 MLC Uncorrectable Clean")				\
+	X(L2, 35, 0x53, "L2 URD Uncorrectable Dirty")				\
+	X(L2, 34, 0x52, "L2 MLC Uncorrectable Dirty")
+
+/* CLUSTER_CLOCKS Uncorrectable RAS ERROR */
+#define CLUSTER_CLOCKS_UNCORR_RAS_ERROR_LIST(X)					\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(CLUSTER_CLOCKS, 32, 0xE4, "Frequency Monitor Error")
+
+/* MMU Uncorrectable RAS ERROR */
+#define MMU_UNCORR_RAS_ERROR_LIST(X)
+
+/* L3 Uncorrectable RAS ERROR */
+#define L3_UNCORR_RAS_ERROR_LIST(X)						\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(L3, 43, 0x7B, "SNOC Interface Parity Error")				\
+	X(L3, 42, 0x7A, "MCF Interface Parity Error")				\
+	X(L3, 41, 0x79, "L3 Tag Parity Error")					\
+	X(L3, 40, 0x78, "L3 Dir Parity Error")					\
+	X(L3, 39, 0x77, "L3 Uncorrectable ECC Error")				\
+	X(L3, 37, 0x75, "Multi-Hit CAM Error")					\
+	X(L3, 36, 0x74, "Multi-Hit Tag Error")					\
+	X(L3, 35, 0x73, "Unrecognized Command Error")				\
+	X(L3, 34, 0x72, "L3 Protocol Error")
+
+/* CCPMU Uncorrectable RAS ERROR */
+#define CCPMU_UNCORR_RAS_ERROR_LIST(X)						\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(CCPMU, 40, 0x87, "CoreSight Access Error")				\
+	X(CCPMU, 36, 0x84, "MCE Ucode Error")					\
+	X(CCPMU, 35, 0x83, "MCE IL1 Parity Error")				\
+	X(CCPMU, 34, 0x82, "MCE Timeout Error")					\
+	X(CCPMU, 33, 0x81, "CRAB Access Error")					\
+	X(CCPMU, 32, 0x80, "MCE Memory Access Error")
+
+/* SCF_IOB Uncorrectable RAS ERROR */
+#define SCF_IOB_UNCORR_RAS_ERROR_LIST(X)					\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(SCF_IOB, 41, 0x99, "Request parity error")				\
+	X(SCF_IOB, 40, 0x98, "Putdata parity error")				\
+	X(SCF_IOB, 39, 0x97, "Uncorrectable ECC on Putdata")			\
+	X(SCF_IOB, 38, 0x96, "CBB Interface Error")				\
+	X(SCF_IOB, 37, 0x95, "MMCRAB Error")					\
+	X(SCF_IOB, 36, 0x94, "IHI Interface Error")				\
+	X(SCF_IOB, 35, 0x93, "CRI Error")					\
+	X(SCF_IOB, 34, 0x92, "TBX Interface Error")				\
+	X(SCF_IOB, 33, 0x91, "EVP Interface Error")
+
+/* SCF_SNOC Uncorrectable RAS ERROR */
+#define SCF_SNOC_UNCORR_RAS_ERROR_LIST(X)					\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(SCF_SNOC, 42, 0xAA, "Misc Client Parity Error")			\
+	X(SCF_SNOC, 41, 0xA9, "Misc Filldata Parity Error")			\
+	X(SCF_SNOC, 40, 0xA8, "Uncorrectable ECC Misc Client")			\
+	X(SCF_SNOC, 39, 0xA7, "DVMU Interface Parity Error")			\
+	X(SCF_SNOC, 38, 0xA6, "DVMU Interface Timeout Error")			\
+	X(SCF_SNOC, 37, 0xA5, "CPE Request Error")				\
+	X(SCF_SNOC, 36, 0xA4, "CPE Response Error")				\
+	X(SCF_SNOC, 35, 0xA3, "CPE Timeout Error")				\
+	X(SCF_SNOC, 34, 0xA2, "Uncorrectable Carveout Error")
+
+/* SCF_CTU Uncorrectable RAS ERROR */
+#define SCF_CTU_UNCORR_RAS_ERROR_LIST(X)					\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(SCF_CTU, 39, 0xB7, "Timeout error for TRC_DMA request")		\
+	X(SCF_CTU, 38, 0xB6, "Timeout error for CTU Snp")			\
+	X(SCF_CTU, 37, 0xB5, "Parity error in CTU TAG RAM")			\
+	X(SCF_CTU, 36, 0xB3, "Parity error in CTU DATA RAM")			\
+	X(SCF_CTU, 35, 0xB4, "Parity error for Cluster Rsp")			\
+	X(SCF_CTU, 34, 0xB2, "Parity error for TRL requests from 9 agents")	\
+	X(SCF_CTU, 33, 0xB1, "Parity error for MCF request")			\
+	X(SCF_CTU, 32, 0xB0, "TRC DMA fillsnoop parity error")
+
+/* CMU_CLOCKS Uncorrectable RAS ERROR */
+#define CMU_CLOCKS_UNCORR_RAS_ERROR_LIST(X)					\
+	/* Name, ERR_CTRL, IERR, ISA Desc */					\
+	X(CMU_CLOCKS, 39, 0xC7, "Cluster 3 frequency monitor error")		\
+	X(CMU_CLOCKS, 38, 0xC6, "Cluster 2 frequency monitor error")		\
+	X(CMU_CLOCKS, 37, 0xC5, "Cluster 1 frequency monitor error")		\
+	X(CMU_CLOCKS, 36, 0xC3, "Cluster 0 frequency monitor error")		\
+	X(CMU_CLOCKS, 35, 0xC4, "Voltage error on ADC1 Monitored Logic")	\
+	X(CMU_CLOCKS, 34, 0xC2, "Voltage error on ADC0 Monitored Logic")	\
+	X(CMU_CLOCKS, 33, 0xC1, "Lookup Table 1 Parity Error")			\
+	X(CMU_CLOCKS, 32, 0xC0, "Lookup Table 0 Parity Error")
+
+/*
+ * Define one ras_error entry.
+ *
+ * This macro wille be used to to generate ras_error records for each node
+ * defined by <NODE_NAME>_UNCORR_RAS_ERROR_LIST macro.
+ */
+#define DEFINE_ONE_RAS_ERROR_MSG(unit, ras_bit, ierr, msg)			\
+	{									\
+		.error_msg = (msg),						\
+		.error_code = (ierr)						\
+	},
+
+/*
+ * Set one implementation defined bit in ERR<n>CTLR
+ *
+ * This macro will be used to collect all defined ERR_CTRL bits for each node
+ * defined by <NODE_NAME>_UNCORR_RAS_ERROR_LIST macro.
+ */
+#define DEFINE_ENABLE_RAS_BIT(unit, ras_bit, ierr, msg)				\
+	do {									\
+		val |= (1ULL << ras_bit##U);					\
+	} while (0);
+
+/* Represent one RAS node with 0 or more error bits (ERR_CTLR) enabled */
+#define DEFINE_ONE_RAS_NODE(node)						\
+static const struct ras_error node##_uncorr_ras_errors[] = {			\
+	node##_UNCORR_RAS_ERROR_LIST(DEFINE_ONE_RAS_ERROR_MSG)			\
+	{									\
+		NULL,								\
+		0U								\
+	},									\
+};										\
+static inline uint64_t node##_err_ctrl(void)					\
+{										\
+	uint64_t val = 0ULL;							\
+	node##_UNCORR_RAS_ERROR_LIST(DEFINE_ENABLE_RAS_BIT)			\
+	return val;								\
+}
+
+#define DEFINE_ONE_RAS_AUX_DATA(node)						\
+	{									\
+		.name = #node,							\
+		.error_records = node##_uncorr_ras_errors,			\
+		.err_ctrl = &node##_err_ctrl					\
+	},
+
+#define PER_CORE_RAS_NODE_LIST(X)						\
+	X(IFU)									\
+	X(JSR_RET)								\
+	X(JSR_MTS)								\
+	X(LSD_STQ)								\
+	X(LSD_DCC)								\
+	X(LSD_L1HPF)
+
+#define PER_CORE_RAS_GROUP_NODES	PER_CORE_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)
+
+#define PER_CLUSTER_RAS_NODE_LIST(X)						\
+	X(L2)									\
+	X(CLUSTER_CLOCKS)							\
+	X(MMU)
+
+#define PER_CLUSTER_RAS_GROUP_NODES	PER_CLUSTER_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)
+
+#define SCF_L3_BANK_RAS_NODE_LIST(X)	X(L3)
+
+/* we have 4 SCF_L3 nodes:3*256 + L3_Bank_ID(0-3) */
+#define SCF_L3_BANK_RAS_GROUP_NODES						\
+	SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)			\
+	SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)			\
+	SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)			\
+	SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)
+
+#define CCPLEX_RAS_NODE_LIST(X)							\
+	X(CCPMU)								\
+	X(SCF_IOB)								\
+	X(SCF_SNOC)								\
+	X(SCF_CTU)								\
+	X(CMU_CLOCKS)
+
+#define CCPLEX_RAS_GROUP_NODES		CCPLEX_RAS_NODE_LIST(DEFINE_ONE_RAS_AUX_DATA)
+
+#endif /* TEGRA194_RAS_PRIVATE */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index f72c9cf..c181c36 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -89,7 +89,7 @@
 
 /* Declarations for tegra_fiq_glue.c */
 void tegra_fiq_handler_setup(void);
-int tegra_fiq_get_intr_context(void);
+int32_t tegra_fiq_get_intr_context(void);
 void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint);
 
 /* Declarations for tegra_security.c */
@@ -157,4 +157,9 @@
 		     void *handle,
 		     uint64_t flags);
 
+#if RAS_EXTENSION
+void tegra194_ras_enable(void);
+void tegra194_ras_corrected_err_clear(void);
+#endif
+
 #endif /* TEGRA_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
index 1fe3aad..6dafeb2 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
@@ -58,6 +58,7 @@
 void nvg_enable_strict_checking_mode(void);
 void nvg_system_shutdown(void);
 void nvg_system_reboot(void);
+void nvg_clear_hsm_corr_status(void);
 
 /* declarations for assembly functions */
 void nvg_set_request_data(uint64_t req, uint64_t data);
@@ -71,5 +72,6 @@
 void mce_enable_strict_checking(void);
 void mce_system_shutdown(void);
 void mce_system_reboot(void);
+void mce_clear_hsm_corr_status(void);
 
 #endif /* MCE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
index 7edd7a0..4663a3d 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
@@ -234,3 +234,11 @@
 {
 	nvg_system_reboot();
 }
+
+/*******************************************************************************
+ * Handler to clear CCPLEX->HSM correctable RAS error signal.
+ ******************************************************************************/
+void mce_clear_hsm_corr_status(void)
+{
+	nvg_clear_hsm_corr_status();
+}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
index ef740a1..fdf9429 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
@@ -236,3 +236,15 @@
 	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_SHUTDOWN,
 			     (uint64_t)TEGRA_NVG_SHUTDOWN);
 }
+
+/*
+ * Request to clear CCPLEX->HSM correctable error signal.
+ * NVGDATA[1]: A write of 1 clears the CCPLEX->HSM correctable error signal,
+ *             A write of 0 has no effect.
+ */
+void nvg_clear_hsm_corr_status(void)
+{
+	nvg_hsm_error_ctrl_channel_t status = { .bits = { .corr = 1U, }, };
+
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL, status.flat);
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c
new file mode 100644
index 0000000..54c2924
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_ras.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <lib/bakery_lock.h>
+#include <lib/extensions/ras.h>
+#include <lib/utils_def.h>
+#include <services/sdei.h>
+
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <tegra194_ras_private.h>
+#include <tegra_def.h>
+#include <tegra_platform.h>
+#include <tegra_private.h>
+
+/*
+ * ERR<n>FR bits[63:32], it indicates supported RAS errors which can be enabled
+ * by setting corresponding bits in ERR<n>CTLR
+ */
+#define ERR_FR_EN_BITS_MASK	0xFFFFFFFF00000000ULL
+
+/* bakery lock for platform RAS handler. */
+static DEFINE_BAKERY_LOCK(ras_handler_lock);
+#define ras_lock()		bakery_lock_get(&ras_handler_lock)
+#define ras_unlock()		bakery_lock_release(&ras_handler_lock)
+
+/*
+ * Function to handle an External Abort received at EL3.
+ * This function is invoked by RAS framework.
+ */
+static void tegra194_ea_handler(unsigned int ea_reason, uint64_t syndrome,
+		void *cookie, void *handle, uint64_t flags)
+{
+	int32_t ret;
+
+	ras_lock();
+
+	ERROR("MPIDR 0x%lx: exception reason=%u syndrome=0x%llx\n",
+		read_mpidr(), ea_reason, syndrome);
+
+	/* Call RAS EA handler */
+	ret = ras_ea_handler(ea_reason, syndrome, cookie, handle, flags);
+	if (ret != 0) {
+		ERROR("RAS error handled!\n");
+		ret = sdei_dispatch_event(TEGRA_SDEI_EP_EVENT_0 +
+				plat_my_core_pos());
+		if (ret != 0)
+			ERROR("sdei_dispatch_event returned %d\n", ret);
+	} else {
+		ERROR("Not a RAS error!\n");
+	}
+
+	ras_unlock();
+}
+
+/*
+ * Function to enable all supported RAS error report.
+ *
+ * Uncorrected errors are set to report as External abort (SError)
+ * Corrected errors are set to report as interrupt.
+ */
+void tegra194_ras_enable(void)
+{
+	VERBOSE("%s\n", __func__);
+
+	/* skip RAS enablement if not a silicon platform. */
+	if (!tegra_platform_is_silicon()) {
+		return;
+	}
+
+	/*
+	 * Iterate for each group(num_idx ERRSELRs starting from idx_start)
+	 * use normal for loop instead of for_each_err_record_info to get rid
+	 * of MISRA noise..
+	 */
+	for (uint32_t i = 0U; i < err_record_mappings.num_err_records; i++) {
+
+		const struct err_record_info *info = &err_record_mappings.err_records[i];
+
+		uint32_t idx_start = info->sysreg.idx_start;
+		uint32_t num_idx = info->sysreg.num_idx;
+		const struct ras_aux_data *aux_data = (const struct ras_aux_data *)info->aux_data;
+
+		assert(aux_data != NULL);
+
+		for (uint32_t j = 0; j < num_idx; j++) {
+
+			/* ERR<n>CTLR register value. */
+			uint64_t err_ctrl = 0ULL;
+			/* all supported errors for this node. */
+			uint64_t err_fr;
+			/* uncorrectable errors */
+			uint64_t uncorr_errs;
+			/* correctable errors */
+			uint64_t corr_errs;
+
+			/*
+			 * Catch error if something wrong with the RAS aux data
+			 * record table.
+			 */
+			assert(aux_data[j].err_ctrl != NULL);
+
+			/*
+			 * Write to ERRSELR_EL1 to select the RAS error node.
+			 * Always program this at first to select corresponding
+			 * RAS node before any other RAS register r/w.
+			 */
+			ser_sys_select_record(idx_start + j);
+
+			err_fr = read_erxfr_el1() & ERR_FR_EN_BITS_MASK;
+			uncorr_errs = aux_data[j].err_ctrl();
+			corr_errs = ~uncorr_errs & err_fr;
+
+			/* enable error reporting */
+			ERR_CTLR_ENABLE_FIELD(err_ctrl, ED);
+
+			/* enable SError reporting for uncorrectable errors */
+			if ((uncorr_errs & err_fr) != 0ULL) {
+				ERR_CTLR_ENABLE_FIELD(err_ctrl, UE);
+			}
+
+			/* generate interrupt for corrected errors. */
+			if (corr_errs != 0ULL) {
+				ERR_CTLR_ENABLE_FIELD(err_ctrl, CFI);
+			}
+
+			/* enable the supported errors */
+			err_ctrl |= err_fr;
+
+			VERBOSE("errselr_el1:0x%x, erxfr:0x%llx, err_ctrl:0x%llx\n",
+				idx_start + j, err_fr, err_ctrl);
+
+			/* 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);
+		}
+	}
+}
+
+/*
+ * Function to clear RAS ERR<n>STATUS for corrected RAS error.
+ * This function ignores any new RAS error signaled during clearing; it is not
+ * multi-core safe(no ras_lock is taken to reduce overhead).
+ */
+void tegra194_ras_corrected_err_clear(void)
+{
+	uint64_t clear_ce_status = 0ULL;
+
+	ERR_STATUS_SET_FIELD(clear_ce_status, AV, 0x1UL);
+	ERR_STATUS_SET_FIELD(clear_ce_status, V, 0x1UL);
+	ERR_STATUS_SET_FIELD(clear_ce_status, OF, 0x1UL);
+	ERR_STATUS_SET_FIELD(clear_ce_status, MV, 0x1UL);
+	ERR_STATUS_SET_FIELD(clear_ce_status, CE, 0x3UL);
+
+	for (uint32_t i = 0U; i < err_record_mappings.num_err_records; i++) {
+
+		const struct err_record_info *info = &err_record_mappings.err_records[i];
+		uint32_t idx_start = info->sysreg.idx_start;
+		uint32_t num_idx = info->sysreg.num_idx;
+
+		for (uint32_t j = 0U; j < num_idx; j++) {
+
+			uint64_t status;
+			uint32_t err_idx = idx_start + j;
+
+			write_errselr_el1(err_idx);
+			status = read_erxstatus_el1();
+
+			if (ERR_STATUS_GET_FIELD(status, CE) != 0U) {
+				write_erxstatus_el1(clear_ce_status);
+			}
+		}
+	}
+}
+
+/* Function to probe an error from error record group. */
+static int32_t tegra194_ras_record_probe(const struct err_record_info *info,
+		int *probe_data)
+{
+	/* Skip probing if not a silicon platform */
+	if (!tegra_platform_is_silicon()) {
+		return 0;
+	}
+
+	return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx, probe_data);
+}
+
+/* Function to handle error from one given node */
+static int32_t tegra194_ras_node_handler(uint32_t errselr, const char *name,
+		const struct ras_error *errors, uint64_t status)
+{
+	bool found = false;
+	uint32_t ierr = (uint32_t)ERR_STATUS_GET_FIELD(status, IERR);
+	uint32_t serr = (uint32_t)ERR_STATUS_GET_FIELD(status, SERR);
+	uint64_t val = 0;
+
+	/* not a valid error. */
+	if (ERR_STATUS_GET_FIELD(status, V) == 0U) {
+		return 0;
+	}
+
+	ERR_STATUS_SET_FIELD(val, V, 1);
+
+	/* keep the log print same as linux arm64_ras driver. */
+	ERROR("**************************************\n");
+	ERROR("RAS Error in %s, ERRSELR_EL1=0x%x:\n", name, errselr);
+	ERROR("\tStatus = 0x%llx\n", status);
+
+	/* Print uncorrectable errror information. */
+	if (ERR_STATUS_GET_FIELD(status, UE) != 0U) {
+
+		ERR_STATUS_SET_FIELD(val, UE, 1);
+		ERR_STATUS_SET_FIELD(val, UET, 1);
+
+		/* IERR to error message */
+		for (uint32_t i = 0; errors[i].error_msg != NULL; i++) {
+			if (ierr == errors[i].error_code) {
+				ERROR("\tIERR = %s: 0x%x\n",
+					errors[i].error_msg, ierr);
+
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			ERROR("\tUnknown IERR: 0x%x\n", ierr);
+		}
+
+		ERROR("SERR = %s: 0x%x\n", ras_serr_to_str(serr), serr);
+
+		/* Overflow, multiple errors have been detected. */
+		if (ERR_STATUS_GET_FIELD(status, OF) != 0U) {
+			ERROR("\tOverflow (there may be more errors) - "
+				"Uncorrectable\n");
+			ERR_STATUS_SET_FIELD(val, OF, 1);
+		}
+
+		ERROR("\tUncorrectable (this is fatal)\n");
+
+		/* Miscellaneous Register Valid. */
+		if (ERR_STATUS_GET_FIELD(status, MV) != 0U) {
+			ERROR("\tMISC0 = 0x%lx\n", read_erxmisc0_el1());
+			ERROR("\tMISC1 = 0x%lx\n", read_erxmisc1_el1());
+			ERR_STATUS_SET_FIELD(val, MV, 1);
+		}
+
+		/* Address Valid. */
+		if (ERR_STATUS_GET_FIELD(status, AV) != 0U) {
+			ERROR("\tADDR = 0x%lx\n", read_erxaddr_el1());
+			ERR_STATUS_SET_FIELD(val, AV, 1);
+		}
+
+		/* Deferred error */
+		if (ERR_STATUS_GET_FIELD(status, DE) != 0U) {
+			ERROR("\tDeferred error\n");
+			ERR_STATUS_SET_FIELD(val, DE, 1);
+		}
+
+	} else {
+		/* For corrected error, simply clear it. */
+		VERBOSE("corrected RAS error is cleared: ERRSELR_EL1:0x%x, "
+			"IERR:0x%x, SERR:0x%x\n", errselr, ierr, serr);
+		ERR_STATUS_SET_FIELD(val, CE, 1);
+	}
+
+	ERROR("**************************************\n");
+
+	/* Write to clear reported errors. */
+	write_erxstatus_el1(val);
+
+	/* error handled */
+	return 0;
+}
+
+/* Function to handle one error node from an error record group. */
+static int32_t tegra194_ras_record_handler(const struct err_record_info *info,
+		int probe_data, const struct err_handler_data *const data __unused)
+{
+	uint32_t num_idx = info->sysreg.num_idx;
+	uint32_t idx_start = info->sysreg.idx_start;
+	const struct ras_aux_data *aux_data = info->aux_data;
+	const struct ras_error *errors;
+	uint32_t offset;
+	const char *node_name;
+
+	uint64_t status = 0ULL;
+
+	VERBOSE("%s\n", __func__);
+
+	assert(probe_data >= 0);
+	assert((uint32_t)probe_data < num_idx);
+
+	offset = (uint32_t)probe_data;
+	errors = aux_data[offset].error_records;
+	node_name = aux_data[offset].name;
+
+	assert(errors != NULL);
+
+	/* Write to ERRSELR_EL1 to select the error record */
+	ser_sys_select_record(idx_start + offset);
+
+	/* Retrieve status register from the error record */
+	status = read_erxstatus_el1();
+
+	return tegra194_ras_node_handler(idx_start + offset, node_name,
+			errors, status);
+}
+
+
+/* Instantiate RAS nodes */
+PER_CORE_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
+PER_CLUSTER_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
+SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
+CCPLEX_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
+
+/* Instantiate RAS node groups */
+static struct ras_aux_data per_core_ras_group[] = {
+	PER_CORE_RAS_GROUP_NODES
+};
+
+static struct ras_aux_data per_cluster_ras_group[] = {
+	PER_CLUSTER_RAS_GROUP_NODES
+};
+
+static struct ras_aux_data scf_l3_ras_group[] = {
+	SCF_L3_BANK_RAS_GROUP_NODES
+};
+
+static struct ras_aux_data ccplex_ras_group[] = {
+    CCPLEX_RAS_GROUP_NODES
+};
+
+/*
+ * We have same probe and handler for each error record group, use a macro to
+ * simply the record definition.
+ */
+#define ADD_ONE_ERR_GROUP(errselr_start, group) \
+	ERR_RECORD_SYSREG_V1((errselr_start), (uint32_t)ARRAY_SIZE((group)), \
+			&tegra194_ras_record_probe, \
+			&tegra194_ras_record_handler, (group))
+
+/* RAS error record group information */
+static struct err_record_info carmel_ras_records[] = {
+	/*
+	 * Per core ras error records
+	 * ERRSELR starts from 0*256 + Logical_CPU_ID*16 + 0 to
+	 * 0*256 + Logical_CPU_ID*16 + 5 for each group.
+	 * 8 cores/groups, 6 * 8 nodes in total.
+	 */
+	ADD_ONE_ERR_GROUP(0x000, per_core_ras_group),
+	ADD_ONE_ERR_GROUP(0x010, per_core_ras_group),
+	ADD_ONE_ERR_GROUP(0x020, per_core_ras_group),
+	ADD_ONE_ERR_GROUP(0x030, per_core_ras_group),
+	ADD_ONE_ERR_GROUP(0x040, per_core_ras_group),
+	ADD_ONE_ERR_GROUP(0x050, per_core_ras_group),
+	ADD_ONE_ERR_GROUP(0x060, per_core_ras_group),
+	ADD_ONE_ERR_GROUP(0x070, per_core_ras_group),
+
+	/*
+	 * Per cluster ras error records
+	 * ERRSELR starts from 2*256 + Logical_Cluster_ID*16 + 0 to
+	 * 2*256 + Logical_Cluster_ID*16 + 3.
+	 * 4 clusters/groups, 3 * 4 nodes in total.
+	 */
+	ADD_ONE_ERR_GROUP(0x200, per_cluster_ras_group),
+	ADD_ONE_ERR_GROUP(0x210, per_cluster_ras_group),
+	ADD_ONE_ERR_GROUP(0x220, per_cluster_ras_group),
+	ADD_ONE_ERR_GROUP(0x230, per_cluster_ras_group),
+
+	/*
+	 * SCF L3_Bank ras error records
+	 * ERRSELR: 3*256 + L3_Bank_ID, L3_Bank_ID: 0-3
+	 * 1 groups, 4 nodes in total.
+	 */
+	ADD_ONE_ERR_GROUP(0x300, scf_l3_ras_group),
+
+	/*
+	 * CCPLEX ras error records
+	 * ERRSELR: 4*256 + Unit_ID, Unit_ID: 0 - 4
+	 * 1 groups, 5 nodes in total.
+	 */
+	ADD_ONE_ERR_GROUP(0x400, ccplex_ras_group),
+};
+
+REGISTER_ERR_RECORD_INFO(carmel_ras_records);
+
+/* dummy RAS interrupt */
+static struct ras_interrupt carmel_ras_interrupts[] = {};
+REGISTER_RAS_INTERRUPTS(carmel_ras_interrupts);
+
+/*******************************************************************************
+ * RAS handler for the platform
+ ******************************************************************************/
+void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
+		void *handle, uint64_t flags)
+{
+#if RAS_EXTENSION
+	tegra194_ea_handler(ea_reason, syndrome, cookie, handle, flags);
+#else
+	ERROR("Unhandled External Abort received on 0x%llx at EL3!\n",
+			read_mpidr_el1());
+	ERROR(" exception reason=%u syndrome=0x%lx\n", ea_reason, syndrome);
+	panic();
+#endif
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
index 5d6c60b..399aebb 100644
--- a/plat/nvidia/tegra/soc/t194/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -208,6 +208,11 @@
 	/* sanity check MCE firmware compatibility */
 	mce_verify_firmware_version();
 
+#if RAS_EXTENSION
+	/* Enable Uncorrectable RAS error */
+	tegra194_ras_enable();
+#endif
+
 	/*
 	 * Program XUSB STREAMIDs
 	 * ======================
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
index 884762d..a3f996d 100644
--- a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
@@ -12,6 +12,7 @@
 #include <common/debug.h>
 #include <errno.h>
 #include <mce.h>
+#include <mce_private.h>
 #include <memctrl.h>
 #include <common/runtime_svc.h>
 #include <tegra_private.h>
@@ -23,6 +24,7 @@
  * Tegra194 SiP SMCs
  ******************************************************************************/
 #define TEGRA_SIP_GET_SMMU_PER		0xC200FF00U
+#define TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS	0xC200FF01U
 
 /*******************************************************************************
  * This function is responsible for handling all T194 SiP calls
@@ -69,6 +71,15 @@
 
 		break;
 
+#if RAS_EXTENSION
+	case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
+		/* clear all RAS error records for corrected errors at first. */
+		tegra194_ras_corrected_err_clear();
+		/* clear HSM corrected error status. */
+		mce_clear_hsm_corr_status();
+		break;
+#endif
+
 	default:
 		ret = -ENOTSUP;
 		break;
diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
index c02128c..d7d15f5 100644
--- a/plat/nvidia/tegra/soc/t194/platform_t194.mk
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -30,6 +30,10 @@
 MAX_MMAP_REGIONS			:= 30
 $(eval $(call add_define,MAX_MMAP_REGIONS))
 
+# enable RAS handling
+HANDLE_EA_EL3_FIRST			:= 1
+RAS_EXTENSION				:= 1
+
 # platform files
 PLAT_INCLUDES		+=	-Iplat/nvidia/tegra/include/t194 \
 				-I${SOC_DIR}/drivers/include
@@ -56,3 +60,10 @@
 ifeq (${ENABLE_CONSOLE_SPE},1)
 BL31_SOURCES		+=	${COMMON_DIR}/drivers/spe/shared_console.S
 endif
+
+# RAS sources
+ifeq (${RAS_EXTENSION},1)
+BL31_SOURCES		+=	lib/extensions/ras/std_err_record.c		\
+				lib/extensions/ras/ras_common.c			\
+				${SOC_DIR}/plat_ras.c
+endif
diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c
index b2fd201..2ff81ed 100644
--- a/plat/rockchip/common/params_setup.c
+++ b/plat/rockchip/common/params_setup.c
@@ -37,7 +37,8 @@
 static uint32_t rk_uart_base = PLAT_RK_UART_BASE;
 static uint32_t rk_uart_baudrate = PLAT_RK_UART_BAUDRATE;
 static uint32_t rk_uart_clock = PLAT_RK_UART_CLOCK;
-static uint8_t fdt_buffer[0x10000];
+#define FDT_BUFFER_SIZE 0x20000
+static uint8_t fdt_buffer[FDT_BUFFER_SIZE];
 
 void *plat_get_fdt(void)
 {
@@ -136,7 +137,7 @@
 	void *fdt = plat_get_fdt();
 	int ret;
 
-	ret = fdt_open_into((void *)param_from_bl2, fdt, 0x10000);
+	ret = fdt_open_into((void *)param_from_bl2, fdt, FDT_BUFFER_SIZE);
 	if (ret < 0)
 		return ret;
 
diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h
index 6fcf2ba..519a025 100644
--- a/plat/rockchip/rk3368/include/platform_def.h
+++ b/plat/rockchip/rk3368/include/platform_def.h
@@ -48,7 +48,7 @@
 					 PLATFORM_CLUSTER_COUNT +	\
 					 PLATFORM_CORE_COUNT)
 
-#define PLAT_RK_CLST_TO_CPUID_SHIFT	8
+#define PLAT_RK_CLST_TO_CPUID_SHIFT	6
 
 #define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL2
 
diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h
index 6db9b57..daf27a7 100644
--- a/tools/cert_create/include/cert.h
+++ b/tools/cert_create/include/cert.h
@@ -12,7 +12,7 @@
 #include "ext.h"
 #include "key.h"
 
-#define CERT_MAX_EXT			5
+#define CERT_MAX_EXT			9
 
 /*
  * This structure contains information related to the generation of the
diff --git a/tools/cert_create/include/dualroot/cot.h b/tools/cert_create/include/dualroot/cot.h
index 5701206..47e371f 100644
--- a/tools/cert_create/include/dualroot/cot.h
+++ b/tools/cert_create/include/dualroot/cot.h
@@ -18,6 +18,7 @@
 	SOC_FW_CONTENT_CERT,
 	TRUSTED_OS_FW_KEY_CERT,
 	TRUSTED_OS_FW_CONTENT_CERT,
+	SIP_SECURE_PARTITION_CONTENT_CERT,
 	FWU_CERT,
 
 	/* Certificates owned by the platform owner. */
@@ -42,6 +43,14 @@
 	TRUSTED_OS_FW_EXTRA1_HASH_EXT,
 	TRUSTED_OS_FW_EXTRA2_HASH_EXT,
 	TRUSTED_OS_FW_CONFIG_HASH_EXT,
+	SP_PKG1_HASH_EXT,
+	SP_PKG2_HASH_EXT,
+	SP_PKG3_HASH_EXT,
+	SP_PKG4_HASH_EXT,
+	SP_PKG5_HASH_EXT,
+	SP_PKG6_HASH_EXT,
+	SP_PKG7_HASH_EXT,
+	SP_PKG8_HASH_EXT,
 	SCP_FWU_CFG_HASH_EXT,
 	AP_FWU_CFG_HASH_EXT,
 	FWU_HASH_EXT,
diff --git a/tools/cert_create/include/tbbr/tbb_cert.h b/tools/cert_create/include/tbbr/tbb_cert.h
index 628ef3a..e5fa3a2 100644
--- a/tools/cert_create/include/tbbr/tbb_cert.h
+++ b/tools/cert_create/include/tbbr/tbb_cert.h
@@ -23,6 +23,7 @@
 	TRUSTED_OS_FW_CONTENT_CERT,
 	NON_TRUSTED_FW_KEY_CERT,
 	NON_TRUSTED_FW_CONTENT_CERT,
+	SIP_SECURE_PARTITION_CONTENT_CERT,
 	FWU_CERT
 };
 
diff --git a/tools/cert_create/include/tbbr/tbb_ext.h b/tools/cert_create/include/tbbr/tbb_ext.h
index 462aafc..7ac97a5 100644
--- a/tools/cert_create/include/tbbr/tbb_ext.h
+++ b/tools/cert_create/include/tbbr/tbb_ext.h
@@ -30,6 +30,14 @@
 	NON_TRUSTED_FW_CONTENT_CERT_PK_EXT,
 	NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT,
 	NON_TRUSTED_FW_CONFIG_HASH_EXT,
+	SP_PKG1_HASH_EXT,
+	SP_PKG2_HASH_EXT,
+	SP_PKG3_HASH_EXT,
+	SP_PKG4_HASH_EXT,
+	SP_PKG5_HASH_EXT,
+	SP_PKG6_HASH_EXT,
+	SP_PKG7_HASH_EXT,
+	SP_PKG8_HASH_EXT,
 	SCP_FWU_CFG_HASH_EXT,
 	AP_FWU_CFG_HASH_EXT,
 	FWU_HASH_EXT
diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c
index 8117ffc..2965828 100644
--- a/tools/cert_create/src/dualroot/cot.c
+++ b/tools/cert_create/src/dualroot/cot.c
@@ -137,6 +137,28 @@
 		.num_ext = 5
 	},
 
+	[SIP_SECURE_PARTITION_CONTENT_CERT] = {
+		.id = SIP_SECURE_PARTITION_CONTENT_CERT,
+		.opt = "sip-sp-cert",
+		.help_msg = "SiP owned Secure Partition Content Certificate (output file)",
+		.fn = NULL,
+		.cn = "SiP owned Secure Partition Content Certificate",
+		.key = TRUSTED_WORLD_KEY,
+		.issuer = SIP_SECURE_PARTITION_CONTENT_CERT,
+		.ext = {
+			TRUSTED_FW_NVCOUNTER_EXT,
+			SP_PKG1_HASH_EXT,
+			SP_PKG2_HASH_EXT,
+			SP_PKG3_HASH_EXT,
+			SP_PKG4_HASH_EXT,
+			SP_PKG5_HASH_EXT,
+			SP_PKG6_HASH_EXT,
+			SP_PKG7_HASH_EXT,
+			SP_PKG8_HASH_EXT,
+		},
+		.num_ext = 9
+	},
+
 	[FWU_CERT] = {
 		.id = FWU_CERT,
 		.opt = "fwu-cert",
@@ -327,6 +349,87 @@
 		.optional = 1
 	},
 
+	[SP_PKG1_HASH_EXT] = {
+		.oid = SP_PKG1_HASH_OID,
+		.opt = "sp-pkg1",
+		.help_msg = "Secure Partition Package1 file",
+		.sn = "SPPkg1Hash",
+		.ln = "SP Pkg1 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG2_HASH_EXT] = {
+		.oid = SP_PKG2_HASH_OID,
+		.opt = "sp-pkg2",
+		.help_msg = "Secure Partition Package2 file",
+		.sn = "SPPkg2Hash",
+		.ln = "SP Pkg2 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG3_HASH_EXT] = {
+		.oid = SP_PKG3_HASH_OID,
+		.opt = "sp-pkg3",
+		.help_msg = "Secure Partition Package3 file",
+		.sn = "SPPkg3Hash",
+		.ln = "SP Pkg3 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG4_HASH_EXT] = {
+		.oid = SP_PKG4_HASH_OID,
+		.opt = "sp-pkg4",
+		.help_msg = "Secure Partition Package4 file",
+		.sn = "SPPkg4Hash",
+		.ln = "SP Pkg4 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG5_HASH_EXT] = {
+		.oid = SP_PKG5_HASH_OID,
+		.opt = "sp-pkg5",
+		.help_msg = "Secure Partition Package5 file",
+		.sn = "SPPkg5Hash",
+		.ln = "SP Pkg5 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG6_HASH_EXT] = {
+		.oid = SP_PKG6_HASH_OID,
+		.opt = "sp-pkg6",
+		.help_msg = "Secure Partition Package6 file",
+		.sn = "SPPkg6Hash",
+		.ln = "SP Pkg6 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG7_HASH_EXT] = {
+		.oid = SP_PKG7_HASH_OID,
+		.opt = "sp-pkg7",
+		.help_msg = "Secure Partition Package7 file",
+		.sn = "SPPkg7Hash",
+		.ln = "SP Pkg7 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG8_HASH_EXT] = {
+		.oid = SP_PKG8_HASH_OID,
+		.opt = "sp-pkg8",
+		.help_msg = "Secure Partition Package8 file",
+		.sn = "SPPkg8Hash",
+		.ln = "SP Pkg8 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+
 	[SCP_FWU_CFG_HASH_EXT] = {
 		.oid = SCP_FWU_CFG_HASH_OID,
 		.opt = "scp-fwu-cfg",
diff --git a/tools/cert_create/src/tbbr/tbb_cert.c b/tools/cert_create/src/tbbr/tbb_cert.c
index 7fb32d8..b614e2e 100644
--- a/tools/cert_create/src/tbbr/tbb_cert.c
+++ b/tools/cert_create/src/tbbr/tbb_cert.c
@@ -164,6 +164,27 @@
 		},
 		.num_ext = 3
 	},
+	[SIP_SECURE_PARTITION_CONTENT_CERT] = {
+		.id = SIP_SECURE_PARTITION_CONTENT_CERT,
+		.opt = "sip-sp-cert",
+		.help_msg = "SiP owned Secure Partition Content Certificate (output file)",
+		.fn = NULL,
+		.cn = "SiP owned Secure Partition Content Certificate",
+		.key = TRUSTED_WORLD_KEY,
+		.issuer = SIP_SECURE_PARTITION_CONTENT_CERT,
+		.ext = {
+			TRUSTED_FW_NVCOUNTER_EXT,
+			SP_PKG1_HASH_EXT,
+			SP_PKG2_HASH_EXT,
+			SP_PKG3_HASH_EXT,
+			SP_PKG4_HASH_EXT,
+			SP_PKG5_HASH_EXT,
+			SP_PKG6_HASH_EXT,
+			SP_PKG7_HASH_EXT,
+			SP_PKG8_HASH_EXT,
+		},
+		.num_ext = 9
+	},
 	[FWU_CERT] = {
 		.id = FWU_CERT,
 		.opt = "fwu-cert",
diff --git a/tools/cert_create/src/tbbr/tbb_ext.c b/tools/cert_create/src/tbbr/tbb_ext.c
index ee5377f..0068d3b 100644
--- a/tools/cert_create/src/tbbr/tbb_ext.c
+++ b/tools/cert_create/src/tbbr/tbb_ext.c
@@ -203,6 +203,86 @@
 		.type = EXT_TYPE_HASH,
 		.optional = 1
 	},
+	[SP_PKG1_HASH_EXT] = {
+		.oid = SP_PKG1_HASH_OID,
+		.opt = "sp-pkg1",
+		.help_msg = "Secure Partition Package1 file",
+		.sn = "SPPkg1Hash",
+		.ln = "SP Pkg1 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG2_HASH_EXT] = {
+		.oid = SP_PKG2_HASH_OID,
+		.opt = "sp-pkg2",
+		.help_msg = "Secure Partition Package2 file",
+		.sn = "SPPkg2Hash",
+		.ln = "SP Pkg2 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG3_HASH_EXT] = {
+		.oid = SP_PKG3_HASH_OID,
+		.opt = "sp-pkg3",
+		.help_msg = "Secure Partition Package3 file",
+		.sn = "SPPkg3Hash",
+		.ln = "SP Pkg3 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG4_HASH_EXT] = {
+		.oid = SP_PKG4_HASH_OID,
+		.opt = "sp-pkg4",
+		.help_msg = "Secure Partition Package4 file",
+		.sn = "SPPkg4Hash",
+		.ln = "SP Pkg4 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG5_HASH_EXT] = {
+		.oid = SP_PKG5_HASH_OID,
+		.opt = "sp-pkg5",
+		.help_msg = "Secure Partition Package5 file",
+		.sn = "SPPkg5Hash",
+		.ln = "SP Pkg5 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG6_HASH_EXT] = {
+		.oid = SP_PKG6_HASH_OID,
+		.opt = "sp-pkg6",
+		.help_msg = "Secure Partition Package6 file",
+		.sn = "SPPkg6Hash",
+		.ln = "SP Pkg6 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG7_HASH_EXT] = {
+		.oid = SP_PKG7_HASH_OID,
+		.opt = "sp-pkg7",
+		.help_msg = "Secure Partition Package7 file",
+		.sn = "SPPkg7Hash",
+		.ln = "SP Pkg7 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[SP_PKG8_HASH_EXT] = {
+		.oid = SP_PKG8_HASH_OID,
+		.opt = "sp-pkg8",
+		.help_msg = "Secure Partition Package8 file",
+		.sn = "SPPkg8Hash",
+		.ln = "SP Pkg8 hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
 	[SCP_FWU_CFG_HASH_EXT] = {
 		.oid = SCP_FWU_CFG_HASH_OID,
 		.opt = "scp-fwu-cfg",
diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c
index 86b8581..1c5ef5f 100644
--- a/tools/fiptool/tbbr_config.c
+++ b/tools/fiptool/tbbr_config.c
@@ -152,6 +152,11 @@
 		.cmdline_name = "nt-fw-cert"
 	},
 	{
+		.name = "SiP owned Secure Partition content certificate",
+		.uuid = UUID_SIP_SECURE_PARTITION_CONTENT_CERT,
+		.cmdline_name = "sip-sp-cert"
+	},
+	{
 		.name = NULL,
 		.uuid = { {0} },
 		.cmdline_name = NULL,
diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py
index 6b6fa19..f2387f6 100755
--- a/tools/sptool/sp_mk_generator.py
+++ b/tools/sptool/sp_mk_generator.py
@@ -11,7 +11,8 @@
 must be relative to it.
 
 This script parses the layout file and generates a make file which updates
-FDT_SOURCES, FIP_ARGS and SPTOOL_ARGS which are used in later build steps.
+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.
 
@@ -24,6 +25,7 @@
     FDT_SOURCES +=  sp1.dts
     SPTOOL_ARGS += -i sp1.bin:sp1.dtb -o sp1.pkg
     FIP_ARGS += --blob uuid=XXXXX-XXX...,file=sp1.pkg
+    CRT_ARGS += --sp-pkg1 sp1.pkg
 
 A typical SP_LAYOUT_FILE file will look like
 {
@@ -59,7 +61,7 @@
 print(dtb_dir)
 
 with open(gen_file, 'w') as out_file:
-    for key in data.keys():
+    for idx, key in enumerate(data.keys()):
 
         """
         Append FDT_SOURCES
@@ -97,4 +99,9 @@
         Append FIP_ARGS
         """
         out_file.write("FIP_ARGS += --blob uuid=" + uuid_std + ",file=" + dst + "\n")
+
+        """
+        Append CRT_ARGS
+        """
+        out_file.write("CRT_ARGS += --sp-pkg" + str(idx + 1) + " " + dst + "\n")
         out_file.write("\n")