Merge pull request #1418 from antonio-nino-diaz-arm/an/arm-multi-console

 plat/arm: Migrate AArch64 port to the multi console driver
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index c6a4fe4..59df9b8 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -221,13 +221,6 @@
      * tables library.
      */
     xlat_table (NOLOAD) : {
-#if ENABLE_SPM
-        __SP_IMAGE_XLAT_TABLES_START__ = .;
-        *secure_partition*.o(xlat_table)
-        /* Make sure that the rest of the page is empty. */
-        . = NEXT(PAGE_SIZE);
-        __SP_IMAGE_XLAT_TABLES_END__ = .;
-#endif
         *(xlat_table)
     } >RAM
 
diff --git a/common/bl_common.c b/common/bl_common.c
index 6b979f6..af51c07 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -184,7 +184,7 @@
 #endif /* LOAD_IMAGE_V2 */
 
 /* Generic function to return the size of an image */
-size_t image_size(unsigned int image_id)
+size_t get_image_size(unsigned int image_id)
 {
 	uintptr_t dev_handle;
 	uintptr_t image_handle;
diff --git a/common/tf_printf.c b/common/tf_printf.c
index d403983..9d8333a 100644
--- a/common/tf_printf.c
+++ b/common/tf_printf.c
@@ -15,13 +15,13 @@
  * The tf_printf implementation for all BL stages
  ***********************************************************/
 
-#define get_num_va_args(args, lcount) \
-	(((lcount) > 1) ? va_arg(args, long long int) :	\
-	((lcount) ? va_arg(args, long int) : va_arg(args, int)))
+#define get_num_va_args(_args, _lcount) \
+	(((_lcount) > 1) ? va_arg(_args, long long int) :	\
+	((_lcount) ? va_arg(_args, long int) : va_arg(_args, int)))
 
-#define get_unum_va_args(args, lcount) \
-	(((lcount) > 1) ? va_arg(args, unsigned long long int) :	\
-	((lcount) ? va_arg(args, unsigned long int) : va_arg(args, unsigned int)))
+#define get_unum_va_args(_args, _lcount) \
+	(((_lcount) > 1) ? va_arg(_args, unsigned long long int) :	\
+	((_lcount) ? va_arg(_args, unsigned long int) : va_arg(_args, unsigned int)))
 
 void tf_string_print(const char *str)
 {
diff --git a/docs/plat/allwinner.rst b/docs/plat/allwinner.rst
new file mode 100644
index 0000000..a7e84a3
--- /dev/null
+++ b/docs/plat/allwinner.rst
@@ -0,0 +1,29 @@
+Trusted Firmware-A for Allwinner ARMv8 SoCs
+===========================================
+
+Trusted Firmware-A (TF-A) implements the EL3 firmware layer for Allwinner
+SoCs with ARMv8 cores. Only BL31 is used to provide proper EL3 setup and
+PSCI runtime services.
+U-Boot's SPL acts as a loader, loading both BL31 and BL33 (typically U-Boot).
+Loading is done from SD card, eMMC or SPI flash, also via an USB debug
+interface (FEL).
+BL31 lives in SRAM A2, which is documented to be accessible from secure
+world only.
+
+Current limitations:
+
+-  Missing PMIC support
+
+After building bl31.bin, the binary must be fed to the U-Boot build system
+to include it in the FIT image that the SPL loader will process.
+bl31.bin can be either copied (or sym-linked) into U-Boot's root directory,
+or the environment variable BL31 must contain the binary's path.
+See the respective `U-Boot documentation`_ for more details.
+
+To build:
+
+::
+
+    make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sun50i_a64 DEBUG=1 bl31
+
+.. _U-Boot documentation: http://git.denx.de/?p=u-boot.git;f=board/sunxi/README.sunxi64;hb=HEAD
diff --git a/docs/plat/rpi3.rst b/docs/plat/rpi3.rst
index b7879a8..659ed7f 100644
--- a/docs/plat/rpi3.rst
+++ b/docs/plat/rpi3.rst
@@ -134,7 +134,7 @@
     0x40000000 +-----------------+
 
 The area between **0x10000000** and **0x11000000** has to be protected so that
-the kernel doesn't use it. That is done by adding ``memmap=256M$16M`` to the
+the kernel doesn't use it. That is done by adding ``memmap=16M$256M`` to the
 command line passed to the kernel. See the `Setup SD card`_ instructions to see
 how to do it.
 
@@ -317,7 +317,7 @@
    bootloader will look for a file called ``armstub8.bin`` and load it at
    address **0x0** instead of a predefined one.
 
-4. Open ``cmdline.txt`` and add ``memmap=256M$16M`` to prevent the kernel from
+4. Open ``cmdline.txt`` and add ``memmap=16M$256M`` to prevent the kernel from
    using the memory needed by TF-A. If you want to enable the serial port
    "Mini UART", make sure that this file also contains
    ``console=serial0,115200 console=tty1``.
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index f6d0c76..7e50dc1 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -486,8 +486,8 @@
    ::
 
        0  (LOG_LEVEL_NONE)
-       10 (LOG_LEVEL_NOTICE)
-       20 (LOG_LEVEL_ERROR)
+       10 (LOG_LEVEL_ERROR)
+       20 (LOG_LEVEL_NOTICE)
        30 (LOG_LEVEL_WARNING)
        40 (LOG_LEVEL_INFO)
        50 (LOG_LEVEL_VERBOSE)
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index 020ec1b..2ea8c72 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -342,7 +342,7 @@
 /*******************************************************************************
  * Helper function to configure the default attributes of SPIs.
  ******************************************************************************/
-void gicv3_spis_configure_defaults(uintptr_t gicd_base)
+void gicv3_spis_config_defaults(uintptr_t gicd_base)
 {
 	unsigned int index, num_ints;
 
@@ -375,7 +375,7 @@
 /*******************************************************************************
  * Helper function to configure secure G0 and G1S SPIs.
  ******************************************************************************/
-void gicv3_secure_spis_configure(uintptr_t gicd_base,
+void gicv3_secure_spis_config(uintptr_t gicd_base,
 				     unsigned int num_ints,
 				     const unsigned int *sec_intr_list,
 				     unsigned int int_grp)
@@ -423,7 +423,7 @@
 /*******************************************************************************
  * Helper function to configure properties of secure SPIs
  ******************************************************************************/
-unsigned int gicv3_secure_spis_configure_props(uintptr_t gicd_base,
+unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
 		const interrupt_prop_t *interrupt_props,
 		unsigned int interrupt_props_num)
 {
@@ -478,7 +478,7 @@
 /*******************************************************************************
  * Helper function to configure the default attributes of SPIs.
  ******************************************************************************/
-void gicv3_ppi_sgi_configure_defaults(uintptr_t gicr_base)
+void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base)
 {
 	unsigned int index;
 
@@ -507,7 +507,7 @@
 /*******************************************************************************
  * Helper function to configure secure G0 and G1S SPIs.
  ******************************************************************************/
-void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base,
+void gicv3_secure_ppi_sgi_config(uintptr_t gicr_base,
 					unsigned int num_ints,
 					const unsigned int *sec_intr_list,
 					unsigned int int_grp)
@@ -546,7 +546,7 @@
 /*******************************************************************************
  * Helper function to configure properties of secure G0 and G1S PPIs and SGIs.
  ******************************************************************************/
-unsigned int gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base,
+unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base,
 		const interrupt_prop_t *interrupt_props,
 		unsigned int interrupt_props_num)
 {
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 82f43d0..83d030a 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -190,12 +190,12 @@
 			CTLR_ARE_S_BIT | CTLR_ARE_NS_BIT, RWP_TRUE);
 
 	/* Set the default attribute of all SPIs */
-	gicv3_spis_configure_defaults(gicv3_driver_data->gicd_base);
+	gicv3_spis_config_defaults(gicv3_driver_data->gicd_base);
 
 #if !ERROR_DEPRECATED
 	if (gicv3_driver_data->interrupt_props != NULL) {
 #endif
-		bitmap = gicv3_secure_spis_configure_props(
+		bitmap = gicv3_secure_spis_config_props(
 				gicv3_driver_data->gicd_base,
 				gicv3_driver_data->interrupt_props,
 				gicv3_driver_data->interrupt_props_num);
@@ -213,7 +213,7 @@
 
 		/* Configure the G1S SPIs */
 		if (gicv3_driver_data->g1s_interrupt_array) {
-			gicv3_secure_spis_configure(gicv3_driver_data->gicd_base,
+			gicv3_secure_spis_config(gicv3_driver_data->gicd_base,
 					gicv3_driver_data->g1s_interrupt_num,
 					gicv3_driver_data->g1s_interrupt_array,
 					INTR_GROUP1S);
@@ -222,7 +222,7 @@
 
 		/* Configure the G0 SPIs */
 		if (gicv3_driver_data->g0_interrupt_array) {
-			gicv3_secure_spis_configure(gicv3_driver_data->gicd_base,
+			gicv3_secure_spis_config(gicv3_driver_data->gicd_base,
 					gicv3_driver_data->g0_interrupt_num,
 					gicv3_driver_data->g0_interrupt_array,
 					INTR_GROUP0);
@@ -263,12 +263,12 @@
 	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
 
 	/* Set the default attribute of all SGIs and PPIs */
-	gicv3_ppi_sgi_configure_defaults(gicr_base);
+	gicv3_ppi_sgi_config_defaults(gicr_base);
 
 #if !ERROR_DEPRECATED
 	if (gicv3_driver_data->interrupt_props != NULL) {
 #endif
-		bitmap = gicv3_secure_ppi_sgi_configure_props(gicr_base,
+		bitmap = gicv3_secure_ppi_sgi_config_props(gicr_base,
 				gicv3_driver_data->interrupt_props,
 				gicv3_driver_data->interrupt_props_num);
 #if !ERROR_DEPRECATED
@@ -285,7 +285,7 @@
 
 		/* Configure the G1S SGIs/PPIs */
 		if (gicv3_driver_data->g1s_interrupt_array) {
-			gicv3_secure_ppi_sgi_configure(gicr_base,
+			gicv3_secure_ppi_sgi_config(gicr_base,
 					gicv3_driver_data->g1s_interrupt_num,
 					gicv3_driver_data->g1s_interrupt_array,
 					INTR_GROUP1S);
@@ -294,7 +294,7 @@
 
 		/* Configure the G0 SGIs/PPIs */
 		if (gicv3_driver_data->g0_interrupt_array) {
-			gicv3_secure_ppi_sgi_configure(gicr_base,
+			gicv3_secure_ppi_sgi_config(gicr_base,
 					gicv3_driver_data->g0_interrupt_num,
 					gicv3_driver_data->g0_interrupt_array,
 					INTR_GROUP0);
diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h
index c4474a4..e1c0775 100644
--- a/drivers/arm/gic/v3/gicv3_private.h
+++ b/drivers/arm/gic/v3/gicv3_private.h
@@ -27,20 +27,20 @@
  * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant
  * to GICv3.
  */
-#define gicd_irouter_val_from_mpidr(mpidr, irm)		\
-	((mpidr & ~(0xff << 24)) |			\
-	 (irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT)
+#define gicd_irouter_val_from_mpidr(_mpidr, _irm)		\
+	((_mpidr & ~(0xff << 24)) |			\
+	 (_irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT)
 
 /*
  * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24]
  * are zeroes.
  */
 #ifdef AARCH32
-#define mpidr_from_gicr_typer(typer_val)	(((typer_val) >> 32) & 0xffffff)
+#define mpidr_from_gicr_typer(_typer_val)	(((_typer_val) >> 32) & 0xffffff)
 #else
-#define mpidr_from_gicr_typer(typer_val)				 \
-	(((((typer_val) >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \
-	 (((typer_val) >> 32) & 0xffffff))
+#define mpidr_from_gicr_typer(_typer_val)				 \
+	(((((_typer_val) >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \
+	 (((_typer_val) >> 32) & 0xffffff))
 #endif
 
 /*******************************************************************************
@@ -85,22 +85,22 @@
 /*******************************************************************************
  * Private GICv3 helper function prototypes
  ******************************************************************************/
-void gicv3_spis_configure_defaults(uintptr_t gicd_base);
-void gicv3_ppi_sgi_configure_defaults(uintptr_t gicr_base);
+void gicv3_spis_config_defaults(uintptr_t gicd_base);
+void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base);
 #if !ERROR_DEPRECATED
-void gicv3_secure_spis_configure(uintptr_t gicd_base,
+void gicv3_secure_spis_config(uintptr_t gicd_base,
 				     unsigned int num_ints,
 				     const unsigned int *sec_intr_list,
 				     unsigned int int_grp);
-void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base,
+void gicv3_secure_ppi_sgi_config(uintptr_t gicr_base,
 					unsigned int num_ints,
 					const unsigned int *sec_intr_list,
 					unsigned int int_grp);
 #endif
-unsigned int gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base,
+unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base,
 		const interrupt_prop_t *interrupt_props,
 		unsigned int interrupt_props_num);
-unsigned int gicv3_secure_spis_configure_props(uintptr_t gicd_base,
+unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
 		const interrupt_prop_t *interrupt_props,
 		unsigned int interrupt_props_num);
 void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index cfe8c2a..7b017e3 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -8,8 +8,8 @@
 #include <smmu_v3.h>
 
 /* Test for pending invalidate */
-#define INVAL_PENDING(base)	\
-	smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK
+#define INVAL_PENDING(_base)	\
+	smmuv3_read_s_init(_base) & SMMU_S_INIT_INV_ALL_MASK
 
 static inline uint32_t smmuv3_read_s_idr1(uintptr_t base)
 {
diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c
index 0999fa5..db4f88a 100644
--- a/drivers/arm/tzc/tzc400.c
+++ b/drivers/arm/tzc/tzc400.c
@@ -54,7 +54,7 @@
 /*
  * Get the open status information for all filter units.
  */
-#define get_gate_keeper_os(base)	((_tzc400_read_gate_keeper(base) >>	\
+#define get_gate_keeper_os(_base)	((_tzc400_read_gate_keeper(_base) >>  \
 					GATE_KEEPER_OS_SHIFT) &		\
 					GATE_KEEPER_OS_MASK)
 
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index 56e7e5c..d46fa61 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -66,6 +66,10 @@
 	/* no interrupt */
 	mov	w3, #0
 	str	w3, [x0, #UARTIER]
+#ifdef TI_16550_MDR_QUIRK
+	/* UART must be enabled on some platforms via the MDR register */
+	str	w3, [x0, #UARTMDR1]
+#endif /* TI_16550_MDR_QUIRK */
 	/* enable fifo, DMA */
 	mov	w3, #(UARTFCR_FIFOEN | UARTFCR_DMAEN)
 	str	w3, [x0, #UARTFCR]
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index c7c7487..f64e6ae 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -207,7 +207,7 @@
 /*******************************************************************************
  * Function & variable prototypes
  ******************************************************************************/
-size_t image_size(unsigned int image_id);
+size_t get_image_size(unsigned int image_id);
 
 int is_mem_free(uintptr_t free_base, size_t free_size,
 		uintptr_t addr, size_t size);
diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h
index 9eba41a..b00f664 100644
--- a/include/drivers/ti/uart/uart_16550.h
+++ b/include/drivers/ti/uart/uart_16550.h
@@ -23,6 +23,8 @@
 #define UARTMSR			0x18
 #define UARTSPR			0x1c
 #define UARTCSR			0x20
+/* Some instances have MDR1 defined as well */
+#define UARTMDR1		0x20
 #define UARTRXFIFOCFG		0x24
 #define UARTMIE			0x28
 #define UARTVNDR		0x2c
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 31b1294..7335103 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -16,7 +16,31 @@
 
 #define SIZE_FROM_LOG2_WORDS(n)		(4 << (n))
 
-#define BIT(nr)				(ULL(1) << (nr))
+#define BIT_32(nr)			(U(1) << (nr))
+#define BIT_64(nr)			(ULL(1) << (nr))
+
+#ifdef AARCH32
+#define BIT				BIT_32
+#else
+#define BIT				BIT_64
+#endif
+
+/*
+ * Create a contiguous bitmask starting at bit position @l and ending at
+ * position @h. For example
+ * GENMASK_64(39, 21) gives us the 64bit vector 0x000000ffffe00000.
+ */
+#define GENMASK_32(h, l) \
+	(((~UINT32_C(0)) << (l)) & (~UINT32_C(0) >> (32 - 1 - (h))))
+
+#define GENMASK_64(h, l) \
+	(((~UINT64_C(0)) << (l)) & (~UINT64_C(0) >> (64 - 1 - (h))))
+
+#ifdef AARCH32
+#define GENMASK				GENMASK_32
+#else
+#define GENMASK				GENMASK_64
+#endif
 
 /*
  * This variant of div_round_up can be used in macro definition but should not
diff --git a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
index a418d2d..808589a 100644
--- a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
+++ b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -66,7 +66,7 @@
  * valid. Therefore, the caller is expected to check it is the case using the
  * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
  */
-#define GET_XLAT_TABLE_LEVEL_BASE(virt_addr_space_size)			\
-	(((virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ? 1 : 2)
+#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size)			\
+	(((_virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ? 1 : 2)
 
 #endif /* __XLAT_TABLES_AARCH32_H__ */
diff --git a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
index 6021e40..ad48a35 100644
--- a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
+++ b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -74,10 +74,10 @@
  * valid. Therefore, the caller is expected to check it is the case using the
  * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
  */
-#define GET_XLAT_TABLE_LEVEL_BASE(virt_addr_space_size)				\
-	(((virt_addr_space_size) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT))		\
+#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size)				\
+	(((_virt_addr_space_size) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT))		\
 	? 0									\
-	 : (((virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT))	\
+	 : (((_virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT))	\
 	 ? 1 : 2))
 
 #endif /* __XLAT_TABLES_AARCH64_H__ */
diff --git a/include/lib/xlat_tables/xlat_mmu_helpers.h b/include/lib/xlat_tables/xlat_mmu_helpers.h
index d83d764..7795317 100644
--- a/include/lib/xlat_tables/xlat_mmu_helpers.h
+++ b/include/lib/xlat_tables/xlat_mmu_helpers.h
@@ -43,6 +43,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <sys/types.h>
+
 #ifdef AARCH32
 /* AArch32 specific translation table API */
 void enable_mmu_secure(unsigned int flags);
@@ -52,6 +54,9 @@
 void enable_mmu_el3(unsigned int flags);
 #endif /* AARCH32 */
 
+int xlat_arch_is_granule_size_supported(size_t size);
+size_t xlat_arch_get_max_supported_granule_size(void);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __XLAT_MMU_HELPERS_H__ */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index d87fc16..e07156c 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -245,13 +245,7 @@
  * The number of regions like RO(code), coherent and data required by
  * different BL stages which need to be mapped in the MMU.
  */
-#if ENABLE_SPM && defined(IMAGE_BL31)
-# if USE_COHERENT_MEM
-#  define ARM_BL_REGIONS		5
-# else
-#  define ARM_BL_REGIONS		4
-# endif
-#elif USE_COHERENT_MEM
+#if USE_COHERENT_MEM
 # define ARM_BL_REGIONS			4
 #else
 # define ARM_BL_REGIONS			3
diff --git a/include/services/secure_partition.h b/include/services/secure_partition.h
index f1fdb73..d4aff1c 100644
--- a/include/services/secure_partition.h
+++ b/include/services/secure_partition.h
@@ -7,18 +7,9 @@
 #ifndef __SECURE_PARTITION_H__
 #define __SECURE_PARTITION_H__
 
-#include <bl_common.h>
 #include <types.h>
 #include <utils_def.h>
 
-/* Import linker symbols */
-IMPORT_SYM(uintptr_t, __SP_IMAGE_XLAT_TABLES_START__,	SP_IMAGE_XLAT_TABLES_START);
-IMPORT_SYM(uintptr_t, __SP_IMAGE_XLAT_TABLES_END__,	SP_IMAGE_XLAT_TABLES_END);
-
-/* Definitions */
-#define SP_IMAGE_XLAT_TABLES_SIZE	\
-	(SP_IMAGE_XLAT_TABLES_END - SP_IMAGE_XLAT_TABLES_START)
-
 /*
  * Flags used by the secure_partition_mp_info structure to describe the
  * characteristics of a cpu. Only a single flag is defined at the moment to
diff --git a/lib/cpus/aarch64/cpuamu.c b/lib/cpus/aarch64/cpuamu.c
index b9bad86..5ad5bf8 100644
--- a/lib/cpus/aarch64/cpuamu.c
+++ b/lib/cpus/aarch64/cpuamu.c
@@ -10,12 +10,12 @@
 
 #define CPUAMU_NR_COUNTERS	5U
 
-struct amu_ctx {
+struct cpuamu_ctx {
 	uint64_t cnts[CPUAMU_NR_COUNTERS];
 	unsigned int mask;
 };
 
-static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT];
+static struct cpuamu_ctx cpuamu_ctxs[PLATFORM_CORE_COUNT];
 
 int midr_match(unsigned int cpu_midr)
 {
@@ -29,7 +29,7 @@
 
 void cpuamu_context_save(unsigned int nr_counters)
 {
-	struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
+	struct cpuamu_ctx *ctx = &cpuamu_ctxs[plat_my_core_pos()];
 	unsigned int i;
 
 	assert(nr_counters <= CPUAMU_NR_COUNTERS);
@@ -48,7 +48,7 @@
 
 void cpuamu_context_restore(unsigned int nr_counters)
 {
-	struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
+	struct cpuamu_ctx *ctx = &cpuamu_ctxs[plat_my_core_pos()];
 	unsigned int i;
 
 	assert(nr_counters <= CPUAMU_NR_COUNTERS);
diff --git a/lib/locks/bakery/bakery_lock_coherent.c b/lib/locks/bakery/bakery_lock_coherent.c
index a857e03..788ba98 100644
--- a/lib/locks/bakery/bakery_lock_coherent.c
+++ b/lib/locks/bakery/bakery_lock_coherent.c
@@ -34,9 +34,9 @@
  * accesses regardless of status of address translation.
  */
 
-#define assert_bakery_entry_valid(entry, bakery) do {	\
-	assert(bakery);					\
-	assert(entry < BAKERY_LOCK_MAX_CPUS);		\
+#define assert_bakery_entry_valid(_entry, _bakery) do {	\
+	assert(_bakery);					\
+	assert(_entry < BAKERY_LOCK_MAX_CPUS);		\
 } while (0)
 
 /* Obtain a ticket for a given CPU */
diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c
index 37697f5..630226a 100644
--- a/lib/locks/bakery/bakery_lock_normal.c
+++ b/lib/locks/bakery/bakery_lock_normal.c
@@ -53,18 +53,18 @@
 IMPORT_SYM(uintptr_t, __PERCPU_BAKERY_LOCK_SIZE__, PERCPU_BAKERY_LOCK_SIZE);
 #endif
 
-#define get_bakery_info(cpu_ix, lock)	\
-	(bakery_info_t *)((uintptr_t)lock + cpu_ix * PERCPU_BAKERY_LOCK_SIZE)
+#define get_bakery_info(_cpu_ix, _lock)	\
+	(bakery_info_t *)((uintptr_t)_lock + _cpu_ix * PERCPU_BAKERY_LOCK_SIZE)
 
-#define write_cache_op(addr, cached)	\
+#define write_cache_op(_addr, _cached)	\
 				do {	\
-					(cached ? dccvac((uintptr_t)addr) :\
-						dcivac((uintptr_t)addr));\
+					(_cached ? dccvac((uintptr_t)_addr) :\
+						dcivac((uintptr_t)_addr));\
 						dsbish();\
 				} while (0)
 
-#define read_cache_op(addr, cached)	if (cached) \
-					    dccivac((uintptr_t)addr)
+#define read_cache_op(_addr, _cached)	if (_cached) \
+					    dccivac((uintptr_t)_addr)
 
 /* Helper function to check if the lock is acquired */
 static inline int is_lock_acquired(const bakery_info_t *my_bakery_info,
diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c
index ac51265..ecf7cc0 100644
--- a/lib/optee/optee_utils.c
+++ b/lib/optee/optee_utils.c
@@ -43,7 +43,7 @@
 	uint8_t arch;
 	uint16_t flags;
 	uint32_t nb_images;
-	optee_image_t optee_image[];
+	optee_image_t optee_image_list[];
 } optee_header_t;
 
 /*******************************************************************************
@@ -51,11 +51,11 @@
  * Return 1 if valid
  * Return 0 if invalid
  ******************************************************************************/
-static inline int tee_validate_header(optee_header_t *optee_header)
+static inline int tee_validate_header(optee_header_t *header)
 {
-	if ((optee_header->magic == TEE_MAGIC_NUM_OPTEE) &&
-		(optee_header->version == 2) &&
-		(optee_header->nb_images <= OPTEE_MAX_IMAGE_NUM)) {
+	if ((header->magic == TEE_MAGIC_NUM_OPTEE) &&
+		(header->version == 2) &&
+		(header->nb_images <= OPTEE_MAX_IMAGE_NUM)) {
 		return 1;
 	}
 
@@ -68,14 +68,14 @@
  * Return 0 on success or a negative error code otherwise.
  ******************************************************************************/
 static int parse_optee_image(image_info_t *image_info,
-		optee_image_t *optee_image)
+		optee_image_t *image)
 {
 	uintptr_t init_load_addr, free_end, requested_end;
 	size_t init_size;
 
-	init_load_addr = ((uint64_t)optee_image->load_addr_hi << 32) |
-					optee_image->load_addr_lo;
-	init_size = optee_image->size;
+	init_load_addr = ((uint64_t)image->load_addr_hi << 32) |
+					image->load_addr_lo;
+	init_size = image->size;
 
 	/*
 	 * -1 indicates loader decided address; take our pre-mapped area
@@ -133,21 +133,21 @@
 		image_info_t *paged_image_info)
 
 {
-	optee_header_t *optee_header;
+	optee_header_t *header;
 	int num, ret;
 
 	assert(header_ep);
-	optee_header = (optee_header_t *)header_ep->pc;
-	assert(optee_header);
+	header = (optee_header_t *)header_ep->pc;
+	assert(header);
 
 	/* Print the OPTEE header information */
 	INFO("OPTEE ep=0x%x\n", (unsigned int)header_ep->pc);
 	INFO("OPTEE header info:\n");
-	INFO("      magic=0x%x\n", optee_header->magic);
-	INFO("      version=0x%x\n", optee_header->version);
-	INFO("      arch=0x%x\n", optee_header->arch);
-	INFO("      flags=0x%x\n", optee_header->flags);
-	INFO("      nb_images=0x%x\n", optee_header->nb_images);
+	INFO("      magic=0x%x\n", header->magic);
+	INFO("      version=0x%x\n", header->version);
+	INFO("      arch=0x%x\n", header->arch);
+	INFO("      flags=0x%x\n", header->flags);
+	INFO("      nb_images=0x%x\n", header->nb_images);
 
 	/*
 	 * OPTEE image has 3 types:
@@ -166,7 +166,7 @@
 	 *	pager and pageable. Remove skip attr for BL32_EXTRA1_IMAGE_ID
 	 *	and BL32_EXTRA2_IMAGE_ID to load pager and paged bin.
 	 */
-	if (!tee_validate_header(optee_header)) {
+	if (!tee_validate_header(header)) {
 		INFO("Invalid OPTEE header, set legacy mode.\n");
 #ifdef AARCH64
 		header_ep->args.arg0 = MODE_RW_64;
@@ -177,15 +177,15 @@
 	}
 
 	/* Parse OPTEE image */
-	for (num = 0; num < optee_header->nb_images; num++) {
-		if (optee_header->optee_image[num].image_id ==
+	for (num = 0; num < header->nb_images; num++) {
+		if (header->optee_image_list[num].image_id ==
 				OPTEE_PAGER_IMAGE_ID) {
 			ret = parse_optee_image(pager_image_info,
-				&optee_header->optee_image[num]);
-		} else if (optee_header->optee_image[num].image_id ==
+				&header->optee_image_list[num]);
+		} else if (header->optee_image_list[num].image_id ==
 				OPTEE_PAGED_IMAGE_ID) {
 			ret = parse_optee_image(paged_image_info,
-				&optee_header->optee_image[num]);
+				&header->optee_image_list[num]);
 		} else {
 			ERROR("Parse optee image failed.\n");
 			return -1;
@@ -211,7 +211,7 @@
 	header_ep->args.arg2 = paged_image_info->image_size;
 
 	/* Set OPTEE runtime arch - aarch32/aarch64 */
-	if (optee_header->arch == 0) {
+	if (header->arch == 0) {
 		header_ep->args.arg0 = MODE_RW_32;
 	} else {
 #ifdef AARCH64
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index c58f329..d452e2a 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -65,8 +65,8 @@
 
 #endif
 
-#define psci_lock_init(non_cpu_pd_node, idx)			\
-	((non_cpu_pd_node)[(idx)].lock_index = (idx))
+#define psci_lock_init(_non_cpu_pd_node, _idx)			\
+	((_non_cpu_pd_node)[(_idx)].lock_index = (_idx))
 
 /*
  * The PSCI capability which are provided by the generic code but does not
@@ -96,35 +96,35 @@
 /*
  * Helper macros to get/set the fields of PSCI per-cpu data.
  */
-#define psci_set_aff_info_state(aff_state) \
-		set_cpu_data(psci_svc_cpu_data.aff_info_state, aff_state)
+#define psci_set_aff_info_state(_aff_state) \
+		set_cpu_data(psci_svc_cpu_data.aff_info_state, _aff_state)
 #define psci_get_aff_info_state() \
 		get_cpu_data(psci_svc_cpu_data.aff_info_state)
-#define psci_get_aff_info_state_by_idx(idx) \
-		get_cpu_data_by_index(idx, psci_svc_cpu_data.aff_info_state)
-#define psci_set_aff_info_state_by_idx(idx, aff_state) \
-		set_cpu_data_by_index(idx, psci_svc_cpu_data.aff_info_state,\
-					aff_state)
+#define psci_get_aff_info_state_by_idx(_idx) \
+		get_cpu_data_by_index(_idx, psci_svc_cpu_data.aff_info_state)
+#define psci_set_aff_info_state_by_idx(_idx, _aff_state) \
+		set_cpu_data_by_index(_idx, psci_svc_cpu_data.aff_info_state,\
+					_aff_state)
 #define psci_get_suspend_pwrlvl() \
 		get_cpu_data(psci_svc_cpu_data.target_pwrlvl)
-#define psci_set_suspend_pwrlvl(target_lvl) \
-		set_cpu_data(psci_svc_cpu_data.target_pwrlvl, target_lvl)
-#define psci_set_cpu_local_state(state) \
-		set_cpu_data(psci_svc_cpu_data.local_state, state)
+#define psci_set_suspend_pwrlvl(_target_lvl) \
+		set_cpu_data(psci_svc_cpu_data.target_pwrlvl, _target_lvl)
+#define psci_set_cpu_local_state(_state) \
+		set_cpu_data(psci_svc_cpu_data.local_state, _state)
 #define psci_get_cpu_local_state() \
 		get_cpu_data(psci_svc_cpu_data.local_state)
-#define psci_get_cpu_local_state_by_idx(idx) \
-		get_cpu_data_by_index(idx, psci_svc_cpu_data.local_state)
+#define psci_get_cpu_local_state_by_idx(_idx) \
+		get_cpu_data_by_index(_idx, psci_svc_cpu_data.local_state)
 
 /*
  * Helper macros for the CPU level spinlocks
  */
-#define psci_spin_lock_cpu(idx)	spin_lock(&psci_cpu_pd_nodes[idx].cpu_lock)
-#define psci_spin_unlock_cpu(idx) spin_unlock(&psci_cpu_pd_nodes[idx].cpu_lock)
+#define psci_spin_lock_cpu(_idx) spin_lock(&psci_cpu_pd_nodes[_idx].cpu_lock)
+#define psci_spin_unlock_cpu(_idx) spin_unlock(&psci_cpu_pd_nodes[_idx].cpu_lock)
 
 /* Helper macro to identify a CPU standby request in PSCI Suspend call */
-#define is_cpu_standby_req(is_power_down_state, retn_lvl) \
-		(((!(is_power_down_state)) && ((retn_lvl) == 0)) ? 1 : 0)
+#define is_cpu_standby_req(_is_power_down_state, _retn_lvl) \
+		(((!(_is_power_down_state)) && ((_retn_lvl) == 0)) ? 1 : 0)
 
 /*******************************************************************************
  * The following two data structures implement the power domain tree. The tree
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 7d67a4a..f66f802 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -18,6 +18,23 @@
 #error ARMv7 target does not support LPAE MMU descriptors
 #endif
 
+/*
+ * Returns 1 if the provided granule size is supported, 0 otherwise.
+ */
+int xlat_arch_is_granule_size_supported(size_t size)
+{
+	/*
+	 * The Trusted Firmware uses long descriptor translation table format,
+	 * which supports 4 KiB pages only.
+	 */
+	return (size == (4U * 1024U));
+}
+
+size_t xlat_arch_get_max_supported_granule_size(void)
+{
+	return 4U * 1024U;
+}
+
 #if ENABLE_ASSERTIONS
 unsigned long long xlat_arch_get_max_supported_pa(void)
 {
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index b3504e1..c501e70 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -16,6 +16,42 @@
 #include <xlat_tables_v2.h>
 #include "../xlat_tables_private.h"
 
+/*
+ * Returns 1 if the provided granule size is supported, 0 otherwise.
+ */
+int xlat_arch_is_granule_size_supported(size_t size)
+{
+	u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
+
+	if (size == (4U * 1024U)) {
+		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
+			 ID_AA64MMFR0_EL1_TGRAN4_MASK) ==
+			 ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED;
+	} else if (size == (16U * 1024U)) {
+		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
+			 ID_AA64MMFR0_EL1_TGRAN16_MASK) ==
+			 ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED;
+	} else if (size == (64U * 1024U)) {
+		return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
+			 ID_AA64MMFR0_EL1_TGRAN64_MASK) ==
+			 ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED;
+	}
+
+	return 0;
+}
+
+size_t xlat_arch_get_max_supported_granule_size(void)
+{
+	if (xlat_arch_is_granule_size_supported(64U * 1024U)) {
+		return 64U * 1024U;
+	} else if (xlat_arch_is_granule_size_supported(16U * 1024U)) {
+		return 16U * 1024U;
+	} else {
+		assert(xlat_arch_is_granule_size_supported(4U * 1024U));
+		return 4U * 1024U;
+	}
+}
+
 unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr)
 {
 	/* Physical address can't exceed 48 bits */
diff --git a/lib/xlat_tables_v2/xlat_tables_internal.c b/lib/xlat_tables_v2/xlat_tables_internal.c
index 8be6d94..a38f97f 100644
--- a/lib/xlat_tables_v2/xlat_tables_internal.c
+++ b/lib/xlat_tables_v2/xlat_tables_internal.c
@@ -735,7 +735,7 @@
 
 void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
 {
-	mmap_region_t *mm_cursor = ctx->mmap;
+	mmap_region_t *mm_cursor = ctx->mmap, *mm_destination;
 	const mmap_region_t *mm_end = ctx->mmap + ctx->mmap_num;
 	mmap_region_t *mm_last;
 	unsigned long long end_pa = mm->base_pa + mm->size - 1;
@@ -784,8 +784,8 @@
 	       && mm_cursor->size)
 		++mm_cursor;
 
-	while ((mm_cursor->base_va + mm_cursor->size - 1 == end_va)
-	       && (mm_cursor->size < mm->size))
+	while ((mm_cursor->base_va + mm_cursor->size - 1 == end_va) &&
+	       (mm_cursor->size != 0U) && (mm_cursor->size < mm->size))
 		++mm_cursor;
 
 	/*
@@ -802,9 +802,10 @@
 	 * that there is free space.
 	 */
 	assert(mm_last->size == 0U);
-
+	
 	/* Make room for new region by moving other regions up by one place */
-	memmove(mm_cursor + 1, mm_cursor,
+	mm_destination = mm_cursor + 1;
+	memmove(mm_destination, mm_cursor,
 		(uintptr_t)mm_last - (uintptr_t)mm_cursor);
 
 	/*
diff --git a/maintainers.rst b/maintainers.rst
index 2217cbe..9b0599e 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -64,6 +64,16 @@
 -  plat/hisilicon/hikey/\*
 -  plat/hisilicon/hikey960/\*
 
+Allwinner ARMv8 platform sub-maintainer
+---------------------------------------
+
+Andre Przywara (andre.przywara@arm.com, `Andre-ARM`_)
+
+Files:
+
+-  docs/plat/allwinner.rst
+-  plat/allwinner/\*
+
 HiSilicon Poplar platform sub-maintainer
 ----------------------------------------
 
@@ -151,3 +161,4 @@
 .. _rockchip-linux: https://github.com/rockchip-linux
 .. _etienne-lms: https://github.com/etienne-lms
 .. _qoriq-open-source: https://github.com/qoriq-open-source
+.. _Andre-ARM: https://github.com/Andre-ARM
diff --git a/plat/allwinner/common/include/plat_macros.S b/plat/allwinner/common/include/plat_macros.S
new file mode 100644
index 0000000..6ee4597
--- /dev/null
+++ b/plat/allwinner/common/include/plat_macros.S
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <arm_macros.S>
+#include <sunxi_mmap.h>
+
+	/* ---------------------------------------------
+	 * The below required platform porting macro
+	 * prints out relevant GIC and CCI registers
+	 * whenever an unhandled exception is taken in
+	 * BL31.
+	 * Clobbers: x0 - x10, x16, x17, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_crash_print_regs
+	mov_imm	x17, SUNXI_GICC_BASE
+	mov_imm	x16, SUNXI_GICD_BASE
+	arm_print_gic_regs
+	.endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
new file mode 100644
index 0000000..ca7db2f
--- /dev/null
+++ b/plat/allwinner/common/include/platform_def.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <common_def.h>
+#include <sunxi_mmap.h>
+#include <tbbr/tbbr_img_def.h>
+
+#define BL31_BASE			SUNXI_SRAM_A2_BASE
+#define BL31_LIMIT			(SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
+
+/* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */
+#define PLAT_SUNXI_NS_IMAGE_OFFSET	(SUNXI_DRAM_BASE + (160U << 20))
+
+#define CACHE_WRITEBACK_SHIFT		6
+#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
+
+#define MAX_MMAP_REGIONS		(4 + PLATFORM_MMAP_REGIONS)
+#define MAX_XLAT_TABLES			2
+
+#define PLAT_MAX_PWR_LVL_STATES		2
+#define PLAT_MAX_RET_STATE		1
+#define PLAT_MAX_OFF_STATE		2
+
+#define PLAT_MAX_PWR_LVL		2
+#define PLAT_NUM_PWR_DOMAINS		(1 + \
+					 PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+
+#define PLATFORM_CLUSTER_COUNT		1
+#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER_COUNT * \
+					 PLATFORM_MAX_CPUS_PER_CLUSTER)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	4
+#define PLATFORM_MMAP_REGIONS		4
+#define PLATFORM_STACK_SIZE		(0x1000 / PLATFORM_CORE_COUNT)
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
new file mode 100644
index 0000000..e68fbe4
--- /dev/null
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SUNXI_DEF_H__
+#define __SUNXI_DEF_H__
+
+/* Clock configuration */
+#define SUNXI_OSC24M_CLK_IN_HZ		24000000
+
+/* UART configuration */
+#define SUNXI_UART0_BAUDRATE		115200
+#define SUNXI_UART0_CLK_IN_HZ		SUNXI_OSC24M_CLK_IN_HZ
+
+#endif /* __SUNXI_DEF_H__ */
diff --git a/plat/allwinner/common/plat_helpers.S b/plat/allwinner/common/plat_helpers.S
new file mode 100644
index 0000000..b00c7ae
--- /dev/null
+++ b/plat/allwinner/common/plat_helpers.S
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <sunxi_def.h>
+#include <sunxi_mmap.h>
+
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_crash_console_flush
+	.globl	plat_my_core_pos
+	.globl	platform_mem_init
+	.globl	plat_report_exception
+
+func plat_crash_console_init
+	mov_imm x0, SUNXI_UART0_BASE
+	mov_imm x1, SUNXI_UART0_CLK_IN_HZ
+	mov_imm x2, SUNXI_UART0_BAUDRATE
+	b	console_16550_core_init
+endfunc plat_crash_console_init
+
+func plat_crash_console_putc
+	mov_imm x1, SUNXI_UART0_BASE
+	b	console_16550_core_putc
+endfunc plat_crash_console_putc
+
+func plat_crash_console_flush
+	ret
+endfunc plat_crash_console_flush
+
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	and	x1, x0, #MPIDR_CLUSTER_MASK
+	and	x0, x0, #MPIDR_CPU_MASK
+	add	x0, x0, x1, LSR #6
+	ret
+endfunc plat_my_core_pos
+
+func platform_mem_init
+	ret
+endfunc platform_mem_init
+
+func plat_report_exception
+	ret
+endfunc plat_report_exception
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
new file mode 100644
index 0000000..d1f1aa1
--- /dev/null
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <generic_delay_timer.h>
+#include <gicv2.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <sunxi_def.h>
+#include <sunxi_mmap.h>
+#include <uart_16550.h>
+
+#include "sunxi_private.h"
+
+static entry_point_info_t bl33_image_ep_info;
+
+static console_16550_t console;
+
+static const gicv2_driver_data_t sunxi_gic_data = {
+	.gicd_base = SUNXI_GICD_BASE,
+	.gicc_base = SUNXI_GICC_BASE,
+};
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	/* Initialize the debug console as soon as possible */
+	console_16550_register(SUNXI_UART0_BASE, SUNXI_UART0_CLK_IN_HZ,
+			       SUNXI_UART0_BAUDRATE, &console);
+
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+	bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+					  DISABLE_ALL_EXCEPTIONS);
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+	/* Turn off all secondary CPUs */
+	sunxi_disable_secondary_cpus(plat_my_core_pos());
+}
+
+void bl31_plat_arch_setup(void)
+{
+	sunxi_configure_mmu_el3(0);
+}
+
+void bl31_platform_setup(void)
+{
+	generic_delay_timer_init();
+
+	/* Configure the interrupt controller */
+	gicv2_driver_init(&sunxi_gic_data);
+	gicv2_distif_init();
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+
+	sunxi_security_setup();
+
+	INFO("BL31: Platform setup done\n");
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	assert(sec_state_is_valid(type) != 0);
+	assert(type == NON_SECURE);
+
+	return &bl33_image_ep_info;
+}
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
new file mode 100644
index 0000000..e36c8b0
--- /dev/null
+++ b/plat/allwinner/common/sunxi_common.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform.h>
+#include <platform_def.h>
+#include <sunxi_def.h>
+#include <xlat_tables_v2.h>
+
+static mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = {
+	MAP_REGION_FLAT(SUNXI_ROM_BASE, SUNXI_ROM_SIZE,
+			MT_MEMORY | MT_RO | MT_SECURE),
+	MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE,
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(SUNXI_DRAM_BASE, SUNXI_DRAM_SIZE,
+			MT_MEMORY | MT_RW | MT_NS),
+	{},
+};
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return SUNXI_OSC24M_CLK_IN_HZ;
+}
+
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+	return PRELOADED_BL33_BASE;
+#else
+	return PLAT_SUNXI_NS_IMAGE_OFFSET;
+#endif
+}
+
+void sunxi_configure_mmu_el3(int flags)
+{
+	mmap_add_region(BL31_BASE, BL31_BASE,
+			BL31_LIMIT - BL31_BASE,
+			MT_MEMORY | MT_RW | MT_SECURE);
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+	mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
+			BL_RO_DATA_END - BL_RO_DATA_BASE,
+			MT_RO_DATA | MT_SECURE);
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE);
+	mmap_add(sunxi_mmap);
+	init_xlat_tables();
+
+	enable_mmu_el3(0);
+}
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
new file mode 100644
index 0000000..be72dee
--- /dev/null
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <sunxi_mmap.h>
+#include <sunxi_cpucfg.h>
+#include <utils_def.h>
+
+#include "sunxi_private.h"
+
+static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core)
+{
+	if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff)
+		return;
+
+	INFO("PSCI: Disabling power to cluster %d core %d\n", cluster, core);
+
+	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xff);
+}
+
+static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core)
+{
+	if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0)
+		return;
+
+	INFO("PSCI: Enabling power to cluster %d core %d\n", cluster, core);
+
+	/* Power enable sequence from original Allwinner sources */
+	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xfe);
+	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xf8);
+	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xe0);
+	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x80);
+	mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00);
+}
+
+void sunxi_cpu_off(unsigned int cluster, unsigned int core)
+{
+	INFO("PSCI: Powering off cluster %d core %d\n", cluster, core);
+
+	/* Deassert DBGPWRDUP */
+	mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+	/* Activate the core output clamps */
+	mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
+	/* Assert CPU power-on reset */
+	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+	/* Remove power from the CPU */
+	sunxi_cpu_disable_power(cluster, core);
+}
+
+void sunxi_cpu_on(unsigned int cluster, unsigned int core)
+{
+	INFO("PSCI: Powering on cluster %d core %d\n", cluster, core);
+
+	/* Assert CPU core reset */
+	mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
+	/* Assert CPU power-on reset */
+	mmio_clrbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+	/* Set CPU to start in AArch64 mode */
+	mmio_setbits_32(SUNXI_CPUCFG_CLS_CTRL_REG0(cluster), BIT(24 + core));
+	/* Apply power to the CPU */
+	sunxi_cpu_enable_power(cluster, core);
+	/* Release the core output clamps */
+	mmio_clrbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core));
+	/* Deassert CPU power-on reset */
+	mmio_setbits_32(SUNXI_POWERON_RST_REG(cluster), BIT(core));
+	/* Deassert CPU core reset */
+	mmio_setbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core));
+	/* Assert DBGPWRDUP */
+	mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core));
+}
+
+void sunxi_disable_secondary_cpus(unsigned int primary_cpu)
+{
+	for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu += 1) {
+		if (cpu == primary_cpu)
+			continue;
+		sunxi_cpu_off(cpu / PLATFORM_MAX_CPUS_PER_CLUSTER,
+			       cpu % PLATFORM_MAX_CPUS_PER_CLUSTER);
+	}
+}
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
new file mode 100644
index 0000000..fcab130
--- /dev/null
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <gicv2.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <psci.h>
+#include <sunxi_mmap.h>
+#include <sunxi_cpucfg.h>
+
+#define SUNXI_WDOG0_CTRL_REG		(SUNXI_WDOG_BASE + 0x0010)
+#define SUNXI_WDOG0_CFG_REG		(SUNXI_WDOG_BASE + 0x0014)
+#define SUNXI_WDOG0_MODE_REG		(SUNXI_WDOG_BASE + 0x0018)
+
+#include "sunxi_private.h"
+
+#define mpidr_is_valid(mpidr) ( \
+	MPIDR_AFFLVL3_VAL(mpidr) == 0 && \
+	MPIDR_AFFLVL2_VAL(mpidr) == 0 && \
+	MPIDR_AFFLVL1_VAL(mpidr) < PLATFORM_CLUSTER_COUNT && \
+	MPIDR_AFFLVL0_VAL(mpidr) < PLATFORM_MAX_CPUS_PER_CLUSTER)
+
+static int sunxi_pwr_domain_on(u_register_t mpidr)
+{
+	if (mpidr_is_valid(mpidr) == 0)
+		return PSCI_E_INTERN_FAIL;
+
+	sunxi_cpu_on(MPIDR_AFFLVL1_VAL(mpidr), MPIDR_AFFLVL0_VAL(mpidr));
+
+	return PSCI_E_SUCCESS;
+}
+
+static void sunxi_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	gicv2_cpuif_disable();
+}
+
+static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+}
+
+static void __dead2 sunxi_system_off(void)
+{
+	/* Turn off all secondary CPUs */
+	sunxi_disable_secondary_cpus(plat_my_core_pos());
+
+	ERROR("PSCI: Full shutdown not implemented, halting\n");
+	wfi();
+	panic();
+}
+
+static void __dead2 sunxi_system_reset(void)
+{
+	/* Reset the whole system when the watchdog times out */
+	mmio_write_32(SUNXI_WDOG0_CFG_REG, 1);
+	/* Enable the watchdog with the shortest timeout (0.5 seconds) */
+	mmio_write_32(SUNXI_WDOG0_MODE_REG, (0 << 4) | 1);
+	/* Wait for twice the watchdog timeout before panicking */
+	mdelay(1000);
+
+	ERROR("PSCI: System reset failed\n");
+	wfi();
+	panic();
+}
+
+static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
+{
+	/* The non-secure entry point must be in DRAM */
+	if (ns_entrypoint >= SUNXI_DRAM_BASE &&
+	    ns_entrypoint < SUNXI_DRAM_BASE + SUNXI_DRAM_SIZE)
+		return PSCI_E_SUCCESS;
+
+	return PSCI_E_INVALID_ADDRESS;
+}
+
+static plat_psci_ops_t sunxi_psci_ops = {
+	.pwr_domain_on			= sunxi_pwr_domain_on,
+	.pwr_domain_off			= sunxi_pwr_domain_off,
+	.pwr_domain_on_finish		= sunxi_pwr_domain_on_finish,
+	.system_off			= sunxi_system_off,
+	.system_reset			= sunxi_system_reset,
+	.validate_ns_entrypoint		= sunxi_validate_ns_entrypoint,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	assert(psci_ops);
+
+	for (int cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu += 1) {
+		mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
+			      sec_entrypoint & 0xffffffff);
+		mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
+			      sec_entrypoint >> 32);
+	}
+
+	*psci_ops = &sunxi_psci_ops;
+
+	return 0;
+}
diff --git a/plat/allwinner/common/sunxi_private.h b/plat/allwinner/common/sunxi_private.h
new file mode 100644
index 0000000..b9f0fb4
--- /dev/null
+++ b/plat/allwinner/common/sunxi_private.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SUNXI_PRIVATE_H__
+#define __SUNXI_PRIVATE_H__
+
+void sunxi_configure_mmu_el3(int flags);
+void sunxi_cpu_off(unsigned int cluster, unsigned int core);
+void sunxi_cpu_on(unsigned int cluster, unsigned int core);
+void sunxi_disable_secondary_cpus(unsigned int primary_cpu);
+
+void sunxi_security_setup(void);
+
+#endif /* __SUNXI_PRIVATE_H__ */
diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c
new file mode 100644
index 0000000..e760072
--- /dev/null
+++ b/plat/allwinner/common/sunxi_security.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <sunxi_mmap.h>
+
+#ifdef SUNXI_SPC_BASE
+#define SPC_DECPORT_STA_REG(p)	(SUNXI_SPC_BASE + ((p) * 0x0c) + 0x4)
+#define SPC_DECPORT_SET_REG(p)	(SUNXI_SPC_BASE + ((p) * 0x0c) + 0x8)
+#define SPC_DECPORT_CLR_REG(p)	(SUNXI_SPC_BASE + ((p) * 0x0c) + 0xc)
+#endif
+
+#define R_PRCM_SEC_SWITCH_REG	0x1d0
+#define DMA_SEC_REG		0x20
+
+/*
+ * Setup the peripherals to be accessible by non-secure world.
+ * This will not work for the Secure Peripherals Controller (SPC) unless
+ * a fuse it burnt (seems to be an erratum), but we do it nevertheless,
+ * to allow booting on boards using secure boot.
+ */
+void sunxi_security_setup(void)
+{
+	int i;
+
+#ifdef SUNXI_SPC_BASE
+	INFO("Configuring SPC Controller\n");
+	/* SPC setup: set all devices to non-secure */
+	for (i = 0; i < 6; i++)
+		mmio_write_32(SPC_DECPORT_SET_REG(i), 0xff);
+#endif
+
+	/* set MBUS clocks, bus clocks (AXI/AHB/APB) and PLLs to non-secure */
+	mmio_write_32(SUNXI_CCU_SEC_SWITCH_REG, 0x7);
+
+	/* set R_PRCM clocks to non-secure */
+	mmio_write_32(SUNXI_R_PRCM_BASE + R_PRCM_SEC_SWITCH_REG, 0x7);
+
+	/* Set all DMA channels (16 max.) to non-secure */
+	mmio_write_32(SUNXI_DMA_BASE + DMA_SEC_REG, 0xffff);
+}
diff --git a/plat/allwinner/common/sunxi_topology.c b/plat/allwinner/common/sunxi_topology.c
new file mode 100644
index 0000000..98cf63c
--- /dev/null
+++ b/plat/allwinner/common/sunxi_topology.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <platform.h>
+#include <platform_def.h>
+
+static unsigned char plat_power_domain_tree_desc[PLAT_MAX_PWR_LVL + 1] = {
+	/* One root node for the SoC */
+	1,
+	/* One node for each cluster */
+	PLATFORM_CLUSTER_COUNT,
+	/* One set of CPUs per cluster */
+	PLATFORM_MAX_CPUS_PER_CLUSTER,
+};
+
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr);
+	unsigned int core = MPIDR_AFFLVL0_VAL(mpidr);
+
+	if (MPIDR_AFFLVL3_VAL(mpidr) > 0 ||
+	    MPIDR_AFFLVL2_VAL(mpidr) > 0 ||
+	    cluster >= PLATFORM_CLUSTER_COUNT ||
+	    core >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
+		return -1;
+	}
+
+	return cluster * PLATFORM_MAX_CPUS_PER_CLUSTER + core;
+}
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return plat_power_domain_tree_desc;
+}
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
new file mode 100644
index 0000000..049c2ad
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/include/sunxi_cpucfg.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SUNXI_CPUCFG_H__
+#define __SUNXI_CPUCFG_H__
+
+#include <sunxi_mmap.h>
+
+/* c = cluster, n = core */
+#define SUNXI_CPUCFG_CLS_CTRL_REG0(c)	(SUNXI_CPUCFG_BASE + 0x0000 + (c) * 16)
+#define SUNXI_CPUCFG_CLS_CTRL_REG1(c)	(SUNXI_CPUCFG_BASE + 0x0004 + (c) * 16)
+#define SUNXI_CPUCFG_CACHE_CFG_REG0	(SUNXI_CPUCFG_BASE + 0x0008)
+#define SUNXI_CPUCFG_CACHE_CFG_REG1	(SUNXI_CPUCFG_BASE + 0x000c)
+#define SUNXI_CPUCFG_DBG_REG0		(SUNXI_CPUCFG_BASE + 0x0020)
+#define SUNXI_CPUCFG_GLB_CTRL_REG	(SUNXI_CPUCFG_BASE + 0x0028)
+#define SUNXI_CPUCFG_CPU_STS_REG(c)	(SUNXI_CPUCFG_BASE + 0x0030 + (c) * 4)
+#define SUNXI_CPUCFG_L2_STS_REG		(SUNXI_CPUCFG_BASE + 0x003c)
+#define SUNXI_CPUCFG_RST_CTRL_REG(c)	(SUNXI_CPUCFG_BASE + 0x0080 + (c) * 4)
+#define SUNXI_CPUCFG_RVBAR_LO_REG(n)	(SUNXI_CPUCFG_BASE + 0x00a0 + (n) * 8)
+#define SUNXI_CPUCFG_RVBAR_HI_REG(n)	(SUNXI_CPUCFG_BASE + 0x00a4 + (n) * 8)
+
+#define SUNXI_CPU_POWER_CLAMP_REG(c, n)	(SUNXI_R_PRCM_BASE + 0x0140 + \
+					 (c) * 16 + (n) * 4)
+#define SUNXI_POWEROFF_GATING_REG(c)	(SUNXI_R_PRCM_BASE + 0x0100 + (c) * 4)
+#define SUNXI_R_CPUCFG_CPUS_RST_REG	(SUNXI_R_CPUCFG_BASE + 0x0000)
+#define SUNXI_POWERON_RST_REG(c)	(SUNXI_R_CPUCFG_BASE + 0x0030 + (c) * 4)
+#define SUNXI_R_CPUCFG_SYS_RST_REG	(SUNXI_R_CPUCFG_BASE + 0x0140)
+#define SUNXI_R_CPUCFG_SS_FLAG_REG	(SUNXI_R_CPUCFG_BASE + 0x01a0)
+#define SUNXI_R_CPUCFG_CPU_ENTRY_REG	(SUNXI_R_CPUCFG_BASE + 0x01a4)
+#define SUNXI_R_CPUCFG_SS_ENTRY_REG	(SUNXI_R_CPUCFG_BASE + 0x01a8)
+#define SUNXI_R_CPUCFG_HP_FLAG_REG	(SUNXI_R_CPUCFG_BASE + 0x01ac)
+
+#endif /* __SUNXI_CPUCFG_H__ */
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
new file mode 100644
index 0000000..cb202a8
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SUNXI_MMAP_H__
+#define __SUNXI_MMAP_H__
+
+/* Memory regions */
+#define SUNXI_ROM_BASE			0x00000000
+#define SUNXI_ROM_SIZE			0x00010000
+#define SUNXI_SRAM_BASE			0x00010000
+#define SUNXI_SRAM_SIZE			0x00044000
+#define SUNXI_SRAM_A1_BASE		0x00010000
+#define SUNXI_SRAM_A1_SIZE		0x00008000
+#define SUNXI_SRAM_A2_BASE		0x00044000
+#define SUNXI_SRAM_A2_SIZE		0x00010000
+#define SUNXI_SRAM_C_BASE		0x00018000
+#define SUNXI_SRAM_C_SIZE		0x0001c000
+#define SUNXI_DEV_BASE			0x01000000
+#define SUNXI_DEV_SIZE			0x01000000
+#define SUNXI_DRAM_BASE			0x40000000
+#define SUNXI_DRAM_SIZE			0x80000000
+
+/* Memory-mapped devices */
+#define SUNXI_CPU_MBIST_BASE		0x01502000
+#define SUNXI_CPUCFG_BASE		0x01700000
+#define SUNXI_SYSCON_BASE		0x01c00000
+#define SUNXI_SRAM_VER_REG		(SUNXI_SYSCON_BASE + 0x24)
+#define SUNXI_DMA_BASE			0x01c02000
+#define SUNXI_KEYMEM_BASE		0x01c0b000
+#define SUNXI_SMHC0_BASE		0x01c0f000
+#define SUNXI_SMHC1_BASE		0x01c10000
+#define SUNXI_SMHC2_BASE		0x01c11000
+#define SUNXI_SID_BASE			0x01c14000
+#define SUNXI_MSGBOX_BASE		0x01c17000
+#define SUNXI_SPINLOCK_BASE		0x01c18000
+#define SUNXI_CCU_BASE			0x01c20000
+#define SUNXI_CCU_SEC_SWITCH_REG	(SUNXI_CCU_BASE + 0x2f0)
+#define SUNXI_PIO_BASE			0x01c20800
+#define SUNXI_TIMER_BASE		0x01c20c00
+#define SUNXI_WDOG_BASE			0x01c20ca0
+#define SUNXI_SPC_BASE			0x01c23400
+#define SUNXI_THS_BASE			0x01c25000
+#define SUNXI_UART0_BASE		0x01c28000
+#define SUNXI_UART1_BASE		0x01c28400
+#define SUNXI_UART2_BASE		0x01c28800
+#define SUNXI_UART3_BASE		0x01c28c00
+#define SUNXI_I2C0_BASE			0x01c2ac00
+#define SUNXI_I2C1_BASE			0x01c2b000
+#define SUNXI_I2C2_BASE			0x01c2b400
+#define SUNXI_DRAMCOM_BASE		0x01c62000
+#define SUNXI_DRAMCTL_BASE		0x01c63000
+#define SUNXI_DRAMPHY_BASE		0x01c65000
+#define SUNXI_SPI0_BASE			0x01c68000
+#define SUNXI_SPI1_BASE			0x01c69000
+#define SUNXI_SCU_BASE			0x01c80000
+#define SUNXI_GICD_BASE			0x01c81000
+#define SUNXI_GICC_BASE			0x01c82000
+#define SUNXI_RTC_BASE			0x01f00000
+#define SUNXI_R_TIMER_BASE		0x01f00800
+#define SUNXI_R_INTC_BASE		0x01f00c00
+#define SUNXI_R_WDOG_BASE		0x01f01000
+#define SUNXI_R_PRCM_BASE		0x01f01400
+#define SUNXI_R_TWD_BASE		0x01f01800
+#define SUNXI_R_CPUCFG_BASE		0x01f01c00
+#define SUNXI_R_CIR_BASE		0x01f02000
+#define SUNXI_R_I2C_BASE		0x01f02400
+#define SUNXI_R_UART_BASE		0x01f02800
+#define SUNXI_R_PIO_BASE		0x01f02c00
+#define SUNXI_R_RSB_BASE		0x01f03400
+#define SUNXI_R_PWM_BASE		0x01f03800
+
+#endif /* __SUNXI_MMAP_H__ */
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
new file mode 100644
index 0000000..236464f
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -0,0 +1,59 @@
+#
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+AW_PLAT			:=	plat/allwinner
+
+PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/		\
+				-Iinclude/plat/arm/common/aarch64	\
+				-I${AW_PLAT}/common/include		\
+				-I${AW_PLAT}/${PLAT}/include
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/console/${ARCH}/console.S	\
+				drivers/ti/uart/${ARCH}/16550_console.S	\
+				${XLAT_TABLES_LIB_SRCS}			\
+				${AW_PLAT}/common/plat_helpers.S	\
+				${AW_PLAT}/common/sunxi_common.c
+
+BL31_SOURCES		+=	drivers/arm/gic/common/gic_common.c	\
+				drivers/arm/gic/v2/gicv2_helpers.c	\
+				drivers/arm/gic/v2/gicv2_main.c		\
+				drivers/delay_timer/delay_timer.c	\
+				drivers/delay_timer/generic_delay_timer.c \
+				lib/cpus/${ARCH}/cortex_a53.S		\
+				plat/common/plat_gicv2.c		\
+				plat/common/plat_psci_common.c		\
+				${AW_PLAT}/common/sunxi_bl31_setup.c	\
+				${AW_PLAT}/common/sunxi_cpu_ops.c	\
+				${AW_PLAT}/common/sunxi_pm.c		\
+				${AW_PLAT}/common/sunxi_security.c	\
+				${AW_PLAT}/common/sunxi_topology.c
+
+# The bootloader is guaranteed to only run on CPU 0 by the boot ROM.
+COLD_BOOT_SINGLE_CPU		:=	1
+
+# Enable workarounds for Cortex-A53 errata. Allwinner uses at least r0p4.
+ERRATA_A53_835769		:=	1
+ERRATA_A53_843419		:=	1
+ERRATA_A53_855873		:=	1
+
+# Disable the PSCI platform compatibility layer.
+ENABLE_PLAT_COMPAT		:= 	0
+
+MULTI_CONSOLE_API		:=	1
+
+# Prohibit using deprecated interfaces. We rely on this for this platform.
+ERROR_DEPRECATED		:=	1
+
+# The reset vector can be changed for each CPU.
+PROGRAMMABLE_RESET_ADDRESS	:=	1
+
+# Allow mapping read-only data as execute-never.
+SEPARATE_CODE_AND_RODATA	:=	1
+
+# BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
+RESET_TO_BL31			:=	1
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 3f0ea01..11bdeac 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -81,14 +81,6 @@
 			MT_DEVICE | MT_RW | MT_SECURE);
 #endif
 
