diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index 8fdfbc396d14bcf2b85493252d1b74e1d8801e6f..479ca59b3984215c7c148260bd293bfe9e77a3a2 100644
--- a/bl32/tsp/aarch64/tsp_entrypoint.S
+++ b/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -220,7 +220,7 @@ func tsp_cpu_on_entry
 	 * Initialise the MMU
 	 * ---------------------------------------------
 	 */
-	bl	enable_mmu_el1
+	bl	bl32_plat_enable_mmu
 
 	/* ---------------------------------------------
 	 * Give ourselves a stack allocated in Normal
diff --git a/include/lib/aarch64/xlat_tables.h b/include/lib/aarch64/xlat_tables.h
index a500f0335581f5a8ff9645c9f297fd3c5339b89a..5df655bd50c01f21f5a1b6696f3ae16b63e77fd9 100644
--- a/include/lib/aarch64/xlat_tables.h
+++ b/include/lib/aarch64/xlat_tables.h
@@ -66,6 +66,7 @@ void mmap_add(const mmap_region_t *mm);
 
 void init_xlat_tables(void);
 
-extern uint64_t l1_xlation_table[];
+void enable_mmu_el1(void);
+void enable_mmu_el3(void);
 
 #endif /* __XLAT_TABLES_H__ */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 630eb1cdc6857cb49e5bc31fbf28e63356572975..9256426ae10fb7979805dfb6af278b3eb3e5fc92 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -50,8 +50,6 @@ struct bl31_params;
  * Mandatory common functions
  ******************************************************************************/
 uint64_t plat_get_syscnt_freq(void);
-void enable_mmu_el1(void);
-void enable_mmu_el3(void);
 int plat_get_image_source(const char *image_name,
 			uintptr_t *dev_handle,
 			uintptr_t *image_spec);
@@ -168,11 +166,21 @@ int plat_get_max_afflvl(void);
 unsigned int plat_get_aff_count(unsigned int, unsigned long);
 unsigned int plat_get_aff_state(unsigned int, unsigned long);
 
+/*******************************************************************************
+ * Optional BL3-1 functions (may be overridden)
+ ******************************************************************************/
+void bl31_plat_enable_mmu();
+
 /*******************************************************************************
  * Mandatory BL3-2 functions (only if platform contains a BL3-2
  ******************************************************************************/
 void bl32_platform_setup(void);
 struct meminfo *bl32_plat_sec_mem_layout(void);
 
+/*******************************************************************************
+ * Optional BL3-2 functions (may be overridden)
+ ******************************************************************************/
+void bl32_plat_enable_mmu();
+
 
 #endif /* __PLATFORM_H__ */
diff --git a/lib/aarch64/xlat_tables.c b/lib/aarch64/xlat_tables.c
index 4e935a50e38c8316283c9e2235d64d192ebf8b87..29b81dbd3c37ca455cbcc0da8bd53e57ba7fd173 100644
--- a/lib/aarch64/xlat_tables.c
+++ b/lib/aarch64/xlat_tables.c
@@ -28,6 +28,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <arch.h>
+#include <arch_helpers.h>
 #include <assert.h>
 #include <platform_def.h>
 #include <string.h>
@@ -49,7 +51,7 @@
 
 #define NUM_L1_ENTRIES (ADDR_SPACE_SIZE >> L1_XLAT_ADDRESS_SHIFT)
 
-uint64_t l1_xlation_table[NUM_L1_ENTRIES]
+static uint64_t l1_xlation_table[NUM_L1_ENTRIES]
 __aligned(NUM_L1_ENTRIES * sizeof(uint64_t));
 
 static uint64_t xlat_tables[MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES]
@@ -226,3 +228,62 @@ void init_xlat_tables(void)
 	print_mmap();
 	init_xlation_table(mmap, 0, l1_xlation_table, 1);
 }
+
+/*******************************************************************************
+ * Macro generating the code for the function enabling the MMU in the given
+ * exception level, assuming that the pagetables have already been created.
+ *
+ *   _el:		Exception level at which the function will run
+ *   _tcr_extra:	Extra bits to set in the TCR register. This mask will
+ *			be OR'ed with the default TCR value.
+ *   _tlbi_fct:		Function to invalidate the TLBs at the current
+ *			exception level
+ ******************************************************************************/
+#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct)		\
+	void enable_mmu_el##_el(void)					\
+	{								\
+		uint64_t mair, tcr, ttbr;				\
+		uint32_t sctlr;						\
+									\
+		assert(IS_IN_EL(_el));					\
+		assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0);	\
+									\
+		/* Set attributes in the right indices of the MAIR */	\
+		mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);	\
+		mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,		\
+				ATTR_IWBWA_OWBWA_NTR_INDEX);		\
+		write_mair_el##_el(mair);				\
+									\
+		/* Invalidate TLBs at the current exception level */	\
+		_tlbi_fct();						\
+									\
+		/* Set TCR bits as well. */				\
+		/* Inner & outer WBWA & shareable + T0SZ = 32 */	\
+		tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA |	\
+			TCR_RGN_INNER_WBA | TCR_T0SZ_4GB;		\
+		tcr |= _tcr_extra;					\
+		write_tcr_el##_el(tcr);					\
+									\
+		/* Set TTBR bits as well */				\
+		ttbr = (uint64_t) l1_xlation_table;			\
+		write_ttbr0_el##_el(ttbr);				\
+									\
+		/* Ensure all translation table writes have drained */	\
+		/* into memory, the TLB invalidation is complete, */	\
+		/* and translation register writes are committed */	\
+		/* before enabling the MMU */				\
+		dsb();							\
+		isb();							\
+									\
+		sctlr = read_sctlr_el##_el();				\
+		sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT;	\
+		sctlr |= SCTLR_A_BIT | SCTLR_C_BIT;			\
+		write_sctlr_el##_el(sctlr);				\
+									\
+		/* Ensure the MMU enable takes effect immediately */	\
+		isb();							\
+	}
+
+/* Define EL1 and EL3 variants of the function enabling the MMU */
+DEFINE_ENABLE_MMU_EL(1, 0, tlbivmalle1)
+DEFINE_ENABLE_MMU_EL(3, TCR_EL3_RES1, tlbialle3)
diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..2abf29d97729afa68cf087cb7e4e3782f767e195
--- /dev/null
+++ b/plat/common/aarch64/plat_common.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <xlat_tables.h>
+
+/*
+ * The following 2 platform setup functions are weakly defined. They
+ * provide typical implementations that may be re-used by multiple
+ * platforms but may also be overridden by a platform if required.
+ */
+#pragma weak bl31_plat_enable_mmu
+#pragma weak bl32_plat_enable_mmu
+
+void bl31_plat_enable_mmu()
+{
+	enable_mmu_el3();
+}
+
+void bl32_plat_enable_mmu()
+{
+	enable_mmu_el1();
+}
diff --git a/plat/fvp/aarch64/fvp_common.c b/plat/fvp/aarch64/fvp_common.c
index b385cc62283c113a3fc38c7b9f308f3ec6b192b7..b990179f1f2e35c0b90160d8fe1acfe3b8035cf7 100644
--- a/plat/fvp/aarch64/fvp_common.c
+++ b/plat/fvp/aarch64/fvp_common.c
@@ -48,65 +48,6 @@
  ******************************************************************************/
 static unsigned long platform_config[CONFIG_LIMIT];
 
