Merge pull request #1505 from Yann-lms/mmc_delays

mmc: add required delays when retrying commands
diff --git a/drivers/arm/cci/cci.c b/drivers/arm/cci/cci.c
index 81808b9..71b65f4 100644
--- a/drivers/arm/cci/cci.c
+++ b/drivers/arm/cci/cci.c
@@ -5,6 +5,7 @@
  */
 
 #include <arch.h>
+#include <arch_helpers.h>
 #include <assert.h>
 #include <cci.h>
 #include <debug.h>
@@ -142,6 +143,12 @@
 		      SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
 		      DVM_EN_BIT | SNOOP_EN_BIT);
 
+	/*
+	 * Wait for the completion of the write to the Snoop Control Register
+	 * before testing the change_pending bit
+	 */
+	dmbish();
+
 	/* Wait for the dust to settle down */
 	while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
 		;
@@ -163,6 +170,12 @@
 		      SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
 		      ~(DVM_EN_BIT | SNOOP_EN_BIT));
 
+	/*
+	 * Wait for the completion of the write to the Snoop Control Register
+	 * before testing the change_pending bit
+	 */
+	dmbish();
+
 	/* Wait for the dust to settle down */
 	while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
 		;
diff --git a/include/lib/xlat_tables/xlat_mmu_helpers.h b/include/lib/xlat_tables/xlat_mmu_helpers.h
index 3906efb..cd42c33 100644
--- a/include/lib/xlat_tables/xlat_mmu_helpers.h
+++ b/include/lib/xlat_tables/xlat_mmu_helpers.h
@@ -52,6 +52,7 @@
 
 #ifndef __ASSEMBLY__
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <sys/types.h>
 
@@ -78,7 +79,7 @@
 void enable_mmu_direct_el3(unsigned int flags);
 #endif /* AARCH32 */
 
-int xlat_arch_is_granule_size_supported(size_t size);
+bool xlat_arch_is_granule_size_supported(size_t size);
 size_t xlat_arch_get_max_supported_granule_size(void);
 
 #endif /* __ASSEMBLY__ */
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index fd61fc4..022acce 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -296,14 +296,15 @@
  * translation tables are not modified by any other code while this function is
  * executing.
  */
-int change_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va, size_t size,
-			  uint32_t attr);
+int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
+				   size_t size, uint32_t attr);
+int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr);
 
 /*
  * Query the memory attributes of a memory page in a set of translation tables.
  *
  * Return 0 on success, a negative error code on error.
- * On success, the attributes are stored into *attributes.
+ * On success, the attributes are stored into *attr.
  *
  * ctx
  *   Translation context to work on.
@@ -311,11 +312,12 @@
  *   Virtual address of the page to get the attributes of.
  *   There are no alignment restrictions on this address. The attributes of the
  *   memory page it lies within are returned.
- * attributes
+ * attr
  *   Output parameter where to store the attributes of the targeted memory page.
  */
-int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va,
-		       uint32_t *attributes);
+int xlat_get_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
+				uint32_t *attr);
+int xlat_get_mem_attributes(uintptr_t base_va, uint32_t *attr);
 
 #endif /*__ASSEMBLY__*/
 #endif /* XLAT_TABLES_V2_H */
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index d3d2fc4..fa89958 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -20,6 +20,7 @@
 
 #include <cassert.h>
 #include <platform_def.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <xlat_tables_arch.h>
 #include <xlat_tables_defs.h>
@@ -95,8 +96,8 @@
 	/* Level of the base translation table. */
 	unsigned int base_level;
 
-	/* Set to 1 when the translation tables are initialized. */
-	int initialized;
+	/* Set to true when the translation tables are initialized. */
+	bool initialized;
 
 	/*
 	 * Translation regime managed by this xlat_ctx_t. It should be one of
@@ -157,7 +158,7 @@
 		.max_pa = 0U,						\
 		.max_va = 0U,						\
 		.next_table = 0,					\
-		.initialized = 0,					\
+		.initialized = false,					\
 	}
 
 #endif /*__ASSEMBLY__*/
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 9a661d7..47f2ac2 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -241,16 +241,25 @@
 						ARM_EL3_TZC_DRAM1_SIZE,	\
 						MT_MEMORY | MT_RW | MT_SECURE)
 
+/*
+ * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section
+ * otherwise one region is defined containing both.
+ */
 #if SEPARATE_CODE_AND_RODATA
-#define ARM_MAP_BL_CODE			MAP_REGION_FLAT(			\
+#define ARM_MAP_BL_RO			MAP_REGION_FLAT(			\
 						BL_CODE_BASE,			\
 						BL_CODE_END - BL_CODE_BASE,	\
-						MT_CODE | MT_SECURE)
-#define ARM_MAP_BL_RO_DATA		MAP_REGION_FLAT(			\
+						MT_CODE | MT_SECURE),		\
+					MAP_REGION_FLAT(			\
 						BL_RO_DATA_BASE,		\
 						BL_RO_DATA_END			\
 							- BL_RO_DATA_BASE,	\
 						MT_RO_DATA | MT_SECURE)
+#else
+#define ARM_MAP_BL_RO			MAP_REGION_FLAT(			\
+						BL_CODE_BASE,			\
+						BL_CODE_END - BL_CODE_BASE,	\
+						MT_CODE | MT_SECURE)
 #endif
 #if USE_COHERENT_MEM
 #define ARM_MAP_BL_COHERENT_RAM		MAP_REGION_FLAT(			\
@@ -261,14 +270,10 @@
 #endif
 
 /*
- * The number of regions like RO(code), coherent and data required by
+ * The max number of regions like RO(code), coherent and data required by
  * different BL stages which need to be mapped in the MMU.
  */
-#if USE_COHERENT_MEM
 # define ARM_BL_REGIONS			4
-#else
-# define ARM_BL_REGIONS			3
-#endif
 
 #define MAX_MMAP_REGIONS		(PLAT_ARM_MMAP_ENTRIES +	\
 					 ARM_BL_REGIONS)
diff --git a/lib/psci/aarch32/psci_helpers.S b/lib/psci/aarch32/psci_helpers.S
index a29a29c..63d7e70 100644
--- a/lib/psci/aarch32/psci_helpers.S
+++ b/lib/psci/aarch32/psci_helpers.S
@@ -91,28 +91,6 @@
 	stcopr	r0, SCTLR
 	isb
 
-#if PLAT_XLAT_TABLES_DYNAMIC
-	/* ---------------------------------------------
-	 * During warm boot the MMU is enabled with data
-	 * cache disabled, then the interconnect is set
-	 * up and finally the data cache is enabled.
-	 *
-	 * During this period, if another CPU modifies
-	 * the translation tables, the MMU table walker
-	 * may read the old entries. This is only a
-	 * problem for dynamic regions, the warm boot
-	 * code isn't affected because it is static.
-	 *
-	 * Invalidate all TLB entries loaded while the
-	 * CPU wasn't coherent with the rest of the
-	 * system.
-	 * ---------------------------------------------
-	 */
-	stcopr	r0, TLBIALL
-	dsb	ish
-	isb
-#endif
-
 	pop	{r12, pc}
 endfunc psci_do_pwrup_cache_maintenance
 
diff --git a/lib/psci/aarch64/psci_helpers.S b/lib/psci/aarch64/psci_helpers.S
index d37ca76..06d6636 100644
--- a/lib/psci/aarch64/psci_helpers.S
+++ b/lib/psci/aarch64/psci_helpers.S
@@ -115,28 +115,6 @@
 	msr	sctlr_el3, x0
 	isb
 
-#if PLAT_XLAT_TABLES_DYNAMIC
-	/* ---------------------------------------------
-	 * During warm boot the MMU is enabled with data
-	 * cache disabled, then the interconnect is set
-	 * up and finally the data cache is enabled.
-	 *
-	 * During this period, if another CPU modifies
-	 * the translation tables, the MMU table walker
-	 * may read the old entries. This is only a
-	 * problem for dynamic regions, the warm boot
-	 * code isn't affected because it is static.
-	 *
-	 * Invalidate all TLB entries loaded while the
-	 * CPU wasn't coherent with the rest of the
-	 * system.
-	 * ---------------------------------------------
-	 */
-	tlbi	alle3
-	dsb	ish
-	isb
-#endif
-
 	ldp	x29, x30, [sp], #16
 	ret
 endfunc psci_do_pwrup_cache_maintenance
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 6a35ff6..fd822bc 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -82,7 +82,7 @@
 	}
 
 	/* Fast path for CPU standby.*/