-#if ENABLE_SPM && defined(IMAGE_BL31)
-	/* The address of the following region is calculated by the linker. */
-	mmap_add_region(SP_IMAGE_XLAT_TABLES_START,
-			SP_IMAGE_XLAT_TABLES_START,
-			SP_IMAGE_XLAT_TABLES_SIZE,
-			MT_MEMORY | MT_RW | MT_SECURE);
-#endif
-
 	/* Now (re-)map the platform-specific memory regions */
 	mmap_add(plat_arm_get_mmap());
 
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h
index 3c94536..cb75ed0 100644
--- a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h
+++ b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h
@@ -18,8 +18,8 @@
 #define MHU_V2_ACCESS_REQ_OFFSET		0xF88
 #define MHU_V2_ACCESS_READY_OFFSET		0xF8C
 
-#define SENDER_REG_STAT(CHANNEL)	(0x20 * (CHANNEL))
-#define SENDER_REG_SET(CHANNEL)		(0x20 * (CHANNEL)) + 0xC
+#define SENDER_REG_STAT(_channel)	(0x20 * (_channel))
+#define SENDER_REG_SET(_channel)	((0x20 * (_channel)) + 0xC)
 
 /* Helper macro to ring doorbell */
 #define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask)	do {	\
diff --git a/plat/arm/css/drivers/scmi/scmi_private.h b/plat/arm/css/drivers/scmi/scmi_private.h
index a07841e..67fe748 100644
--- a/plat/arm/css/drivers/scmi/scmi_private.h
+++ b/plat/arm/css/drivers/scmi/scmi_private.h
@@ -60,14 +60,14 @@
  * Helper macro to create an SCMI message header given protocol, message id
  * and token.
  */