-/*******************************************************************************
- * Macro generating the code for the function enabling the MMU in the given
- * exception level, assuming that the pagetables have already been created.
- *
- *   _el:		Exception level at which the function will run
- *   _tcr_extra:	Extra bits to set in the TCR register. This mask will
- *			be OR'ed with the default TCR value.
- *   _tlbi_fct:		Function to invalidate the TLBs at the current
- *			exception level
- ******************************************************************************/
-#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct)		\
-	void enable_mmu_el##_el(void)					\
-	{								\
-		uint64_t mair, tcr, ttbr;				\
-		uint32_t sctlr;						\
-									\
-		assert(IS_IN_EL(_el));					\
-		assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0);	\
-									\
-		/* Set attributes in the right indices of the MAIR */	\
-		mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);	\
-		mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,		\
-				ATTR_IWBWA_OWBWA_NTR_INDEX);		\
-		write_mair_el##_el(mair);				\
-									\
-		/* Invalidate TLBs at the current exception level */	\
-		_tlbi_fct();						\
-									\
-		/* Set TCR bits as well. */				\
-		/* Inner & outer WBWA & shareable + T0SZ = 32 */	\
-		tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA |	\
-			TCR_RGN_INNER_WBA | TCR_T0SZ_4GB;		\
-		tcr |= _tcr_extra;					\
-		write_tcr_el##_el(tcr);					\
-									\
-		/* Set TTBR bits as well */				\
-		ttbr = (uint64_t) l1_xlation_table;			\
-		write_ttbr0_el##_el(ttbr);				\
-									\
-		/* Ensure all translation table writes have drained */	\
-		/* into memory, the TLB invalidation is complete, */	\
-		/* and translation register writes are committed */	\
-		/* before enabling the MMU */				\
-		dsb();							\
-		isb();							\
-									\
-		sctlr = read_sctlr_el##_el();				\
-		sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT;	\
-		sctlr |= SCTLR_A_BIT | SCTLR_C_BIT;			\
-		write_sctlr_el##_el(sctlr);				\
-									\
-		/* Ensure the MMU enable takes effect immediately */	\
-		isb();							\
-	}
-
-/* Define EL1 and EL3 variants of the function enabling the MMU */
-DEFINE_ENABLE_MMU_EL(1, 0, tlbivmalle1)
-DEFINE_ENABLE_MMU_EL(3, TCR_EL3_RES1, tlbialle3)
-
 /*
  * Table of regions to map using the MMU.
  * This doesn't include TZRAM as the 'mem_layout' argument passed to
diff --git a/plat/fvp/platform.mk b/plat/fvp/platform.mk
index 35fa5bfc3248dd482eaad24bcecab197f4e8b87c..5df2ff668b78a2d38a2a92eef026dd10e8cafbe5 100644
--- a/plat/fvp/platform.mk
+++ b/plat/fvp/platform.mk
@@ -55,6 +55,7 @@ PLAT_BL_COMMON_SOURCES	:=	drivers/arm/pl011/pl011.c			\
 				lib/aarch64/xlat_tables.c			\
 				lib/semihosting/semihosting.c			\
 				lib/semihosting/aarch64/semihosting_call.S	\
+				plat/common/aarch64/plat_common.c		\
 				plat/fvp/fvp_io_storage.c
 
 BL1_SOURCES		+=	drivers/arm/cci400/cci400.c			\
diff --git a/services/std_svc/psci/psci_afflvl_on.c b/services/std_svc/psci/psci_afflvl_on.c
index 1e5828caca24b60de4e8b47c771de4f38dab691a..e3a1831c2967ddfa6358d1d77862a98159827136 100644
--- a/services/std_svc/psci/psci_afflvl_on.c
+++ b/services/std_svc/psci/psci_afflvl_on.c
@@ -363,7 +363,7 @@ static unsigned int psci_afflvl0_on_finish(unsigned long mpidr,
 	/*
 	 * Arch. management: Turn on mmu & restore architectural state
 	 */
-	enable_mmu_el3();
+	bl31_plat_enable_mmu();
 
 	/*
 	 * All the platform specific actions for turning this cpu