-	if (is_cpu_standby_req(is_power_down_state, target_pwrlvl) != 0) {
+	if (is_cpu_standby_req(is_power_down_state, target_pwrlvl)) {
 		if  (psci_plat_pm_ops->cpu_standby == NULL)
 			return PSCI_E_INVALID_PARAMS;
 
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index 2ea9f76..82b951d 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -14,6 +14,7 @@
 #include <cpu_data.h>
 #include <psci.h>
 #include <spinlock.h>
+#include <stdbool.h>
 
 /*
  * The PSCI capability which are provided by the generic code but does not
@@ -93,10 +94,10 @@
 }
 
 /* Helper function to identify a CPU standby request in PSCI Suspend call */
-static inline int is_cpu_standby_req(unsigned int is_power_down_state,
-				     unsigned int retn_lvl)
+static inline bool is_cpu_standby_req(unsigned int is_power_down_state,
+				      unsigned int retn_lvl)
 {
-	return ((is_power_down_state == 0U) && (retn_lvl == 0U)) ? 1 : 0;
+	return (is_power_down_state == 0U) && (retn_lvl == 0U);
 }
 
 /*******************************************************************************
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index a2850cb..65d3f0f 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -11,6 +11,7 @@
 #include <common_def.h>
 #include <debug.h>
 #include <platform_def.h>
+#include <stdbool.h>
 #include <string.h>
 #include <types.h>
 #include <utils.h>
@@ -100,17 +101,16 @@
 		 * Check if one of the regions is completely inside the other
 		 * one.
 		 */
-		int fully_overlapped_va =
-			(((base_va >= mm->base_va) && (end_va <= mm_end_va)) ||
-			((mm->base_va >= base_va) && (mm_end_va <= end_va)))
-			? 1 : 0;
+		bool fully_overlapped_va =
+			((base_va >= mm->base_va) && (end_va <= mm_end_va)) ||
+			((mm->base_va >= base_va) && (mm_end_va <= end_va));
 
 		/*
 		 * Full VA overlaps are only allowed if both regions are
 		 * identity mapped (zero offset) or have the same VA to PA
 		 * offset. Also, make sure that it's not the exact same area.
 		 */
-		if (fully_overlapped_va == 1) {
+		if (fully_overlapped_va) {
 			assert((mm->base_va - mm->base_pa) ==
 			       (base_va - base_pa));
 			assert((base_va != mm->base_va) || (size != mm->size));
@@ -124,12 +124,12 @@
 			unsigned long long mm_end_pa =
 						     mm->base_pa + mm->size - 1;
 
-			int separated_pa = ((end_pa < mm->base_pa) ||
-				(base_pa > mm_end_pa)) ? 1 : 0;
-			int separated_va = ((end_va < mm->base_va) ||
-				(base_va > mm_end_va)) ? 1 : 0;
+			bool separated_pa = (end_pa < mm->base_pa) ||
+				(base_pa > mm_end_pa);
+			bool separated_va = (end_va < mm->base_va) ||
+				(base_va > mm_end_va);
 
-			assert((separated_va == 1) && (separated_pa == 1));
+			assert(separated_va && separated_pa);
 		}
 	}
 
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 21bb22d..2482840 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -9,7 +9,7 @@
 #include <assert.h>
 #include <cassert.h>
 #include <platform_def.h>
-#include <utils.h>
+#include <stdbool.h>
 #include <utils_def.h>
 #include <xlat_tables_v2.h>
 #include "../xlat_tables_private.h"
@@ -19,15 +19,15 @@
 #endif
 
 /*
- * Returns 1 if the provided granule size is supported, 0 otherwise.
+ * Returns true if the provided granule size is supported, false otherwise.
  */
-int xlat_arch_is_granule_size_supported(size_t size)
+bool xlat_arch_is_granule_size_supported(size_t size)
 {
 	/*
 	 * The library uses the long descriptor translation table format, which
 	 * supports 4 KiB pages only.
 	 */
-	return (size == PAGE_SIZE_4KB) ? 1 : 0;
+	return size == PAGE_SIZE_4KB;
 }
 
 size_t xlat_arch_get_max_supported_granule_size(void)
@@ -43,11 +43,16 @@
 }
 #endif /* ENABLE_ASSERTIONS*/
 
-int is_mmu_enabled_ctx(const xlat_ctx_t *ctx __unused)
+bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx __unused)
 {
 	return (read_sctlr() & SCTLR_M_BIT) != 0;
 }
 