-#define SCMI_MSG_CREATE(protocol, msg_id, token)				\
-	((((protocol) & SCMI_MSG_PROTO_ID_MASK) << SCMI_MSG_PROTO_ID_SHIFT) |	\
-	(((msg_id) & SCMI_MSG_ID_MASK) << SCMI_MSG_ID_SHIFT) |			\
-	(((token) & SCMI_MSG_TOKEN_MASK) << SCMI_MSG_TOKEN_SHIFT))
+#define SCMI_MSG_CREATE(_protocol, _msg_id, _token)				\
+	((((_protocol) & SCMI_MSG_PROTO_ID_MASK) << SCMI_MSG_PROTO_ID_SHIFT) |	\
+	(((_msg_id) & SCMI_MSG_ID_MASK) << SCMI_MSG_ID_SHIFT) |			\
+	(((_token) & SCMI_MSG_TOKEN_MASK) << SCMI_MSG_TOKEN_SHIFT))
 
 /* Helper macro to get the token from a SCMI message header */
-#define SCMI_MSG_GET_TOKEN(msg)				\
-	(((msg) >> SCMI_MSG_TOKEN_SHIFT) & SCMI_MSG_TOKEN_MASK)
+#define SCMI_MSG_GET_TOKEN(_msg)				\
+	(((_msg) >> SCMI_MSG_TOKEN_SHIFT) & SCMI_MSG_TOKEN_MASK)
 
 /* SCMI Channel Status bit fields */
 #define SCMI_CH_STATUS_RES0_MASK	0xFFFFFFFE
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c
index c0ed487..3a25509 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scmi.c
@@ -36,21 +36,21 @@
 #define SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH	4
 #define SCMI_PWR_STATE_MAX_PWR_LVL_MASK		\
 				((1 << SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH) - 1)
-#define SCMI_SET_PWR_STATE_MAX_PWR_LVL(pwr_state, max_lvl)		\
-		(pwr_state) |= ((max_lvl) & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)	\
+#define SCMI_SET_PWR_STATE_MAX_PWR_LVL(_power_state, _max_level)		\
+		(_power_state) |= ((_max_level) & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)\
 				<< SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT
-#define SCMI_GET_PWR_STATE_MAX_PWR_LVL(pwr_state)		\
-		(((pwr_state) >> SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT)	\
+#define SCMI_GET_PWR_STATE_MAX_PWR_LVL(_power_state)		\
+		(((_power_state) >> SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT)	\
 				& SCMI_PWR_STATE_MAX_PWR_LVL_MASK)
 
 #define SCMI_PWR_STATE_LVL_WIDTH		4
 #define SCMI_PWR_STATE_LVL_MASK			\
 				((1 << SCMI_PWR_STATE_LVL_WIDTH) - 1)
-#define SCMI_SET_PWR_STATE_LVL(pwr_state, lvl, lvl_state)		\
-		(pwr_state) |= ((lvl_state) & SCMI_PWR_STATE_LVL_MASK)	\
-				<< (SCMI_PWR_STATE_LVL_WIDTH * (lvl))
-#define SCMI_GET_PWR_STATE_LVL(pwr_state, lvl)		\
-		(((pwr_state) >> (SCMI_PWR_STATE_LVL_WIDTH * (lvl))) &	\
+#define SCMI_SET_PWR_STATE_LVL(_power_state, _level, _level_state)		\
+		(_power_state) |= ((_level_state) & SCMI_PWR_STATE_LVL_MASK)	\
+				<< (SCMI_PWR_STATE_LVL_WIDTH * (_level))
+#define SCMI_GET_PWR_STATE_LVL(_power_state, _level)		\
+		(((_power_state) >> (SCMI_PWR_STATE_LVL_WIDTH * (_level))) &	\
 				SCMI_PWR_STATE_LVL_MASK)
 
 /*
@@ -69,7 +69,7 @@
 static void *scmi_handle;
 
 /* The SCMI channel global object */
-static scmi_channel_t scmi_channel;
+static scmi_channel_t channel;
 
 ARM_INSTANTIATE_LOCK;
 
@@ -308,9 +308,9 @@
 
 void plat_arm_pwrc_setup(void)
 {
-	scmi_channel.info = &plat_css_scmi_plat_info;
-	scmi_channel.lock = ARM_LOCK_GET_INSTANCE;
-	scmi_handle = scmi_init(&scmi_channel);
+	channel.info = &plat_css_scmi_plat_info;
+	channel.lock = ARM_LOCK_GET_INSTANCE;
+	scmi_handle = scmi_init(&channel);
 	if (scmi_handle == NULL) {
 		ERROR("SCMI Initialization failed\n");
 		panic();
diff --git a/plat/arm/css/drivers/sds/sds_private.h b/plat/arm/css/drivers/sds/sds_private.h
index 649576b..43b97f6 100644
--- a/plat/arm/css/drivers/sds/sds_private.h
+++ b/plat/arm/css/drivers/sds/sds_private.h
@@ -67,18 +67,18 @@
 	uint32_t reg[2];
 } struct_header_t;
 
-#define GET_SDS_HEADER_ID(header)			\
-	((((struct_header_t *)(header))->reg[0]) & SDS_HEADER_ID_MASK)
-#define GET_SDS_HEADER_VERSION(header)			\
-	(((((struct_header_t *)(header))->reg[0]) >> SDS_HEADER_MINOR_VERSION_SHIFT)\
+#define GET_SDS_HEADER_ID(_header)			\
+	((((struct_header_t *)(_header))->reg[0]) & SDS_HEADER_ID_MASK)
+#define GET_SDS_HEADER_VERSION(_header)			\
+	(((((struct_header_t *)(_header))->reg[0]) >> SDS_HEADER_MINOR_VERSION_SHIFT)\
 	& SDS_HEADER_VERSION_MASK)
-#define GET_SDS_HEADER_STRUCT_SIZE(header)		\
-	(((((struct_header_t *)(header))->reg[1]) >> SDS_HEADER_STRUCT_SIZE_SHIFT)\
+#define GET_SDS_HEADER_STRUCT_SIZE(_header)		\
+	(((((struct_header_t *)(_header))->reg[1]) >> SDS_HEADER_STRUCT_SIZE_SHIFT)\
 	& SDS_HEADER_STRUCT_SIZE_MASK)
-#define IS_SDS_HEADER_VALID(header)			\
-	((((struct_header_t *)(header))->reg[1]) & SDS_HEADER_VALID_MASK)
-#define GET_SDS_STRUCT_FIELD(header, field_offset)	\
-	((((uint8_t *)(header)) + sizeof(struct_header_t)) + (field_offset))
+#define IS_SDS_HEADER_VALID(_header)			\
+	((((struct_header_t *)(_header))->reg[1]) & SDS_HEADER_VALID_MASK)
+#define GET_SDS_STRUCT_FIELD(_header, _field_offset)	\
+	((((uint8_t *)(_header)) + sizeof(struct_header_t)) + (_field_offset))
 
 /* Region Descriptor describing the SDS Memory Region */
 typedef struct region_descriptor {
diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.h b/plat/rockchip/rk3399/drivers/dram/dfs.h
index 679216c..e847b2e 100644
--- a/plat/rockchip/rk3399/drivers/dram/dfs.h
+++ b/plat/rockchip/rk3399/drivers/dram/dfs.h
@@ -7,6 +7,8 @@
 #ifndef __SOC_ROCKCHIP_RK3399_DFS_H__
 #define __SOC_ROCKCHIP_RK3399_DFS_H__
 
+#include <stdint.h>
+
 struct rk3399_sdram_default_config {
 	unsigned char bl;
 	/* 1:auto precharge, 0:never auto precharge */
diff --git a/plat/rockchip/rk3399/plat_sip_calls.c b/plat/rockchip/rk3399/plat_sip_calls.c
index ae74c9c..3f0f619 100644
--- a/plat/rockchip/rk3399/plat_sip_calls.c
+++ b/plat/rockchip/rk3399/plat_sip_calls.c
@@ -11,7 +11,6 @@
 #include <plat_sip_calls.h>
 #include <rockchip_sip_svc.h>
 #include <runtime_svc.h>
-#include <stdint.h>
 
 #define RK_SIP_DDR_CFG		0x82000008
 #define DRAM_INIT		0x00
diff --git a/plat/socionext/uniphier/uniphier_cci.c b/plat/socionext/uniphier/uniphier_cci.c
index 30f4b47..9e00c56 100644
--- a/plat/socionext/uniphier/uniphier_cci.c
+++ b/plat/socionext/uniphier/uniphier_cci.c
@@ -13,7 +13,7 @@
 
 #define UNIPHIER_CCI500_BASE	0x5FD00000
 
-static const int uniphier_cci_map[] = {0, 1};
+static const int uniphier_cci_map[] = {1, 0};
 
 static void __uniphier_cci_init(void)
 {
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index ac58e04..01ec2a2 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -34,7 +34,7 @@
  * Address of the entrypoint vector table in OPTEE. It is
  * initialised once on the primary core after a cold boot.
  ******************************************************************************/
-optee_vectors_t *optee_vectors;
+optee_vectors_t *optee_vector_table;
 
 /*******************************************************************************
  * Array to keep track of per-cpu OPTEE state
@@ -71,7 +71,7 @@
 	optee_ctx = &opteed_sp_context[linear_id];
 	assert(&optee_ctx->cpu_ctx == cm_get_context(SECURE));
 
-	cm_set_elr_el3(SECURE, (uint64_t)&optee_vectors->fiq_entry);
+	cm_set_elr_el3(SECURE, (uint64_t)&optee_vector_table->fiq_entry);
 	cm_el1_sysregs_context_restore(SECURE);
 	cm_set_next_eret_context(SECURE);
 
@@ -236,10 +236,10 @@
 		 */
 		if (GET_SMC_TYPE(smc_fid) == SMC_TYPE_FAST) {
 			cm_set_elr_el3(SECURE, (uint64_t)
-					&optee_vectors->fast_smc_entry);
+					&optee_vector_table->fast_smc_entry);
 		} else {
 			cm_set_elr_el3(SECURE, (uint64_t)
-					&optee_vectors->yield_smc_entry);
+					&optee_vector_table->yield_smc_entry);
 		}
 
 		cm_el1_sysregs_context_restore(SECURE);
@@ -279,10 +279,10 @@
 		 * Stash the OPTEE entry points information. This is done
 		 * only once on the primary cpu
 		 */
-		assert(optee_vectors == NULL);
-		optee_vectors = (optee_vectors_t *) x1;
+		assert(optee_vector_table == NULL);
+		optee_vector_table = (optee_vectors_t *) x1;
 
-		if (optee_vectors) {
+		if (optee_vector_table) {
 			set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_ON);
 
 			/*
diff --git a/services/spd/opteed/opteed_pm.c b/services/spd/opteed/opteed_pm.c
index 7efc234..bdacf98 100644
--- a/services/spd/opteed/opteed_pm.c
+++ b/services/spd/opteed/opteed_pm.c
@@ -30,11 +30,11 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
-	assert(optee_vectors);
+	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
 	/* Program the entry point and enter OPTEE */
-	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->cpu_off_entry);
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vector_table->cpu_off_entry);
 	rc = opteed_synchronous_sp_entry(optee_ctx);
 
 	/*
@@ -63,11 +63,11 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
-	assert(optee_vectors);
+	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
 	/* Program the entry point and enter OPTEE */
-	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->cpu_suspend_entry);
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vector_table->cpu_suspend_entry);
 	rc = opteed_synchronous_sp_entry(optee_ctx);
 
 	/*
@@ -94,11 +94,11 @@
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 	entry_point_info_t optee_on_entrypoint;
 
-	assert(optee_vectors);
+	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_OFF);
 
 	opteed_init_optee_ep_state(&optee_on_entrypoint, opteed_rw,
-				(uint64_t)&optee_vectors->cpu_on_entry,
+				(uint64_t)&optee_vector_table->cpu_on_entry,
 				0, 0, 0, optee_ctx);
 
 	/* Initialise this cpu's secure context */
@@ -129,14 +129,14 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
-	assert(optee_vectors);
+	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_SUSPEND);
 
 	/* Program the entry point, max_off_pwrlvl and enter the SP */
 	write_ctx_reg(get_gpregs_ctx(&optee_ctx->cpu_ctx),
 		      CTX_GPREG_X0,
 		      max_off_pwrlvl);
-	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->cpu_resume_entry);
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vector_table->cpu_resume_entry);
 	rc = opteed_synchronous_sp_entry(optee_ctx);
 
 	/*
@@ -168,11 +168,11 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
-	assert(optee_vectors);
+	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
 	/* Program the entry point */