+bool is_dcache_enabled(void)
+{
+	return (read_sctlr() & SCTLR_C_BIT) != 0;
+}
+
 uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime __unused)
 {
 	return UPPER_ATTRS(XN);
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 2494846..cf8070a 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -8,30 +8,31 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <cassert.h>
+#include <stdbool.h>
 #include <sys/types.h>
 #include <utils_def.h>
 #include <xlat_tables_v2.h>
 #include "../xlat_tables_private.h"
 
 /*
- * Returns 1 if the provided granule size is supported, 0 otherwise.
+ * Returns true if the provided granule size is supported, false otherwise.
  */
-int xlat_arch_is_granule_size_supported(size_t size)
+bool xlat_arch_is_granule_size_supported(size_t size)
 {
 	u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
 
 	if (size == PAGE_SIZE_4KB) {
-		return (((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
+		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
 			 ID_AA64MMFR0_EL1_TGRAN4_MASK) ==
-			 ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED) ? 1 : 0;
+			 ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED;
 	} else if (size == PAGE_SIZE_16KB) {
-		return (((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
+		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
 			 ID_AA64MMFR0_EL1_TGRAN16_MASK) ==
-			 ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED) ? 1 : 0;
+			 ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED;
 	} else if (size == PAGE_SIZE_64KB) {
-		return (((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
+		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
 			 ID_AA64MMFR0_EL1_TGRAN64_MASK) ==
-			 ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED) ? 1 : 0;
+			 ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED;
 	} else {
 		return 0;
 	}
@@ -39,12 +40,12 @@
 
 size_t xlat_arch_get_max_supported_granule_size(void)
 {
-	if (xlat_arch_is_granule_size_supported(PAGE_SIZE_64KB) != 0) {
+	if (xlat_arch_is_granule_size_supported(PAGE_SIZE_64KB)) {
 		return PAGE_SIZE_64KB;
-	} else if (xlat_arch_is_granule_size_supported(PAGE_SIZE_16KB) != 0) {
+	} else if (xlat_arch_is_granule_size_supported(PAGE_SIZE_16KB)) {
 		return PAGE_SIZE_16KB;
 	} else {
-		assert(xlat_arch_is_granule_size_supported(PAGE_SIZE_4KB) != 0);
+		assert(xlat_arch_is_granule_size_supported(PAGE_SIZE_4KB));
 		return PAGE_SIZE_4KB;
 	}
 }
@@ -99,15 +100,26 @@
 }
 #endif /* ENABLE_ASSERTIONS*/
 
-int is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
+bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
 {
 	if (ctx->xlat_regime == EL1_EL0_REGIME) {
 		assert(xlat_arch_current_el() >= 1U);
-		return ((read_sctlr_el1() & SCTLR_M_BIT) != 0U) ? 1 : 0;
+		return (read_sctlr_el1() & SCTLR_M_BIT) != 0U;
 	} else {
 		assert(ctx->xlat_regime == EL3_REGIME);
 		assert(xlat_arch_current_el() >= 3U);
-		return ((read_sctlr_el3() & SCTLR_M_BIT) != 0U) ? 1 : 0;
+		return (read_sctlr_el3() & SCTLR_M_BIT) != 0U;
+	}
+}
+
+bool is_dcache_enabled(void)
+{
+	unsigned int el = (unsigned int)GET_EL(read_CurrentEl());
+
+	if (el == 1U) {
+		return (read_sctlr_el1() & SCTLR_C_BIT) != 0U;
+	} else {
+		return (read_sctlr_el3() & SCTLR_C_BIT) != 0U;
 	}
 }
 
diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c
index d7b2ebf..143f08a 100644
--- a/lib/xlat_tables_v2/xlat_tables_context.c
+++ b/lib/xlat_tables_v2/xlat_tables_context.c
@@ -90,6 +90,16 @@
 	init_xlat_tables_ctx(&tf_xlat_ctx);
 }
 
+int xlat_get_mem_attributes(uintptr_t base_va, uint32_t *attr)
+{
+	return xlat_get_mem_attributes_ctx(&tf_xlat_ctx, base_va, attr);
+}
+
+int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr)
+{
+	return xlat_change_mem_attributes_ctx(&tf_xlat_ctx, base_va, size, attr);
+}
+
 /*
  * If dynamic allocation of new regions is disabled then by the time we call the
  * function enabling the MMU, we'll have registered all the memory regions to
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index 80cd0a2..56b9514 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -9,6 +9,7 @@
 #include <debug.h>
 #include <errno.h>
 #include <platform_def.h>
+#include <stdbool.h>
 #include <string.h>
 #include <types.h>
 #include <utils_def.h>
@@ -17,6 +18,13 @@
 
 #include "xlat_tables_private.h"
 
+/* Helper function that cleans the data cache only if it is enabled. */
+static inline void xlat_clean_dcache_range(uintptr_t addr, size_t size)
+{
+	if (is_dcache_enabled())
+		clean_dcache_range(addr, size);
+}
+
 #if PLAT_XLAT_TABLES_DYNAMIC
 
 /*
@@ -39,7 +47,7 @@
 	 * Maybe we were asked to get the index of the base level table, which
 	 * should never happen.
 	 */
-	assert(0);
+	assert(false);
 
 	return -1;
 }
@@ -73,10 +81,9 @@
 }
 
 /* Returns 0 if the specified table isn't empty, otherwise 1. */
-static int xlat_table_is_empty(const xlat_ctx_t *ctx, const uint64_t *table)
+static bool xlat_table_is_empty(const xlat_ctx_t *ctx, const uint64_t *table)
 {
-	return (ctx->tables_mapped_regions[xlat_table_get_index(ctx, table)] == 0)
-		? 1 : 0;
+	return ctx->tables_mapped_regions[xlat_table_get_index(ctx, table)] == 0;
 }
 
 #else /* PLAT_XLAT_TABLES_DYNAMIC */
@@ -329,11 +336,14 @@
 			xlat_tables_unmap_region(ctx, mm, table_idx_va,
 						 subtable, XLAT_TABLE_ENTRIES,
 						 level + 1U);
-
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+			xlat_clean_dcache_range((uintptr_t)subtable,
+				XLAT_TABLE_ENTRIES * sizeof(uint64_t));
+#endif
 			/*
 			 * If the subtable is now empty, remove its reference.
 			 */
-			if (xlat_table_is_empty(ctx, subtable) != 0) {
+			if (xlat_table_is_empty(ctx, subtable)) {
 				table_base[table_idx] = INVALID_DESC;
 				xlat_arch_tlbi_va(table_idx_va,
 						  ctx->xlat_regime);
@@ -563,6 +573,10 @@
 			end_va = xlat_tables_map_region(ctx, mm, table_idx_va,
 					       subtable, XLAT_TABLE_ENTRIES,
 					       level + 1U);
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+			xlat_clean_dcache_range((uintptr_t)subtable,
+				XLAT_TABLE_ENTRIES * sizeof(uint64_t));
+#endif
 			if (end_va !=
 				(table_idx_va + XLAT_BLOCK_SIZE(level) - 1U))
 				return end_va;
@@ -575,6 +589,10 @@
 			end_va = xlat_tables_map_region(ctx, mm, table_idx_va,
 					       subtable, XLAT_TABLE_ENTRIES,
 					       level + 1U);
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+			xlat_clean_dcache_range((uintptr_t)subtable,
+				XLAT_TABLE_ENTRIES * sizeof(uint64_t));
+#endif
 			if (end_va !=
 				(table_idx_va + XLAT_BLOCK_SIZE(level) - 1U))
 				return end_va;
@@ -650,12 +668,11 @@
 		 * Check if one of the regions is completely inside the other
 		 * one.
 		 */
-		int fully_overlapped_va =
-			(((base_va >= mm_cursor->base_va) &&
+		bool fully_overlapped_va =
+			((base_va >= mm_cursor->base_va) &&
 					(end_va <= mm_cursor_end_va)) ||
-			 ((mm_cursor->base_va >= base_va) &&
-						(mm_cursor_end_va <= end_va)))
-			? 1 : 0;
+			((mm_cursor->base_va >= base_va) &&
+						(mm_cursor_end_va <= end_va));
 
 		/*
 		 * Full VA overlaps are only allowed if both regions are
@@ -663,7 +680,7 @@
 		 * offset. Also, make sure that it's not the exact same area.
 		 * This can only be done with static regions.
 		 */
-		if (fully_overlapped_va != 0) {
+		if (fully_overlapped_va) {
 
 #if PLAT_XLAT_TABLES_DYNAMIC
 			if (((mm->attr & MT_DYNAMIC) != 0U) ||
@@ -688,12 +705,12 @@
 			unsigned long long mm_cursor_end_pa =
 				     mm_cursor->base_pa + mm_cursor->size - 1U;
 
-			int separated_pa = ((end_pa < mm_cursor->base_pa) ||
-				(base_pa > mm_cursor_end_pa)) ? 1 : 0;
-			int separated_va = ((end_va < mm_cursor->base_va) ||
-				(base_va > mm_cursor_end_va)) ? 1 : 0;
+			bool separated_pa = (end_pa < mm_cursor->base_pa) ||
+				(base_pa > mm_cursor_end_pa);
+			bool separated_va = (end_va < mm_cursor->base_va) ||
+				(base_va > mm_cursor_end_va);
 
-			if ((separated_va == 0) || (separated_pa == 0))
+			if (!separated_va || !separated_pa)
 				return -EPERM;
 		}
 	}
@@ -715,12 +732,12 @@
 		return;
 
 	/* Static regions must be added before initializing the xlat tables. */
-	assert(ctx->initialized == 0);
+	assert(!ctx->initialized);
 
 	ret = mmap_add_region_check(ctx, mm);
 	if (ret != 0) {
 		ERROR("mmap_add_region_check() failed. error %d\n", ret);
-		assert(0);
+		assert(false);
 		return;
 	}
 
@@ -856,11 +873,14 @@
 	 * Update the translation tables if the xlat tables are initialized. If
 	 * not, this region will be mapped when they are initialized.
 	 */
-	if (ctx->initialized != 0) {
+	if (ctx->initialized) {
 		end_va = xlat_tables_map_region(ctx, mm_cursor,
 				0U, ctx->base_table, ctx->base_table_entries,
 				ctx->base_level);
-
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+		xlat_clean_dcache_range((uintptr_t)ctx->base_table,
+				   ctx->base_table_entries * sizeof(uint64_t));
+#endif
 		/* Failed to map, remove mmap entry, unmap and return error. */
 		if (end_va != (mm_cursor->base_va + mm_cursor->size - 1U)) {
 			(void)memmove(mm_cursor, mm_cursor + 1U,
@@ -886,7 +906,10 @@
 			xlat_tables_unmap_region(ctx, &unmap_mm, 0U,
 				ctx->base_table, ctx->base_table_entries,
 				ctx->base_level);
-
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+			xlat_clean_dcache_range((uintptr_t)ctx->base_table,
+				ctx->base_table_entries * sizeof(uint64_t));
+#endif
 			return -ENOMEM;
 		}
 
@@ -948,10 +971,14 @@
 		update_max_pa_needed = 1;
 
 	/* Update the translation tables if needed */
-	if (ctx->initialized != 0) {
+	if (ctx->initialized) {
 		xlat_tables_unmap_region(ctx, mm, 0U, ctx->base_table,
 					 ctx->base_table_entries,
 					 ctx->base_level);
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+		xlat_clean_dcache_range((uintptr_t)ctx->base_table,
+			ctx->base_table_entries * sizeof(uint64_t));
+#endif
 		xlat_arch_tlbi_va_sync();
 	}
 
@@ -987,10 +1014,10 @@
 void init_xlat_tables_ctx(xlat_ctx_t *ctx)
 {
 	assert(ctx != NULL);
-	assert(ctx->initialized == 0);
+	assert(!ctx->initialized);
 	assert((ctx->xlat_regime == EL3_REGIME) ||
 	       (ctx->xlat_regime == EL1_EL0_REGIME));
-	assert(is_mmu_enabled_ctx(ctx) == 0);
+	assert(!is_mmu_enabled_ctx(ctx));
 
 	mmap_region_t *mm = ctx->mmap;
 
@@ -1013,7 +1040,10 @@
 		uintptr_t end_va = xlat_tables_map_region(ctx, mm, 0U,
 				ctx->base_table, ctx->base_table_entries,
 				ctx->base_level);
-
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+		xlat_clean_dcache_range((uintptr_t)ctx->base_table,
+				   ctx->base_table_entries * sizeof(uint64_t));
+#endif
 		if (end_va != (mm->base_va + mm->size - 1U)) {
 			ERROR("Not enough memory to map region:\n"
 			      " VA:0x%lx  PA:0x%llx  size:0x%zx  attr:0x%x\n",
@@ -1028,7 +1058,7 @@
 	assert(ctx->max_va <= ctx->va_max_address);
 	assert(ctx->max_pa <= ctx->pa_max_address);
 
-	ctx->initialized = 1;
+	ctx->initialized = true;
 
 	xlat_tables_print(ctx);
 }
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index 47c5ae8..528996a 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -8,6 +8,7 @@
 #define XLAT_TABLES_PRIVATE_H
 
 #include <platform_def.h>
+#include <stdbool.h>
 #include <xlat_tables_defs.h>
 
 #if PLAT_XLAT_TABLES_DYNAMIC
@@ -91,9 +92,12 @@
 unsigned long long xlat_arch_get_max_supported_pa(void);
 
 /*
- * Return 1 if the MMU of the translation regime managed by the given xlat_ctx_t
- * is enabled, 0 otherwise.
+ * Returns true if the MMU of the translation regime managed by the given
+ * xlat_ctx_t is enabled, false otherwise.
  */
-int is_mmu_enabled_ctx(const xlat_ctx_t *ctx);
+bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx);
+
+/* Returns true if the data cache is enabled at the current EL. */
+bool is_dcache_enabled(void);
 
 #endif /* XLAT_TABLES_PRIVATE_H */
diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c
index 0026e91..8cad348 100644
--- a/lib/xlat_tables_v2/xlat_tables_utils.c
+++ b/lib/xlat_tables_v2/xlat_tables_utils.c
@@ -9,6 +9,7 @@
 #include <debug.h>
 #include <errno.h>
 #include <platform_def.h>
+#include <stdbool.h>
 #include <types.h>
 #include <utils_def.h>
 #include <xlat_tables_defs.h>
@@ -307,14 +308,14 @@
 	 * This shouldn't be reached, the translation table walk should end at
 	 * most at level XLAT_TABLE_LEVEL_MAX and return from inside the loop.
 	 */
-	assert(0);
+	assert(false);
 
 	return NULL;
 }
 
 
-static int get_mem_attributes_internal(const xlat_ctx_t *ctx, uintptr_t base_va,
-		uint32_t *attributes, uint64_t **table_entry,
+static int xlat_get_mem_attributes_internal(const xlat_ctx_t *ctx,
+		uintptr_t base_va, uint32_t *attributes, uint64_t **table_entry,
 		unsigned long long *addr_pa, unsigned int *table_level)
 {
 	uint64_t *entry;
@@ -326,7 +327,7 @@
 	 * Sanity-check arguments.
 	 */
 	assert(ctx != NULL);
-	assert(ctx->initialized != 0);
+	assert(ctx->initialized);
 	assert((ctx->xlat_regime == EL1_EL0_REGIME) ||
 	       (ctx->xlat_regime == EL3_REGIME));
 
@@ -406,23 +407,21 @@
 }
 
 
-int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va,
-		       uint32_t *attributes)
+int xlat_get_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
+				uint32_t *attr)
 {
-	return get_mem_attributes_internal(ctx, base_va, attributes,
-					   NULL, NULL, NULL);
+	return xlat_get_mem_attributes_internal(ctx, base_va, attr,
+				NULL, NULL, NULL);
 }
 
 
-int change_mem_attributes(const xlat_ctx_t *ctx,
-			uintptr_t base_va,
-			size_t size,
-			uint32_t attr)
+int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
+				   size_t size, uint32_t attr)
 {
 	/* Note: This implementation isn't optimized. */
 
 	assert(ctx != NULL);
-	assert(ctx->initialized != 0);
+	assert(ctx->initialized);
 
 	unsigned long long virt_addr_space_size =
 		(unsigned long long)ctx->va_max_address + 1U;
@@ -516,7 +515,7 @@
 		unsigned int level = 0U;
 		unsigned long long addr_pa = 0ULL;
 
-		(void) get_mem_attributes_internal(ctx, base_va, &old_attr,
+		(void) xlat_get_mem_attributes_internal(ctx, base_va, &old_attr,
 					    &entry, &addr_pa, &level);
 
 		/*
@@ -540,7 +539,9 @@
 		 * before writing the new descriptor.
 		 */
 		*entry = INVALID_DESC;
-
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+		dccvac((uintptr_t)entry);
+#endif
 		/* Invalidate any cached copy of this mapping in the TLBs. */
 		xlat_arch_tlbi_va(base_va, ctx->xlat_regime);
 
@@ -549,7 +550,9 @@
 
 		/* Write new descriptor */
 		*entry = xlat_desc(ctx, new_attr, addr_pa, level);
-
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+		dccvac((uintptr_t)entry);
+#endif
 		base_va += PAGE_SIZE;
 	}
 
diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
new file mode 100644
index 0000000..9502549
--- /dev/null
+++ b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	/* Platform Config */
+	plat_arm_bl2 {
+		compatible = "arm,tb_fw";
+		hw_config_addr = <0x0 0x83000000>;
+		hw_config_max_size = <0x01000000>;
+	};
+};
diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h
new file mode 100644
index 0000000..babe093
--- /dev/null
+++ b/plat/arm/board/sgm775/include/platform_def.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <sgm_base_platform_def.h>
+
+#define PLAT_MAX_CPUS_PER_CLUSTER	8
+#define PLAT_MAX_PE_PER_CPU		1
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
new file mode 100644
index 0000000..71e71e1
--- /dev/null
+++ b/plat/arm/board/sgm775/platform.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/arm/css/sgm/sgm-common.mk
+
+SGM775_BASE= plat/arm/board/sgm775
+
+FDT_SOURCES += ${SGM775_BASE}/fdts/sgm775_tb_fw_config.dts
+
+PLAT_INCLUDES +=-I${SGM775_BASE}/include/
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 9483976..a192a06 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -28,15 +28,26 @@
 					bl1_tzram_layout.total_base,	\
 					bl1_tzram_layout.total_size,	\
 					MT_MEMORY | MT_RW | MT_SECURE)
-#define MAP_BL1_CODE		MAP_REGION_FLAT(			\
+/*
+ * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section
+ * otherwise one region is defined containing both
+ */
+#if SEPARATE_CODE_AND_RODATA
+#define MAP_BL1_RO		MAP_REGION_FLAT(			\
 					BL_CODE_BASE,			\
 					BL1_CODE_END - BL_CODE_BASE,	\
-					MT_CODE | MT_SECURE)
-#define MAP_BL1_RO_DATA		MAP_REGION_FLAT(			\
+					MT_CODE | MT_SECURE),		\
+				MAP_REGION_FLAT(			\
 					BL1_RO_DATA_BASE,		\
 					BL1_RO_DATA_END			\
 						- BL_RO_DATA_BASE,	\
 					MT_RO_DATA | MT_SECURE)
+#else
+#define MAP_BL1_RO		MAP_REGION_FLAT(			\
+					BL_CODE_BASE,			\
+					BL1_CODE_END - BL_CODE_BASE,	\
+					MT_CODE | MT_SECURE)
+#endif
 
 /* Data structure which holds the extents of the trusted SRAM for BL1*/
 static meminfo_t bl1_tzram_layout;
@@ -105,8 +116,7 @@
 
 	const mmap_region_t bl_regions[] = {
 		MAP_BL1_TOTAL,
-		MAP_BL1_CODE,
-		MAP_BL1_RO_DATA,
+		MAP_BL1_RO,
 		{0}
 	};
 
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index 1d602bb..1c93214 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -75,8 +75,7 @@
 
 	const mmap_region_t bl_regions[] = {
 		MAP_BL2_EL3_TOTAL,
-		ARM_MAP_BL_CODE,
-		ARM_MAP_BL_RO_DATA,
+		ARM_MAP_BL_RO,
 		{0}
 	};
 
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 88c0bc9..39aceb3 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -245,8 +245,7 @@
 
 	const mmap_region_t bl_regions[] = {
 		MAP_BL2_TOTAL,
-		ARM_MAP_BL_CODE,
-		ARM_MAP_BL_RO_DATA,
+		ARM_MAP_BL_RO,
 		{0}
 	};
 
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index 2bf8a93..a626830 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -72,8 +72,7 @@
 
 	const mmap_region_t bl_regions[] = {
 		MAP_BL2U_TOTAL,
-		ARM_MAP_BL_CODE,
-		ARM_MAP_BL_RO_DATA,
+		ARM_MAP_BL_RO,
 		{0}
 	};
 
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 557854c..0b64804 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -287,8 +287,7 @@
 
 	const mmap_region_t bl_regions[] = {
 		MAP_BL31_TOTAL,
-		ARM_MAP_BL_CODE,
-		ARM_MAP_BL_RO_DATA,
+		ARM_MAP_BL_RO,
 #if USE_COHERENT_MEM
 		ARM_MAP_BL_COHERENT_RAM,
 #endif
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index 89c502c..8cb81e7 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -7,6 +7,7 @@
 #include <arm_def.h>
 #include <assert.h>
 #include <debug.h>
+#include <plat_arm.h>
 #include <platform_def.h>
 #include <tzc_dmc500.h>
 
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index c7f317c..935290e 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -203,8 +203,7 @@
 {
 	const mmap_region_t bl_regions[] = {
 		MAP_BL_SP_MIN_TOTAL,
-		ARM_MAP_BL_CODE,
-		ARM_MAP_BL_RO_DATA,
+		ARM_MAP_BL_RO,
 #if USE_COHERENT_MEM
 		ARM_MAP_BL_COHERENT_RAM,
 #endif
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index 491705d..2d42d8e 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -81,8 +81,7 @@
 
 	const mmap_region_t bl_regions[] = {
 		MAP_BL_TSP_TOTAL,
-		ARM_MAP_BL_CODE,
-		ARM_MAP_BL_RO_DATA,
+		ARM_MAP_BL_RO,
 		{0}
 	};
 
diff --git a/plat/arm/css/common/css_topology.c b/plat/arm/css/common/css_topology.c
index 42f9455..d1f1c98 100644
--- a/plat/arm/css/common/css_topology.c
+++ b/plat/arm/css/common/css_topology.c
@@ -23,6 +23,12 @@
 	if (arm_check_mpidr(mpidr) == 0) {
 #if ARM_PLAT_MT
 		assert((read_mpidr_el1() & MPIDR_MT_MASK) != 0);
+
+		/*
+		 * The DTB files don't provide the MT bit in the mpidr argument
+		 * so set it manually before calculating core position
+		 */
+		mpidr |= MPIDR_MT_MASK;
 #endif
 		return plat_arm_calc_core_pos(mpidr);
 	}
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c
index 7032267..cb39da2 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scmi.c
@@ -79,8 +79,7 @@
  */
 void css_scp_suspend(const struct psci_power_state *target_state)
 {
-	int lvl, ret;
-	uint32_t scmi_pwr_state = 0;
+	int ret;
 
 	/* At least power domain level 0 should be specified to be suspended */
 	assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
@@ -99,7 +98,9 @@
 		}
 		return;
 	}
-
+#if !HW_ASSISTED_COHERENCY
+	int lvl;
+	uint32_t scmi_pwr_state = 0;
 	/*
 	 * If we reach here, then assert that power down at system power domain
 	 * level is running.
@@ -136,6 +137,7 @@
 				ret);
 		panic();
 	}
+#endif
 }
 
 /*
diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S
index aaa5156..dd0fc5b 100644
--- a/plat/arm/css/sgi/aarch64/sgi_helper.S
+++ b/plat/arm/css/sgi/aarch64/sgi_helper.S
@@ -7,30 +7,12 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <platform_def.h>
+#include <cortex_a75.h>
 
-	.globl	plat_is_my_cpu_primary
 	.globl	plat_arm_calc_core_pos
+	.globl	plat_reset_handler
 
 	/* -----------------------------------------------------
-	 * unsigned int plat_is_my_cpu_primary (void);
-	 *
-	 * Find out whether the current cpu is the primary
-	 * cpu (applicable only after a cold boot)
-	 * -----------------------------------------------------
-	 */
-func plat_is_my_cpu_primary
-	mov	x9, x30
-	bl	plat_my_core_pos
-	ldr	x1, =SGI_BOOT_CFG_ADDR
-	ldr	x1, [x1]
-	ubfx	x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \
-			#PLAT_CSS_PRIMARY_CPU_BIT_WIDTH
-	cmp	x0, x1
-	cset	w0, eq
-	ret	x9
-endfunc plat_is_my_cpu_primary
-
-	/* -----------------------------------------------------
 	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
 	 *
 	 * Helper function to calculate the core position.
@@ -65,3 +47,41 @@
 	madd    x0, x1, x5, x0
 	ret
 endfunc plat_arm_calc_core_pos
+
+	/* ------------------------------------------------------
+	 * Helper macro that reads the part number of the current
+	 * CPU and jumps to the given label if it matches the CPU
+	 * MIDR provided.
+	 *
+	 * Clobbers x0.
+	 * -----------------------------------------------------
+	 */
+	.macro  jump_if_cpu_midr _cpu_midr, _label
+	mrs	x0, midr_el1
+	ubfx	x0, x0, MIDR_PN_SHIFT, #12
+	cmp	w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+	b.eq	\_label
+	.endm
+
+	/* -----------------------------------------------------
+	 * void plat_reset_handler(void);
+	 *
+	 * Determine the CPU MIDR and disable power down bit for
+	 * that CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_reset_handler
+	jump_if_cpu_midr CORTEX_A75_MIDR, A75
+	ret
+
+	/* -----------------------------------------------------
+	 * Disable CPU power down bit in power control register
+	 * -----------------------------------------------------
+	 */
+A75:
+	mrs	x0, CORTEX_A75_CPUPWRCTLR_EL1
+	bic	x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
+	msr	CORTEX_A75_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc plat_reset_handler
diff --git a/plat/arm/css/sgi/include/platform_def.h b/plat/arm/css/sgi/include/platform_def.h
index 169ae1b..c645d10 100644
--- a/plat/arm/css/sgi/include/platform_def.h
+++ b/plat/arm/css/sgi/include/platform_def.h
@@ -77,11 +77,6 @@
 					CSS_SGI_DEVICE_SIZE,	\
 					MT_DEVICE | MT_RW | MT_SECURE)
 
-#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE	0x45400000
-#define SGI_BOOT_CFG_ADDR			0x45410000
-#define PLAT_CSS_PRIMARY_CPU_SHIFT		8
-#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH		6
-
 /* GIC related constants */
 #define PLAT_ARM_GICD_BASE		0x30000000
 #define PLAT_ARM_GICC_BASE		0x2C000000
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index e0996c7..74d255c 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -4,6 +4,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+CSS_USE_SCMI_SDS_DRIVER		:=	1
+
 ENABLE_PLAT_COMPAT		:=	0
 
 CSS_ENT_BASE			:=	plat/arm/css/sgi
diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/css/sgi/sgi_topology.c
index 1d2e027..3f6357b 100644
--- a/plat/arm/css/sgi/sgi_topology.c
+++ b/plat/arm/css/sgi/sgi_topology.c
@@ -42,3 +42,12 @@
 {
 	return sgi_topology.plat_cluster_core_count;
 }
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[32] = {
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,		\
+	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
+};
diff --git a/plat/arm/css/sgm/aarch64/css_sgm_helpers.S b/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
new file mode 100644
index 0000000..d9b3df6
--- /dev/null
+++ b/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+#include <cortex_a75.h>
+#include <cortex_a55.h>
+
+	.globl	plat_arm_calc_core_pos
+	.globl	plat_reset_handler
+
+	/* ---------------------------------------------------------------------
+	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+	 *
+	 * Function to calculate the core position on FVP.
+	 *
+	 * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) +
+	 * (CPUId * MAX_PE_PER_CPU) +
+	 * ThreadId
+	 *
+	 * which can be simplified as:
+	 *
+	 * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * MAX_PE_PER_CPU)
+	 * + ThreadId
+	 * ---------------------------------------------------------------------
+	 */
+func plat_arm_calc_core_pos
+	/*
+	 * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+	 * look as if in a multi-threaded implementation.
+	 */
+	tst	x0, #MPIDR_MT_MASK
+	lsr	x3, x0, #MPIDR_AFFINITY_BITS
+	csel	x3, x3, x0, eq
+
+	/* Extract individual affinity fields from MPIDR */
+	ubfx	x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+	/* Compute linear position */
+	mov	x4, #PLAT_MAX_CPUS_PER_CLUSTER
+	madd	x1, x2, x4, x1
+	mov	x5, #PLAT_MAX_PE_PER_CPU
+	madd	x0, x1, x5, x0
+	ret
+endfunc plat_arm_calc_core_pos
+
+	/* ------------------------------------------------------
+	 * Helper macro that reads the part number of the current
+	 * CPU and jumps to the given label if it matches the CPU
+	 * MIDR provided.
+	 *
+	 * Clobbers x0.
+	 * -----------------------------------------------------
+	 */
+	.macro  jump_if_cpu_midr _cpu_midr, _label
+	mrs	x0, midr_el1
+	ubfx	x0, x0, MIDR_PN_SHIFT, #12
+	cmp	w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+	b.eq	\_label
+	.endm
+
+	/* -----------------------------------------------------
+	 * void plat_reset_handler(void);
+	 *
+	 * Determine the CPU MIDR and disable power down bit for
+	 * that CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_reset_handler
+	jump_if_cpu_midr CORTEX_A75_MIDR, A75
+	jump_if_cpu_midr CORTEX_A55_MIDR, A55
+	ret
+
+	/* -----------------------------------------------------
+	 * Disable CPU power down bit in power control register
+	 * -----------------------------------------------------
+	 */
+A75:
+	mrs	x0, CORTEX_A75_CPUPWRCTLR_EL1
+	bic	x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
+	msr	CORTEX_A75_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+A55:
+	mrs	x0, CORTEX_A55_CPUPWRCTLR_EL1
+	bic	x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
+	msr	CORTEX_A55_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc plat_reset_handler
diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
new file mode 100644
index 0000000..9502549
--- /dev/null
+++ b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	/* Platform Config */
+	plat_arm_bl2 {
+		compatible = "arm,tb_fw";
+		hw_config_addr = <0x0 0x83000000>;
+		hw_config_max_size = <0x01000000>;
+	};
+};
diff --git a/plat/arm/css/sgm/include/plat_macros.S b/plat/arm/css/sgm/include/plat_macros.S
new file mode 100644
index 0000000..d877ef8
--- /dev/null
+++ b/plat/arm/css/sgm/include/plat_macros.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <cci_macros.S>
+#include <css_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ * ---------------------------------------------
+ */
+.macro plat_crash_print_regs
+css_print_gic_regs
+print_cci_regs
+.endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/arm/css/sgm/include/platform_oid.h b/plat/arm/css/sgm/include/platform_oid.h
new file mode 100644
index 0000000..18d41e3
--- /dev/null
+++ b/plat/arm/css/sgm/include/platform_oid.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "../../../../../include/plat/arm/board/common/board_arm_oid.h"
+
+/*
+ * Required platform OIDs
+ * (Provided by included header)
+ */
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
new file mode 100644
index 0000000..2498430
--- /dev/null
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGM_BASE_PLATFORM_DEF_H__
+#define __SGM_BASE_PLATFORM_DEF_H__
+
+#include <arm_def.h>
+#include <board_arm_def.h>
+#include <board_css_def.h>
+#include <common_def.h>
+#include <css_def.h>
+#include <soc_css_def.h>
+#include <tzc400.h>
+#include <tzc_common.h>
+
+/* CPU topology */
+#define PLAT_ARM_CLUSTER_COUNT		1
+#define PLAT_ARM_CLUSTER_CORE_COUNT	8
+#define PLATFORM_CORE_COUNT		PLAT_ARM_CLUSTER_CORE_COUNT
+
+#define PLAT_MAX_PWR_LVL		ARM_PWR_LVL2
+#define PLAT_NUM_PWR_DOMAINS		(ARM_SYSTEM_COUNT + \
+					PLAT_ARM_CLUSTER_COUNT + \
+					PLATFORM_CORE_COUNT)
+
+/*
+ * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+			CSS_G1S_IRQ_PROPS(grp), \
+			ARM_G1S_IRQ_PROPS(grp)
+
+#define PLAT_ARM_G0_IRQ_PROPS(grp)	ARM_G0_IRQ_PROPS(grp)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE		0x30000000
+#define PLAT_ARM_GICR_BASE		0x300C0000
+#define PLAT_ARM_GICC_BASE		0x2c000000
+
+#define CSS_GIC_SIZE			0x00200000
+
+#define CSS_MAP_GIC_DEVICE		MAP_REGION_FLAT(	\
+					PLAT_ARM_GICD_BASE,	\
+					CSS_GIC_SIZE,		\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+/* Platform ID address */
+#define SSC_VERSION                     (SSC_REG_BASE + SSC_VERSION_OFFSET)
+#ifndef __ASSEMBLY__
+/* SSC_VERSION related accessors */
+/* Returns the part number of the platform */
+#define GET_PLAT_PART_NUM                                       \
+		GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
+/* Returns the configuration number of the platform */
+#define GET_PLAT_CONFIG_NUM                                     \
+		GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
+#endif /* __ASSEMBLY__ */
+
+
+/*************************************************************************
+ * Definitions common to all SGM CSS based platforms
+ *************************************************************************/
+
+/* TZC-400 related constants */
+#define PLAT_ARM_TZC_BASE		0x2a500000
+#define TZC_NSAID_ALL_AP		0  /* Note: Same as default NSAID!! */
+#define TZC_NSAID_HDLCD0		2
+#define TZC_NSAID_HDLCD1		3
+#define TZC_NSAID_GPU			9
+#define TZC_NSAID_VIDEO			10
+#define TZC_NSAID_DISP0			11
+#define TZC_NSAID_DISP1			12
+
+
+/*************************************************************************
+ * Required platform porting definitions common to all SGM CSS based
+ * platforms
+ *************************************************************************/
+
+/* MHU related constants */
+#define PLAT_CSS_MHU_BASE		0x2b1f0000
+
+#define PLAT_ARM_TRUSTED_ROM_BASE	0x00000000
+#define PLAT_ARM_TRUSTED_ROM_SIZE	0x00080000
+
+#define PLAT_ARM_CCI_BASE		0x2a000000
+
+/* Cluster to CCI slave mapping */
+#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX	6
+#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX	5
+
+/* System timer related constants */
+#define PLAT_ARM_NSTIMER_FRAME_ID	0
+
+/* TZC related constants */
+#define PLAT_ARM_TZC_NS_DEV_ACCESS	(				\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD1)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_GPU)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIDEO)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP0)	|	\
+		TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP1))
+
+/* Display Processor register definitions to setup the NSAIDs */
+#define MALI_DP_BASE           0x2cc00000
+#define DP_NPROT_NSAID_OFFSET     0x1000c
+#define W_NPROT_NSAID_SHIFT            24
+#define LS_NPORT_NSAID_SHIFT           12
+
+/*
+ * Base address of the first memory region used for communication between AP
+ * and SCP. Used by the BootOverMHU and SCPI protocols.
+ */
+#if !CSS_USE_SCMI_SDS_DRIVER
+/*
+ * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which
+ * means the SCP/AP configuration data gets overwritten when the AP initiates
+ * communication with the SCP. The configuration data is expected to be a
+ * 32-bit word on all CSS platforms. Part of this configuration is
+ * which CPU is the primary, according to the shift and mask definitions below.
+ */
+#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE	(ARM_TRUSTED_SRAM_BASE + 0x80)
+#define PLAT_CSS_PRIMARY_CPU_SHIFT		8
+#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH		4
+#endif
+
+/*
+ * tspd support is conditional so enable this for CSS sgm platforms.
+ */
+#define SPD_tspd
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
+ * SCP_BL2 size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x15000
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
+ * SCP_BL2U size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x15000
+
+/*
+ * Most platform porting definitions provided by included headers
+ */
+
+/*
+ * If ARM_BOARD_OPTIMISE_MEM=0 then use the default, unoptimised values
+ * defined for ARM development platforms.
+ */
+#if ARM_BOARD_OPTIMISE_MEM
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#if IMAGE_BL1
+# if TRUSTED_BOARD_BOOT
+#  define PLAT_ARM_MMAP_ENTRIES		7
+# else
+#  define PLAT_ARM_MMAP_ENTRIES		6
+# endif /* TRUSTED_BOARD_BOOT */
+#elif IMAGE_BL2
+#  define PLAT_ARM_MMAP_ENTRIES		8
+#elif IMAGE_BL2U
+#  define PLAT_ARM_MMAP_ENTRIES		4
+#elif IMAGE_BL31
+#  define PLAT_ARM_MMAP_ENTRIES		6
+#elif IMAGE_BL32
+#  define PLAT_ARM_MMAP_ENTRIES		5
+#endif
+
+/*
+ * Platform specific page table and MMU setup constants
+ */
+#if IMAGE_BL1
+# if TRUSTED_BOARD_BOOT
+#  define MAX_XLAT_TABLES		4
+# else
+#  define MAX_XLAT_TABLES		3
+#endif
+#elif IMAGE_BL2
+#  define MAX_XLAT_TABLES		4
+#elif IMAGE_BL2U
+#  define MAX_XLAT_TABLES		4
+#elif IMAGE_BL31
+#  define MAX_XLAT_TABLES		2
+#elif IMAGE_BL32
+# if ARM_TSP_RAM_LOCATION_ID == ARM_DRAM_ID
+#  define MAX_XLAT_TABLES		3
+# else
+#  define MAX_XLAT_TABLES		2
+# endif
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+# define PLAT_ARM_MAX_BL1_RW_SIZE	0xA000
+#else
+# define PLAT_ARM_MAX_BL1_RW_SIZE	0x7000
+#endif
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth.
+ */
+#if TRUSTED_BOARD_BOOT
+# define PLAT_ARM_MAX_BL2_SIZE		0x1D000
+#else
+# define PLAT_ARM_MAX_BL2_SIZE		0xD000
+#endif
+
+#endif /* ARM_BOARD_OPTIMISE_MEM */
+
+/*******************************************************************************
+ * Memprotect definitions
+ ******************************************************************************/
+/* PSCI memory protect definitions:
+ * This variable is stored in a non-secure flash because some ARM reference
+ * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
+ * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
+ */
+#define PLAT_ARM_MEM_PROT_ADDR		(V2M_FLASH0_BASE + \
+					 V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+#endif /* __SGM_BASE_PLATFORM_DEF_H__ */
diff --git a/plat/arm/css/sgm/include/sgm_plat_config.h b/plat/arm/css/sgm/include/sgm_plat_config.h
new file mode 100644
index 0000000..b171d9a
--- /dev/null
+++ b/plat/arm/css/sgm/include/sgm_plat_config.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGM_PLAT_CONFIG_H__
+#define __SGM_PLAT_CONFIG_H__
+
+#include <arm_gic.h>
+#include <ccn.h>
+#include <gicv3.h>
+
+/* The type of interconnect */
+typedef enum {
+	ARM_CCI = 0,
+	ARM_CCN,
+	ARM_CMN
+} css_inteconn_type_t;
+
+typedef ccn_desc_t inteconn_desc_t;
+
+/* Interconnect configurations */
+typedef struct css_inteconn_config {
+	css_inteconn_type_t ip_type;
+	const inteconn_desc_t *plat_inteconn_desc;
+} css_inteconn_config_t;
+
+/* Topology configurations */
+typedef struct css_topology {
+	const unsigned char *power_tree;
+	unsigned int plat_cluster_core_count;
+} css_topology_t;
+
+typedef struct css_plat_config {
+	const gicv3_driver_data_t *gic_data;
+	const css_inteconn_config_t *inteconn;
+	const css_topology_t *topology;
+} css_plat_config_t;
+
+void plat_config_init(void);
+css_plat_config_t *get_plat_config(void);
+#endif /* __SGM_PLAT_CONFIG_H__ */
diff --git a/plat/arm/css/sgm/include/sgm_variant.h b/plat/arm/css/sgm/include/sgm_variant.h
new file mode 100644
index 0000000..a0a91b0
--- /dev/null
+++ b/plat/arm/css/sgm/include/sgm_variant.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGM_VARIANT_H__
+#define __SGM_VARIANT_H__
+
+/* SSC_VERSION values for sgm */
+#define SGM775_SSC_VER_PART_NUM		0x0790
+
+/* DMC configuration for sgm */
+#define SGM_DMC_SIZE			0x40000
+#define SGM775_DMC_COUNT		4
+
+#endif /* __SGM_VARIANT_H__ */
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
new file mode 100644
index 0000000..6a3caba
--- /dev/null
+++ b/plat/arm/css/sgm/sgm-common.mk
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+CSS_SGM_BASE		:=	plat/arm/css/sgm
+
+PLAT_INCLUDES		:=	-I${CSS_SGM_BASE}/include
+
+PLAT_BL_COMMON_SOURCES	:=	${CSS_SGM_BASE}/sgm_mmap_config.c	\
+				${CSS_SGM_BASE}/aarch64/css_sgm_helpers.S
+
+SECURITY_SOURCES	:=	drivers/arm/tzc/tzc_dmc500.c		\
+				plat/arm/common/arm_tzc_dmc500.c 	\
+				${CSS_SGM_BASE}/sgm_security.c
+
+SGM_CPU_SOURCES		:=	lib/cpus/aarch64/cortex_a55.S		\
+				lib/cpus/aarch64/cortex_a75.S
+
+INTERCONNECT_SOURCES	:=	${CSS_SGM_BASE}/sgm_interconnect.c
+
+SGM_GIC_SOURCES		:=	drivers/arm/gic/common/gic_common.c	\
+				drivers/arm/gic/v3/gicv3_main.c		\
+				drivers/arm/gic/v3/gicv3_helpers.c	\
+				plat/common/plat_gicv3.c		\
+				plat/arm/common/arm_gicv3.c		\
+				drivers/arm/gic/v3/gic600.c		\
+				drivers/arm/gic/v3/arm_gicv3_common.c
+
+BL1_SOURCES		+=	$(SGM_CPU_SOURCES)			\
+				${INTERCONNECT_SOURCES}			\
+				${CSS_SGM_BASE}/sgm_bl1_setup.c	\
+				${CSS_SGM_BASE}/sgm_plat_config.c
+
+BL2_SOURCES		+=	${SECURITY_SOURCES}
+
+BL2U_SOURCES		+=	${SECURITY_SOURCES}
+
+BL31_SOURCES		+=	$(SGM_CPU_SOURCES)			\
+				${INTERCONNECT_SOURCES}			\
+				${SECURITY_SOURCES}			\
+				${SGM_GIC_SOURCES}			\
+				${CSS_SGM_BASE}/sgm_topology.c	\
+				${CSS_SGM_BASE}/sgm_bl31_setup.c	\
+				${CSS_SGM_BASE}/sgm_plat_config.c
+
+# sgm uses CCI-500 as Cache Coherent Interconnect
+ARM_CCI_PRODUCT_ID	:=	500
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT	:=	0
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY	:=	1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM	:=	0
+
+override ARM_PLAT_MT	:=	1
+
+$(eval $(call add_define,SGM_PLAT))
+
+include plat/arm/common/arm_common.mk
+include plat/arm/board/common/board_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
new file mode 100644
index 0000000..51e3e53
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_bl1_setup.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+#include <soc_css.h>
+
+void bl1_early_platform_setup(void)
+{
+	/* Initialize the platform configuration structure */
+	plat_config_init();
+
+	arm_bl1_early_platform_setup();
+
+#if !HW_ASSISTED_COHERENCY
+	/*
+	 * Initialize Interconnect for this cluster during cold boot.
+	 * No need for locks as no other CPU is active.
+	 */
+	plat_arm_interconnect_init();
+	/*
+	 * Enable Interconnect coherency for the primary CPU's cluster.
+	 */
+	plat_arm_interconnect_enter_coherency();
+#endif
+}
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
new file mode 100644
index 0000000..a55176a
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_bl31_setup.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	uint32_t plat_version;
+	bl_params_node_t *bl_params;
+
+	bl_params = ((bl_params_t *)arg0)->head;
+
+	/* Initialize the platform configuration structure */
+	plat_config_init();
+
+	while (bl_params) {
+		if (bl_params->image_id == BL33_IMAGE_ID) {
+			plat_version = mmio_read_32(SSC_VERSION);
+			bl_params->ep_info->args.arg2 = plat_version;
+			break;
+		}
+
+		bl_params = bl_params->next_params_info;
+	}
+
+	arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+}
diff --git a/plat/arm/css/sgm/sgm_interconnect.c b/plat/arm/css/sgm/sgm_interconnect.c
new file mode 100644
index 0000000..301ea84
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_interconnect.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * As the SGM platform supports FCM (with automatic interconnect
+ * enter/exit), we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers.
+ */
+
+/******************************************************************************
+ * Helper function to initialize ARM interconnect driver.
+ *****************************************************************************/
+void plat_arm_interconnect_init(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to place current master into coherency
+ *****************************************************************************/
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to remove current master from coherency
+ *****************************************************************************/
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
diff --git a/plat/arm/css/sgm/sgm_mmap_config.c b/plat/arm/css/sgm/sgm_mmap_config.c
new file mode 100644
index 0000000..009ee64
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_mmap_config.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_def.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <platform_def.h>
+#include <sgm_variant.h>
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * arm_configure_mmu_elx() will give the available subset of that.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	V2M_MAP_FLASH0_RO,
+	V2M_MAP_IOFPGA,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+#if TRUSTED_BOARD_BOOT
+	ARM_MAP_NS_DRAM1,
+#endif
+	{0}
+};
+#endif
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	V2M_MAP_FLASH0_RO,
+	V2M_MAP_IOFPGA,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	ARM_MAP_NS_DRAM1,
+	ARM_MAP_TSP_SEC_MEM,
+#ifdef SPD_opteed
+	ARM_OPTEE_PAGEABLE_LOAD_MEM,
+#endif
+	{0}
+};
+#endif
+#if IMAGE_BL2U
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	{0}
+};
+#endif
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	V2M_MAP_IOFPGA,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	{0}
+};
+#endif
+#if IMAGE_BL32
+const mmap_region_t plat_arm_mmap[] = {
+	V2M_MAP_IOFPGA,
+	CSS_MAP_DEVICE,
+	CSS_MAP_GIC_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	{0}
+};
+#endif
+
+ARM_CASSERT_MMAP
+
+const mmap_region_t *plat_arm_get_mmap(void)
+{
+	return plat_arm_mmap;
+}
diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c
new file mode 100644
index 0000000..809edf6
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_plat_config.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <platform_def.h>
+#include <sgm_plat_config.h>
+#include <sgm_variant.h>
+#include <string.h>
+
+static css_plat_config_t *css_plat_info;
+
+/* Interconnect */
+const css_inteconn_config_t sgm_inteconn = {
+	.ip_type = ARM_CCI,
+	.plat_inteconn_desc = NULL
+};
+
+/* Special definition for SGM775 */
+/* Topology configuration for SGM775 */
+const unsigned char sgm775_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	ARM_SYSTEM_COUNT,
+	/* No of children for the root node */
+	PLAT_ARM_CLUSTER_COUNT,
+	/* No of children for the first cluster node */
+	PLAT_ARM_CLUSTER_CORE_COUNT,
+};
+
+const css_topology_t sgm775_topology = {
+	.power_tree = sgm775_power_domain_tree_desc,
+	.plat_cluster_core_count = PLAT_ARM_CLUSTER_CORE_COUNT
+};
+
+/* Configuration structure for SGM775 */
+css_plat_config_t sgm775_config = {
+	.inteconn = &sgm_inteconn,
+	.topology = &sgm775_topology
+};
+
+/*******************************************************************************
+ * This function initializes the platform structure.
+ ******************************************************************************/
+void plat_config_init(void)
+{
+	/* Get the platform configurations */
+	switch (GET_PLAT_PART_NUM) {
+	case SGM775_SSC_VER_PART_NUM:
+		css_plat_info = &sgm775_config;
+
+		break;
+	default:
+		ERROR("Not a valid sgm variant!\n");
+		panic();
+	}
+}
+
+/*******************************************************************************
+ * This function returns the platform structure pointer.
+ ******************************************************************************/
+css_plat_config_t *get_plat_config(void)
+{
+	assert(css_plat_info != NULL);
+	return css_plat_info;
+}
diff --git a/plat/arm/css/sgm/sgm_security.c b/plat/arm/css/sgm/sgm_security.c
new file mode 100644
index 0000000..7f98060
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_security.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <plat_arm.h>
+#include <sgm_variant.h>
+#include <soc_css.h>
+#include <tzc_dmc500.h>
+
+/* Is populated with the DMC-500 controllers base addresses */
+static tzc_dmc500_driver_data_t plat_driver_data;
+
+void plat_sgm_dp_security_setup(void)
+{
+	unsigned int nprot_nsaid;
+
+	/*
+	 * At reset the Mali display processors start with NSAIDs set to zero
+	 * so the firmware must set them up to the expected values for ARM sgm
+	 * platforms.
+	 */
+
+	nprot_nsaid = mmio_read_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET);
+	nprot_nsaid &= ~((0xF << W_NPROT_NSAID_SHIFT) |
+			(0xF << LS_NPORT_NSAID_SHIFT));
+	nprot_nsaid |= ((TZC_NSAID_DISP1 << W_NPROT_NSAID_SHIFT) |
+			(TZC_NSAID_DISP0 << LS_NPORT_NSAID_SHIFT));
+	mmio_write_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET, nprot_nsaid);
+}
+
+void plat_arm_security_setup(void)
+{
+	unsigned int i;
+	unsigned int part_num = GET_PLAT_PART_NUM;
+
+	INFO("part_num: 0x%x\n", part_num);
+
+	/*
+	 * Initialise plat_driver_data with platform specific DMC_BASE
+	 * addresses
+	 */
+	switch (part_num) {
+	case SGM775_SSC_VER_PART_NUM:
+		for (i = 0; i < SGM775_DMC_COUNT; i++)
+			plat_driver_data.dmc_base[i] = PLAT_ARM_TZC_BASE
+					+ SGM_DMC_SIZE * i;
+		plat_driver_data.dmc_count = SGM775_DMC_COUNT;
+		break;
+	default:
+		/* Unexpected platform */
+		ERROR("Unexpected platform\n");
+		panic();
+	}
+	/* Initialize the TrustZone Controller in DMC-500 */
+	arm_tzc_dmc500_setup(&plat_driver_data, NULL);
+
+	/* Do DP NSAID setup */
+	plat_sgm_dp_security_setup();
+	/* Do ARM CSS SoC security setup */
+	soc_css_security_setup();
+}
diff --git a/plat/arm/css/sgm/sgm_topology.c b/plat/arm/css/sgm/sgm_topology.c
new file mode 100644
index 0000000..ce72464
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_topology.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return get_plat_config()->topology->power_tree;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+	return get_plat_config()->topology->plat_cluster_core_count;
+}
+
+/*
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ */
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
+			0, 1, 2, 3, 4, 5, 6, 7 };
diff --git a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
new file mode 100644
index 0000000..39bba94
--- /dev/null
+++ b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+
+void tsp_early_platform_setup(void)
+{
+	/* Initialize the platform configuration structure */
+	plat_config_init();
+
+	arm_tsp_early_platform_setup();
+}
diff --git a/plat/arm/css/sgm/tsp/tsp-sgm.mk b/plat/arm/css/sgm/tsp/tsp-sgm.mk
new file mode 100644
index 0000000..a9e4131
--- /dev/null
+++ b/plat/arm/css/sgm/tsp/tsp-sgm.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES		+= 	${SGM_GIC_SOURCES}			\
+				${CSS_SGM_BASE}/sgm_plat_config.c	\
+				plat/arm/board/sgm/tsp/sgm_tsp_setup.c
+
+include plat/arm/common/tsp/arm_tsp.mk
diff --git a/readme.rst b/readme.rst
index c87936c..a82af64 100644
--- a/readme.rst
+++ b/readme.rst
@@ -33,16 +33,25 @@
 -  The stdlib source code is derived from FreeBSD code, which uses various
    BSD licenses, including BSD-3-Clause and BSD-2-Clause.
 