-	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->system_off_entry);
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vector_table->system_off_entry);
 
 	/* Enter OPTEE. We do not care about the return value because we
 	 * must continue the shutdown anyway */
@@ -188,11 +188,11 @@
 	uint32_t linear_id = plat_my_core_pos();
 	optee_context_t *optee_ctx = &opteed_sp_context[linear_id];
 
-	assert(optee_vectors);
+	assert(optee_vector_table);
 	assert(get_optee_pstate(optee_ctx->state) == OPTEE_PSTATE_ON);
 
 	/* Program the entry point */
-	cm_set_elr_el3(SECURE, (uint64_t) &optee_vectors->system_reset_entry);
+	cm_set_elr_el3(SECURE, (uint64_t) &optee_vector_table->system_reset_entry);
 
 	/* Enter OPTEE. We do not care about the return value because we
 	 * must continue the reset anyway */
diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h
index 6cda2c8..b77b6d3 100644
--- a/services/spd/opteed/opteed_private.h
+++ b/services/spd/opteed/opteed_private.h
@@ -154,7 +154,7 @@
 
 extern optee_context_t opteed_sp_context[OPTEED_CORE_COUNT];
 extern uint32_t opteed_rw;
-extern struct optee_vectors *optee_vectors;
+extern struct optee_vectors *optee_vector_table;
 #endif /*__ASSEMBLY__*/
 
 #endif /* __OPTEED_PRIVATE_H__ */
diff --git a/services/spd/tspd/tspd_private.h b/services/spd/tspd/tspd_private.h
index 692a967..080e757 100644
--- a/services/spd/tspd/tspd_private.h
+++ b/services/spd/tspd/tspd_private.h
@@ -190,14 +190,14 @@
 } tsp_context_t;
 
 /* Helper macros to store and retrieve tsp args from tsp_context */
-#define store_tsp_args(tsp_ctx, x1, x2)		do {\
-				tsp_ctx->saved_tsp_args[0] = x1;\
-				tsp_ctx->saved_tsp_args[1] = x2;\
+#define store_tsp_args(_tsp_ctx, _x1, _x2)		do {\
+				_tsp_ctx->saved_tsp_args[0] = _x1;\
+				_tsp_ctx->saved_tsp_args[1] = _x2;\
 			} while (0)
 
-#define get_tsp_args(tsp_ctx, x1, x2)	do {\
-				x1 = tsp_ctx->saved_tsp_args[0];\
-				x2 = tsp_ctx->saved_tsp_args[1];\
+#define get_tsp_args(_tsp_ctx, _x1, _x2)	do {\
+				_x1 = _tsp_ctx->saved_tsp_args[0];\
+				_x2 = _tsp_ctx->saved_tsp_args[1];\
 			} while (0)
 
 /* TSPD power management handlers */