--  The libfdt source code is dual licensed. It is used by this project under
-   the terms of the BSD-2-Clause license.
+-  The libfdt source code is disjunctively dual licensed
+   (GPL-2.0+ OR BSD-2-Clause). It is used by this project under the terms of
+   the BSD-2-Clause license. Any contributions to this code must be made under
+   the terms of both licenses.
 
--  The LLVM compiler-rt source code is dual licensed. It is used by this
-   project under the terms of the NCSA license (also known as the University of
-   Illinois/NCSA Open Source License).
+-  The LLVM compiler-rt source code is disjunctively dual licensed
+   (NCSA OR MIT). It is used by this project under the terms of the NCSA
+   license (also known as the University of Illinois/NCSA Open Source License),
+   which is a permissive license compatible with BSD-3-Clause. Any
+   contributions to this code must be made under the terms of both licenses.
 
 -  The zlib source code is licensed under the Zlib license, which is a
    permissive license compatible with BSD-3-Clause.
 
+-  Some STMicroelectronics platform source code is disjunctively dual licensed
+   (GPL-2.0+ OR BSD-3-Clause). It is used by this project under the terms of the
+   BSD-3-Clause license. Any contributions to this code must be made under the
+   terms of both licenses.
+
 This release
 ------------
 
diff --git a/services/spd/trusty/generic-arm64-smcall.c b/services/spd/trusty/generic-arm64-smcall.c
index 38da279..feeecaa 100644
--- a/services/spd/trusty/generic-arm64-smcall.c
+++ b/services/spd/trusty/generic-arm64-smcall.c
@@ -57,14 +57,14 @@
 	}
 }
 