diff --git a/services/std_svc/spm/sp_setup.c b/services/std_svc/spm/sp_setup.c
index de27e3e..b9b67f7 100644
--- a/services/std_svc/spm/sp_setup.c
+++ b/services/std_svc/spm/sp_setup.c
@@ -33,16 +33,11 @@
 	entry_point_info_t ep_info = {0};
 
 	SET_PARAM_HEAD(&ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
+
+	/* Setup entrypoint and SPSR */
 	ep_info.pc = BL32_BASE;
 	ep_info.spsr = SPSR_64(MODE_EL0, MODE_SP_EL0, DISABLE_ALL_EXCEPTIONS);
 
-	cm_setup_context(ctx, &ep_info);
-
-	/*
-	 * General-Purpose registers
-	 * -------------------------
-	 */
-
 	/*
 	 * X0: Virtual address of a buffer shared between EL3 and Secure EL0.
 	 *     The buffer will be mapped in the Secure EL1 translation regime
@@ -55,12 +50,14 @@
 	 *
 	 * X3: cookie value (Implementation Defined)
 	 *
-	 * X4 to X30 = 0 (already done by cm_init_my_context())
+	 * X4 to X7 = 0
 	 */
-	write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0, PLAT_SPM_BUF_BASE);
-	write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1, PLAT_SPM_BUF_SIZE);
-	write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2, PLAT_SPM_COOKIE_0);
-	write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3, PLAT_SPM_COOKIE_1);
+	ep_info.args.arg0 = PLAT_SPM_BUF_BASE;
+	ep_info.args.arg1 = PLAT_SPM_BUF_SIZE;
+	ep_info.args.arg2 = PLAT_SPM_COOKIE_0;
+	ep_info.args.arg3 = PLAT_SPM_COOKIE_1;
+
+	cm_setup_context(ctx, &ep_info);
 
 	/*
 	 * SP_EL0: A non-zero value will indicate to the SP that the SPM has
@@ -78,45 +75,18 @@
 #if ENABLE_ASSERTIONS
 
 	/* Get max granularity supported by the platform. */
+	unsigned int max_granule = xlat_arch_get_max_supported_granule_size();
 
-	u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
+	VERBOSE("Max translation granule size supported: %u KiB\n",
+		max_granule / 1024U);
 
-	int tgran64_supported =
-		((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
-		 ID_AA64MMFR0_EL1_TGRAN64_MASK) ==
-		 ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED;
-
-	int tgran16_supported =
-		((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
-		 ID_AA64MMFR0_EL1_TGRAN16_MASK) ==
-		 ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED;
-
-	int tgran4_supported =
-		((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
-		 ID_AA64MMFR0_EL1_TGRAN4_MASK) ==
-		 ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED;
-
-	uintptr_t max_granule_size;
-
-	if (tgran64_supported) {
-		max_granule_size = 64 * 1024;
-	} else if (tgran16_supported) {
-		max_granule_size = 16 * 1024;
-	} else {
-		assert(tgran4_supported);
-		max_granule_size = 4 * 1024;
-	}
-
-	VERBOSE("Max translation granule supported: %lu KiB\n",
-		max_granule_size / 1024);
-
-	uintptr_t max_granule_size_mask = max_granule_size - 1;
+	unsigned int max_granule_mask = max_granule - 1U;
 
 	/* Base must be aligned to the max granularity */
-	assert((ARM_SP_IMAGE_NS_BUF_BASE & max_granule_size_mask) == 0);
+	assert((ARM_SP_IMAGE_NS_BUF_BASE & max_granule_mask) == 0);
 
 	/* Size must be a multiple of the max granularity */
-	assert((ARM_SP_IMAGE_NS_BUF_SIZE & max_granule_size_mask) == 0);
+	assert((ARM_SP_IMAGE_NS_BUF_SIZE & max_granule_mask) == 0);
 
 #endif /* ENABLE_ASSERTIONS */
 
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index be76dc2..f63f9c4 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -81,10 +81,13 @@
 }
 
 /*******************************************************************************
- * This function takes an SP context pointer and prepares the CPU to enter.
+ * This function takes an SP context pointer and performs a synchronous entry
+ * into it.
  ******************************************************************************/
-static void spm_sp_prepare_enter(sp_context_t *sp_ctx)
+static uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx)
 {
+	uint64_t rc;
+
 	assert(sp_ctx != NULL);
 
 	/* Assign the context of the SP to this CPU */
@@ -97,15 +100,32 @@
 	/* Invalidate TLBs at EL1. */
 	tlbivmalle1();
 	dsbish();
+
+	/* Enter Secure Partition */
+	rc = spm_secure_partition_enter(&sp_ctx->c_rt_ctx);
+
+	/* Save secure state */
+	cm_el1_sysregs_context_save(SECURE);
+
+	return rc;
 }
 
 /*******************************************************************************
- * Enter SP after preparing it with spm_sp_prepare_enter().
+ * This function returns to the place where spm_sp_synchronous_entry() was
+ * called originally.
  ******************************************************************************/
-static uint64_t spm_sp_enter(sp_context_t *sp_ctx)
+__dead2 static void spm_sp_synchronous_exit(uint64_t rc)
 {
-	/* Enter Secure Partition */
-	return spm_secure_partition_enter(&sp_ctx->c_rt_ctx);
+	sp_context_t *ctx = &sp_ctx;
+
+	/*
+	 * The SPM must have initiated the original request through a
+	 * synchronous entry into the secure partition. Jump back to the
+	 * original C runtime context with the value of rc in x0;
+	 */
+	spm_secure_partition_exit(ctx->c_rt_ctx, rc);
+
+	panic();
 }
 
 /*******************************************************************************
@@ -113,7 +133,7 @@
  ******************************************************************************/
 static int32_t spm_init(void)
 {
-	uint64_t rc = 0;
+	uint64_t rc;
 	sp_context_t *ctx;
 
 	INFO("Secure Partition init...\n");
@@ -122,8 +142,7 @@
 
 	ctx->state = SP_STATE_RESET;
 
-	spm_sp_prepare_enter(ctx);
-	rc |= spm_sp_enter(ctx);
+	rc = spm_sp_synchronous_entry(ctx);
 	assert(rc == 0);
 
 	ctx->state = SP_STATE_IDLE;
@@ -168,6 +187,7 @@
 			       uint64_t comm_buffer_address,
 			       uint64_t comm_size_address, void *handle)
 {
+	uint64_t rc;
 	sp_context_t *ctx = &sp_ctx;
 
 	/* Cookie. Reserved for future use. It must be zero. */
@@ -188,59 +208,29 @@
 	/* Save the Normal world context */
 	cm_el1_sysregs_context_save(NON_SECURE);
 
-	/* Wait until the Secure Partition is IDLE and set it to BUSY. */
+	/* Wait until the Secure Partition is idle and set it to busy. */
 	sp_state_wait_switch(ctx, SP_STATE_IDLE, SP_STATE_BUSY);
 
+	/* Set values for registers on SP entry */
+	cpu_context_t *cpu_ctx = &(ctx->cpu_ctx);
+
+	write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X0, smc_fid);
+	write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X1, comm_buffer_address);
+	write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X2, comm_size_address);
+	write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3, plat_my_core_pos());
+
 	/* Jump to the Secure Partition. */
-	spm_sp_prepare_enter(ctx);
+	rc = spm_sp_synchronous_entry(ctx);
 
-	SMC_RET4(&(ctx->cpu_ctx), smc_fid, comm_buffer_address,
-		 comm_size_address, plat_my_core_pos());
-}
-
-/*******************************************************************************
- * SP_EVENT_COMPLETE_AARCH64 handler
- ******************************************************************************/
-static uint64_t sp_event_complete(uint64_t x1)
-{
-	sp_context_t *ctx = &sp_ctx;
-
-	/* Save secure state */
-	cm_el1_sysregs_context_save(SECURE);
-
-	if (ctx->state == SP_STATE_RESET) {
-		/*
-		 * SPM reports completion. The SPM must have initiated the
-		 * original request through a synchronous entry into the secure
-		 * partition. Jump back to the original C runtime context.
-		 */
-		spm_secure_partition_exit(ctx->c_rt_ctx, x1);
-
-		/* spm_secure_partition_exit doesn't return */
-	}
-
-	/*
-	 * This is the result from the Secure partition of an earlier request.
-	 * Copy the result into the non-secure context and return to the
-	 * non-secure state.
-	 */
-
-	/* Mark Secure Partition as idle */
+	/* Flag Secure Partition as idle. */
 	assert(ctx->state == SP_STATE_BUSY);
-
 	sp_state_set(ctx, SP_STATE_IDLE);
 
-	/* Get a reference to the non-secure context */
-	cpu_context_t *ns_cpu_context = cm_get_context(NON_SECURE);
-
-	assert(ns_cpu_context != NULL);
-
 	/* Restore non-secure state */
 	cm_el1_sysregs_context_restore(NON_SECURE);
 	cm_set_next_eret_context(NON_SECURE);
 
-	/* Return to non-secure world */
-	SMC_RET1(ns_cpu_context, x1);
+	SMC_RET1(handle, rc);
 }
 
 /*******************************************************************************
@@ -275,7 +265,7 @@
 			SMC_RET1(handle, SPM_VERSION_COMPILED);
 
 		case SP_EVENT_COMPLETE_AARCH64:
-			return sp_event_complete(x1);
+			spm_sp_synchronous_exit(x1);
 
 		case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
 			INFO("Received SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC\n");
@@ -305,6 +295,8 @@
 
 		/* Handle SMCs from Non-secure world. */
 
+		assert(handle == cm_get_context(NON_SECURE));
+
 		switch (smc_fid) {
 
 		case MM_VERSION_AARCH32:
diff --git a/services/std_svc/spm/spm_private.h b/services/std_svc/spm/spm_private.h
index 64d8cf8..f094739 100644
--- a/services/std_svc/spm/spm_private.h
+++ b/services/std_svc/spm/spm_private.h
@@ -35,7 +35,7 @@
 #include <stdint.h>
 #include <xlat_tables_v2.h>
 
-typedef enum secure_partition_state {
+typedef enum sp_state {
 	SP_STATE_RESET = 0,
 	SP_STATE_IDLE,
 	SP_STATE_BUSY