-static uint64_t trusty_generic_platform_smc(uint32_t smc_fid,
-			 uint64_t x1,
-			 uint64_t x2,
-			 uint64_t x3,
-			 uint64_t x4,
+static uintptr_t trusty_generic_platform_smc(uint32_t smc_fid,
+			 u_register_t x1,
+			 u_register_t x2,
+			 u_register_t x3,
+			 u_register_t x4,
 			 void *cookie,
 			 void *handle,
-			 uint64_t flags)
+			 u_register_t flags)
 {
 	switch (smc_fid) {
 	case SMC_FC_DEBUG_PUTC:
diff --git a/services/std_svc/spm/sp_xlat.c b/services/std_svc/spm/sp_xlat.c
index 2aa2fa1..3527138 100644
--- a/services/std_svc/spm/sp_xlat.c
+++ b/services/std_svc/spm/sp_xlat.c
@@ -44,7 +44,7 @@
  * converts an attributes value from the SMC format to the mmap_attr_t format by
  * setting MT_RW/MT_RO, MT_USER/MT_PRIVILEGED and MT_EXECUTE/MT_EXECUTE_NEVER.
  * The other fields are left as 0 because they are ignored by the function
- * change_mem_attributes().
+ * xlat_change_mem_attributes_ctx().
  */
 static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
 {
@@ -112,12 +112,12 @@
 
 	spin_lock(&mem_attr_smc_lock);
 
-	int rc = get_mem_attributes(sp_ctx->xlat_ctx_handle,
+	int rc = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
 				     base_va, &attributes);
 
 	spin_unlock(&mem_attr_smc_lock);
 
-	/* Convert error codes of get_mem_attributes() into SPM ones. */
+	/* Convert error codes of xlat_get_mem_attributes_ctx() into SPM. */
 	assert((rc == 0) || (rc == -EINVAL));
 
 	if (rc == 0) {
@@ -142,13 +142,13 @@
 
 	spin_lock(&mem_attr_smc_lock);
 
-	int ret = change_mem_attributes(sp_ctx->xlat_ctx_handle,
+	int ret = xlat_change_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
 					base_va, size,
 					smc_attr_to_mmap_attr(attributes));
 
 	spin_unlock(&mem_attr_smc_lock);
 
-	/* Convert error codes of change_mem_attributes() into SPM ones. */
+	/* Convert error codes of xlat_change_mem_attributes_ctx() into SPM. */
 	assert((ret == 0) || (ret == -EINVAL));
 
 	return (ret == 0) ? SPM_SUCCESS : SPM_INVALID_PARAMETER;