Merge pull request #1650 from chandnich/sgiclark-ares-support

Sgiclark ares support
diff --git a/Makefile b/Makefile
index be543fa..74d5180 100644
--- a/Makefile
+++ b/Makefile
@@ -205,11 +205,6 @@
 				-Os -ffunction-sections -fdata-sections
 
 GCC_V_OUTPUT		:=	$(shell $(CC) -v 2>&1)
-PIE_FOUND		:=	$(findstring --enable-default-pie,${GCC_V_OUTPUT})
-
-ifneq ($(PIE_FOUND),)
-TF_CFLAGS		+=	-fno-PIE
-endif
 
 # Force the compiler to include the frame pointer
 ifeq (${ENABLE_BACKTRACE},1)
@@ -335,6 +330,16 @@
 include make_helpers/armv7-a-cpus.mk
 endif
 
+ifeq ($(ENABLE_PIE),1)
+    TF_CFLAGS		+=	-fpie
+    TF_LDFLAGS		+=	-pie
+else
+    PIE_FOUND		:=	$(findstring --enable-default-pie,${GCC_V_OUTPUT})
+    ifneq ($(PIE_FOUND),)
+        TF_CFLAGS		+=	-fno-PIE
+    endif
+endif
+
 # Include the CPU specific operations makefile, which provides default
 # values for all CPU errata workarounds and CPU specific optimisations.
 # This can be overridden by the platform.
@@ -565,6 +570,7 @@
 $(eval $(call assert_boolean,ENABLE_ASSERTIONS))
 $(eval $(call assert_boolean,ENABLE_BACKTRACE))
 $(eval $(call assert_boolean,ENABLE_MPAM_FOR_LOWER_ELS))
+$(eval $(call assert_boolean,ENABLE_PIE))
 $(eval $(call assert_boolean,ENABLE_PMF))
 $(eval $(call assert_boolean,ENABLE_PSCI_STAT))
 $(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION))
@@ -615,6 +621,7 @@
 $(eval $(call add_define,ENABLE_ASSERTIONS))
 $(eval $(call add_define,ENABLE_BACKTRACE))
 $(eval $(call add_define,ENABLE_MPAM_FOR_LOWER_ELS))
+$(eval $(call add_define,ENABLE_PIE))
 $(eval $(call add_define,ENABLE_PMF))
 $(eval $(call add_define,ENABLE_PSCI_STAT))
 $(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION))
diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S
index bc8cbfd..30a5c59 100644
--- a/bl2/aarch64/bl2_entrypoint.S
+++ b/bl2/aarch64/bl2_entrypoint.S
@@ -70,13 +70,19 @@
 	 *   - the coherent memory section.
 	 * ---------------------------------------------
 	 */
-	ldr	x0, =__BSS_START__
-	ldr	x1, =__BSS_SIZE__
+	adrp	x0, __BSS_START__
+	add	x0, x0, :lo12:__BSS_START__
+	adrp	x1, __BSS_END__
+	add	x1, x1, :lo12:__BSS_END__
+	sub	x1, x1, x0
 	bl	zeromem
 
 #if USE_COHERENT_MEM
-	ldr	x0, =__COHERENT_RAM_START__
-	ldr	x1, =__COHERENT_RAM_UNALIGNED_SIZE__
+	adrp	x0, __COHERENT_RAM_START__
+	add	x0, x0, :lo12:__COHERENT_RAM_START__
+	adrp	x1, __COHERENT_RAM_END_UNALIGNED__
+	add	x1, x1, :lo12:__COHERENT_RAM_END_UNALIGNED__
+	sub	x1, x1, x0
 	bl	zeromem
 #endif
 
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index 3a45e53..7c116a2 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -7,6 +7,7 @@
 #include <arch.h>
 #include <bl_common.h>
 #include <el3_common_macros.S>
+#include <platform_def.h>
 #include <pmf_asm_macros.S>
 #include <runtime_instr.h>
 #include <xlat_mmu_helpers.h>
@@ -73,6 +74,18 @@
 	mov	x22, 0
 	mov	x23, 0
 #endif /* RESET_TO_BL31 */
+
+	/* --------------------------------------------------------------------
+	 * If PIE is enabled, fixup the Global descriptor Table and dynamic
+	 * relocations
+	 * --------------------------------------------------------------------
+	 */
+#if ENABLE_PIE
+	mov_imm	x0, BL31_BASE
+	mov_imm	x1, BL31_LIMIT
+	bl	fixup_gdt_reloc
+#endif /* ENABLE_PIE */
+
 	/* ---------------------------------------------
 	 * Perform platform specific early arch. setup
 	 * ---------------------------------------------
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 81e7ba3..43d0ed4 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -26,6 +26,8 @@
     ASSERT(. == ALIGN(PAGE_SIZE),
            "BL31_BASE address is not aligned on a page boundary.")
 
+    __BL31_START__ = .;
+
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
         __TEXT_START__ = .;
@@ -63,6 +65,16 @@
         KEEP(*(cpu_ops))
         __CPU_OPS_END__ = .;
 
+        /*
+         * Keep the .got section in the RO section as the it is patched
+         * prior to enabling the MMU and having the .got in RO is better for
+         * security.
+         */
+        . = ALIGN(16);
+        __GOT_START__ = .;
+        *(.got)
+        __GOT_END__ = .;
+
         /* Place pubsub sections for events */
         . = ALIGN(8);
 #include <pubsub_events.h>
@@ -153,6 +165,16 @@
         __DATA_END__ = .;
     } >RAM
 
+    . = ALIGN(16);
+    /*
+     * .rela.dyn needs to come after .data for the read-elf utility to parse
+     * this section correctly.
+     */
+    __RELA_START__ = .;
+    .rela.dyn . : {
+    } >RAM
+    __RELA_END__ = .;
+
 #ifdef BL31_PROGBITS_LIMIT
     ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
 #endif
@@ -265,11 +287,5 @@
     __RW_END__ = .;
     __BL31_END__ = .;
 
-    __BSS_SIZE__ = SIZEOF(.bss);
-#if USE_COHERENT_MEM
-    __COHERENT_RAM_UNALIGNED_SIZE__ =
-        __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
-
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
 }
diff --git a/docs/plat/meson-gxbb.rst b/docs/plat/meson-gxbb.rst
new file mode 100644
index 0000000..f909e99
--- /dev/null
+++ b/docs/plat/meson-gxbb.rst
@@ -0,0 +1,26 @@
+Trusted Firmware-A for Amlogic Meson S905 (GXBB)
+================================================
+
+The Amlogic Meson S905 is a SoC with a quad core Arm Cortex-A53 running at
+1.5Ghz. It also contains a Cortex-M3 used as SCP.
+
+This port is a minimal implementation of BL31 capable of booting mainline U-Boot
+and Linux:
+
+- SCPI support.
+- Basic PSCI support (CPU_ON, CPU_OFF, SYSTEM_RESET, SYSTEM_OFF). Note that CPU0
+  can't be turned off, so there is a workaround to hide this from the caller.
+- GICv2 driver set up.
+- Basic SIP services (read efuse data, enable/disable JTAG).
+
+In order to build it:
+
+::
+
+    CROSS_COMPILE=aarch64-linux-gnu- make DEBUG=1 PLAT=gxbb bl31
+
+This port has been tested in a ODROID-C2. After building it, follow the
+instructions in the `U-Boot repository`_, replacing the mentioned **bl31.bin**
+by the one built from this port.
+
+.. _U-Boot repository: https://github.com/u-boot/u-boot/blob/master/board/amlogic/odroid-c2/README
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index 9e731a4..f8379b4 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -76,7 +76,23 @@
 .. code:: bash
 
     make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min
+    cd <u-boot_directory>
+    make stm32mp15_basic_defconfig
+    make DEVICE_TREE=stm32mp157c_ev1 all
+    ./tools/mkimage -T stm32image -a 0xC0100000 -e 0xC0100000 -d u-boot.bin u-boot.stm32
 
 The following build options are supported:
 
 - ``ENABLE_STACK_PROTECTOR``: To enable the stack protection.
+
+
+Populate SD-card
+----------------
+
+The SD-card has to be formated with GPT.
+It should contain at least those partitions:
+
+- fsbl: to copy the tf-a-stm32mp157c-ev1.stm32 binary
+- ssbl: to copy the u-boot.stm32 binary
+
+Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition fsbl.
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index f4ef85d..52cb45c 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -371,6 +371,10 @@
    partitioning in EL3, however. Platform initialisation code should configure
    and use partitions in EL3 as required. This option defaults to ``0``.
 
+-  ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE)
+   support within generic code in TF-A. This option is currently only supported
+   in BL31. Default is 0.
+
 -  ``ENABLE_PMF``: Boolean option to enable support for optional Performance
    Measurement Framework(PMF). Default is 0.
 
diff --git a/drivers/allwinner/sunxi_rsb.c b/drivers/allwinner/sunxi_rsb.c
new file mode 100644
index 0000000..7075c67
--- /dev/null
+++ b/drivers/allwinner/sunxi_rsb.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2017-2018 ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <sunxi_mmap.h>
+
+#define RSB_CTRL	0x00
+#define RSB_CCR		0x04
+#define RSB_INTE	0x08
+#define RSB_STAT	0x0c
+#define RSB_DADDR0	0x10
+#define RSB_DLEN	0x18
+#define RSB_DATA0	0x1c
+#define RSB_LCR		0x24
+#define RSB_PMCR	0x28
+#define RSB_CMD		0x2c
+#define RSB_SADDR	0x30
+
+#define RSBCMD_SRTA	0xE8
+#define RSBCMD_RD8	0x8B
+#define RSBCMD_RD16	0x9C
+#define RSBCMD_RD32	0xA6
+#define RSBCMD_WR8	0x4E
+#define RSBCMD_WR16	0x59
+#define RSBCMD_WR32	0x63
+
+#define MAX_TRIES	100000
+
+static int rsb_wait_bit(const char *desc, unsigned int offset, uint32_t mask)
+{
+	uint32_t reg, tries = MAX_TRIES;
+
+	do
+		reg = mmio_read_32(SUNXI_R_RSB_BASE + offset);
+	while ((reg & mask) && --tries);	/* transaction in progress */
+	if (reg & mask) {
+		ERROR("%s: timed out\n", desc);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int rsb_wait_stat(const char *desc)
+{
+	uint32_t reg;
+	int ret = rsb_wait_bit(desc, RSB_CTRL, BIT(7));
+
+	if (ret)
+		return ret;
+
+	reg = mmio_read_32(SUNXI_R_RSB_BASE + RSB_STAT);
+	if (reg == 0x01)
+		return 0;
+
+	ERROR("%s: 0x%x\n", desc, reg);
+	return -reg;
+}
+
+/* Initialize the RSB controller. */
+int rsb_init_controller(void)
+{
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_CTRL, 0x01); /* soft reset */
+
+	return rsb_wait_bit("RSB: reset controller", RSB_CTRL, BIT(0));
+}
+
+int rsb_read(uint8_t rt_addr, uint8_t reg_addr)
+{
+	int ret;
+
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_CMD, RSBCMD_RD8); /* read a byte */
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_SADDR, rt_addr << 16);
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_DADDR0, reg_addr);
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_CTRL, 0x80);/* start transaction */
+
+	ret = rsb_wait_stat("RSB: read command");
+	if (ret)
+		return ret;
+
+	return mmio_read_32(SUNXI_R_RSB_BASE + RSB_DATA0) & 0xff; /* result */
+}
+
+int rsb_write(uint8_t rt_addr, uint8_t reg_addr, uint8_t value)
+{
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_CMD, RSBCMD_WR8);	/* byte write */
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_SADDR, rt_addr << 16);
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_DADDR0, reg_addr);
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_DATA0, value);
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_CTRL, 0x80);/* start transaction */
+
+	return rsb_wait_stat("RSB: write command");
+}
+
+int rsb_set_device_mode(uint32_t device_mode)
+{
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_PMCR,
+		      (device_mode & 0x00ffffff) | BIT(31));
+
+	return rsb_wait_bit("RSB: set device to RSB", RSB_PMCR, BIT(31));
+}
+
+int rsb_set_bus_speed(uint32_t source_freq, uint32_t bus_freq)
+{
+	uint32_t reg;
+
+	if (bus_freq == 0)
+		return -EINVAL;
+
+	reg = source_freq / bus_freq;
+	if (reg < 2)
+		return -EINVAL;
+
+	reg = reg / 2 - 1;
+	reg |= (1U << 8);		/* one cycle of CD output delay */
+
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_CCR, reg);
+
+	return 0;
+}
+
+/* Initialize the RSB PMIC connection. */
+int rsb_assign_runtime_address(uint16_t hw_addr, uint8_t rt_addr)
+{
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_SADDR, hw_addr | (rt_addr << 16));
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_CMD, RSBCMD_SRTA);
+	mmio_write_32(SUNXI_R_RSB_BASE + RSB_CTRL, 0x80);
+
+	return rsb_wait_stat("RSB: set run-time address");
+}
diff --git a/drivers/meson/console/aarch64/meson_console.S b/drivers/meson/console/aarch64/meson_console.S
new file mode 100644
index 0000000..eaee10e
--- /dev/null
+++ b/drivers/meson/console/aarch64/meson_console.S
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <assert_macros.S>
+#define USE_FINISH_CONSOLE_REG_2
+#include <console_macros.S>
+#include <meson_console.h>
+
+	.globl console_meson_register
+	.globl console_meson_init
+	.globl console_meson_putc
+	.globl console_meson_getc
+	.globl console_meson_flush
+	.globl console_meson_core_putc
+	.globl console_meson_core_getc
+	.globl console_meson_core_flush
+
+	/* -----------------------------------------------
+	 * Hardware definitions
+	 * -----------------------------------------------
+	 */
+#define MESON_WFIFO_OFFSET			0x0
+#define MESON_RFIFO_OFFSET			0x4
+#define MESON_CONTROL_OFFSET			0x8
+#define MESON_STATUS_OFFSET			0xC
+#define MESON_MISC_OFFSET			0x10
+#define MESON_REG5_OFFSET			0x14
+
+#define MESON_CONTROL_CLR_ERROR_BIT		24
+#define MESON_CONTROL_RX_RESET_BIT		23
+#define MESON_CONTROL_TX_RESET_BIT		22
+#define MESON_CONTROL_RX_ENABLE_BIT		13
+#define MESON_CONTROL_TX_ENABLE_BIT		12
+
+#define MESON_STATUS_RX_EMPTY_BIT		20
+#define MESON_STATUS_TX_FULL_BIT		21
+#define MESON_STATUS_TX_EMPTY_BIT		22
+
+#define MESON_REG5_USE_XTAL_CLK_BIT		24
+#define MESON_REG5_USE_NEW_RATE_BIT		23
+#define MESON_REG5_NEW_BAUD_RATE_MASK		0x7FFFFF
+
+	/* -----------------------------------------------
+	 * int console_meson_register(uintptr_t base,
+	 *     uint32_t clk, uint32_t baud,
+	 *     console_meson_t *console);
+	 * Function to initialize and register a new MESON
+	 * console. Storage passed in for the console struct
+	 * *must* be persistent (i.e. not from the stack).
+	 * In: x0 - UART register base address
+	 *     w1 - UART clock in Hz
+	 *     w2 - Baud rate
+	 *     x3 - pointer to empty console_meson_t struct
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : x0, x1, x2, x6, x7, x14
+	 * -----------------------------------------------
+	 */
+func console_meson_register
+	mov	x7, x30
+	mov	x6, x3
+	cbz	x6, register_fail
+	str	x0, [x6, #CONSOLE_T_MESON_BASE]
+
+	bl	console_meson_init
+	cbz	x0, register_fail
+
+	mov	x0, x6
+	mov	x30, x7
+	finish_console_register meson putc=1, getc=1, flush=1
+
+register_fail:
+	ret	x7
+endfunc console_meson_register
+
+	/* -----------------------------------------------
+	 * int console_meson_init(uintptr_t base_addr,
+	 * unsigned int uart_clk, unsigned int baud_rate)
+	 * Function to initialize the console without a
+	 * C Runtime to print debug information. This
+	 * function will be accessed by console_init and
+	 * crash reporting.
+	 * In: x0 - console base address
+	 *     w1 - Uart clock in Hz
+	 *     w2 - Baud rate
+	 * Out: return 1 on success else 0 on error
+	 * Clobber list : x0-x3
+	 * -----------------------------------------------
+	 */
+func console_meson_init
+	cmp	w0, #0
+	beq	init_fail
+	mov_imm	w3, 24000000 /* TODO: This only works with a 24 MHz clock. */
+	cmp	w1, w3
+	bne	init_fail
+	cmp	w2, #0
+	beq	init_fail
+	/* Set baud rate: value = ((clock / 3) / baudrate) - 1 */
+	mov	w3, #3
+	udiv	w3, w1, w3
+	udiv	w3, w3, w2
+	sub	w3, w3, #1
+	orr	w3, w3, #((1 << MESON_REG5_USE_XTAL_CLK_BIT) | \
+			  (1 << MESON_REG5_USE_NEW_RATE_BIT))
+	str	w3, [x0, #MESON_REG5_OFFSET]
+	/* Reset UART and clear error flag */
+	ldr	w3, [x0, #MESON_CONTROL_OFFSET]
+	orr	w3, w3, #((1 << MESON_CONTROL_CLR_ERROR_BIT) | \
+			  (1 << MESON_CONTROL_RX_RESET_BIT) | \
+			  (1 << MESON_CONTROL_TX_RESET_BIT))
+	str	w3, [x0, #MESON_CONTROL_OFFSET]
+	bic	w3, w3, #((1 << MESON_CONTROL_CLR_ERROR_BIT) | \
+			  (1 << MESON_CONTROL_RX_RESET_BIT) | \
+			  (1 << MESON_CONTROL_TX_RESET_BIT))
+	str	w3, [x0, #MESON_CONTROL_OFFSET]
+	/* Enable transfer and receive FIFO */
+	orr	w3, w3, #((1 << MESON_CONTROL_RX_ENABLE_BIT) | \
+			  (1 << MESON_CONTROL_TX_ENABLE_BIT))
+	str	w3, [x0, #MESON_CONTROL_OFFSET]
+	/* Success */
+	mov	w0, #1
+	ret
+init_fail:
+	mov	w0, wzr
+	ret
+endfunc console_meson_init
+
+	/* --------------------------------------------------------
+	 * int console_meson_putc(int c, console_meson_t *console)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - pointer to console_t structure
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_meson_putc
+#if ENABLE_ASSERTIONS
+	cmp	x1, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	x1, [x1, #CONSOLE_T_MESON_BASE]
+	b	console_meson_core_putc
+endfunc console_meson_putc
+
+	/* --------------------------------------------------------
+	 * int console_meson_core_putc(int c, uintptr_t base_addr)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - console base address
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_meson_core_putc
+#if ENABLE_ASSERTIONS
+	cmp	x1, #0
+	ASM_ASSERT(ne)
+#endif
+	/* Prepend '\r' to '\n' */
+	cmp	w0, #0xA
+	b.ne	2f
+	/* Wait until the transmit FIFO isn't full */
+1:	ldr	w2, [x1, #MESON_STATUS_OFFSET]
+	tbnz	w2, #MESON_STATUS_TX_FULL_BIT, 1b
+	/* Write '\r' if needed */
+	mov	w2, #0xD
+	str	w2, [x1, #MESON_WFIFO_OFFSET]
+	/* Wait until the transmit FIFO isn't full */
+2:	ldr	w2, [x1, #MESON_STATUS_OFFSET]
+	tbnz	w2, #MESON_STATUS_TX_FULL_BIT, 2b
+	/* Write input character */
+	str	w0, [x1, #MESON_WFIFO_OFFSET]
+	ret
+endfunc console_meson_core_putc
+
+	/* ---------------------------------------------
+	 * int console_meson_getc(console_meson_t *console)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 if no character is available.
+	 * In : x0 - pointer to console_t structure
+	 * Out: w0 - character if available, else -1
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_meson_getc
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	x0, [x0, #CONSOLE_T_MESON_BASE]
+	b	console_meson_core_getc
+endfunc console_meson_getc
+
+	/* ---------------------------------------------
+	 * int console_meson_core_getc(uintptr_t base_addr)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 if no character is available.
+	 * In : x0 - console base address
+	 * Out: w0 - character if available, else -1
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_meson_core_getc
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
+	/* Is the receive FIFO empty? */
+	ldr	w1, [x0, #MESON_STATUS_OFFSET]
+	tbnz	w1, #MESON_STATUS_RX_EMPTY_BIT, 1f
+	/* Read one character from the RX FIFO */
+	ldr	w0, [x0, #MESON_RFIFO_OFFSET]
+	ret
+1:
+	mov	w0, #ERROR_NO_PENDING_CHAR
+	ret
+endfunc console_meson_core_getc
+
+	/* ---------------------------------------------
+	 * int console_meson_flush(console_meson_t *console)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : x0 - pointer to console_t structure
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_meson_flush
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	x0, [x0, #CONSOLE_T_MESON_BASE]
+	b	console_meson_core_flush
+endfunc console_meson_flush
+
+	/* ---------------------------------------------
+	 * int console_meson_core_flush(uintptr_t base_addr)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : x0 - console base address
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_meson_core_flush
+#if ENABLE_ASSERTIONS
+	cmp	x0, #0
+	ASM_ASSERT(ne)
+#endif
+	/* Wait until the transmit FIFO is empty */
+1:	ldr	w1, [x0, #MESON_STATUS_OFFSET]
+	tbz	w1, #MESON_STATUS_TX_EMPTY_BIT, 1b
+	mov	w0, #0
+	ret
+endfunc console_meson_core_flush
diff --git a/include/common/aarch64/asm_macros.S b/include/common/aarch64/asm_macros.S
index 9621a1c..91416e4 100644
--- a/include/common/aarch64/asm_macros.S
+++ b/include/common/aarch64/asm_macros.S
@@ -105,8 +105,9 @@
 	 * Clobber: X30, X1, X2
 	 */
 	.macro get_my_mp_stack _name, _size
-	bl  plat_my_core_pos
-	ldr x2, =(\_name + \_size)
+	bl	plat_my_core_pos
+	adrp	x2, (\_name + \_size)
+	add	x2, x2, :lo12:(\_name + \_size)
 	mov x1, #\_size
 	madd x0, x0, x1, x2
 	.endm
@@ -117,7 +118,8 @@
 	 * Out: X0 = physical address of stack base
 	 */
 	.macro get_up_stack _name, _size
-	ldr x0, =(\_name + \_size)
+	adrp	x0, (\_name + \_size)
+	add	x0, x0, :lo12:(\_name + \_size)
 	.endm
 
 	/*
diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S
index 143c70c..4902583 100644
--- a/include/common/aarch64/el3_common_macros.S
+++ b/include/common/aarch64/el3_common_macros.S
@@ -283,26 +283,38 @@
 		 * an earlier boot loader stage.
 		 * -------------------------------------------------------------
 		 */
-		ldr	x0, =__RW_START__
-		ldr	x1, =__RW_END__
+		adrp	x0, __RW_START__
+		add	x0, x0, :lo12:__RW_START__
+		adrp	x1, __RW_END__
+		add	x1, x1, :lo12:__RW_END__
 		sub	x1, x1, x0
 		bl	inv_dcache_range
 #endif
+		adrp	x0, __BSS_START__
+		add	x0, x0, :lo12:__BSS_START__
 
-		ldr	x0, =__BSS_START__
-		ldr	x1, =__BSS_SIZE__
+		adrp	x1, __BSS_END__
+		add	x1, x1, :lo12:__BSS_END__
+		sub	x1, x1, x0
 		bl	zeromem
 
 #if USE_COHERENT_MEM
-		ldr	x0, =__COHERENT_RAM_START__
-		ldr	x1, =__COHERENT_RAM_UNALIGNED_SIZE__
+		adrp	x0, __COHERENT_RAM_START__
+		add	x0, x0, :lo12:__COHERENT_RAM_START__
+		adrp	x1, __COHERENT_RAM_END_UNALIGNED__
+		add	x1, x1, :lo12: __COHERENT_RAM_END_UNALIGNED__
+		sub	x1, x1, x0
 		bl	zeromem
 #endif
 
 #if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_IN_XIP_MEM)
-		ldr	x0, =__DATA_RAM_START__
-		ldr	x1, =__DATA_ROM_START__
-		ldr	x2, =__DATA_SIZE__
+		adrp	x0, __DATA_RAM_START__
+		add	x0, x0, :lo12:__DATA_RAM_START__
+		adrp	x1, __DATA_ROM_START__
+		add	x1, x1, :lo12:__DATA_ROM_START__
+		adrp	x2, __DATA_RAM_END__
+		add	x2, x2, :lo12:__DATA_RAM_END__
+		sub	x2, x2, x0
 		bl	memcpy16
 #endif
 	.endif /* _init_c_runtime */
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index af598d0..6a79dc3 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -83,6 +83,7 @@
 #elif defined(IMAGE_BL2U)
 IMPORT_SYM(unsigned long, __BL2U_END__,		BL2U_END);
 #elif defined(IMAGE_BL31)
+IMPORT_SYM(unsigned long, __BL31_START__,	BL31_START);
 IMPORT_SYM(unsigned long, __BL31_END__,		BL31_END);
 #elif defined(IMAGE_BL32)
 IMPORT_SYM(unsigned long, __BL32_END__,		BL32_END);
@@ -193,6 +194,11 @@
 void print_entry_point_info(const entry_point_info_t *ep_info);
 uintptr_t page_align(uintptr_t value, unsigned dir);
 
+struct mmap_region;
+
+void setup_page_tables(const struct mmap_region *bl_regions,
+			   const struct mmap_region *plat_regions);
+
 #endif /*__ASSEMBLY__*/
 
 #endif /* __BL_COMMON_H__ */
diff --git a/include/drivers/allwinner/sunxi_rsb.h b/include/drivers/allwinner/sunxi_rsb.h
new file mode 100644
index 0000000..5a69d35
--- /dev/null
+++ b/include/drivers/allwinner/sunxi_rsb.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017-2018 ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SUNXI_RSB_H
+#define SUNXI_RSB_H
+
+#include <stdint.h>
+
+int rsb_init_controller(void);
+int rsb_set_bus_speed(uint32_t source_freq, uint32_t bus_freq);
+int rsb_set_device_mode(uint32_t device_mode);
+int rsb_assign_runtime_address(uint16_t hw_addr, uint8_t rt_addr);
+
+int rsb_read(uint8_t rt_addr, uint8_t reg_addr);
+int rsb_write(uint8_t rt_addr, uint8_t reg_addr, uint8_t value);
+
+#endif
diff --git a/include/drivers/meson/meson_console.h b/include/drivers/meson/meson_console.h
new file mode 100644
index 0000000..759571d
--- /dev/null
+++ b/include/drivers/meson/meson_console.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MESON_CONSOLE_H
+#define MESON_CONSOLE_H
+
+#include <console.h>
+
+#define CONSOLE_T_MESON_BASE	CONSOLE_T_DRVDATA
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+typedef struct {
+	console_t console;
+	uintptr_t base;
+} console_meson_t;
+
+/*
+ * Initialize a new meson console instance and register it with the console
+ * framework. The |console| pointer must point to storage that will be valid
+ * for the lifetime of the console, such as a global or static local variable.
+ * Its contents will be reinitialized from scratch.
+ *
+ * NOTE: The clock is actually fixed to 24 MHz. The argument is only there in
+ * order to make this function future-proof.
+ */
+int console_meson_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+			   console_meson_t *console);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* MESON_CONSOLE_H */
diff --git a/include/lib/cpus/aarch32/cpu_macros.S b/include/lib/cpus/aarch32/cpu_macros.S
index 525e18c..aa728b2 100644
--- a/include/lib/cpus/aarch32/cpu_macros.S
+++ b/include/lib/cpus/aarch32/cpu_macros.S
@@ -161,10 +161,9 @@
 	.endif
 
 	/*
-	 * Weakly-bound, optional errata status printing function for CPUs of
+	 * Mandatory errata status printing function for CPUs of
 	 * this class.
 	 */
-	.weak \_name\()_errata_report
 	.word \_name\()_errata_report
 
 #ifdef IMAGE_BL32
diff --git a/include/lib/cpus/aarch64/cortex_a75.h b/include/lib/cpus/aarch64/cortex_a75.h
index 493c7d4..f68f98f 100644
--- a/include/lib/cpus/aarch64/cortex_a75.h
+++ b/include/lib/cpus/aarch64/cortex_a75.h
@@ -4,11 +4,13 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __CORTEX_A75_H__
-#define __CORTEX_A75_H__
+#ifndef CORTEX_A75_H
+#define CORTEX_A75_H
+
+#include <utils_def.h>
 
 /* Cortex-A75 MIDR */
-#define CORTEX_A75_MIDR		0x410fd0a0
+#define CORTEX_A75_MIDR		U(0x410fd0a0)
 
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
@@ -24,7 +26,7 @@
 #define CORTEX_A75_CPUACTLR_EL1_DISABLE_LOAD_PASS_STORE	(1 << 35)
 
 /* Definitions of register field mask in CORTEX_A75_CPUPWRCTLR_EL1 */
-#define CORTEX_A75_CORE_PWRDN_EN_MASK	0x1
+#define CORTEX_A75_CORE_PWRDN_EN_MASK	U(0x1)
 
 #define CORTEX_A75_ACTLR_AMEN_BIT	(U(1) << 4)
 
@@ -50,4 +52,4 @@
 void cortex_a75_amu_write_cpuamcntenclr_el0(unsigned int mask);
 #endif /* __ASSEMBLY__ */
 
-#endif /* __CORTEX_A75_H__ */
+#endif /* CORTEX_A75_H */
diff --git a/include/lib/cpus/aarch64/cortex_ares.h b/include/lib/cpus/aarch64/cortex_ares.h
index 84955b1..4f3e812 100644
--- a/include/lib/cpus/aarch64/cortex_ares.h
+++ b/include/lib/cpus/aarch64/cortex_ares.h
@@ -4,11 +4,13 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __CORTEX_ARES_H__
-#define __CORTEX_ARES_H__
+#ifndef CORTEX_ARES_H
+#define CORTEX_ARES_H
+
+#include <utils_def.h>
 
 /* Cortex-ARES MIDR for revision 0 */
-#define CORTEX_ARES_MIDR		0x410fd0c0
+#define CORTEX_ARES_MIDR		U(0x410fd0c0)
 
 /*******************************************************************************
  * CPU Extended Control register specific definitions.
@@ -17,7 +19,7 @@
 #define CORTEX_ARES_CPUECTLR_EL1	S3_0_C15_C1_4
 
 /* Definitions of register field mask in CORTEX_ARES_CPUPWRCTLR_EL1 */
-#define CORTEX_ARES_CORE_PWRDN_EN_MASK	0x1
+#define CORTEX_ARES_CORE_PWRDN_EN_MASK	U(0x1)
 
 #define CORTEX_ARES_ACTLR_AMEN_BIT	(U(1) << 4)
 
@@ -30,4 +32,4 @@
 #define CPUPOR_EL3	S3_6_C15_C8_2
 #define CPUPMR_EL3	S3_6_C15_C8_3
 
-#endif /* __CORTEX_ARES_H__ */
+#endif /* CORTEX_ARES_H */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index 4672cbc..14616ac 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -183,10 +183,9 @@
 	.endif
 
 	/*
-	 * Weakly-bound, optional errata status printing function for CPUs of
+	 * Mandatory errata status printing function for CPUs of
 	 * this class.
 	 */
-	.weak \_name\()_errata_report
 	.quad \_name\()_errata_report
 
 #ifdef IMAGE_BL31
diff --git a/include/lib/cpus/aarch64/cpuamu.h b/include/lib/cpus/aarch64/cpuamu.h
index 960a524..921abdb 100644
--- a/include/lib/cpus/aarch64/cpuamu.h
+++ b/include/lib/cpus/aarch64/cpuamu.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __CPUAMU_H__
-#define __CPUAMU_H__
+#ifndef CPUAMU_H
+#define CPUAMU_H
 
 /*******************************************************************************
  * CPU Activity Monitor Unit register specific definitions.
@@ -32,8 +32,8 @@
 #ifndef __ASSEMBLY__
 #include <stdint.h>
 
-uint64_t cpuamu_cnt_read(int idx);
-void cpuamu_cnt_write(int idx, uint64_t val);
+uint64_t cpuamu_cnt_read(unsigned int idx);
+void cpuamu_cnt_write(unsigned int idx, uint64_t val);
 unsigned int cpuamu_read_cpuamcntenset_el0(void);
 unsigned int cpuamu_read_cpuamcntenclr_el0(void);
 void cpuamu_write_cpuamcntenset_el0(unsigned int mask);
@@ -45,4 +45,4 @@
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* __CPUAMU_H__ */
+#endif /* CPUAMU_H */
diff --git a/include/lib/cpus/errata_report.h b/include/lib/cpus/errata_report.h
index d2138bf..c97d4c2 100644
--- a/include/lib/cpus/errata_report.h
+++ b/include/lib/cpus/errata_report.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __ERRATA_H__
-#define __ERRATA_H__
+#ifndef ERRATA_REPORT_H
+#define ERRATA_REPORT_H
 
 #ifndef __ASSEMBLY__
 
@@ -30,5 +30,4 @@
 #define ERRATA_APPLIES		1
 #define ERRATA_MISSING		2
 
-#endif /* __ERRATA_H__ */
-
+#endif /* ERRATA_REPORT_H */
diff --git a/include/lib/cpus/wa_cve_2017_5715.h b/include/lib/cpus/wa_cve_2017_5715.h
index 0a65a56..940fc65 100644
--- a/include/lib/cpus/wa_cve_2017_5715.h
+++ b/include/lib/cpus/wa_cve_2017_5715.h
@@ -4,9 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __WA_CVE_2017_5715_H__
-#define __WA_CVE_2017_5715_H__
+#ifndef WA_CVE_2017_5715_H
+#define WA_CVE_2017_5715_H
 
 int check_wa_cve_2017_5715(void);
 
-#endif /* __WA_CVE_2017_5715_H__ */
+#endif /* WA_CVE_2017_5715_H */
diff --git a/include/lib/cpus/wa_cve_2018_3639.h b/include/lib/cpus/wa_cve_2018_3639.h
index 36546f7..e37db37 100644
--- a/include/lib/cpus/wa_cve_2018_3639.h
+++ b/include/lib/cpus/wa_cve_2018_3639.h
@@ -4,9 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __WA_CVE_2018_3639_H__
-#define __WA_CVE_2018_3639_H__
+#ifndef WA_CVE_2018_3639_H
+#define WA_CVE_2018_3639_H
 
 void *wa_cve_2018_3639_get_disable_ptr(void);
 
-#endif /* __WA_CVE_2018_3639_H__ */
+#endif /* WA_CVE_2018_3639_H */
diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h
index 15d34eb..b695950 100644
--- a/include/lib/el3_runtime/cpu_data.h
+++ b/include/lib/el3_runtime/cpu_data.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __CPU_DATA_H__
-#define __CPU_DATA_H__
+#ifndef CPU_DATA_H
+#define CPU_DATA_H
 
 #include <ehf.h>
 #include <platform_def.h>	/* CACHE_WRITEBACK_GRANULE required */
@@ -161,4 +161,4 @@
 
 
 #endif /* __ASSEMBLY__ */
-#endif /* __CPU_DATA_H__ */
+#endif /* CPU_DATA_H */
diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h
index 46d5e15..1836fe5 100644
--- a/include/lib/extensions/amu.h
+++ b/include/lib/extensions/amu.h
@@ -4,33 +4,35 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __AMU_H__
-#define __AMU_H__
+#ifndef AMU_H
+#define AMU_H
 
 #include <cassert.h>
 #include <platform_def.h>
+#include <stdbool.h>
 #include <stdint.h>
+#include <utils_def.h>
 
 /* All group 0 counters */
-#define AMU_GROUP0_COUNTERS_MASK	0xf
+#define AMU_GROUP0_COUNTERS_MASK	U(0xf)
 
 #ifdef PLAT_AMU_GROUP1_COUNTERS_MASK
 #define AMU_GROUP1_COUNTERS_MASK	PLAT_AMU_GROUP1_COUNTERS_MASK
 #else
-#define AMU_GROUP1_COUNTERS_MASK	0
+#define AMU_GROUP1_COUNTERS_MASK	U(0)
 #endif
 
 #ifdef PLAT_AMU_GROUP1_NR_COUNTERS
 #define AMU_GROUP1_NR_COUNTERS		PLAT_AMU_GROUP1_NR_COUNTERS
 #else
-#define AMU_GROUP1_NR_COUNTERS		0
+#define AMU_GROUP1_NR_COUNTERS		U(0)
 #endif
 
 CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask);
 CASSERT(AMU_GROUP1_NR_COUNTERS <= 16, invalid_amu_group1_nr_counters);
 
-int amu_supported(void);
-void amu_enable(int el2_unused);
+bool amu_supported(void);
+void amu_enable(bool el2_unused);
 
 /* Group 0 configuration helpers */
 uint64_t amu_group0_cnt_read(int idx);
@@ -41,4 +43,4 @@
 void amu_group1_cnt_write(int idx, uint64_t val);
 void amu_group1_set_evtype(int idx, unsigned int val);
 
-#endif /* __AMU_H__ */
+#endif /* AMU_H */
diff --git a/include/lib/extensions/amu_private.h b/include/lib/extensions/amu_private.h
index 0c660bb..ab4e6aa 100644
--- a/include/lib/extensions/amu_private.h
+++ b/include/lib/extensions/amu_private.h
@@ -1,19 +1,19 @@
 /*
- * 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
  */
 
-#ifndef __AMU_PRIVATE_H__
-#define __AMU_PRIVATE_H__
+#ifndef AMU_PRIVATE_H
+#define AMU_PRIVATE_H
 
 #include <stdint.h>
 
 uint64_t amu_group0_cnt_read_internal(int idx);
-void amu_group0_cnt_write_internal(int idx, uint64_t);
+void amu_group0_cnt_write_internal(int idx, uint64_t val);
 
 uint64_t amu_group1_cnt_read_internal(int idx);
-void amu_group1_cnt_write_internal(int idx, uint64_t);
+void amu_group1_cnt_write_internal(int idx, uint64_t val);
 void amu_group1_set_evtype_internal(int idx, unsigned int val);
 
-#endif /* __AMU_PRIVATE_H__ */
+#endif /* AMU_PRIVATE_H */
diff --git a/include/lib/extensions/mpam.h b/include/lib/extensions/mpam.h
index 571b96b..ac8c00a 100644
--- a/include/lib/extensions/mpam.h
+++ b/include/lib/extensions/mpam.h
@@ -10,6 +10,6 @@
 #include <stdbool.h>
 
 bool mpam_supported(void);
-void mpam_enable(int el2_unused);
+void mpam_enable(bool el2_unused);
 
 #endif /* MPAM_H */
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
index b2b188e..d4b925f 100644
--- a/include/lib/extensions/spe.h
+++ b/include/lib/extensions/spe.h
@@ -4,11 +4,13 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __SPE_H__
-#define __SPE_H__
+#ifndef SPE_H
+#define SPE_H
 
-int spe_supported(void);
-void spe_enable(int el2_unused);
+#include <stdbool.h>
+
+bool spe_supported(void);
+void spe_enable(bool el2_unused);
 void spe_disable(void);
 
-#endif /* __SPE_H__ */
+#endif /* SPE_H */
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index 9c7f37f..83df177 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -4,10 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __SVE_H__
-#define __SVE_H__
+#ifndef SVE_H
+#define SVE_H
 
-int sve_supported(void);
-void sve_enable(int el2_unused);
+#include <stdbool.h>
+
+bool sve_supported(void);
+void sve_enable(bool el2_unused);
 
-#endif /* __SVE_H__ */
+#endif /* SVE_H */
diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h
index a3812fb..18ef0a5 100644
--- a/include/lib/pmf/pmf.h
+++ b/include/lib/pmf/pmf.h
@@ -9,17 +9,18 @@
 
 #include <cassert.h>
 #include <pmf_helpers.h>
+#include <utils_def.h>
 
 /*
  * Constants used for/by PMF services.
  */
-#define PMF_ARM_TIF_IMPL_ID	0x41
+#define PMF_ARM_TIF_IMPL_ID	U(0x41)
 #define PMF_TID_SHIFT		0
-#define PMF_TID_MASK		(0xFF << PMF_TID_SHIFT)
+#define PMF_TID_MASK		(U(0xFF) << PMF_TID_SHIFT)
 #define PMF_SVC_ID_SHIFT	10
-#define PMF_SVC_ID_MASK		(0x3F << PMF_SVC_ID_SHIFT)
+#define PMF_SVC_ID_MASK		(U(0x3F) << PMF_SVC_ID_SHIFT)
 #define PMF_IMPL_ID_SHIFT	24
-#define PMF_IMPL_ID_MASK	(0xFFU << PMF_IMPL_ID_SHIFT)
+#define PMF_IMPL_ID_MASK	(U(0xFF) << PMF_IMPL_ID_SHIFT)
 
 /*
  * Flags passed to PMF_REGISTER_SERVICE
@@ -37,16 +38,16 @@
 /*
  * Defines for PMF SMC function ids.
  */
-#define PMF_SMC_GET_TIMESTAMP_32	0x82000010u
-#define PMF_SMC_GET_TIMESTAMP_64	0xC2000010u
+#define PMF_SMC_GET_TIMESTAMP_32	U(0x82000010)
+#define PMF_SMC_GET_TIMESTAMP_64	U(0xC2000010)
 #define PMF_NUM_SMC_CALLS		2
 
 /*
  * The macros below are used to identify
  * PMF calls from the SMC function ID.
  */
-#define PMF_FID_MASK	0xffe0u
-#define PMF_FID_VALUE	0u
+#define PMF_FID_MASK	U(0xffe0)
+#define PMF_FID_VALUE	U(0)
 #define is_pmf_fid(_fid)	(((_fid) & PMF_FID_MASK) == PMF_FID_VALUE)
 
 /* Following are the supported PMF service IDs */
diff --git a/include/lib/pmf/pmf_asm_macros.S b/include/lib/pmf/pmf_asm_macros.S
index d58829e..5e19e62 100644
--- a/include/lib/pmf/pmf_asm_macros.S
+++ b/include/lib/pmf/pmf_asm_macros.S
@@ -18,10 +18,12 @@
 	mov	x9, x30
 	bl	plat_my_core_pos
 	mov	x30, x9
-	ldr	x1, =__PERCPU_TIMESTAMP_SIZE__
+	adr	x2, __PMF_PERCPU_TIMESTAMP_END__
+	adr	x1, __PMF_TIMESTAMP_START__
+	sub	x1, x2, x1
 	mov	x2, #(\_tid * PMF_TS_SIZE)
 	madd	x0, x0, x1, x2
-	ldr	x1, =pmf_ts_mem_\_name
+	adr	x1, pmf_ts_mem_\_name
 	add	x0, x0, x1
 	.endm
 
diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h
index b9757de..c535b22 100644
--- a/include/lib/pmf/pmf_helpers.h
+++ b/include/lib/pmf/pmf_helpers.h
@@ -11,7 +11,6 @@
 #include <assert.h>
 #include <bl_common.h>
 #include <platform.h>
-#include <pmf.h>
 #include <stddef.h>
 #include <stdint.h>
 
diff --git a/include/lib/utils.h b/include/lib/utils.h
index d46d846..f324a99 100644
--- a/include/lib/utils.h
+++ b/include/lib/utils.h
@@ -67,6 +67,29 @@
  *       zeroing.
  */
 void zeromem(void *mem, u_register_t length);
+
+/*
+ * Utility function to return the address of a symbol. By default, the
+ * compiler generates adr/adrp instruction pair to return the reference
+ * to the symbol and this utility is used to override this compiler
+ * generated to code to use `ldr` instruction.
+ *
+ * This helps when Position Independent Executable needs to reference a symbol
+ * which is constant and does not depend on the execute address of the binary.
+ */
+#define DEFINE_LOAD_SYM_ADDR(_name)		\
+static inline u_register_t load_addr_## _name(void)		\
+{								\
+	u_register_t v;						\
+	/* Create a void reference to silence compiler */	\
+	(void) _name;						\
+	__asm__ volatile ("ldr %0, =" #_name : "=r" (v));	\
+	return v;						\
+}
+
+/* Helper to invoke the function defined by DEFINE_LOAD_SYM_ADDR() */
+#define LOAD_ADDR_OF(_name)	(typeof(_name) *) load_addr_## _name()
+
 #endif /* !(defined(__LINKER__) || defined(__ASSEMBLY__)) */
 
 #endif /* __UTILS_H__ */
diff --git a/include/lib/xlat_tables/xlat_tables_compat.h b/include/lib/xlat_tables/xlat_tables_compat.h
new file mode 100644
index 0000000..4650a8c
--- /dev/null
+++ b/include/lib/xlat_tables/xlat_tables_compat.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if XLAT_TABLES_LIB_V2
+#include <xlat_tables_v2.h>
+#else
+#include <xlat_tables.h>
+#endif
diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h
index 02c3494..4a1d43c 100644
--- a/include/plat/arm/board/common/v2m_def.h
+++ b/include/plat/arm/board/common/v2m_def.h
@@ -6,8 +6,7 @@
 #ifndef V2M_DEF_H
 #define V2M_DEF_H
 
-#include <arm_xlat_tables.h>
-
+#include <xlat_tables_compat.h>
 
 /* V2M motherboard system registers & offsets */
 #define V2M_SYSREGS_BASE		UL(0x1c010000)
diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h
index 68375af..3e25cbc 100644
--- a/include/plat/arm/common/arm_sip_svc.h
+++ b/include/plat/arm/common/arm_sip_svc.h
@@ -1,24 +1,26 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __ARM_SIP_SVC_H__
-#define __ARM_SIP_SVC_H__
+#ifndef ARM_SIP_SVC_H
+#define ARM_SIP_SVC_H
+
+#include <utils_def.h>
 
 /* SMC function IDs for SiP Service queries */
 
-#define ARM_SIP_SVC_CALL_COUNT		0x8200ff00
-#define ARM_SIP_SVC_UID			0x8200ff01
-/*					0x8200ff02 is reserved */
-#define ARM_SIP_SVC_VERSION		0x8200ff03
+#define ARM_SIP_SVC_CALL_COUNT		U(0x8200ff00)
+#define ARM_SIP_SVC_UID			U(0x8200ff01)
+/*					U(0x8200ff02) is reserved */
+#define ARM_SIP_SVC_VERSION		U(0x8200ff03)
 
 /* Function ID for requesting state switch of lower EL */
-#define ARM_SIP_SVC_EXE_STATE_SWITCH	0x82000020
+#define ARM_SIP_SVC_EXE_STATE_SWITCH	U(0x82000020)
 
 /* ARM SiP Service Calls version numbers */
-#define ARM_SIP_SVC_VERSION_MAJOR		0x0
-#define ARM_SIP_SVC_VERSION_MINOR		0x2
+#define ARM_SIP_SVC_VERSION_MAJOR		U(0x0)
+#define ARM_SIP_SVC_VERSION_MINOR		U(0x2)
 
-#endif /* __ARM_SIP_SVC_H__ */
+#endif /* ARM_SIP_SVC_H */
diff --git a/include/plat/arm/common/arm_xlat_tables.h b/include/plat/arm/common/arm_xlat_tables.h
deleted file mode 100644
index 0923ad8..0000000
--- a/include/plat/arm/common/arm_xlat_tables.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#if ARM_XLAT_TABLES_LIB_V1
-#include <xlat_tables.h>
-#else
-#include <xlat_tables_v2.h>
-#endif /* ARM_XLAT_TABLES_LIB_V1 */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 773c360..e7082d0 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -3,10 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#ifndef __PLAT_ARM_H__
-#define __PLAT_ARM_H__
+#ifndef PLAT_ARM_H
+#define PLAT_ARM_H
 
-#include <arm_xlat_tables.h>
 #include <bakery_lock.h>
 #include <cassert.h>
 #include <cpu_data.h>
@@ -14,6 +13,7 @@
 #include <spinlock.h>
 #include <tzc_common.h>
 #include <utils_def.h>
+#include <xlat_tables_compat.h>
 
 /*******************************************************************************
  * Forward declarations
@@ -66,12 +66,6 @@
 		<= MAX_MMAP_REGIONS,					  \
 		assert_max_mmap_regions);
 
-/*
- * Utility functions common to ARM standard platforms
- */
-void arm_setup_page_tables(const mmap_region_t bl_regions[],
-			   const mmap_region_t plat_regions[]);
-
 void arm_setup_romlib(void);
 
 #if defined(IMAGE_BL31) || (defined(AARCH32) && defined(IMAGE_BL32))
@@ -298,4 +292,4 @@
 extern const mmap_region_t plat_arm_mmap[];
 extern const unsigned int arm_pm_idle_states[];
 
-#endif /* __PLAT_ARM_H__ */
+#endif /* PLAT_ARM_H */
diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S
index 1a075aa..002942e 100644
--- a/lib/aarch64/misc_helpers.S
+++ b/lib/aarch64/misc_helpers.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <assert_macros.S>
+#include <xlat_tables_defs.h>
 
 	.globl	get_afflvl_shift
 	.globl	mpidr_mask_lower_afflvls
@@ -23,6 +24,8 @@
 	.globl	disable_mmu_icache_el1
 	.globl	disable_mmu_icache_el3
 
+	.globl	fixup_gdt_reloc
+
 #if SUPPORT_VFP
 	.globl	enable_vfp
 #endif
@@ -497,3 +500,114 @@
 	ret
 endfunc enable_vfp
 #endif
+
+/* ---------------------------------------------------------------------------
+ * Helper to fixup Global Descriptor table (GDT) and dynamic relocations
+ * (.rela.dyn) at runtime.
+ *
+ * This function is meant to be used when the firmware is compiled with -fpie
+ * and linked with -pie options. We rely on the linker script exporting
+ * appropriate markers for start and end of the section. For GOT, we
+ * expect __GOT_START__ and __GOT_END__. Similarly for .rela.dyn, we expect
+ * __RELA_START__ and __RELA_END__.
+ *
+ * The function takes the limits of the memory to apply fixups to as
+ * arguments (which is usually the limits of the relocable BL image).
+ *   x0 -  the start of the fixup region
+ *   x1 -  the limit of the fixup region
+ * These addresses have to be page (4KB aligned).
+ * ---------------------------------------------------------------------------
+ */
+func fixup_gdt_reloc
+	mov	x6, x0
+	mov	x7, x1
+
+	/* Test if the limits are 4K aligned */
+#if ENABLE_ASSERTIONS
+	orr	x0, x0, x1
+	tst	x0, #(PAGE_SIZE - 1)
+	ASM_ASSERT(eq)
+#endif
+	/*
+	 * Calculate the offset based on return address in x30.
+	 * Assume that this funtion is called within a page of the start of
+	 * of fixup region.
+	 */
+	and	x2, x30, #~(PAGE_SIZE - 1)
+	sub	x0, x2, x6	/* Diff(S) = Current Address - Compiled Address */
+
+	adrp	x1, __GOT_START__
+	add	x1, x1, :lo12:__GOT_START__
+	adrp	x2, __GOT_END__
+	add	x2, x2, :lo12:__GOT_END__
+
+	/*
+	 * GOT is an array of 64_bit addresses which must be fixed up as
+	 * new_addr = old_addr + Diff(S).
+	 * The new_addr is the address currently the binary is executing from
+	 * and old_addr is the address at compile time.
+	 */
+1:
+	ldr	x3, [x1]
+	/* Skip adding offset if address is < lower limit */
+	cmp	x3, x6
+	b.lo	2f
+	/* Skip adding offset if address is >= upper limit */
+	cmp	x3, x7
+	b.ge	2f
+	add	x3, x3, x0
+	str	x3, [x1]
+2:
+	add	x1, x1, #8
+	cmp	x1, x2
+	b.lo	1b
+
+	/* Starting dynamic relocations. Use adrp/adr to get RELA_START and END */
+	adrp	x1, __RELA_START__
+	add	x1, x1, :lo12:__RELA_START__
+	adrp	x2, __RELA_END__
+	add	x2, x2, :lo12:__RELA_END__
+	/*
+	 * According to ELF-64 specification, the RELA data structure is as
+	 * follows:
+	 *	typedef struct
+	 * 	{
+	 *		Elf64_Addr r_offset;
+	 *		Elf64_Xword r_info;
+	 *		Elf64_Sxword r_addend;
+	 *	} Elf64_Rela;
+	 *
+	 * r_offset is address of reference
+	 * r_info is symbol index and type of relocation (in this case
+	 * 0x403 which corresponds to R_AARCH64_RELATIV).
+	 * r_addend is constant part of expression.
+	 *
+	 * Size of Elf64_Rela structure is 24 bytes.
+	 */
+1:
+	/* Assert that the relocation type is R_AARCH64_RELATIV */
+#if ENABLE_ASSERTIONS
+	ldr	x3, [x1, #8]
+	cmp	x3, #0x403
+	ASM_ASSERT(eq)
+#endif
+	ldr	x3, [x1]	/* r_offset */
+	add	x3, x0, x3
+	ldr	x4, [x1, #16]	/* r_addend */
+
+	/* Skip adding offset if r_addend is < lower limit */
+	cmp	x4, x6
+	b.lo	2f
+	/* Skip adding offset if r_addend entry is >= upper limit */
+	cmp	x4, x7
+	b.ge	2f
+
+	add	x4, x0, x4	/* Diff(S) + r_addend */
+	str	x4, [x3]
+
+2:	add	x1, x1, #24
+	cmp	x1, x2
+	b.lo	1b
+
+	ret
+endfunc fixup_gdt_reloc
diff --git a/lib/cpus/aarch32/aem_generic.S b/lib/cpus/aarch32/aem_generic.S
index 5f3d744..7bd586a 100644
--- a/lib/cpus/aarch32/aem_generic.S
+++ b/lib/cpus/aarch32/aem_generic.S
@@ -40,6 +40,15 @@
 	b	dcsw_op_all
 endfunc aem_generic_cluster_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for AEM. Must follow AAPCS.
+ */
+func aem_generic_errata_report
+	bx	lr
+endfunc aem_generic_errata_report
+#endif
+
 /* cpu_ops for Base AEM FVP */
 declare_cpu_ops aem_generic, BASE_AEM_MIDR, CPU_NO_RESET_FUNC, \
 	aem_generic_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a12.S b/lib/cpus/aarch32/cortex_a12.S
index 73c9750..5300fe0 100644
--- a/lib/cpus/aarch32/cortex_a12.S
+++ b/lib/cpus/aarch32/cortex_a12.S
@@ -69,6 +69,15 @@
 	b	cortex_a12_disable_smp
 endfunc cortex_a12_cluster_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex-A12. Must follow AAPCS.
+ */
+func cortex_a12_errata_report
+	bx	lr
+endfunc cortex_a12_errata_report
+#endif
+
 declare_cpu_ops cortex_a12, CORTEX_A12_MIDR, \
 	cortex_a12_reset_func, \
 	cortex_a12_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a32.S b/lib/cpus/aarch32/cortex_a32.S
index 2b6df27..c262276 100644
--- a/lib/cpus/aarch32/cortex_a32.S
+++ b/lib/cpus/aarch32/cortex_a32.S
@@ -117,6 +117,15 @@
 	b	cortex_a32_disable_smp
 endfunc cortex_a32_cluster_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex-A32. Must follow AAPCS.
+ */
+func cortex_a32_errata_report
+	bx	lr
+endfunc cortex_a32_errata_report
+#endif
+
 declare_cpu_ops cortex_a32, CORTEX_A32_MIDR, \
 	cortex_a32_reset_func, \
 	cortex_a32_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a5.S b/lib/cpus/aarch32/cortex_a5.S
index c07c13e..8abb66f 100644
--- a/lib/cpus/aarch32/cortex_a5.S
+++ b/lib/cpus/aarch32/cortex_a5.S
@@ -69,6 +69,15 @@
 	b	cortex_a5_disable_smp
 endfunc cortex_a5_cluster_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex-A5. Must follow AAPCS.
+ */
+func cortex_a5_errata_report
+	bx	lr
+endfunc cortex_a5_errata_report
+#endif
+
 declare_cpu_ops cortex_a5, CORTEX_A5_MIDR, \
 	cortex_a5_reset_func, \
 	cortex_a5_core_pwr_dwn, \
diff --git a/lib/cpus/aarch32/cortex_a7.S b/lib/cpus/aarch32/cortex_a7.S
index 0278d1f..4d4bb77 100644
--- a/lib/cpus/aarch32/cortex_a7.S
+++ b/lib/cpus/aarch32/cortex_a7.S
@@ -69,6 +69,15 @@
 	b	cortex_a7_disable_smp
 endfunc cortex_a7_cluster_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex-A7. Must follow AAPCS.
+ */
+func cortex_a7_errata_report
+	bx	lr
+endfunc cortex_a7_errata_report
+#endif
+
 declare_cpu_ops cortex_a7, CORTEX_A7_MIDR, \
 	cortex_a7_reset_func, \
 	cortex_a7_core_pwr_dwn, \
diff --git a/lib/cpus/aarch64/aem_generic.S b/lib/cpus/aarch64/aem_generic.S
index 7592e3d..51b5ce9 100644
--- a/lib/cpus/aarch64/aem_generic.S
+++ b/lib/cpus/aarch64/aem_generic.S
@@ -46,6 +46,15 @@
 	b	dcsw_op_all
 endfunc aem_generic_cluster_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for AEM. Must follow AAPCS.
+ */
+func aem_generic_errata_report
+	ret
+endfunc aem_generic_errata_report
+#endif
+
 	/* ---------------------------------------------
 	 * This function provides cpu specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a35.S b/lib/cpus/aarch64/cortex_a35.S
index b22189c..2e0d631 100644
--- a/lib/cpus/aarch64/cortex_a35.S
+++ b/lib/cpus/aarch64/cortex_a35.S
@@ -114,6 +114,16 @@
 	b	cortex_a35_disable_smp
 endfunc cortex_a35_cluster_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex A35. Must follow AAPCS.
+ */
+func cortex_a35_errata_report
+	ret
+endfunc cortex_a35_errata_report
+#endif
+
+
 	/* ---------------------------------------------
 	 * This function provides cortex_a35 specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_a75_pubsub.c b/lib/cpus/aarch64/cortex_a75_pubsub.c
index 16f62f4..f4ca486 100644
--- a/lib/cpus/aarch64/cortex_a75_pubsub.c
+++ b/lib/cpus/aarch64/cortex_a75_pubsub.c
@@ -12,14 +12,16 @@
 {
 	if (midr_match(CORTEX_A75_MIDR) != 0)
 		cpuamu_context_save(CORTEX_A75_AMU_NR_COUNTERS);
-	return 0;
+
+	return (void *)0;
 }
 
 static void *cortex_a75_context_restore(const void *arg)
 {
 	if (midr_match(CORTEX_A75_MIDR) != 0)
 		cpuamu_context_restore(CORTEX_A75_AMU_NR_COUNTERS);
-	return 0;
+
+	return (void *)0;
 }
 
 SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, cortex_a75_context_save);
diff --git a/lib/cpus/aarch64/cortex_ares_pubsub.c b/lib/cpus/aarch64/cortex_ares_pubsub.c
index c7d850a..9566223 100644
--- a/lib/cpus/aarch64/cortex_ares_pubsub.c
+++ b/lib/cpus/aarch64/cortex_ares_pubsub.c
@@ -12,14 +12,16 @@
 {
 	if (midr_match(CORTEX_ARES_MIDR) != 0)
 		cpuamu_context_save(CORTEX_ARES_AMU_NR_COUNTERS);
-	return 0;
+
+	return (void *)0;
 }
 
 static void *cortex_ares_context_restore(const void *arg)
 {
 	if (midr_match(CORTEX_ARES_MIDR) != 0)
 		cpuamu_context_restore(CORTEX_ARES_AMU_NR_COUNTERS);
-	return 0;
+
+	return (void *)0;
 }
 
 SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, cortex_ares_context_save);
diff --git a/lib/cpus/aarch64/cortex_deimos.S b/lib/cpus/aarch64/cortex_deimos.S
index aec62a2..cad906f 100644
--- a/lib/cpus/aarch64/cortex_deimos.S
+++ b/lib/cpus/aarch64/cortex_deimos.S
@@ -27,6 +27,16 @@
 	ret
 endfunc cortex_deimos_core_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex Deimos. Must follow AAPCS.
+ */
+func cortex_deimos_errata_report
+	ret
+endfunc cortex_deimos_errata_report
+#endif
+
+
 	/* ---------------------------------------------
 	 * This function provides Cortex-Deimos specific
 	 * register information for crash reporting.
diff --git a/lib/cpus/aarch64/cortex_helios.S b/lib/cpus/aarch64/cortex_helios.S
index bcda741..4812ac4 100644
--- a/lib/cpus/aarch64/cortex_helios.S
+++ b/lib/cpus/aarch64/cortex_helios.S
@@ -19,6 +19,16 @@
 	ret
 endfunc cortex_helios_cpu_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex Helios. Must follow AAPCS.
+ */
+func cortex_helios_errata_report
+	ret
+endfunc cortex_helios_errata_report
+#endif
+
+
 .section .rodata.cortex_helios_regs, "aS"
 cortex_helios_regs:  /* The ascii list of register names to be reported */
 	.asciz	"cpuectlr_el1", ""
diff --git a/lib/cpus/aarch64/cpuamu_helpers.S b/lib/cpus/aarch64/cpuamu_helpers.S
index 8965d6d..79b7288 100644
--- a/lib/cpus/aarch64/cpuamu_helpers.S
+++ b/lib/cpus/aarch64/cpuamu_helpers.S
@@ -16,7 +16,7 @@
 	.globl	cpuamu_write_cpuamcntenclr_el0
 
 /*
- * uint64_t cpuamu_cnt_read(int idx);
+ * uint64_t cpuamu_cnt_read(unsigned int idx);
  *
  * Given `idx`, read the corresponding AMU counter
  * and return it in `x0`.
@@ -41,7 +41,7 @@
 endfunc cpuamu_cnt_read
 
 /*
- * void cpuamu_cnt_write(int idx, uint64_t val);
+ * void cpuamu_cnt_write(unsigned int idx, uint64_t val);
  *
  * Given `idx`, write `val` to the corresponding AMU counter.
  */
diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c
index c679336..42603cb 100644
--- a/lib/cpus/errata_report.c
+++ b/lib/cpus/errata_report.c
@@ -12,6 +12,7 @@
 #include <debug.h>
 #include <errata_report.h>
 #include <spinlock.h>
+#include <stdbool.h>
 #include <utils.h>
 
 #ifdef IMAGE_BL1
@@ -35,10 +36,10 @@
  */
 int errata_needs_reporting(spinlock_t *lock, uint32_t *reported)
 {
-	int report_now;
+	bool report_now;
 
 	/* If already reported, return false. */
-	if (*reported)
+	if (*reported != 0U)
 		return 0;
 
 	/*
@@ -46,7 +47,7 @@
 	 * report status to true.
 	 */
 	spin_lock(lock);
-	report_now = !(*reported);
+	report_now = (*reported == 0U);
 	if (report_now)
 		*reported = 1;
 	spin_unlock(lock);
@@ -75,8 +76,8 @@
 
 
 	assert(status < ARRAY_SIZE(errata_status_str));
-	assert(cpu);
-	assert(id);
+	assert(cpu != NULL);
+	assert(id != NULL);
 
 	msg = errata_status_str[status];
 
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 11ef6e5..80cea28 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -14,6 +14,7 @@
 #include <platform.h>
 #include <platform_def.h>
 #include <smccc_helpers.h>
+#include <stdbool.h>
 #include <string.h>
 #include <utils.h>
 
@@ -129,7 +130,7 @@
  * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
  * it is zero.
  ******************************************************************************/
-static void enable_extensions_nonsecure(int el2_unused)
+static void enable_extensions_nonsecure(bool el2_unused)
 {
 #if IMAGE_BL32
 #if ENABLE_AMU
@@ -175,7 +176,7 @@
 {
 	uint32_t hsctlr, scr;
 	cpu_context_t *ctx = cm_get_context(security_state);
-	int el2_unused = 0;
+	bool el2_unused = false;
 
 	assert(ctx);
 
@@ -200,7 +201,7 @@
 			isb();
 		} else if (read_id_pfr1() &
 			(ID_PFR1_VIRTEXT_MASK << ID_PFR1_VIRTEXT_SHIFT)) {
-			el2_unused = 1;
+			el2_unused = true;
 
 			/*
 			 * Set the NS bit to access NS copies of certain banked
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index d3984a2..f037e18 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -18,6 +18,7 @@
 #include <pubsub_events.h>
 #include <smccc_helpers.h>
 #include <spe.h>
+#include <stdbool.h>
 #include <string.h>
 #include <sve.h>
 #include <utils.h>
@@ -231,7 +232,7 @@
  * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
  * it is zero.
  ******************************************************************************/
-static void enable_extensions_nonsecure(int el2_unused)
+static void enable_extensions_nonsecure(bool el2_unused)
 {
 #if IMAGE_BL31
 #if ENABLE_SPE_FOR_LOWER_ELS
@@ -289,7 +290,7 @@
 {
 	uint32_t sctlr_elx, scr_el3, mdcr_el2;
 	cpu_context_t *ctx = cm_get_context(security_state);
-	int el2_unused = 0;
+	bool el2_unused = false;
 	uint64_t hcr_el2 = 0;
 
 	assert(ctx);
@@ -304,7 +305,7 @@
 			sctlr_elx |= SCTLR_EL2_RES1;
 			write_sctlr_el2(sctlr_elx);
 		} else if (EL_IMPLEMENTED(2)) {
-			el2_unused = 1;
+			el2_unused = true;
 
 			/*
 			 * EL2 present but unused, need to disable safely.
diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c
index 05c98f1..585d908 100644
--- a/lib/extensions/amu/aarch32/amu.c
+++ b/lib/extensions/amu/aarch32/amu.c
@@ -10,6 +10,7 @@
 #include <arch_helpers.h>
 #include <platform.h>
 #include <pubsub_events.h>
+#include <stdbool.h>
 
 #define AMU_GROUP0_NR_COUNTERS	4
 
@@ -20,17 +21,17 @@
 
 static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT];
 
-int amu_supported(void)
+bool amu_supported(void)
 {
 	uint64_t features;
 
 	features = read_id_pfr0() >> ID_PFR0_AMU_SHIFT;
-	return (features & ID_PFR0_AMU_MASK) == 1;
+	return (features & ID_PFR0_AMU_MASK) == 1U;
 }
 
-void amu_enable(int el2_unused)
+void amu_enable(bool el2_unused)
 {
-	if (amu_supported() == 0)
+	if (!amu_supported())
 		return;
 
 	if (el2_unused) {
@@ -54,8 +55,8 @@
 /* Read the group 0 counter identified by the given `idx`. */
 uint64_t amu_group0_cnt_read(int idx)
 {
-	assert(amu_supported() != 0);
-	assert(idx >= 0 && idx < AMU_GROUP0_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS));
 
 	return amu_group0_cnt_read_internal(idx);
 }
@@ -63,8 +64,8 @@
 /* Write the group 0 counter identified by the given `idx` with `val`. */
 void amu_group0_cnt_write(int idx, uint64_t val)
 {
-	assert(amu_supported() != 0);
-	assert(idx >= 0 && idx < AMU_GROUP0_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS));
 
 	amu_group0_cnt_write_internal(idx, val);
 	isb();
@@ -73,8 +74,8 @@
 /* Read the group 1 counter identified by the given `idx`. */
 uint64_t amu_group1_cnt_read(int idx)
 {
-	assert(amu_supported() != 0);
-	assert(idx >= 0 && idx < AMU_GROUP1_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
 
 	return amu_group1_cnt_read_internal(idx);
 }
@@ -82,8 +83,8 @@
 /* Write the group 1 counter identified by the given `idx` with `val`. */
 void amu_group1_cnt_write(int idx, uint64_t val)
 {
-	assert(amu_supported() != 0);
-	assert(idx >= 0 && idx < AMU_GROUP1_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
 
 	amu_group1_cnt_write_internal(idx, val);
 	isb();
@@ -91,8 +92,8 @@
 
 void amu_group1_set_evtype(int idx, unsigned int val)
 {
-	assert(amu_supported() != 0);
-	assert(idx >= 0 && idx < AMU_GROUP1_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
 
 	amu_group1_set_evtype_internal(idx, val);
 	isb();
@@ -103,7 +104,7 @@
 	struct amu_ctx *ctx;
 	int i;
 
-	if (amu_supported() == 0)
+	if (!amu_supported())
 		return (void *)-1;
 
 	ctx = &amu_ctxs[plat_my_core_pos()];
@@ -126,7 +127,7 @@
 	for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++)
 		ctx->group1_cnts[i] = amu_group1_cnt_read(i);
 
-	return 0;
+	return (void *)0;
 }
 
 static void *amu_context_restore(const void *arg)
@@ -134,13 +135,13 @@
 	struct amu_ctx *ctx;
 	int i;
 
-	if (amu_supported() == 0)
+	if (!amu_supported())
 		return (void *)-1;
 
 	ctx = &amu_ctxs[plat_my_core_pos()];
 
 	/* Counters were disabled in `amu_context_save()` */
-	assert(read_amcntenset0() == 0 && read_amcntenset1() == 0);
+	assert((read_amcntenset0() == 0U) && (read_amcntenset1() == 0U));
 
 	/* Restore group 0 counters */
 	for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++)
@@ -153,7 +154,7 @@
 
 	/* Enable group 1 counters */
 	write_amcntenset1(AMU_GROUP1_COUNTERS_MASK);
-	return 0;
+	return (void *)0;
 }
 
 SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, amu_context_save);
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
index 5d556e5..1564e84 100644
--- a/lib/extensions/amu/aarch64/amu.c
+++ b/lib/extensions/amu/aarch64/amu.c
@@ -11,6 +11,7 @@
 #include <assert.h>
 #include <platform.h>
 #include <pubsub_events.h>
+#include <stdbool.h>
 
 #define AMU_GROUP0_NR_COUNTERS	4
 
@@ -21,23 +22,23 @@
 
 static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT];
 
-int amu_supported(void)
+bool amu_supported(void)
 {
 	uint64_t features;
 
 	features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT;
-	return (features & ID_AA64PFR0_AMU_MASK) == 1;
+	return (features & ID_AA64PFR0_AMU_MASK) == 1U;
 }
 
 /*
  * Enable counters.  This function is meant to be invoked
  * by the context management library before exiting from EL3.
  */
-void amu_enable(int el2_unused)
+void amu_enable(bool el2_unused)
 {
 	uint64_t v;
 
-	if (amu_supported() == 0)
+	if (!amu_supported())
 		return;
 
 	if (el2_unused) {
@@ -67,8 +68,8 @@
 /* Read the group 0 counter identified by the given `idx`. */
 uint64_t amu_group0_cnt_read(int idx)
 {
-	assert(amu_supported() != 0);
-	assert(idx >= 0 && idx < AMU_GROUP0_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS));
 
 	return amu_group0_cnt_read_internal(idx);
 }
@@ -76,8 +77,8 @@
 /* Write the group 0 counter identified by the given `idx` with `val`. */
 void amu_group0_cnt_write(int idx, uint64_t val)
 {
-	assert(amu_supported() != 0);
-	assert(idx >= 0 && idx < AMU_GROUP0_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP0_NR_COUNTERS));
 
 	amu_group0_cnt_write_internal(idx, val);
 	isb();
@@ -86,8 +87,8 @@
 /* Read the group 1 counter identified by the given `idx`. */
 uint64_t amu_group1_cnt_read(int idx)
 {
-	assert(amu_supported() != 0);
-	assert(idx >= 0 && idx < AMU_GROUP1_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
 
 	return amu_group1_cnt_read_internal(idx);
 }
@@ -95,8 +96,8 @@
 /* Write the group 1 counter identified by the given `idx` with `val`. */
 void amu_group1_cnt_write(int idx, uint64_t val)
 {
-	assert(amu_supported() != 0);
-	assert(idx >= 0 && idx < AMU_GROUP1_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
 
 	amu_group1_cnt_write_internal(idx, val);
 	isb();
@@ -108,8 +109,8 @@
  */
 void amu_group1_set_evtype(int idx, unsigned int val)
 {
-	assert(amu_supported() != 0);
-	assert (idx >= 0 && idx < AMU_GROUP1_NR_COUNTERS);
+	assert(amu_supported());
+	assert((idx >= 0) && (idx < AMU_GROUP1_NR_COUNTERS));
 
 	amu_group1_set_evtype_internal(idx, val);
 	isb();
@@ -120,14 +121,14 @@
 	struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
 	int i;
 
-	if (amu_supported() == 0)
+	if (!amu_supported())
 		return (void *)-1;
 
 	/* Assert that group 0/1 counter configuration is what we expect */
-	assert(read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK &&
-	       read_amcntenset1_el0() == AMU_GROUP1_COUNTERS_MASK);
+	assert((read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK) &&
+	       (read_amcntenset1_el0() == AMU_GROUP1_COUNTERS_MASK));
 
-	assert((sizeof(int) * 8) - __builtin_clz(AMU_GROUP1_COUNTERS_MASK)
+	assert(((sizeof(int) * 8) - __builtin_clz(AMU_GROUP1_COUNTERS_MASK))
 		<= AMU_GROUP1_NR_COUNTERS);
 
 	/*
@@ -146,7 +147,7 @@
 	for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++)
 		ctx->group1_cnts[i] = amu_group1_cnt_read(i);
 
-	return 0;
+	return (void *)0;
 }
 
 static void *amu_context_restore(const void *arg)
@@ -154,30 +155,30 @@
 	struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()];
 	int i;
 
-	if (amu_supported() == 0)
+	if (!amu_supported())
 		return (void *)-1;
 
 	/* Counters were disabled in `amu_context_save()` */
-	assert(read_amcntenset0_el0() == 0 && read_amcntenset1_el0() == 0);
+	assert((read_amcntenset0_el0() == 0U) && (read_amcntenset1_el0() == 0U));
 
-	assert((sizeof(int) * 8) - __builtin_clz(AMU_GROUP1_COUNTERS_MASK)
+	assert(((sizeof(int) * 8U) - __builtin_clz(AMU_GROUP1_COUNTERS_MASK))
 		<= AMU_GROUP1_NR_COUNTERS);
 
 	/* Restore group 0 counters */
 	for (i = 0; i < AMU_GROUP0_NR_COUNTERS; i++)
-		if (AMU_GROUP0_COUNTERS_MASK & (1U << i))
+		if ((AMU_GROUP0_COUNTERS_MASK & (1U << i)) != 0U)
 			amu_group0_cnt_write(i, ctx->group0_cnts[i]);
 
 	/* Restore group 1 counters */
 	for (i = 0; i < AMU_GROUP1_NR_COUNTERS; i++)
-		if (AMU_GROUP1_COUNTERS_MASK & (1U << i))
+		if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U)
 			amu_group1_cnt_write(i, ctx->group1_cnts[i]);
 
 	/* Restore group 0/1 counter configuration */
 	write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK);
 	write_amcntenset1_el0(AMU_GROUP1_COUNTERS_MASK);
 
-	return 0;
+	return (void *)0;
 }
 
 SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, amu_context_save);
diff --git a/lib/extensions/mpam/mpam.c b/lib/extensions/mpam/mpam.c
index e628827..d57bb47 100644
--- a/lib/extensions/mpam/mpam.c
+++ b/lib/extensions/mpam/mpam.c
@@ -16,7 +16,7 @@
 	return ((features & ID_AA64PFR0_MPAM_MASK) != 0U);
 }
 
-void mpam_enable(int el2_unused)
+void mpam_enable(bool el2_unused)
 {
 	if (!mpam_supported())
 		return;
@@ -31,7 +31,7 @@
 	 * If EL2 is implemented but unused, disable trapping to EL2 when lower
 	 * ELs access their own MPAM registers.
 	 */
-	if (el2_unused != 0) {
+	if (el2_unused) {
 		write_mpam2_el2(0);
 
 		if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U)
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
index dc35840..e5df015 100644
--- a/lib/extensions/spe/spe.c
+++ b/lib/extensions/spe/spe.c
@@ -8,26 +8,30 @@
 #include <arch_helpers.h>
 #include <pubsub.h>
 #include <spe.h>
+#include <stdbool.h>
 
-/*
- * The assembler does not yet understand the psb csync mnemonic
- * so use the equivalent hint instruction.
- */
-#define psb_csync()	asm volatile("hint #17")
+static inline void psb_csync(void)
+{
+	/*
+	 * The assembler does not yet understand the psb csync mnemonic
+	 * so use the equivalent hint instruction.
+	 */
+	__asm__ volatile("hint #17");
+}
 
-int spe_supported(void)
+bool spe_supported(void)
 {
 	uint64_t features;
 
 	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
-	return (features & ID_AA64DFR0_PMS_MASK) == 1;
+	return (features & ID_AA64DFR0_PMS_MASK) == 1U;
 }
 
-void spe_enable(int el2_unused)
+void spe_enable(bool el2_unused)
 {
 	uint64_t v;
 
-	if (spe_supported() == 0)
+	if (!spe_supported())
 		return;
 
 	if (el2_unused) {
@@ -59,7 +63,7 @@
 {
 	uint64_t v;
 
-	if (spe_supported() == 0)
+	if (!spe_supported())
 		return;
 
 	/* Drain buffered data */
@@ -75,13 +79,14 @@
 
 static void *spe_drain_buffers_hook(const void *arg)
 {
-	if (spe_supported() == 0)
+	if (!spe_supported())
 		return (void *)-1;
 
 	/* Drain buffered data */
 	psb_csync();
 	dsbnsh();
-	return 0;
+
+	return (void *)0;
 }
 
 SUBSCRIBE_TO_EVENT(cm_entering_secure_world, spe_drain_buffers_hook);
diff --git a/lib/extensions/sve/sve.c b/lib/extensions/sve/sve.c
index 6442487..e031bf6 100644
--- a/lib/extensions/sve/sve.c
+++ b/lib/extensions/sve/sve.c
@@ -7,21 +7,22 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <pubsub.h>
+#include <stdbool.h>
 #include <sve.h>
 
-int sve_supported(void)
+bool sve_supported(void)
 {
 	uint64_t features;
 
 	features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_SVE_SHIFT;
-	return (features & ID_AA64PFR0_SVE_MASK) == 1;
+	return (features & ID_AA64PFR0_SVE_MASK) == 1U;
 }
 
 static void *disable_sve_hook(const void *arg)
 {
 	uint64_t cptr;
 
-	if (sve_supported() == 0)
+	if (!sve_supported())
 		return (void *)-1;
 
 	/*
@@ -39,14 +40,14 @@
 	 * No explicit ISB required here as ERET to switch to Secure
 	 * world covers it
 	 */
-	return 0;
+	return (void *)0;
 }
 
 static void *enable_sve_hook(const void *arg)
 {
 	uint64_t cptr;
 
-	if (sve_supported() == 0)
+	if (!sve_supported())
 		return (void *)-1;
 
 	/*
@@ -60,14 +61,14 @@
 	 * No explicit ISB required here as ERET to switch to Non-secure
 	 * world covers it
 	 */
-	return 0;
+	return (void *)0;
 }
 
-void sve_enable(int el2_unused)
+void sve_enable(bool el2_unused)
 {
 	uint64_t cptr;
 
-	if (sve_supported() == 0)
+	if (!sve_supported())
 		return;
 
 #if CTX_INCLUDE_FPREGS
diff --git a/lib/pmf/pmf_main.c b/lib/pmf/pmf_main.c
index a020860..fe7bb74 100644
--- a/lib/pmf/pmf_main.c
+++ b/lib/pmf/pmf_main.c
@@ -25,9 +25,10 @@
 
 IMPORT_SYM(uintptr_t, __PMF_SVC_DESCS_START__,		PMF_SVC_DESCS_START);
 IMPORT_SYM(uintptr_t, __PMF_SVC_DESCS_END__,		PMF_SVC_DESCS_END);
-IMPORT_SYM(uintptr_t, __PERCPU_TIMESTAMP_SIZE__,	PMF_PERCPU_TIMESTAMP_SIZE);
-IMPORT_SYM(intptr_t,  __PMF_TIMESTAMP_START__,		PMF_TIMESTAMP_ARRAY_START);
-IMPORT_SYM(uintptr_t, __PMF_TIMESTAMP_END__,		PMF_TIMESTAMP_ARRAY_END);
+IMPORT_SYM(uintptr_t, __PMF_PERCPU_TIMESTAMP_END__,	PMF_PERCPU_TIMESTAMP_END);
+IMPORT_SYM(uintptr_t,  __PMF_TIMESTAMP_START__,		PMF_TIMESTAMP_ARRAY_START);
+
+#define PMF_PERCPU_TIMESTAMP_SIZE	(PMF_PERCPU_TIMESTAMP_END - PMF_TIMESTAMP_ARRAY_START)
 
 #define PMF_SVC_DESCS_MAX		10
 
@@ -66,15 +67,15 @@
 	pmf_svc_descs = (pmf_svc_desc_t *) PMF_SVC_DESCS_START;
 	for (ii = 0; ii < pmf_svc_descs_num; ii++) {
 
-		assert(pmf_svc_descs[ii].get_ts);
+		assert(pmf_svc_descs[ii].get_ts != NULL);
 
 		/*
 		 * Call the initialization routine for this
 		 * PMF service, if it is defined.
 		 */
-		if (pmf_svc_descs[ii].init) {
+		if (pmf_svc_descs[ii].init != NULL) {
 			rc = pmf_svc_descs[ii].init();
-			if (rc) {
+			if (rc != 0) {
 				WARN("Could not initialize PMF"
 					"service %s - skipping \n",
 					pmf_svc_descs[ii].name);
@@ -124,7 +125,7 @@
 	if (pmf_num_services == 0)
 		return NULL;
 
-	assert(pmf_svc_descs);
+	assert(pmf_svc_descs != NULL);
 
 	do {
 		mid = (low + high) / 2;
@@ -157,7 +158,7 @@
 		unsigned long long *ts_value)
 {
 	pmf_svc_desc_t *svc_desc;
-	assert(ts_value);
+	assert(ts_value != NULL);
 
 	/* Search for registered service. */
 	svc_desc = get_service(tid);
@@ -246,7 +247,7 @@
 	unsigned long long *ts_addr = (unsigned long long *)calc_ts_addr(base_addr,
 				tid, cpuid);
 
-	if (flags & PMF_CACHE_MAINT)
+	if ((flags & PMF_CACHE_MAINT) != 0U)
 		inv_dcache_range((uintptr_t)ts_addr, sizeof(unsigned long long));
 
 	return *ts_addr;
diff --git a/lib/pmf/pmf_smc.c b/lib/pmf/pmf_smc.c
index e866118..4c5b14f 100644
--- a/lib/pmf/pmf_smc.c
+++ b/lib/pmf/pmf_smc.c
@@ -37,7 +37,8 @@
 			 * x0 --> error code.
 			 * x1 - x2 --> time-stamp value.
 			 */
-			rc = pmf_get_timestamp_smc(x1, x2, x3, &ts_value);
+			rc = pmf_get_timestamp_smc((unsigned int)x1, x2,
+					(unsigned int)x3, &ts_value);
 			SMC_RET3(handle, rc, (uint32_t)ts_value,
 					(uint32_t)(ts_value >> 32));
 		}
@@ -49,7 +50,8 @@
 			 * x0 --> error code.
 			 * x1 --> time-stamp value.
 			 */
-			rc = pmf_get_timestamp_smc(x1, x2, x3, &ts_value);
+			rc = pmf_get_timestamp_smc((unsigned int)x1, x2,
+					(unsigned int)x3, &ts_value);
 			SMC_RET2(handle, rc, ts_value);
 		}
 	}
diff --git a/lib/romlib/init.s b/lib/romlib/init.s
index 5cf2aca..7d97e4d 100644
--- a/lib/romlib/init.s
+++ b/lib/romlib/init.s
@@ -5,7 +5,7 @@
  */
 
 	.globl	rom_lib_init
-	.extern	__DATA_RAM_START__, __DATA_ROM_START__, __DATA_SIZE__
+	.extern	__DATA_RAM_START__, __DATA_ROM_START__, __DATA_RAM_END__
 	.extern	memset, memcpy
 
 rom_lib_init:
@@ -16,13 +16,19 @@
 
 1:	stp	x29, x30, [sp, #-16]!
 	adrp	x0, __DATA_RAM_START__
-	ldr	x1,= __DATA_ROM_START__
-	ldr	x2, =__DATA_SIZE__
+	adrp	x1, __DATA_ROM_START__
+	add	x1, x1, :lo12:__DATA_ROM_START__
+	adrp	x2, __DATA_RAM_END__
+	add	x2, x2, :lo12:__DATA_RAM_END__
+	sub	x2, x2, x0
 	bl	memcpy
 
-	ldr	x0, =__BSS_START__
+	adrp	x0,__BSS_START__
+	add	x0, x0, :lo12:__BSS_START__
 	mov	x1, #0
-	ldr	x2, =__BSS_SIZE__
+	adrp	x2, __BSS_END__
+	add	x2, x2, :lo12:__BSS_END__
+	sub	x2, x2, x0
 	bl	memset
 	ldp	x29, x30, [sp], #16
 
diff --git a/lib/xlat_tables_v2/aarch64/enable_mmu.S b/lib/xlat_tables_v2/aarch64/enable_mmu.S
index 21717d2..504c03c 100644
--- a/lib/xlat_tables_v2/aarch64/enable_mmu.S
+++ b/lib/xlat_tables_v2/aarch64/enable_mmu.S
@@ -45,7 +45,8 @@
 		tlbi_invalidate_all \el
 
 		mov	x7, x0
-		ldr	x0, =mmu_cfg_params
+		adrp	x0, mmu_cfg_params
+		add	x0, x0, :lo12:mmu_cfg_params
 
 		/* MAIR */
 		ldr	x1, [x0, #(MMU_CFG_MAIR << 3)]
diff --git a/lib/xlat_tables_v2/xlat_tables.mk b/lib/xlat_tables_v2/xlat_tables.mk
index 9507ad7..c946315 100644
--- a/lib/xlat_tables_v2/xlat_tables.mk
+++ b/lib/xlat_tables_v2/xlat_tables.mk
@@ -10,3 +10,6 @@
 				xlat_tables_context.c			\
 				xlat_tables_core.c			\
 				xlat_tables_utils.c)
+
+XLAT_TABLES_LIB_V2	:=	1
+$(eval $(call add_define,XLAT_TABLES_LIB_V2))
diff --git a/maintainers.rst b/maintainers.rst
index 5fb4494..6d649c3 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -26,6 +26,14 @@
 :F: plat/allwinner/
 :F: drivers/allwinner/
 
+Amlogic Meson S905 (GXBB) platform port
+---------------------------------------
+:M: Antonio Niño Díaz <antonio.ninodiaz@arm.com>
+:G: `antonio-nino-diaz-arm`_
+:F: docs/plat/meson-gxbb.rst
+:F: drivers/meson/
+:F: plat/meson/gxbb/
+
 Armv7-A architecture port
 -------------------------
 :M: Etienne Carriere <etienne.carriere@linaro.org>
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 435de20..4a3f541 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -64,6 +64,9 @@
 # Build option to enable MPAM for lower ELs
 ENABLE_MPAM_FOR_LOWER_ELS	:= 0
 
+# Flag to Enable Position Independant support (PIE)
+ENABLE_PIE			:= 0
+
 # Flag to enable Performance Measurement Framework
 ENABLE_PMF			:= 0
 
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
new file mode 100644
index 0000000..2dc058f
--- /dev/null
+++ b/plat/allwinner/common/allwinner-common.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
+
+include lib/libfdt/libfdt.mk
+
+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}/${PLAT}/sunxi_power.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
+
+MULTI_CONSOLE_API		:=	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
+
+# We are short on memory, so save 3.5KB by not having an extra coherent page.
+USE_COHERENT_MEM		:=	0
diff --git a/plat/allwinner/common/arisc_off.S b/plat/allwinner/common/arisc_off.S
new file mode 100644
index 0000000..ed10832
--- /dev/null
+++ b/plat/allwinner/common/arisc_off.S
@@ -0,0 +1,115 @@
+# turn_off_core.S
+#
+# Copyright (c) 2018, Andre Przywara <osp@andrep.de>
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# OpenRISC assembly to turn off an ARM core on an Allwinner SoC from
+# the arisc management controller.
+# Generate a binary representation with:
+# $ or1k-elf-as -c -o turn_off_core.o turn_off_core.S
+# $ or1k-elf-objcopy -O binary --reverse-bytes=4 turn_off_core.o \
+#   turn_off_core.bin
+# The encoded instructions go into an array defined in
+# plat/allwinner/sun50i_*/include/core_off_arisc.h, to be handed off to
+# the arisc processor.
+#
+# This routine is meant to be called directly from arisc reset (put the
+# start address in the reset vector), to be actually triggered by that
+# very ARM core to be turned off.
+# It expects the core number presented as a mask in the upper half of
+# r3, so to be patched in the lower 16 bits of the first instruction,
+# overwriting the 0 in this code here.
+# The code will do the following:
+# - Read the C_CPU_STATUS register, which contains the status of the WFI
+#   lines of each of the four A53 cores.
+# - Loop until the core in question reaches WFI.
+# - Using that mask, activate the core output clamps by setting the
+#   respective core bit in CPUX_PWROFF_GATING_REG (0x1f01500).
+#   Note that the clamp for core 0 covers more than just the core, activating
+#   it hangs the whole system. So we skip this step for core 0.
+# - Using the negated mask, assert the core's reset line by clearing the
+#   respective bit in C_RST_CTRL (0x1f01c30).
+# - Finally turn off the core's power switch by writing 0xff to the
+#   respective CPUx_PWR_SWITCH_REG (0x1f01540 ff.)
+# - Assert the arisc's own reset to end execution.
+#   This also signals other arisc users that the chip is free again.
+# So in C this would look like:
+#	while (!(readl(0x1700030) & (1U << core_nr)))
+#		;
+#	if (core_nr != 0)
+#		writel(readl(0x1f01500) | (1U << core_nr), 0x1f01500);
+#	writel(readl(0x1f01c30) & ~(1U << core_nr), 0x1f01c30);
+#	writel(0xff, 0x1f01540 + (core_nr * 4));
+# (using A64/H5 addresses)
+
+.text
+_start:
+	l.movhi	r3, 0				# FIXUP! with core mask
+	l.movhi r0, 0				# clear r0
+	l.movhi	r13, 0x170			# r13: CPU_CFG_BASE=0x01700000
+wait_wfi:
+	l.lwz	r5, 0x30(r13)			# load C_CPU_STATUS
+	l.and	r5, r5, r3			# mask requested core
+	l.sfeq	r5, r0				# is it not yet in WFI?
+	l.bf	wait_wfi			# try again
+
+	l.srli	r6, r3, 16			# move mask to lower 16 bits
+	l.sfeqi	r6, 1				# core 0 is special
+	l.bf	1f				# don't touch the bit for core 0
+	l.movhi	r13, 0x1f0			# address of R_CPUCFG (delay)
+	l.lwz	r5, 0x1500(r13)			# core output clamps
+	l.or	r5, r5, r6			# set bit to ...
+	l.sw	0x1500(r13), r5			# ... activate for our core
+
+1:	l.lwz	r5, 0x1c30(r13)			# CPU power-on reset
+	l.xori	r6, r6, -1			# negate core mask
+	l.and	r5, r5, r6			# clear bit to ...
+	l.sw	0x1c30(r13), r5			# ... assert for our core
+
+	l.ff1	r6, r3				# get core number from high mask
+	l.addi	r6, r6, -17			# convert to 0-3
+	l.slli	r6, r6, 2			# r5: core number*4 (0-12)
+	l.add	r6, r6, r13			# add to base address
+	l.ori	r5, r0, 0xff			# 0xff means all switches off
+	l.sw	0x1540(r6), r5			# core power switch registers
+
+reset:	l.sw	0x1c00(r13),r0			# pull down our own reset line
+
+	l.j	reset				# just in case ....
+	l.nop	0x0				# (delay slot)
+
+# same as above, but with the MMIO addresses matching the H6 SoC
+_start_h6:
+	l.movhi	r3, 0				# FIXUP! with core mask
+	l.movhi r0, 0				# clear r0
+	l.movhi	r13, 0x901			# r13: CPU_CFG_BASE=0x09010000
+1:
+	l.lwz	r5, 0x80(r13)			# load C_CPU_STATUS
+	l.and	r5, r5, r3			# mask requested core
+	l.sfeq	r5, r0				# is it not yet in WFI?
+	l.bf	1b				# try again
+
+	l.srli	r6, r3, 16			# move mask to lower 16 bits(ds)
+	l.sfeqi	r6, 1				# core 0 is special
+	l.bf	1f				# don't touch the bit for core 0
+	l.movhi	r13, 0x700			# address of R_CPUCFG (ds)
+	l.lwz	r5, 0x0444(r13)			# core output clamps
+	l.or	r5, r5, r6			# set bit to ...
+	l.sw	0x0444(r13), r5			# ... activate for our core
+
+1:	l.lwz	r5, 0x0440(r13)			# CPU power-on reset
+	l.xori	r6, r6, -1			# negate core mask
+	l.and	r5, r5, r6			# clear bit to ...
+	l.sw	0x0440(r13), r5			# ... assert for our core
+
+	l.ff1	r6, r3				# get core number from high mask
+	l.addi	r6, r6, -17			# convert to 0-3
+	l.slli	r6, r6, 2			# r5: core number*4 (0-12)
+	l.add	r6, r6, r13			# add to base address
+	l.ori	r5, r0, 0xff			# 0xff means all switches off
+	l.sw	0x0450(r6), r5			# core power switch registers
+
+1:	l.sw	0x0400(r13),r0			# pull down our own reset line
+
+	l.j	1b				# just in case ...
+	l.nop	0x0				# (delay slot)
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index b46d410..08eb5cf 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -18,11 +18,17 @@
 /* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */
 #define PLAT_SUNXI_NS_IMAGE_OFFSET	(SUNXI_DRAM_BASE + (160U << 20))
 
+/* How much memory to reserve as secure for BL32, if configured */
+#define SUNXI_DRAM_SEC_SIZE		(32U << 20)
+
+/* How much DRAM to map (to map BL33, for fetching the DTB from U-Boot) */
+#define SUNXI_DRAM_MAP_SIZE		(64U << 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 MAX_MMAP_REGIONS		(3 + PLATFORM_MMAP_REGIONS)
+#define MAX_XLAT_TABLES			1
 
 #define PLAT_MAX_PWR_LVL_STATES		U(2)
 #define PLAT_MAX_RET_STATE		U(1)
@@ -34,13 +40,13 @@
 					 PLATFORM_CORE_COUNT)
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 28)
 
 #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		3
+#define PLATFORM_MMAP_REGIONS		4
 #define PLATFORM_STACK_SIZE		(0x1000 / PLATFORM_CORE_COUNT)
 
 #ifndef SPD_none
diff --git a/plat/allwinner/common/include/sunxi_def.h b/plat/allwinner/common/include/sunxi_def.h
index e68fbe4..da87b23 100644
--- a/plat/allwinner/common/include/sunxi_def.h
+++ b/plat/allwinner/common/include/sunxi_def.h
@@ -14,4 +14,8 @@
 #define SUNXI_UART0_BAUDRATE		115200
 #define SUNXI_UART0_CLK_IN_HZ		SUNXI_OSC24M_CLK_IN_HZ
 
+#define SUNXI_SOC_A64			0x1689
+#define SUNXI_SOC_H5			0x1718
+#define SUNXI_SOC_H6			0x1728
+
 #endif /* __SUNXI_DEF_H__ */
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
new file mode 100644
index 0000000..1e1b0a4
--- /dev/null
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -0,0 +1,26 @@
+/*
+ * 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_on(unsigned int cluster, unsigned int core);
+void sunxi_cpu_off(unsigned int cluster, unsigned int core);
+void sunxi_disable_secondary_cpus(unsigned int primary_cpu);
+void __dead2 sunxi_power_down(void);
+
+int sunxi_pmic_setup(uint16_t socid, const void *fdt);
+void sunxi_security_setup(void);
+
+uint16_t sunxi_read_soc_id(void);
+void sunxi_set_gpio_out(char port, int pin, bool level_high);
+int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
+void sunxi_execute_arisc_code(uint32_t *code, size_t size,
+			      int patch_offset, uint16_t param);
+
+#endif /* SUNXI_PRIVATE_H */
diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c
index 7e11cec..8f597c3 100644
--- a/plat/allwinner/common/sunxi_bl31_setup.c
+++ b/plat/allwinner/common/sunxi_bl31_setup.c
@@ -10,13 +10,14 @@
 #include <debug.h>
 #include <generic_delay_timer.h>
 #include <gicv2.h>
+#include <libfdt.h>
 #include <platform.h>
 #include <platform_def.h>
 #include <sunxi_def.h>
 #include <sunxi_mmap.h>
+#include <sunxi_private.h>
 #include <uart_16550.h>
 
-#include "sunxi_private.h"
 
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
@@ -28,6 +29,47 @@
 	.gicc_base = SUNXI_GICC_BASE,
 };
 
+/*
+ * Try to find a DTB loaded in memory by previous stages.
+ *
+ * At the moment we implement a heuristic to find the DTB attached to U-Boot:
+ * U-Boot appends its DTB to the end of the image. Assuming that BL33 is
+ * U-Boot, try to find the size of the U-Boot image to learn the DTB address.
+ * The generic ARMv8 U-Boot image contains the load address and its size
+ * as u64 variables at the beginning of the image. There might be padding
+ * or other headers before that data, so scan the first 2KB after the BL33
+ * entry point to find the load address, which should be followed by the
+ * size. Adding those together gives us the address of the DTB.
+ */
+static void *sunxi_find_dtb(void)
+{
+	uint64_t *u_boot_base;
+	int i;
+
+	u_boot_base = (void *)(SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE);
+
+	for (i = 0; i < 2048 / sizeof(uint64_t); i++) {
+		uint32_t *dtb_base;
+
+		if (u_boot_base[i] != PLAT_SUNXI_NS_IMAGE_OFFSET)
+			continue;
+
+		/* Does the suspected U-Boot size look anyhow reasonable? */
+		if (u_boot_base[i + 1] >= 256 * 1024 * 1024)
+			continue;
+
+		/* end of the image: base address + size */
+		dtb_base = (void *)((char *)u_boot_base + u_boot_base[i + 1]);
+
+		if (fdt_check_header(dtb_base) != 0)
+			continue;
+
+		return dtb_base;
+	}
+
+	return NULL;
+}
+
 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				u_register_t arg2, u_register_t arg3)
 {
@@ -66,15 +108,16 @@
 {
 	const char *soc_name;
 	uint16_t soc_id = sunxi_read_soc_id();
+	void *fdt;
 
 	switch (soc_id) {
-	case 0x1689:
+	case SUNXI_SOC_A64:
 		soc_name = "A64/H64/R18";
 		break;
-	case 0x1718:
+	case SUNXI_SOC_H5:
 		soc_name = "H5";
 		break;
-	case 0x1728:
+	case SUNXI_SOC_H6:
 		soc_name = "H6";
 		break;
 	default:
@@ -85,6 +128,18 @@
 
 	generic_delay_timer_init();
 
+	fdt = sunxi_find_dtb();
+	if (fdt) {
+		const char *model;
+		int length;
+
+		model = fdt_getprop(fdt, 0, "model", &length);
+		NOTICE("BL31: Found U-Boot DTB at %p, model: %s\n", fdt,
+		     model ?: "unknown");
+	} else {
+		NOTICE("BL31: No DTB found.\n");
+	}
+
 	/* Configure the interrupt controller */
 	gicv2_driver_init(&sunxi_gic_data);
 	gicv2_distif_init();
@@ -93,7 +148,7 @@
 
 	sunxi_security_setup();
 
-	sunxi_pmic_setup();
+	sunxi_pmic_setup(soc_id, fdt);
 
 	INFO("BL31: Platform setup done\n");
 }
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index fc9bf20..2eb26a9 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -4,21 +4,28 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
 #include <mmio.h>
 #include <platform.h>
 #include <platform_def.h>
 #include <sunxi_def.h>
+#include <sunxi_mmap.h>
+#include <sunxi_private.h>
 #include <xlat_tables_v2.h>
 
-#include "sunxi_private.h"
-
 static mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = {
 	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),
+	MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE,
+			MT_MEMORY | MT_RW | MT_SECURE),
+	MAP_REGION(PLAT_SUNXI_NS_IMAGE_OFFSET,
+		   SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE,
+		   SUNXI_DRAM_MAP_SIZE,
+		   MT_MEMORY | MT_RO | MT_NS),
 	{},
 };
 
@@ -47,9 +54,6 @@
 	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();
 
@@ -71,3 +75,136 @@
 
 	return reg >> 16;
 }
+
+/*
+ * Configure a given pin to the GPIO-OUT function and sets its level.
+ * The port is given as a capital letter, the pin is the number within
+ * this port group.
+ * So to set pin PC7 to high, use: sunxi_set_gpio_out('C', 7, true);
+ */
+void sunxi_set_gpio_out(char port, int pin, bool level_high)
+{
+	uintptr_t port_base;
+
+	if (port < 'A' || port > 'L')
+		return;
+	if (port == 'L')
+		port_base = SUNXI_R_PIO_BASE;
+	else
+		port_base = SUNXI_PIO_BASE + (port - 'A') * 0x24;
+
+	/* Set the new level first before configuring the pin. */
+	if (level_high)
+		mmio_setbits_32(port_base + 0x10, BIT(pin));
+	else
+		mmio_clrbits_32(port_base + 0x10, BIT(pin));
+
+	/* configure pin as GPIO out (4(3) bits per pin, 1: GPIO out */
+	mmio_clrsetbits_32(port_base + (pin / 8) * 4,
+			   0x7 << ((pin % 8) * 4),
+			   0x1 << ((pin % 8) * 4));
+}
+
+int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb)
+{
+	uint32_t pin_func = 0x77;
+	uint32_t device_bit;
+	unsigned int reset_offset = 0xb0;
+
+	switch (socid) {
+	case SUNXI_SOC_H5:
+		if (use_rsb)
+			return -ENODEV;
+		pin_func = 0x22;
+		device_bit = BIT(6);
+		break;
+	case SUNXI_SOC_H6:
+		if (use_rsb)
+			return -ENODEV;
+		pin_func = 0x33;
+		device_bit = BIT(16);
+		reset_offset = 0x19c;
+		break;
+	case SUNXI_SOC_A64:
+		pin_func = use_rsb ? 0x22 : 0x33;
+		device_bit = use_rsb ? BIT(3) : BIT(6);
+		break;
+	default:
+		INFO("R_I2C/RSB on Allwinner 0x%x SoC not supported\n", socid);
+		return -ENODEV;
+	}
+
+	/* un-gate R_PIO clock */
+	if (socid != SUNXI_SOC_H6)
+		mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, BIT(0));
+
+	/* switch pins PL0 and PL1 to the desired function */
+	mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x00, 0xffU, pin_func);
+
+	/* level 2 drive strength */
+	mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x14, 0x0fU, 0xaU);
+
+	/* set both pins to pull-up */
+	mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U);
+
+	/* assert, then de-assert reset of I2C/RSB controller */
+	mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+	mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+
+	/* un-gate clock */
+	if (socid != SUNXI_SOC_H6)
+		mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit);
+	else
+		mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0));
+
+	return 0;
+}
+
+/* This lock synchronises access to the arisc management processor. */
+DEFINE_BAKERY_LOCK(arisc_lock);
+
+/*
+ * Tell the "arisc" SCP core (an OpenRISC core) to execute some code.
+ * We don't have any service running there, so we place some OpenRISC code
+ * in SRAM, put the address of that into the reset vector and release the
+ * arisc reset line. The SCP will execute that code and pull the line up again.
+ */
+void sunxi_execute_arisc_code(uint32_t *code, size_t size,
+			      int patch_offset, uint16_t param)
+{
+	uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE - 0x4000 + 0x100;
+
+	do {
+		bakery_lock_get(&arisc_lock);
+		/* Wait until the arisc is in reset state. */
+		if (!(mmio_read_32(SUNXI_R_CPUCFG_BASE) & BIT(0)))
+			break;
+
+		bakery_lock_release(&arisc_lock);
+	} while (1);
+
+	/* Patch up the code to feed in an input parameter. */
+	if (patch_offset >= 0 && patch_offset <= (size - 4))
+		code[patch_offset] = (code[patch_offset] & ~0xffff) | param;
+	clean_dcache_range((uintptr_t)code, size);
+
+	/*
+	 * The OpenRISC unconditional branch has opcode 0, the branch offset
+	 * is in the lower 26 bits, containing the distance to the target,
+	 * in instruction granularity (32 bits).
+	 */
+	mmio_write_32(arisc_reset_vec, ((uintptr_t)code - arisc_reset_vec) / 4);
+	clean_dcache_range(arisc_reset_vec, 4);
+
+	/* De-assert the arisc reset line to let it run. */
+	mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0));
+
+	/*
+	 * We release the lock here, although the arisc is still busy.
+	 * But as long as it runs, the reset line is high, so other users
+	 * won't leave the loop above.
+	 * Once it has finished, the code is supposed to clear the reset line,
+	 * to signal this to other users.
+	 */
+	bakery_lock_release(&arisc_lock);
+}
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index aaee65c..3b732b5 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -4,15 +4,19 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arch_helpers.h>
+#include <assert.h>
+#include <core_off_arisc.h>
 #include <debug.h>
+#include <delay_timer.h>
 #include <mmio.h>
+#include <platform.h>
 #include <platform_def.h>
-#include <sunxi_mmap.h>
 #include <sunxi_cpucfg.h>
+#include <sunxi_mmap.h>
+#include <sunxi_private.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)
@@ -40,16 +44,37 @@
 
 void sunxi_cpu_off(unsigned int cluster, unsigned int core)
 {
+	int corenr = cluster * PLATFORM_MAX_CPUS_PER_CLUSTER + core;
+
 	VERBOSE("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);
+
+	/* We can't turn ourself off like this, but it works for other cores. */
+	if (plat_my_core_pos() != corenr) {
+		/* Activate the core output clamps, but not for core 0. */
+		if (corenr != 0)
+			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);
+
+		return;
+	}
+
+	/* Simplifies assembly, all SoCs so far are single cluster anyway. */
+	assert(cluster == 0);
+
+	/*
+	 * If we are supposed to turn ourself off, tell the arisc SCP
+	 * to do that work for us. The code expects the core mask to be
+	 * patched into the first instruction.
+	 */
+	sunxi_execute_arisc_code(arisc_core_off, sizeof(arisc_core_off),
+				 0, BIT_32(core));
 }
 
 void sunxi_cpu_on(unsigned int cluster, unsigned int core)
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index e4bb582..7d13cda 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -13,15 +13,14 @@
 #include <platform.h>
 #include <platform_def.h>
 #include <psci.h>
-#include <sunxi_mmap.h>
 #include <sunxi_cpucfg.h>
+#include <sunxi_mmap.h>
+#include <sunxi_private.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 && \
@@ -43,6 +42,16 @@
 	gicv2_cpuif_disable();
 }
 
+static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state)
+{
+	u_register_t mpidr = read_mpidr();
+
+	sunxi_cpu_off(MPIDR_AFFLVL1_VAL(mpidr), MPIDR_AFFLVL0_VAL(mpidr));
+
+	while (1)
+		wfi();
+}
+
 static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	gicv2_pcpu_distif_init();
@@ -83,6 +92,7 @@
 static plat_psci_ops_t sunxi_psci_ops = {
 	.pwr_domain_on			= sunxi_pwr_domain_on,
 	.pwr_domain_off			= sunxi_pwr_domain_off,
+	.pwr_domain_pwr_down_wfi	= sunxi_pwr_down_wfi,
 	.pwr_domain_on_finish		= sunxi_pwr_domain_on_finish,
 	.system_off			= sunxi_system_off,
 	.system_reset			= sunxi_system_reset,
diff --git a/plat/allwinner/common/sunxi_private.h b/plat/allwinner/common/sunxi_private.h
deleted file mode 100644
index 20fa23e..0000000
--- a/plat/allwinner/common/sunxi_private.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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);
-
-uint16_t sunxi_read_soc_id(void);
-
-void sunxi_pmic_setup(void);
-void sunxi_security_setup(void);
-
-void __dead2 sunxi_power_down(void);
-
-#endif /* __SUNXI_PRIVATE_H__ */
diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c
index 80fed6a..9053728 100644
--- a/plat/allwinner/common/sunxi_security.c
+++ b/plat/allwinner/common/sunxi_security.c
@@ -7,6 +7,7 @@
 #include <debug.h>
 #include <mmio.h>
 #include <sunxi_mmap.h>
+#include <sunxi_private.h>
 
 #ifdef SUNXI_SPC_BASE
 #define SPC_DECPORT_STA_REG(p)	(SUNXI_SPC_BASE + ((p) * 0x0c) + 0x4)
diff --git a/plat/allwinner/sun50i_a64/include/core_off_arisc.h b/plat/allwinner/sun50i_a64/include/core_off_arisc.h
new file mode 100644
index 0000000..ae436ca
--- /dev/null
+++ b/plat/allwinner/sun50i_a64/include/core_off_arisc.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+static uint32_t arisc_core_off[] = {
+	0x18600000, /* l.movhi	r3, <corenr>	*/
+	0x18000000, /* l.movhi	r0, 0x0		*/
+	0x19a00170, /* l.movhi	r13, 0x170	*/
+	0x84ad0030, /* l.lwz	r5, 0x30(r13)	*/
+	0xe0a51803, /* l.and	r5, r5, r3	*/
+	0xe4050000, /* l.sfeq	r5, r0		*/
+	0x13fffffd, /* l.bf	-12		*/
+
+	0xb8c30050, /* l.srli	r6, r3, 16	*/
+	0xbc060001, /* l.sfeqi	r6, 1		*/
+	0x10000005, /* l.bf	+20		*/
+	0x19a001f0, /* l.movhi	r13, 0x1f0	*/
+	0x84ad1500, /* l.lwz	r5, 0x1500(r13)	*/
+	0xe0a53004, /* l.or	r5, r5, r6	*/
+	0xd44d2d00, /* l.sw	0x1500(r13), r5	*/
+
+	0x84ad1c30, /* l.lwz	r5, 0x1c30(r13)	*/
+	0xacc6ffff, /* l.xori	r6, r6, -1	*/
+	0xe0a53003, /* l.and	r5, r5, r6	*/
+	0xd46d2c30, /* l.sw	0x1c30(r13), r5	*/
+
+	0xe0c3000f, /* l.ff1	r6, r3		*/
+	0x9cc6ffef, /* l.addi	r6, r6, -17	*/
+	0xb8c60002, /* l.slli	r6, r6, 2	*/
+	0xe0c66800, /* l.add	r6, r6, r13	*/
+	0xa8a000ff, /* l.ori	r5, r0, 0xff	*/
+	0xd4462d40, /* l.sw	0x1540(r6), r5	*/
+
+	0xd46d0400, /* l.sw	0x1c00(r13), r0	*/
+	0x03ffffff, /* l.j	-1		*/
+	0x15000000, /* l.nop			*/
+};
diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
index 7d46487..28b1dd3 100644
--- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h
@@ -21,7 +21,7 @@
 #define SUNXI_DEV_BASE			0x01000000
 #define SUNXI_DEV_SIZE			0x01000000
 #define SUNXI_DRAM_BASE			0x40000000
-#define SUNXI_DRAM_SIZE			0x80000000
+#define SUNXI_DRAM_VIRT_BASE		0x02000000
 
 /* Memory-mapped devices */
 #define SUNXI_CPU_MBIST_BASE		0x01502000
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index 2216654..b46fbc2 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -4,51 +4,7 @@
 # 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}/sun50i_a64/sunxi_power.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
-
-MULTI_CONSOLE_API		:=	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
+# The differences between the platform are covered by the include files.
+include plat/allwinner/common/allwinner-common.mk
 
-# BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
-RESET_TO_BL31			:=	1
+PLAT_BL_COMMON_SOURCES	+=	drivers/allwinner/sunxi_rsb.c
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index c1907d6..af30477 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -5,20 +5,350 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <allwinner/sunxi_rsb.h>
 #include <arch_helpers.h>
 #include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <sunxi_def.h>
+#include <sunxi_mmap.h>
+#include <sunxi_private.h>
 
-int sunxi_pmic_setup(void)
+static enum pmic_type {
+	GENERIC_H5,
+	GENERIC_A64,
+	REF_DESIGN_H5,	/* regulators controlled by GPIO pins on port L */
+	AXP803_RSB,	/* PMIC connected via RSB on most A64 boards */
+} pmic;
+
+#define AXP803_HW_ADDR	0x3a3
+#define AXP803_RT_ADDR	0x2d
+
+/*
+ * On boards without a proper PMIC we struggle to turn off the system properly.
+ * Try to turn off as much off the system as we can, to reduce power
+ * consumption. This should be entered with only one core running and SMP
+ * disabled.
+ * This function only cares about peripherals.
+ */
+void sunxi_turn_off_soc(uint16_t socid)
+{
+	int i;
+
+	/** Turn off most peripherals, most importantly DRAM users. **/
+	/* Keep DRAM controller running for now. */
+	mmio_clrbits_32(SUNXI_CCU_BASE + 0x2c0, ~BIT_32(14));
+	mmio_clrbits_32(SUNXI_CCU_BASE + 0x60, ~BIT_32(14));
+	/* Contains msgbox (bit 21) and spinlock (bit 22) */
+	mmio_write_32(SUNXI_CCU_BASE + 0x2c4, 0);
+	mmio_write_32(SUNXI_CCU_BASE + 0x64, 0);
+	mmio_write_32(SUNXI_CCU_BASE + 0x2c8, 0);
+	/* Keep PIO controller running for now. */
+	mmio_clrbits_32(SUNXI_CCU_BASE + 0x68, ~(BIT_32(5)));
+	mmio_write_32(SUNXI_CCU_BASE + 0x2d0, 0);
+	/* Contains UART0 (bit 16) */
+	mmio_write_32(SUNXI_CCU_BASE + 0x2d8, 0);
+	mmio_write_32(SUNXI_CCU_BASE + 0x6c, 0);
+	mmio_write_32(SUNXI_CCU_BASE + 0x70, 0);
+
+	/** Turn off DRAM controller. **/
+	mmio_clrbits_32(SUNXI_CCU_BASE + 0x2c0, BIT_32(14));
+	mmio_clrbits_32(SUNXI_CCU_BASE + 0x60, BIT_32(14));
+
+	/** Migrate CPU and bus clocks away from the PLLs. **/
+	/* AHB1: use OSC24M/1, APB1 = AHB1 / 2 */
+	mmio_write_32(SUNXI_CCU_BASE + 0x54, 0x1000);
+	/* APB2: use OSC24M */
+	mmio_write_32(SUNXI_CCU_BASE + 0x58, 0x1000000);
+	/* AHB2: use AHB1 clock */
+	mmio_write_32(SUNXI_CCU_BASE + 0x5c, 0);
+	/* CPU: use OSC24M */
+	mmio_write_32(SUNXI_CCU_BASE + 0x50, 0x10000);
+
+	/** Turn off PLLs. **/
+	for (i = 0; i < 6; i++)
+		mmio_clrbits_32(SUNXI_CCU_BASE + i * 8, BIT(31));
+	switch (socid) {
+	case SUNXI_SOC_H5:
+		mmio_clrbits_32(SUNXI_CCU_BASE + 0x44, BIT(31));
+		break;
+	case SUNXI_SOC_A64:
+		mmio_clrbits_32(SUNXI_CCU_BASE + 0x2c, BIT(31));
+		mmio_clrbits_32(SUNXI_CCU_BASE + 0x4c, BIT(31));
+		break;
+	}
+}
+
+static int rsb_init(void)
+{
+	int ret;
+
+	ret = rsb_init_controller();
+	if (ret)
+		return ret;
+
+	/* Start with 400 KHz to issue the I2C->RSB switch command. */
+	ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 400000);
+	if (ret)
+		return ret;
+
+	/*
+	 * Initiate an I2C transaction to write 0x7c into register 0x3e,
+	 * switching the PMIC to RSB mode.
+	 */
+	ret = rsb_set_device_mode(0x7c3e00);
+	if (ret)
+		return ret;
+
+	/* Now in RSB mode, switch to the recommended 3 MHz. */
+	ret = rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ, 3000000);
+	if (ret)
+		return ret;
+
+	/* Associate the 8-bit runtime address with the 12-bit bus address. */
+	return rsb_assign_runtime_address(AXP803_HW_ADDR,
+					  AXP803_RT_ADDR);
+}
+
+static int axp_write(uint8_t reg, uint8_t val)
 {
-	/* STUB */
-	NOTICE("BL31: STUB PMIC setup code called\n");
+	return rsb_write(AXP803_RT_ADDR, reg, val);
+}
+
+static int axp_setbits(uint8_t reg, uint8_t set_mask)
+{
+	uint8_t regval;
+	int ret;
+
+	ret = rsb_read(AXP803_RT_ADDR, reg);
+	if (ret < 0)
+		return ret;
+
+	regval = ret | set_mask;
+
+	return rsb_write(AXP803_RT_ADDR, reg, regval);
+}
+
+static bool should_enable_regulator(const void *fdt, int node)
+{
+	if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
+		return true;
+	if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
+		return true;
+	return false;
+}
+
+/*
+ * Retrieve the voltage from a given regulator DTB node.
+ * Both the regulator-{min,max}-microvolt properties must be present and
+ * have the same value. Return that value in millivolts.
+ */
+static int fdt_get_regulator_millivolt(const void *fdt, int node)
+{
+	const fdt32_t *prop;
+	uint32_t min_volt;
+
+	prop = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
+	if (prop == NULL)
+		return -EINVAL;
+	min_volt = fdt32_to_cpu(*prop);
+
+	prop = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
+	if (prop == NULL)
+		return -EINVAL;
+
+	if (fdt32_to_cpu(*prop) != min_volt)
+		return -EINVAL;
+
+	return min_volt / 1000;
+}
+
+#define NO_SPLIT 0xff
+
+struct axp_regulator {
+	char *dt_name;
+	uint16_t min_volt;
+	uint16_t max_volt;
+	uint16_t step;
+	unsigned char split;
+	unsigned char volt_reg;
+	unsigned char switch_reg;
+	unsigned char switch_bit;
+} regulators[] = {
+	{"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0xff, 9},
+	{"dcdc5",  800, 1840,  10,       32, 0x24, 0xff, 9},
+	{"dldo1",  700, 3300, 100, NO_SPLIT, 0x15, 0x12, 3},
+	{"dldo2",  700, 4200, 100,       27, 0x16, 0x12, 4},
+	{"dldo3",  700, 3300, 100, NO_SPLIT, 0x17, 0x12, 5},
+	{"fldo1",  700, 1450,  50, NO_SPLIT, 0x1c, 0x13, 2},
+	{}
+};
+
+static int setup_regulator(const void *fdt, int node,
+			   const struct axp_regulator *reg)
+{
+	int mvolt;
+	uint8_t regval;
+
+	if (!should_enable_regulator(fdt, node))
+		return -ENOENT;
+
+	mvolt = fdt_get_regulator_millivolt(fdt, node);
+	if (mvolt < reg->min_volt || mvolt > reg->max_volt)
+		return -EINVAL;
+
+	regval = (mvolt / reg->step) - (reg->min_volt / reg->step);
+	if (regval > reg->split)
+		regval = ((regval - reg->split) / 2) + reg->split;
+
+	axp_write(reg->volt_reg, regval);
+	if (reg->switch_reg < 0xff)
+		axp_setbits(reg->switch_reg, BIT(reg->switch_bit));
+
+	INFO("PMIC: AXP803: %s voltage: %d.%03dV\n", reg->dt_name,
+	     mvolt / 1000, mvolt % 1000);
 
 	return 0;
 }
 
+static void setup_axp803_rails(const void *fdt)
+{
+	int node;
+	bool dc1sw = false;
+
+	/* locate the PMIC DT node, bail out if not found */
+	node = fdt_node_offset_by_compatible(fdt, -1, "x-powers,axp803");
+	if (node == -FDT_ERR_NOTFOUND) {
+		WARN("BL31: PMIC: No AXP803 DT node, skipping initial setup.\n");
+		return;
+	}
+
+	if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL))
+		axp_setbits(0x8f, BIT(4));
+
+	/* descend into the "regulators" subnode */
+	node = fdt_first_subnode(fdt, node);
+
+	/* iterate over all regulators to find used ones */
+	for (node = fdt_first_subnode(fdt, node);
+	     node != -FDT_ERR_NOTFOUND;
+	     node = fdt_next_subnode(fdt, node)) {
+		struct axp_regulator *reg;
+		const char *name;
+		int length;
+
+		/* We only care if it's always on or referenced. */
+		if (!should_enable_regulator(fdt, node))
+			continue;
+
+		name = fdt_get_name(fdt, node, &length);
+		for (reg = regulators; reg->dt_name; reg++) {
+			if (!strncmp(name, reg->dt_name, length)) {
+				setup_regulator(fdt, node, reg);
+				break;
+			}
+		}
+
+		if (!strncmp(name, "dc1sw", length)) {
+			/* Delay DC1SW enablement to avoid overheating. */
+			dc1sw = true;
+			continue;
+		}
+	}
+	/*
+	 * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts
+	 * down. So always enable DC1SW as the very last regulator.
+	 */
+	if (dc1sw) {
+		INFO("PMIC: AXP803: Enabling DC1SW\n");
+		axp_setbits(0x12, BIT(7));
+	}
+}
+
+int sunxi_pmic_setup(uint16_t socid, const void *fdt)
+{
+	int ret;
+
+	switch (socid) {
+	case SUNXI_SOC_H5:
+		pmic = REF_DESIGN_H5;
+		NOTICE("BL31: PMIC: Defaulting to PortL GPIO according to H5 reference design.\n");
+		break;
+	case SUNXI_SOC_A64:
+		pmic = GENERIC_A64;
+		ret = sunxi_init_platform_r_twi(socid, true);
+		if (ret)
+			return ret;
+
+		ret = rsb_init();
+		if (ret)
+			return ret;
+
+		pmic = AXP803_RSB;
+		NOTICE("BL31: PMIC: Detected AXP803 on RSB.\n");
+
+		if (fdt)
+			setup_axp803_rails(fdt);
+
+		break;
+	default:
+		NOTICE("BL31: PMIC: No support for Allwinner %x SoC.\n", socid);
+		return -ENODEV;
+	}
+	return 0;
+}
+
 void __dead2 sunxi_power_down(void)
 {
-	ERROR("PSCI: Full shutdown not implemented, halting\n");
+	switch (pmic) {
+	case GENERIC_H5:
+		/* Turn off as many peripherals and clocks as we can. */
+		sunxi_turn_off_soc(SUNXI_SOC_H5);
+		/* Turn off the pin controller now. */
+		mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
+		break;
+	case GENERIC_A64:
+		/* Turn off as many peripherals and clocks as we can. */
+		sunxi_turn_off_soc(SUNXI_SOC_A64);
+		/* Turn off the pin controller now. */
+		mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
+		break;
+	case REF_DESIGN_H5:
+		sunxi_turn_off_soc(SUNXI_SOC_H5);
+
+		/*
+		 * Switch PL pins to power off the board:
+		 * - PL5 (VCC_IO) -> high
+		 * - PL8 (PWR-STB = CPU power supply) -> low
+		 * - PL9 (PWR-DRAM) ->low
+		 * - PL10 (power LED) -> low
+		 * Note: Clearing PL8 will reset the board, so keep it up.
+		 */
+		sunxi_set_gpio_out('L', 5, 1);
+		sunxi_set_gpio_out('L', 9, 0);
+		sunxi_set_gpio_out('L', 10, 0);
+
+		/* Turn off pin controller now. */
+		mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
+
+		break;
+	case AXP803_RSB:
+		/* (Re-)init RSB in case the rich OS has disabled it. */
+		sunxi_init_platform_r_twi(SUNXI_SOC_A64, true);
+		rsb_init();
+
+		/* Set "power disable control" bit */
+		axp_setbits(0x32, BIT(7));
+		break;
+	default:
+		break;
+	}
+
+	udelay(1000);
+	ERROR("PSCI: Cannot turn off system, halting.\n");
 	wfi();
 	panic();
 }
diff --git a/plat/allwinner/sun50i_h6/include/core_off_arisc.h b/plat/allwinner/sun50i_h6/include/core_off_arisc.h
new file mode 100644
index 0000000..63a5d8d
--- /dev/null
+++ b/plat/allwinner/sun50i_h6/include/core_off_arisc.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+static uint32_t arisc_core_off[] = {
+	0x18600000, /* l.movhi	r3, <corenr>	*/
+	0x18000000, /* l.movhi	r0, 0x0		*/
+	0x19a00901, /* l.movhi	r13, 0x901	*/
+	0x84ad0080, /* l.lwz	r5, 0x80(r13)	*/
+	0xe0a51803, /* l.and	r5, r5, r3	*/
+	0xe4050000, /* l.sfeq	r5, r0		*/
+	0x13fffffd, /* l.bf	-12		*/
+	0xb8c30050, /* l.srli	r6, r3, 16	*/
+
+	0xbc060001, /* l.sfeqi	r6, 1		*/
+	0x10000005, /* l.bf	+20		*/
+	0x19a00700, /* l.movhi	r13, 0x700	*/
+	0x84ad0444, /* l.lwz	r5, 0x0444(r13)	*/
+	0xe0a53004, /* l.or	r5, r5, r6	*/
+	0xd40d2c44, /* l.sw	0x0444(r13), r5	*/
+
+	0x84ad0440, /* l.lwz	r5, 0x0440(r13)	*/
+	0xacc6ffff, /* l.xori	r6, r6, -1	*/
+	0xe0a53003, /* l.and	r5, r5, r6	*/
+	0xd40d2c40, /* l.sw	0x0440(r13), r5	*/
+
+	0xe0c3000f, /* l.ff1	r6, r3		*/
+	0x9cc6ffef, /* l.addi	r6, r6, -17	*/
+	0xb8c60002, /* l.slli	r6, r6, 2	*/
+	0xe0c66800, /* l.add	r6, r6, r13	*/
+	0xa8a000ff, /* l.ori	r5, r0, 0xff	*/
+	0xd4062c50, /* l.sw	0x0450(r6), r5	*/
+
+	0xd40d0400, /* l.sw	0x0400(r13), r0	*/
+	0x03ffffff, /* l.j	-1		*/
+	0x15000000, /* l.nop			*/
+};
diff --git a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
index f2d5aed..ff1eb61 100644
--- a/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
+++ b/plat/allwinner/sun50i_h6/include/sunxi_mmap.h
@@ -11,7 +11,7 @@
 #define SUNXI_ROM_BASE			0x00000000
 #define SUNXI_ROM_SIZE			0x00010000
 #define SUNXI_SRAM_BASE			0x00020000
-#define SUNXI_SRAM_SIZE			0x00098000
+#define SUNXI_SRAM_SIZE			0x000f8000
 #define SUNXI_SRAM_A1_BASE		0x00020000
 #define SUNXI_SRAM_A1_SIZE		0x00008000
 #define SUNXI_SRAM_A2_BASE		0x00104000
@@ -21,7 +21,7 @@
 #define SUNXI_DEV_BASE			0x01000000
 #define SUNXI_DEV_SIZE			0x09000000
 #define SUNXI_DRAM_BASE			0x40000000
-#define SUNXI_DRAM_SIZE			0xc0000000
+#define SUNXI_DRAM_VIRT_BASE		0x0a000000
 
 /* Memory-mapped devices */
 #define SUNXI_SYSCON_BASE		0x03000000
diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk
index 4fb8986..5c21ead 100644
--- a/plat/allwinner/sun50i_h6/platform.mk
+++ b/plat/allwinner/sun50i_h6/platform.mk
@@ -4,53 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-include lib/xlat_tables_v2/xlat_tables.mk
-
-AW_PLAT			:=	plat/allwinner
-AW_DRIVERS		:=	drivers/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/mentor/i2c/mi2cv.c		\
-				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}/sun50i_h6/sunxi_power.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
-
-MULTI_CONSOLE_API		:=	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
+# The differences between the platform are covered by the include files.
+include plat/allwinner/common/allwinner-common.mk
 
-# BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
-RESET_TO_BL31			:=	1
+PLAT_BL_COMMON_SOURCES	+=	drivers/mentor/i2c/mi2cv.c
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index 12438b3..7bdac8a 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -12,7 +12,9 @@
 #include <mmio.h>
 #include <mentor/mi2cv.h>
 #include <string.h>
+#include <sunxi_def.h>
 #include <sunxi_mmap.h>
+#include <sunxi_private.h>
 
 #define AXP805_ADDR	0x36
 #define AXP805_ID	0x03
@@ -24,36 +26,6 @@
 
 enum pmic_type pmic;
 
-static int sunxi_init_r_i2c(void)
-{
-	uint32_t reg;
-
-	/* switch pins PL0 and PL1 to I2C */
-	reg = mmio_read_32(SUNXI_R_PIO_BASE + 0x00);
-	mmio_write_32(SUNXI_R_PIO_BASE + 0x00, (reg & ~0xff) | 0x33);
-
-	/* level 2 drive strength */
-	reg = mmio_read_32(SUNXI_R_PIO_BASE + 0x14);
-	mmio_write_32(SUNXI_R_PIO_BASE + 0x14, (reg & ~0x0f) | 0xa);
-
-	/* set both ports to pull-up */
-	reg = mmio_read_32(SUNXI_R_PIO_BASE + 0x1c);
-	mmio_write_32(SUNXI_R_PIO_BASE + 0x1c, (reg & ~0x0f) | 0x5);
-
-	/* assert & de-assert reset of R_I2C */
-	reg = mmio_read_32(SUNXI_R_PRCM_BASE + 0x19c);
-	mmio_write_32(SUNXI_R_PRCM_BASE + 0x19c, reg & ~BIT(16));
-	mmio_write_32(SUNXI_R_PRCM_BASE + 0x19c, reg | BIT(16));
-
-	/* un-gate R_I2C clock */
-	mmio_write_32(SUNXI_R_PRCM_BASE + 0x19c, reg | BIT(16) | BIT(0));
-
-	/* call mi2cv driver */
-	i2c_init((void *)SUNXI_R_I2C_BASE);
-
-	return 0;
-}
-
 int axp_i2c_read(uint8_t chip, uint8_t reg, uint8_t *val)
 {
 	int ret;
@@ -96,11 +68,13 @@
 	return 0;
 }
 
-int sunxi_pmic_setup(void)
+int sunxi_pmic_setup(uint16_t socid, const void *fdt)
 {
 	int ret;
 
-	sunxi_init_r_i2c();
+	sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+	/* initialise mi2cv driver */
+	i2c_init((void *)SUNXI_R_I2C_BASE);
 
 	NOTICE("PMIC: Probing AXP805\n");
 	pmic = AXP805;
@@ -120,7 +94,10 @@
 
 	switch (pmic) {
 	case AXP805:
-		sunxi_init_r_i2c();
+		/* Re-initialise after rich OS might have used it. */
+		sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+		/* initialise mi2cv driver */
+		i2c_init((void *)SUNXI_R_I2C_BASE);
 		axp_i2c_read(AXP805_ADDR, 0x32, &val);
 		axp_i2c_write(AXP805_ADDR, 0x32, val | 0x80);
 		break;
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 88fcdb1..abc3ceb 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -19,7 +19,7 @@
 	.globl	plat_arm_calc_core_pos
 
 	.macro	fvp_choose_gicmmap  param1, param2, x_tmp, w_tmp, res
-	ldr	\x_tmp, =V2M_SYSREGS_BASE + V2M_SYS_ID
+	mov_imm	\x_tmp, V2M_SYSREGS_BASE + V2M_SYS_ID
 	ldr	\w_tmp, [\x_tmp]
 	ubfx	\w_tmp, \w_tmp, #V2M_SYS_ID_BLD_SHIFT, #V2M_SYS_ID_BLD_LENGTH
 	cmp	\w_tmp, #BLD_GIC_VE_MMAP
@@ -48,7 +48,7 @@
 	 * ---------------------------------------------
 	 */
 	mrs	x0, mpidr_el1
-	ldr	x1, =PWRC_BASE
+	mov_imm	x1, PWRC_BASE
 	str	w0, [x1, #PPOFFR_OFF]
 
 	/* ---------------------------------------------
@@ -72,8 +72,8 @@
 	b	secondary_cold_boot_wait
 
 gicv2_bypass_disable:
-	ldr	x0, =VE_GICC_BASE
-	ldr	x1, =BASE_GICC_BASE
+	mov_imm	x0, VE_GICC_BASE
+	mov_imm	x1, BASE_GICC_BASE
 	fvp_choose_gicmmap	x0, x1, x2, w2, x1
 	mov	w0, #(IRQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP1)
 	orr	w0, w0, #(IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP0)
@@ -128,7 +128,7 @@
 	 * ---------------------------------------------------------------------
 	 */
 	mrs	x2, mpidr_el1
-	ldr	x1, =PWRC_BASE
+	mov_imm	x1, PWRC_BASE
 	str	w2, [x1, #PSYSR_OFF]
 	ldr	w2, [x1, #PSYSR_OFF]
 	ubfx	w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH
@@ -171,7 +171,7 @@
 	 */
 func plat_is_my_cpu_primary
 	mrs	x0, mpidr_el1
-	ldr	x1, =MPIDR_AFFINITY_MASK
+	mov_imm	x1, MPIDR_AFFINITY_MASK
 	and	x0, x0, x1
 	cmp	x0, #FVP_PRIMARY_CPU
 	cset	w0, eq
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index aa4f839..f5198f6 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -7,7 +7,6 @@
 #include <arm_config.h>
 #include <arm_def.h>
 #include <arm_spm_def.h>
-#include <arm_xlat_tables.h>
 #include <assert.h>
 #include <cci.h>
 #include <ccn.h>
@@ -18,6 +17,8 @@
 #include <platform.h>
 #include <secure_partition.h>
 #include <v2m_def.h>
+#include <xlat_tables_compat.h>
+
 #include "../fvp_def.h"
 #include "fvp_private.h"
 
@@ -52,8 +53,8 @@
 
 /*
  * Table of memory regions for various BL stages to map using the MMU.
- * This doesn't include Trusted SRAM as arm_setup_page_tables() already
- * takes care of mapping it.
+ * This doesn't include Trusted SRAM as setup_page_tables() already takes care
+ * of mapping it.
  *
  * The flash needs to be mapped as writable in order to erase the FIP's Table of
  * Contents in case of unrecoverable error (see plat_error_handler()).
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 332df4d..3d858c2 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -202,7 +202,9 @@
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
 # Enable reclaiming of BL31 initialisation code for secondary cores stacks for FVP
+ifneq (${RESET_TO_BL31},1)
 RECLAIM_INIT_CODE	:=	1
+endif
 
 ifeq (${ENABLE_AMU},1)
 BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a75_pubsub.c	\
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index 40b1a27..2e6b011 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -8,8 +8,8 @@
 
 /*
  * Table of memory regions for different BL stages to map using the MMU.
- * This doesn't include Trusted SRAM as arm_setup_page_tables() already
- * takes care of mapping it.
+ * This doesn't include Trusted SRAM as setup_page_tables() already takes care
+ * of mapping it.
  */
 #ifdef IMAGE_BL1
 const mmap_region_t plat_arm_mmap[] = {
diff --git a/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S
new file mode 100644
index 0000000..6eb01aa
--- /dev/null
+++ b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cortex_ares.h>
+#include <cpu_macros.S>
+#include <platform_def.h>
+
+	.globl	plat_arm_calc_core_pos
+	.globl	plat_reset_handler
+
+	/* -----------------------------------------------------
+	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+	 *
+	 * Helper function to calculate the core position.
+	 * (ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER * N1SDP_MAX_PE_PER_CPU) +
+	 * (CPUId * N1SDP_MAX_PE_PER_CPU) +
+	 * ThreadId
+	 *
+	 * which can be simplified as:
+	 *
+	 * ((ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER + CPUId) *
+	 * N1SDP_MAX_PE_PER_CPU) + ThreadId
+	 * ------------------------------------------------------
+	 */
+
+func plat_arm_calc_core_pos
+	mov	x3, x0
+
+	/*
+	 * The MT bit in MPIDR is always set for n1sdp and the
+	 * affinity level 0 corresponds to thread affinity level.
+	 */
+
+	/* Extract individual affinity fields from MPIDR */
+	ubfx	x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+	/* Compute linear position */
+	mov	x4, #N1SDP_MAX_CPUS_PER_CLUSTER
+	madd	x1, x2, x4, x1
+	mov	x5, #N1SDP_MAX_PE_PER_CPU
+	madd	x0, x1, x5, x0
+	ret
+endfunc plat_arm_calc_core_pos
+
+	/* -----------------------------------------------------
+	 * void plat_reset_handler(void);
+	 *
+	 * Determine the CPU MIDR and disable power down bit for
+	 * that CPU.
+	 * -----------------------------------------------------
+	 */
+
+func plat_reset_handler
+	jump_if_cpu_midr CORTEX_ARES_MIDR, ARES
+	ret
+
+	/* -----------------------------------------------------
+	 * Disable CPU power down bit in power control register
+	 * -----------------------------------------------------
+	 */
+ARES:
+	mrs	x0, CORTEX_ARES_CPUPWRCTLR_EL1
+	bic	x0, x0, #CORTEX_ARES_CORE_PWRDN_EN_MASK
+	msr	CORTEX_ARES_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc plat_reset_handler
diff --git a/plat/arm/board/n1sdp/include/plat_macros.S b/plat/arm/board/n1sdp/include/plat_macros.S
new file mode 100644
index 0000000..fe9a66c
--- /dev/null
+++ b/plat/arm/board/n1sdp/include/plat_macros.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <css_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ *
+ * There are currently no platform specific regs
+ * to print.
+ * ---------------------------------------------
+ */
+	.macro plat_crash_print_regs
+	.endm
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
new file mode 100644
index 0000000..d26f559
--- /dev/null
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arm_def.h>
+#include <board_css_def.h>
+#include <css_def.h>
+
+#if CSS_USE_SCMI_SDS_DRIVER
+#define N1SDP_SCMI_PAYLOAD_BASE			0x45400000
+#else
+#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE	0x45400000
+#endif
+
+#define PLAT_ARM_TRUSTED_SRAM_SIZE		0x00080000	/* 512 KB */
+#define PLAT_ARM_MAX_BL31_SIZE			0X20000
+
+
+/*******************************************************************************
+ * N1SDP topology related constants
+ ******************************************************************************/
+#define N1SDP_MAX_CPUS_PER_CLUSTER		2
+#define PLAT_ARM_CLUSTER_COUNT			2
+#define N1SDP_MAX_PE_PER_CPU			1
+
+#define PLATFORM_CORE_COUNT			(PLAT_ARM_CLUSTER_COUNT *	\
+						N1SDP_MAX_CPUS_PER_CLUSTER *	\
+						N1SDP_MAX_PE_PER_CPU)
+
+
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#define PLAT_ARM_MMAP_ENTRIES			3
+#define MAX_XLAT_TABLES				4
+
+#define PLATFORM_STACK_SIZE			0x400
+
+#define PLAT_ARM_NSTIMER_FRAME_ID		0
+#define PLAT_CSS_MHU_BASE			0x45000000
+#define PLAT_MAX_PWR_LVL			1
+
+#define PLAT_ARM_G1S_IRQS			ARM_G1S_IRQS,			\
+						CSS_IRQ_MHU
+#define PLAT_ARM_G0_IRQS			ARM_G0_IRQS
+
+#define PLAT_ARM_G1S_IRQ_PROPS(grp)		CSS_G1S_IRQ_PROPS(grp)
+#define PLAT_ARM_G0_IRQ_PROPS(grp)		ARM_G0_IRQ_PROPS(grp)
+
+
+#define N1SDP_DEVICE_BASE			(0x20000000)
+#define N1SDP_DEVICE_SIZE			(0x20000000)
+#define N1SDP_MAP_DEVICE			MAP_REGION_FLAT(	\
+						N1SDP_DEVICE_BASE,	\
+						N1SDP_DEVICE_SIZE,	\
+						MT_DEVICE | MT_RW | MT_SECURE)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE			0x30000000
+#define PLAT_ARM_GICC_BASE			0x2C000000
+#define PLAT_ARM_GICR_BASE			0x300C0000
+
+/* Platform ID address */
+#define SSC_VERSION				(SSC_REG_BASE + SSC_VERSION_OFFSET)
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
new file mode 100644
index 0000000..65aad9c
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "../../css/drivers/scmi/scmi.h"
+#include "../../css/drivers/mhu/css_mhu_doorbell.h"
+#include <platform_def.h>
+
+static scmi_channel_plat_info_t n1sdp_scmi_plat_info = {
+		.scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE,
+		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
+		.db_preserve_mask = 0xfffffffe,
+		.db_modify_mask = 0x1,
+		.ring_doorbell = &mhu_ring_doorbell,
+};
+
+scmi_channel_plat_info_t *plat_css_get_scmi_info()
+{
+	return &n1sdp_scmi_plat_info;
+}
diff --git a/plat/arm/board/n1sdp/n1sdp_interconnect.c b/plat/arm/board/n1sdp/n1sdp_interconnect.c
new file mode 100644
index 0000000..908f41c
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_interconnect.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*
+ * For N1SDP which support FCM (with automatic interconnect enter/exit),
+ * we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers.
+ */
+
+/******************************************************************************
+ * Helper function to initialize ARM interconnect driver.
+ *****************************************************************************/
+void plat_arm_interconnect_init(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to place current master into coherency
+ *****************************************************************************/
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to remove current master from coherency
+ *****************************************************************************/
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
new file mode 100644
index 0000000..8c057c5
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_plat.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_def.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <platform.h>
+#include <platform_def.h>
+
+/*
+ * Table of regions to map using the MMU.
+ * Replace or extend the below regions as required
+ */
+
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	N1SDP_MAP_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	{0}
+};
+
diff --git a/plat/arm/board/n1sdp/n1sdp_security.c b/plat/arm/board/n1sdp/n1sdp_security.c
new file mode 100644
index 0000000..d2a187b
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_security.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * TZC programming is currently not done.
+ */
+void plat_arm_security_setup(void)
+{
+}
diff --git a/plat/arm/board/n1sdp/n1sdp_topology.c b/plat/arm/board/n1sdp/n1sdp_topology.c
new file mode 100644
index 0000000..c3b4550
--- /dev/null
+++ b/plat/arm/board/n1sdp/n1sdp_topology.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_arm.h>
+
+/* Topology */
+typedef struct n1sdp_topology {
+	const unsigned char *power_tree;
+	unsigned int plat_cluster_core_count;
+} n1sdp_topology_t;
+
+/*
+ * The power domain tree descriptor. The cluster power domains are
+ * arranged so that when the PSCI generic code creates the power domain tree,
+ * the indices of the CPU power domain nodes it allocates match the linear
+ * indices returned by plat_core_pos_by_mpidr().
+ */
+const unsigned char n1sdp_pd_tree_desc[] = {
+	PLAT_ARM_CLUSTER_COUNT,
+	N1SDP_MAX_CPUS_PER_CLUSTER,
+	N1SDP_MAX_CPUS_PER_CLUSTER
+};
+
+/* Topology configuration for n1sdp */
+const n1sdp_topology_t n1sdp_topology = {
+	.power_tree = n1sdp_pd_tree_desc,
+	.plat_cluster_core_count = N1SDP_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return n1sdp_topology.power_tree;
+}
+
+/*******************************************************************************
+ * This function returns the core count within the cluster corresponding to
+ * `mpidr`.
+ ******************************************************************************/
+unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
+{
+	return n1sdp_topology.plat_cluster_core_count;
+}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
+	0, 1, 2, 3};
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
new file mode 100644
index 0000000..c9acb49
--- /dev/null
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+N1SDP_BASE		:=	plat/arm/board/n1sdp
+
+INTERCONNECT_SOURCES	:=	${N1SDP_BASE}/n1sdp_interconnect.c
+
+PLAT_INCLUDES		:=	-I${N1SDP_BASE}/include
+
+
+N1SDP_CPU_SOURCES	:=	lib/cpus/aarch64/cortex_ares.S
+
+
+N1SDP_GIC_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
+				drivers/arm/gic/v3/gicv3_main.c		\
+				drivers/arm/gic/v3/gicv3_helpers.c	\
+				plat/common/plat_gicv3.c		\
+				plat/arm/common/arm_gicv3.c		\
+				drivers/arm/gic/v3/gic600.c
+
+PLAT_BL_COMMON_SOURCES	:=	${N1SDP_BASE}/n1sdp_plat.c	        \
+				${N1SDP_BASE}/aarch64/n1sdp_helper.S
+
+
+BL31_SOURCES		:=	${N1SDP_CPU_SOURCES}			\
+				${INTERCONNECT_SOURCES}			\
+				${N1SDP_GIC_SOURCES}			\
+				${N1SDP_BASE}/n1sdp_bl31_setup.c	        \
+				${N1SDP_BASE}/n1sdp_topology.c	        \
+				${N1SDP_BASE}/n1sdp_security.c
+
+
+# TF-A not required to load the SCP Images
+override CSS_LOAD_SCP_IMAGES	  	:=	0
+
+# BL1/BL2 Image not a part of the capsule Image for n1sdp
+override NEED_BL1		  	:=	no
+override NEED_BL2		  	:=	no
+override NEED_BL2U		  	:=	no
+
+#TFA for n1sdp starts from BL31
+override RESET_TO_BL31            	:=	1
+
+# 32 bit mode not supported
+override CTX_INCLUDE_AARCH32_REGS 	:=	0
+
+override ARM_PLAT_MT              	:=	1
+
+# Select SCMI/SDS drivers instead of SCPI/BOM driver for communicating with the
+# SCP during power management operations and for SCP RAM Firmware transfer.
+CSS_USE_SCMI_SDS_DRIVER		  	:=	1
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY			:=	1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM			:=	0
+include plat/arm/common/arm_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/soc/common/soc_css.mk
+include plat/arm/board/common/board_common.mk
+
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 717e96f..f760e18 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -6,7 +6,6 @@
 
 #include <arch.h>
 #include <arm_def.h>
-#include <arm_xlat_tables.h>
 #include <assert.h>
 #include <bl1.h>
 #include <bl_common.h>
@@ -15,6 +14,8 @@
 #include <platform_def.h>
 #include <sp805.h>
 #include <utils.h>
+#include <xlat_tables_compat.h>
+
 #include "../../../bl1/bl1_private.h"
 
 /* Weak definitions may be overridden in specific ARM standard platform */
@@ -122,7 +123,7 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 #ifdef AARCH32
 	enable_mmu_svc_mon(0);
 #else
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index c67ab49..4f5e6a9 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -79,7 +79,7 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 
 #ifdef AARCH32
 	enable_mmu_svc_mon(0);
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index d31f6dc..628a50d 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -125,7 +125,7 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 
 #ifdef AARCH32
 	enable_mmu_svc_mon(0);
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index b518f0f..3848aa0 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -80,7 +80,7 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 
 #ifdef AARCH32
 	enable_mmu_svc_mon(0);
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index e218c2f..1b05f46 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -16,7 +16,7 @@
 #include <platform.h>
 #include <ras.h>
 #include <utils.h>
-#include <arm_xlat_tables.h>
+#include <xlat_tables_compat.h>
 
 /*
  * Placeholder variables for copying the arguments that have been passed to
@@ -25,11 +25,13 @@
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
 
+#if !RESET_TO_BL31
 /*
  * Check that BL31_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page
  * is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
  */
 CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
+#endif
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak bl31_early_platform_setup2
@@ -38,8 +40,8 @@
 #pragma weak bl31_plat_get_next_image_ep_info
 
 #define MAP_BL31_TOTAL		MAP_REGION_FLAT(			\
-					BL31_BASE,			\
-					BL31_END - BL31_BASE,		\
+					BL31_START,			\
+					BL31_END - BL31_START,		\
 					MT_MEMORY | MT_RW | MT_SECURE)
 #if RECLAIM_INIT_CODE
 IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE);
@@ -302,7 +304,7 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 
 	enable_mmu_el3(0);
 
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index a21d189..6b14785 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -5,7 +5,6 @@
  */
 #include <arch.h>
 #include <arch_helpers.h>
-#include <arm_xlat_tables.h>
 #include <assert.h>
 #include <debug.h>
 #include <mmio.h>
@@ -14,6 +13,7 @@
 #include <platform_def.h>
 #include <romlib.h>
 #include <secure_partition.h>
+#include <xlat_tables_compat.h>
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak plat_get_ns_image_entrypoint
@@ -32,42 +32,6 @@
 #endif
 }
 
-/*
- * Set up the page tables for the generic and platform-specific memory regions.
- * The size of the Trusted SRAM seen by the BL image must be specified as well
- * as an array specifying the generic memory regions which can be;
- * - Code section;
- * - Read-only data section;
- * - Init code section, if applicable
- * - Coherent memory region, if applicable.
- */
-
-void __init arm_setup_page_tables(const mmap_region_t bl_regions[],
-			   const mmap_region_t plat_regions[])
-{
-#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
-	const mmap_region_t *regions = bl_regions;
-
-	while (regions->size != 0U) {
-		VERBOSE("Region: 0x%lx - 0x%lx has attributes 0x%x\n",
-				regions->base_va,
-				(regions->base_va + regions->size),
-				regions->attr);
-		regions++;
-	}
-#endif
-	/*
-	 * Map the Trusted SRAM with appropriate memory attributes.
-	 * Subsequent mappings will adjust the attributes for specific regions.
-	 */
-	mmap_add(bl_regions);
-	/* Now (re-)map the platform-specific memory regions */
-	mmap_add(plat_regions);
-
-	/* Create the page tables to reflect the above mappings */
-	init_xlat_tables();
-}
-
 uintptr_t plat_get_ns_image_entrypoint(void)
 {
 #ifdef PRELOADED_BL33_BASE
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 3fb1eff..23777fb 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -130,6 +130,11 @@
 $(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG))
 $(eval $(call add_define,ARM_CRYPTOCELL_INTEG))
 
+# Enable PIE support for RESET_TO_BL31 case
+ifeq (${RESET_TO_BL31},1)
+    ENABLE_PIE			:=	1
+endif
+
 # CryptoCell integration relies on coherent buffers for passing data from
 # the AP CPU to the CryptoCell
 ifeq (${ARM_CRYPTOCELL_INTEG},1)
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index e9e8a74..a43bff3 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -10,6 +10,7 @@
 #include <plat_arm.h>
 #include <platform.h>
 #include <platform_def.h>
+#include <utils.h>
 
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
@@ -33,10 +34,16 @@
 
 /*
  * We save and restore the GICv3 context on system suspend. Allocate the
- * data in the designated EL3 Secure carve-out memory
+ * data in the designated EL3 Secure carve-out memory. The `volatile`
+ * is used to prevent the compiler from removing the gicv3 contexts even
+ * though the DEFINE_LOAD_SYM_ADDR creates a dummy reference to it.
  */
-static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram");
-static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram");
+static volatile gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram");
+static volatile gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram");
+
+/* Define accessor function to get reference to the GICv3 context */
+DEFINE_LOAD_SYM_ADDR(rdist_ctx)
+DEFINE_LOAD_SYM_ADDR(dist_ctx)
 
 /*
  * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
@@ -134,6 +141,10 @@
  *****************************************************************************/
 void plat_arm_gic_save(void)
 {
+	gicv3_redist_ctx_t * const rdist_context =
+			(gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx);
+	gicv3_dist_ctx_t * const dist_context =
+			(gicv3_dist_ctx_t *)LOAD_ADDR_OF(dist_ctx);
 
 	/*
 	 * If an ITS is available, save its context before
@@ -149,10 +160,10 @@
 	 * we only need to save the context of the CPU that is issuing
 	 * the SYSTEM SUSPEND call, i.e. the current CPU.
 	 */
-	gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
+	gicv3_rdistif_save(plat_my_core_pos(), rdist_context);
 
 	/* Save the GIC Distributor context */
-	gicv3_distif_save(&dist_ctx);
+	gicv3_distif_save(dist_context);
 
 	/*
 	 * From here, all the components of the GIC can be safely powered down
@@ -163,8 +174,13 @@
 
 void plat_arm_gic_resume(void)
 {
+	const gicv3_redist_ctx_t *rdist_context =
+			(gicv3_redist_ctx_t *)LOAD_ADDR_OF(rdist_ctx);
+	const gicv3_dist_ctx_t *dist_context =
+			(gicv3_dist_ctx_t *)LOAD_ADDR_OF(dist_ctx);
+
 	/* Restore the GIC Distributor context */
-	gicv3_distif_init_restore(&dist_ctx);
+	gicv3_distif_init_restore(dist_context);
 
 	/*
 	 * Restore the GIC Redistributor and ITS contexts after the
@@ -172,7 +188,7 @@
 	 * we only need to restore the context of the CPU that issued
 	 * the SYSTEM SUSPEND call.
 	 */
-	gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
+	gicv3_rdistif_init_restore(plat_my_core_pos(), rdist_context);
 
 	/*
 	 * If an ITS is available, restore its context after
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index e450c6f..e482a89 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -58,7 +58,7 @@
 
 		/* Validate supplied entry point */
 		pc = (u_register_t) ((x1 << 32) | (uint32_t) x2);
-		if (arm_validate_ns_entrypoint(pc))
+		if (arm_validate_ns_entrypoint(pc) != 0)
 			SMC_RET1(handle, STATE_SW_E_PARAM);
 
 		/*
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index b8234c1..e151073 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -208,7 +208,7 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 
 	enable_mmu_svc_mon(0);
 }
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index 2d42d8e..3cf8825 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -85,6 +85,6 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 	enable_mmu_el1(0);
 }
diff --git a/plat/arm/css/common/aarch64/css_helpers.S b/plat/arm/css/common/aarch64/css_helpers.S
index 59d9206..5096d8d 100644
--- a/plat/arm/css/common/aarch64/css_helpers.S
+++ b/plat/arm/css/common/aarch64/css_helpers.S
@@ -108,7 +108,7 @@
 func plat_is_my_cpu_primary
 	mov	x9, x30
 	bl	plat_my_core_pos
-	ldr	x1, =SCP_BOOT_CFG_ADDR
+	mov_imm	x1, SCP_BOOT_CFG_ADDR
 	ldr	x1, [x1]
 	ubfx	x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \
 			#PLAT_CSS_PRIMARY_CPU_BIT_WIDTH
diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c
index 264d518..4cf1cc5 100644
--- a/plat/common/plat_bl_common.c
+++ b/plat/common/plat_bl_common.c
@@ -13,6 +13,7 @@
 #include <mbedtls_config.h>
 #endif
 #include <platform.h>
+#include <xlat_tables_compat.h>
 
 /*
  * The following platform functions are weakly defined. The Platforms
@@ -72,3 +73,40 @@
 	return 0;
 }
 #endif /* TRUSTED_BOARD_BOOT */
+
+/*
+ * Set up the page tables for the generic and platform-specific memory regions.
+ * The size of the Trusted SRAM seen by the BL image must be specified as well
+ * as an array specifying the generic memory regions which can be;
+ * - Code section;
+ * - Read-only data section;
+ * - Init code section, if applicable
+ * - Coherent memory region, if applicable.
+ */
+
+void __init setup_page_tables(const mmap_region_t *bl_regions,
+			      const mmap_region_t *plat_regions)
+{
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+	const mmap_region_t *regions = bl_regions;
+
+	while (regions->size != 0U) {
+		VERBOSE("Region: 0x%lx - 0x%lx has attributes 0x%x\n",
+				regions->base_va,
+				regions->base_va + regions->size,
+				regions->attr);
+		regions++;
+	}
+#endif
+	/*
+	 * Map the Trusted SRAM with appropriate memory attributes.
+	 * Subsequent mappings will adjust the attributes for specific regions.
+	 */
+	mmap_add(bl_regions);
+
+	/* Now (re-)map the platform-specific memory regions */
+	mmap_add(plat_regions);
+
+	/* Create the page tables to reflect the above mappings */
+	init_xlat_tables();
+}
diff --git a/plat/hisilicon/poplar/aarch64/poplar_helpers.S b/plat/hisilicon/poplar/aarch64/poplar_helpers.S
new file mode 100644
index 0000000..928dbef
--- /dev/null
+++ b/plat/hisilicon/poplar/aarch64/poplar_helpers.S
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_macros.S>
+#include <platform_def.h>
+
+	.globl	plat_my_core_pos
+	.globl	poplar_calc_core_pos
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	plat_crash_console_flush
+	.globl	platform_mem_init
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *  This function uses poplar_calc_core_pos()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	poplar_calc_core_pos
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int poplar_calc_core_pos(u_register_t mpidr)
+	 *  Helper function to calculate the core position.
+	 *  With this function: CorePos = (ClusterId * 4) +
+	 *  				  CoreId
+	 * -----------------------------------------------------
+	 */
+func poplar_calc_core_pos
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+endfunc poplar_calc_core_pos
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize the crash console
+	 * without a C Runtime to print crash report.
+	 * Clobber list : x0 - x4
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+	mov_imm	x0, POPLAR_CRASH_UART_BASE
+	mov_imm	x1, POPLAR_CRASH_UART_CLK_IN_HZ
+	mov_imm	x2, POPLAR_CONSOLE_BAUDRATE
+	b	console_pl011_core_init
+endfunc plat_crash_console_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to print a character on the crash
+	 * console without a C Runtime.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, POPLAR_CRASH_UART_BASE
+	b	console_pl011_core_putc
+endfunc plat_crash_console_putc
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_flush()
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : r0
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_flush
+	mov_imm	x0, POPLAR_CRASH_UART_BASE
+	b	console_pl011_core_flush
+endfunc plat_crash_console_flush
+
+	/* ---------------------------------------------------------------------
+	 * We don't need to carry out any memory initialization on ARM
+	 * platforms. The Secure RAM is accessible straight away.
+	 * ---------------------------------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c
index 83803a6..20a613d 100644
--- a/plat/hisilicon/poplar/bl31_plat_setup.c
+++ b/plat/hisilicon/poplar/bl31_plat_setup.c
@@ -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
  */
@@ -15,13 +15,12 @@
 #include <errno.h>
 #include <generic_delay_timer.h>
 #include <mmio.h>
-#include <plat_arm.h>
 #include <platform.h>
+#include <platform_def.h>
 #include <stddef.h>
 #include <string.h>
 #include "hi3798cv200.h"
 #include "plat_private.h"
-#include "platform_def.h"
 
 /* Memory ranges for code and RO data sections */
 #define BL31_RO_BASE	(unsigned long)(&__RO_START__)
@@ -113,8 +112,8 @@
 	generic_delay_timer_init();
 
 	/* Init GIC distributor and CPU interface */
-	plat_arm_gic_driver_init();
-	plat_arm_gic_init();
+	poplar_gic_driver_init();
+	poplar_gic_init();
 
 	/* Init security properties of IP blocks */
 	hisi_tzpc_sec_init();
diff --git a/plat/hisilicon/poplar/include/plat_private.h b/plat/hisilicon/poplar/include/plat_private.h
index 845b1bd..63b7d76 100644
--- a/plat/hisilicon/poplar/include/plat_private.h
+++ b/plat/hisilicon/poplar/include/plat_private.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
  */
@@ -26,4 +26,11 @@
 
 void plat_io_setup(void);
 
+unsigned int poplar_calc_core_pos(u_register_t mpidr);
+
+void poplar_gic_driver_init(void);
+void poplar_gic_init(void);
+void poplar_gic_cpuif_enable(void);
+void poplar_gic_pcpu_init(void);
+
 #endif /* __PLAT_PRIVATE_H__ */
diff --git a/plat/hisilicon/poplar/include/platform_def.h b/plat/hisilicon/poplar/include/platform_def.h
index 99fd996..6287a76 100644
--- a/plat/hisilicon/poplar/include/platform_def.h
+++ b/plat/hisilicon/poplar/include/platform_def.h
@@ -22,9 +22,9 @@
 #define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
 #define PLATFORM_LINKER_ARCH		aarch64
 
-#define PLAT_ARM_CRASH_UART_BASE	PL011_UART0_BASE
-#define PLAT_ARM_CRASH_UART_CLK_IN_HZ	PL011_UART0_CLK_IN_HZ
-#define ARM_CONSOLE_BAUDRATE		PL011_BAUDRATE
+#define POPLAR_CRASH_UART_BASE		PL011_UART0_BASE
+#define POPLAR_CRASH_UART_CLK_IN_HZ	PL011_UART0_CLK_IN_HZ
+#define POPLAR_CONSOLE_BAUDRATE		PL011_BAUDRATE
 
 /* Generic platform constants */
 #define PLATFORM_STACK_SIZE		(0x800)
@@ -134,10 +134,10 @@
 #define PLAT_MAX_RET_STATE		U(1)
 
 /* Interrupt controller */
-#define PLAT_ARM_GICD_BASE	GICD_BASE
-#define PLAT_ARM_GICC_BASE	GICC_BASE
+#define POPLAR_GICD_BASE	GICD_BASE
+#define POPLAR_GICC_BASE	GICC_BASE
 
-#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+#define POPLAR_G1S_IRQ_PROPS(grp) \
 	INTR_PROP_DESC(HISI_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL), \
 	INTR_PROP_DESC(HISI_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
@@ -165,6 +165,6 @@
 	INTR_PROP_DESC(HISI_IRQ_SEC_AXI, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_LEVEL)
 
-#define PLAT_ARM_G0_IRQ_PROPS(grp)
+#define POPLAR_G0_IRQ_PROPS(grp)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/hisilicon/poplar/plat_pm.c b/plat/hisilicon/poplar/plat_pm.c
index e59cac9..dcbcec4 100644
--- a/plat/hisilicon/poplar/plat_pm.c
+++ b/plat/hisilicon/poplar/plat_pm.c
@@ -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
  */
@@ -12,12 +12,11 @@
 #include <context_mgmt.h>
 #include <debug.h>
 #include <mmio.h>
-#include <plat_arm.h>
 #include <platform.h>
+#include <platform_def.h>
 #include <psci.h>
 #include "hi3798cv200.h"
 #include "plat_private.h"
-#include "platform_def.h"
 
 #define REG_PERI_CPU_RVBARADDR		0xF8A80034
 #define REG_PERI_CPU_AARCH_MODE		0xF8A80030
@@ -76,10 +75,10 @@
 					PLAT_MAX_OFF_STATE);
 
 	/* Enable the gic cpu interface */
-	plat_arm_gic_pcpu_init();
+	poplar_gic_pcpu_init();
 
 	/* Program the gic per-cpu distributor or re-distributor interface */
-	plat_arm_gic_cpuif_enable();
+	poplar_gic_cpuif_enable();
 }
 
 static void poplar_pwr_domain_suspend_finish(
diff --git a/plat/hisilicon/poplar/plat_topology.c b/plat/hisilicon/poplar/plat_topology.c
index 3dd818e..bb53c6b 100644
--- a/plat/hisilicon/poplar/plat_topology.c
+++ b/plat/hisilicon/poplar/plat_topology.c
@@ -1,13 +1,13 @@
 /*
- * 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
  */
 
 #include <arch.h>
-#include <plat_arm.h>
 #include <psci.h>
 #include "platform_def.h"
+#include "plat_private.h"
 
 const unsigned char hisi_power_domain_tree_desc[] = {
 	PLATFORM_CLUSTER_COUNT,
@@ -27,5 +27,5 @@
 	if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT)
 		return -1;
 
-	return plat_arm_calc_core_pos(mpidr);
+	return poplar_calc_core_pos(mpidr);
 }
diff --git a/plat/hisilicon/poplar/platform.mk b/plat/hisilicon/poplar/platform.mk
index 9d2b617..de262ad 100644
--- a/plat/hisilicon/poplar/platform.mk
+++ b/plat/hisilicon/poplar/platform.mk
@@ -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
 #
@@ -53,7 +53,6 @@
 $(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
 
 PLAT_INCLUDES	:=	-Iplat/hisilicon/poplar/include		\
-			-Iinclude/plat/arm/common/		\
 			-Iplat/hisilicon/poplar			\
 			-Iinclude/common/tbbr			\
 			-Iinclude/drivers/synopsys		\
@@ -68,10 +67,10 @@
 		drivers/delay_timer/delay_timer.c			\
 		drivers/arm/pl011/aarch64/pl011_console.S		\
 		drivers/arm/gic/v2/gicv2_main.c				\
-		plat/arm/common/aarch64/arm_helpers.S			\
-		plat/arm/common/arm_gicv2.c				\
 		plat/common/plat_gicv2.c				\
-		plat/hisilicon/poplar/aarch64/platform_common.c
+		plat/hisilicon/poplar/aarch64/platform_common.c		\
+		plat/hisilicon/poplar/aarch64/poplar_helpers.S		\
+		plat/hisilicon/poplar/poplar_gicv2.c
 
 BL1_SOURCES	+=							\
 		lib/cpus/aarch64/cortex_a53.S				\
diff --git a/plat/hisilicon/poplar/poplar_gicv2.c b/plat/hisilicon/poplar/poplar_gicv2.c
new file mode 100644
index 0000000..1c1be47
--- /dev/null
+++ b/plat/hisilicon/poplar/poplar_gicv2.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <gicv2.h>
+#include <platform.h>
+#include <platform_def.h>
+
+/******************************************************************************
+ * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
+ * interrupts.
+ *****************************************************************************/
+static const interrupt_prop_t poplar_interrupt_props[] = {
+	POPLAR_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
+	POPLAR_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
+};
+
+static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
+
+static const gicv2_driver_data_t poplar_gic_data = {
+	.gicd_base = POPLAR_GICD_BASE,
+	.gicc_base = POPLAR_GICC_BASE,
+	.interrupt_props = poplar_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(poplar_interrupt_props),
+	.target_masks = target_mask_array,
+	.target_masks_num = ARRAY_SIZE(target_mask_array),
+};
+
+/******************************************************************************
+ * Helper to initialize the GICv2 only driver.
+ *****************************************************************************/
+void poplar_gic_driver_init(void)
+{
+	gicv2_driver_init(&poplar_gic_data);
+}
+
+void poplar_gic_init(void)
+{
+	gicv2_distif_init();
+	gicv2_pcpu_distif_init();
+	gicv2_set_pe_target_mask(plat_my_core_pos());
+	gicv2_cpuif_enable();
+}
+
+/******************************************************************************
+ * Helper to enable the GICv2 CPU interface
+ *****************************************************************************/
+void poplar_gic_cpuif_enable(void)
+{
+	gicv2_cpuif_enable();
+}
+
+/******************************************************************************
+ * Helper to initialize the per cpu distributor interface in GICv2
+ *****************************************************************************/
+void poplar_gic_pcpu_init(void)
+{
+	gicv2_pcpu_distif_init();
+	gicv2_set_pe_target_mask(plat_my_core_pos());
+}
diff --git a/plat/imx/imx7/warp7/platform.mk b/plat/imx/imx7/warp7/platform.mk
index deb4c41..a771865 100644
--- a/plat/imx/imx7/warp7/platform.mk
+++ b/plat/imx/imx7/warp7/platform.mk
@@ -22,7 +22,6 @@
 # Platform
 PLAT_INCLUDES		:=	-Idrivers/imx/uart			\
 				-Iinclude/common/tbbr			\
-				-Iinclude/plat/arm/common/		\
 				-Iplat/imx/common/include/		\
 				-Iplat/imx/imx7/warp7/include		\
 				-Idrivers/imx/timer			\
diff --git a/plat/layerscape/board/ls1043/platform.mk b/plat/layerscape/board/ls1043/platform.mk
index c554ac3..678205c 100644
--- a/plat/layerscape/board/ls1043/platform.mk
+++ b/plat/layerscape/board/ls1043/platform.mk
@@ -22,7 +22,6 @@
 					plat/layerscape/board/ls1043/ls1043_security.c
 
 PLAT_INCLUDES			:=	-Iplat/layerscape/board/ls1043/include   \
-					-Iinclude/plat/arm/common	\
 					-Iplat/layerscape/common/include	\
 					-Iinclude/drivers/arm   \
 					-Iinclude/lib		\
diff --git a/plat/meson/gxbb/aarch64/gxbb_helpers.S b/plat/meson/gxbb/aarch64/gxbb_helpers.S
new file mode 100644
index 0000000..760d6c4
--- /dev/null
+++ b/plat/meson/gxbb/aarch64/gxbb_helpers.S
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <platform_def.h>
+
+	.globl	plat_crash_console_flush
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	platform_mem_init
+	.globl	plat_is_my_cpu_primary
+	.globl	plat_my_core_pos
+	.globl	plat_reset_handler
+	.globl	plat_gxbb_calc_core_pos
+
+	/* -----------------------------------------------------
+	 * unsigned int plat_my_core_pos(void);
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_gxbb_calc_core_pos
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_gxbb_calc_core_pos(u_register_t mpidr);
+	 * -----------------------------------------------------
+	 */
+func plat_gxbb_calc_core_pos
+	and	x0, x0, #MPIDR_CPU_MASK
+	ret
+endfunc plat_gxbb_calc_core_pos
+
+	/* -----------------------------------------------------
+	 * unsigned int plat_is_my_cpu_primary(void);
+	 * -----------------------------------------------------
+	 */
+func plat_is_my_cpu_primary
+	mrs	x0, mpidr_el1
+	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+	cmp	x0, #GXBB_PRIMARY_CPU
+	cset	w0, eq
+	ret
+endfunc plat_is_my_cpu_primary
+
+	/* ---------------------------------------------
+	 * void platform_mem_init(void);
+	 * ---------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+	mov_imm	x0, GXBB_UART0_AO_BASE
+	mov_imm	x1, GXBB_UART0_AO_CLK_IN_HZ
+	mov_imm	x2, GXBB_UART_BAUDRATE
+	b	console_meson_init
+endfunc plat_crash_console_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, GXBB_UART0_AO_BASE
+	b	console_meson_core_putc
+endfunc plat_crash_console_putc
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_flush()
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_flush
+	mov_imm	x0, GXBB_UART0_AO_BASE
+	b	console_meson_core_flush
+endfunc plat_crash_console_flush
+
+	/* ---------------------------------------------
+	 * void plat_reset_handler(void);
+	 * ---------------------------------------------
+	 */
+func plat_reset_handler
+	ret
+endfunc plat_reset_handler
diff --git a/plat/meson/gxbb/gxbb_bl31_setup.c b/plat/meson/gxbb/gxbb_bl31_setup.c
new file mode 100644
index 0000000..3e176f9
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_bl31_setup.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <gicv2.h>
+#include <interrupt_props.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <xlat_mmu_helpers.h>
+
+#include "gxbb_private.h"
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl33_image_ep_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	entry_point_info_t *next_image_info;
+
+	assert(type == NON_SECURE);
+
+	next_image_info = &bl33_image_ep_info;
+
+	/* None of the images can have 0x0 as the entrypoint. */
+	if (next_image_info->pc != 0U) {
+		return next_image_info;
+	} else {
+		return NULL;
+	}
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before
+ * they are lost (potentially). This needs to be done before the MMU is
+ * initialized so that the memory layout can be used while creating page
+ * tables. BL2 has flushed this information to memory, so we are guaranteed
+ * to pick up good data.
+ ******************************************************************************/
+struct gxbb_bl31_param {
+	param_header_t h;
+	image_info_t *bl31_image_info;
+	entry_point_info_t *bl32_ep_info;
+	image_info_t *bl32_image_info;
+	entry_point_info_t *bl33_ep_info;
+	image_info_t *bl33_image_info;
+};
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+				u_register_t arg2, u_register_t arg3)
+{
+	struct gxbb_bl31_param *from_bl2;
+
+	/* Initialize the console to provide early debug support */
+	gxbb_console_init();
+
+	/*
+	 * In debug builds, we pass a special value in 'arg1' to verify platform
+	 * parameters from BL2 to BL31. In release builds it's not used.
+	 */
+	assert(arg1 == GXBB_BL31_PLAT_PARAM_VAL);
+
+	/* Check that params passed from BL2 are not NULL. */
+	from_bl2 = (struct gxbb_bl31_param *) arg0;
+
+	/* Check params passed from BL2 are not NULL. */
+	assert(from_bl2 != NULL);
+	assert(from_bl2->h.type == PARAM_BL31);
+	assert(from_bl2->h.version >= VERSION_1);
+
+	/*
+	 * Copy BL33 entry point information. It is stored in Secure RAM, in
+	 * BL2's address space.
+	 */
+	bl33_image_ep_info = *from_bl2->bl33_ep_info;
+
+	if (bl33_image_ep_info.pc == 0U) {
+		ERROR("BL31: BL33 entrypoint not obtained from BL2\n");
+		panic();
+	}
+}
+
+void bl31_plat_arch_setup(void)
+{
+	gxbb_setup_page_tables();
+
+	enable_mmu_el3(0);
+}
+
+/*******************************************************************************
+ * GICv2 driver setup information
+ ******************************************************************************/
+static const interrupt_prop_t gxbb_interrupt_props[] = {
+	INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+	INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
+};
+
+static const gicv2_driver_data_t gxbb_gic_data = {
+	.gicd_base = GXBB_GICD_BASE,
+	.gicc_base = GXBB_GICC_BASE,
+	.interrupt_props = gxbb_interrupt_props,
+	.interrupt_props_num = ARRAY_SIZE(gxbb_interrupt_props),
+};
+
+void bl31_platform_setup(void)
+{
+	mhu_secure_init();
+
+	gicv2_driver_init(&gxbb_gic_data);
+	gicv2_distif_init();
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+
+	gxbb_thermal_unknown();
+}
diff --git a/plat/meson/gxbb/gxbb_common.c b/plat/meson/gxbb/gxbb_common.c
new file mode 100644
index 0000000..349d02f
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_common.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <ep_info.h>
+#include <interrupt_mgmt.h>
+#include <meson_console.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdint.h>
+#include <xlat_tables_v2.h>
+
+/*******************************************************************************
+ * Platform memory map regions
+ ******************************************************************************/
+#define MAP_NSDRAM0	MAP_REGION_FLAT(GXBB_NSDRAM0_BASE,		\
+					GXBB_NSDRAM0_SIZE,		\
+					MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_NSDRAM1	MAP_REGION_FLAT(GXBB_NSDRAM1_BASE,		\
+					GXBB_NSDRAM1_SIZE,		\
+					MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_SEC_DEVICE0	MAP_REGION_FLAT(GXBB_SEC_DEVICE0_BASE,		\
+					GXBB_SEC_DEVICE0_SIZE,		\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE1	MAP_REGION_FLAT(GXBB_SEC_DEVICE1_BASE,		\
+					GXBB_SEC_DEVICE1_SIZE,		\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_TZRAM	MAP_REGION_FLAT(GXBB_TZRAM_BASE,		\
+					GXBB_TZRAM_SIZE,		\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE2	MAP_REGION_FLAT(GXBB_SEC_DEVICE2_BASE,		\
+					GXBB_SEC_DEVICE2_SIZE,		\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SEC_DEVICE3	MAP_REGION_FLAT(GXBB_SEC_DEVICE3_BASE,		\
+					GXBB_SEC_DEVICE3_SIZE,		\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+static const mmap_region_t gxbb_mmap[] = {
+	MAP_NSDRAM0,
+	MAP_NSDRAM1,
+	MAP_SEC_DEVICE0,
+	MAP_SEC_DEVICE1,
+	MAP_TZRAM,
+	MAP_SEC_DEVICE2,
+	MAP_SEC_DEVICE3,
+	{0}
+};
+
+/*******************************************************************************
+ * Per-image regions
+ ******************************************************************************/
+#define MAP_BL31	MAP_REGION_FLAT(BL31_BASE,			\
+				BL31_END - BL31_BASE,			\
+				MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MAP_BL_CODE	MAP_REGION_FLAT(BL_CODE_BASE,			\
+				BL_CODE_END - BL_CODE_BASE,		\
+				MT_CODE | MT_SECURE)
+
+#define MAP_BL_RO_DATA	MAP_REGION_FLAT(BL_RO_DATA_BASE,		\
+				BL_RO_DATA_END - BL_RO_DATA_BASE,	\
+				MT_RO_DATA | MT_SECURE)
+
+#define MAP_BL_COHERENT	MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,		\
+				BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, \
+				MT_DEVICE | MT_RW | MT_SECURE)
+
+/*******************************************************************************
+ * Function that sets up the translation tables.
+ ******************************************************************************/
+void gxbb_setup_page_tables(void)
+{
+#if IMAGE_BL31
+	const mmap_region_t gxbb_bl_mmap[] = {
+		MAP_BL31,
+		MAP_BL_CODE,
+		MAP_BL_RO_DATA,
+#if USE_COHERENT_MEM
+		MAP_BL_COHERENT,
+#endif
+		{0}
+	};
+#endif
+
+	mmap_add(gxbb_bl_mmap);
+
+	mmap_add(gxbb_mmap);
+
+	init_xlat_tables();
+}
+
+/*******************************************************************************
+ * Function that sets up the console
+ ******************************************************************************/
+static console_meson_t gxbb_console;
+
+void gxbb_console_init(void)
+{
+	int rc = console_meson_register(GXBB_UART0_AO_BASE,
+					GXBB_UART0_AO_CLK_IN_HZ,
+					GXBB_UART_BAUDRATE,
+					&gxbb_console);
+	if (rc == 0) {
+		/*
+		 * The crash console doesn't use the multi console API, it uses
+		 * the core console functions directly. It is safe to call panic
+		 * and let it print debug information.
+		 */
+		panic();
+	}
+
+	console_set_scope(&gxbb_console.console,
+			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+}
+
+/*******************************************************************************
+ * Function that returns the system counter frequency
+ ******************************************************************************/
+unsigned int plat_get_syscnt_freq2(void)
+{
+	uint32_t val;
+
+	val = mmio_read_32(GXBB_SYS_CPU_CFG7);
+	val &= 0xFDFFFFFF;
+	mmio_write_32(GXBB_SYS_CPU_CFG7, val);
+
+	val = mmio_read_32(GXBB_AO_TIMESTAMP_CNTL);
+	val &= 0xFFFFFE00;
+	mmio_write_32(GXBB_AO_TIMESTAMP_CNTL, val);
+
+	return GXBB_OSC24M_CLK_IN_HZ;
+}
diff --git a/plat/meson/gxbb/gxbb_def.h b/plat/meson/gxbb/gxbb_def.h
new file mode 100644
index 0000000..0c73ac0
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_def.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GXBB_DEF_H
+#define GXBB_DEF_H
+
+#include <utils_def.h>
+
+/*******************************************************************************
+ * System oscillator
+ ******************************************************************************/
+#define GXBB_OSC24M_CLK_IN_HZ			ULL(24000000) /* 24 MHz */
+
+/*******************************************************************************
+ * Memory regions
+ ******************************************************************************/
+#define GXBB_NSDRAM0_BASE			UL(0x01000000)
+#define GXBB_NSDRAM0_SIZE			UL(0x0F000000)
+
+#define GXBB_NSDRAM1_BASE			UL(0x10000000)
+#define GXBB_NSDRAM1_SIZE			UL(0x00100000)
+
+#define BL31_BASE				UL(0x10100000)
+#define BL31_SIZE				UL(0x000C0000)
+#define BL31_LIMIT				(BL31_BASE + BL31_SIZE)
+
+/* Shared memory used for SMC services */
+#define GXBB_SHARE_MEM_INPUT_BASE		UL(0x100FE000)
+#define GXBB_SHARE_MEM_OUTPUT_BASE		UL(0x100FF000)
+
+#define GXBB_SEC_DEVICE0_BASE			UL(0xC0000000)
+#define GXBB_SEC_DEVICE0_SIZE			UL(0x09000000)
+
+#define GXBB_SEC_DEVICE1_BASE			UL(0xD0040000)
+#define GXBB_SEC_DEVICE1_SIZE			UL(0x00008000)
+
+#define GXBB_TZRAM_BASE				UL(0xD9000000)
+#define GXBB_TZRAM_SIZE				UL(0x00014000)
+/* Top 0xC000 bytes (up to 0xD9020000) used by BL2 */
+
+/* Mailboxes */
+#define GXBB_MHU_SECURE_SCP_TO_AP_PAYLOAD	UL(0xD9013800)
+#define GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD	UL(0xD9013A00)
+#define GXBB_PSCI_MAILBOX_BASE			UL(0xD9013F00)
+
+#define GXBB_TZROM_BASE				UL(0xD9040000)
+#define GXBB_TZROM_SIZE				UL(0x00010000)
+
+#define GXBB_SEC_DEVICE2_BASE			UL(0xDA000000)
+#define GXBB_SEC_DEVICE2_SIZE			UL(0x00200000)
+
+#define GXBB_SEC_DEVICE3_BASE			UL(0xDA800000)
+#define GXBB_SEC_DEVICE3_SIZE			UL(0x00200000)
+
+/*******************************************************************************
+ * GIC-400 and interrupt handling related constants
+ ******************************************************************************/
+#define GXBB_GICD_BASE				UL(0xC4301000)
+#define GXBB_GICC_BASE				UL(0xC4302000)
+
+#define IRQ_SEC_PHY_TIMER			29
+
+#define IRQ_SEC_SGI_0				8
+#define IRQ_SEC_SGI_1				9
+#define IRQ_SEC_SGI_2				10
+#define IRQ_SEC_SGI_3				11
+#define IRQ_SEC_SGI_4				12
+#define IRQ_SEC_SGI_5				13
+#define IRQ_SEC_SGI_6				14
+#define IRQ_SEC_SGI_7				15
+
+/*******************************************************************************
+ * UART definitions
+ ******************************************************************************/
+#define GXBB_UART0_AO_BASE			UL(0xC81004C0)
+#define GXBB_UART0_AO_CLK_IN_HZ			GXBB_OSC24M_CLK_IN_HZ
+#define GXBB_UART_BAUDRATE			U(115200)
+
+/*******************************************************************************
+ * Memory-mapped I/O Registers
+ ******************************************************************************/
+#define GXBB_AO_TIMESTAMP_CNTL			UL(0xC81000B4)
+
+#define GXBB_SYS_CPU_CFG7			UL(0xC8834664)
+
+#define GXBB_AO_RTI_STATUS_REG3			UL(0xDA10001C)
+
+#define GXBB_HIU_MAILBOX_SET_0			UL(0xDA83C404)
+#define GXBB_HIU_MAILBOX_STAT_0			UL(0xDA83C408)
+#define GXBB_HIU_MAILBOX_CLR_0			UL(0xDA83C40C)
+#define GXBB_HIU_MAILBOX_SET_3			UL(0xDA83C428)
+#define GXBB_HIU_MAILBOX_STAT_3			UL(0xDA83C42C)
+#define GXBB_HIU_MAILBOX_CLR_3			UL(0xDA83C430)
+
+/*******************************************************************************
+ * System Monitor Call IDs and arguments
+ ******************************************************************************/
+#define GXBB_SM_GET_SHARE_MEM_INPUT_BASE	U(0x82000020)
+#define GXBB_SM_GET_SHARE_MEM_OUTPUT_BASE	U(0x82000021)
+
+#define GXBB_SM_EFUSE_READ			U(0x82000030)
+#define GXBB_SM_EFUSE_USER_MAX			U(0x82000033)
+
+#define GXBB_SM_JTAG_ON				U(0x82000040)
+#define GXBB_SM_JTAG_OFF			U(0x82000041)
+
+#define GXBB_JTAG_STATE_ON			U(0)
+#define GXBB_JTAG_STATE_OFF			U(1)
+
+#define GXBB_JTAG_M3_AO				U(0)
+#define GXBB_JTAG_M3_EE				U(1)
+#define GXBB_JTAG_A53_AO			U(2)
+#define GXBB_JTAG_A53_EE			U(3)
+
+#endif /* GXBB_DEF_H */
diff --git a/plat/meson/gxbb/gxbb_efuse.c b/plat/meson/gxbb/gxbb_efuse.c
new file mode 100644
index 0000000..edea542
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_efuse.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include "gxbb_private.h"
+
+#define EFUSE_BASE	0x140
+#define EFUSE_SIZE	0xC0
+
+uint64_t gxbb_efuse_read(void *dst, uint32_t offset, uint32_t size)
+{
+	if ((uint64_t)(offset + size) > (uint64_t)EFUSE_SIZE)
+		return 0;
+
+	return scpi_efuse_read(dst, offset + EFUSE_BASE, size);
+}
+
+uint64_t gxbb_efuse_user_max(void)
+{
+	return EFUSE_SIZE;
+}
diff --git a/plat/meson/gxbb/gxbb_mhu.c b/plat/meson/gxbb/gxbb_mhu.c
new file mode 100644
index 0000000..78b895c
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_mhu.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bakery_lock.h>
+#include <mmio.h>
+#include <platform_def.h>
+
+static DEFINE_BAKERY_LOCK(mhu_lock);
+
+void mhu_secure_message_start(void)
+{
+	bakery_lock_get(&mhu_lock);
+
+	while (mmio_read_32(GXBB_HIU_MAILBOX_STAT_3) != 0)
+		;
+}
+
+void mhu_secure_message_send(uint32_t msg)
+{
+	mmio_write_32(GXBB_HIU_MAILBOX_SET_3, msg);
+
+	while (mmio_read_32(GXBB_HIU_MAILBOX_STAT_3) != 0)
+		;
+}
+
+uint32_t mhu_secure_message_wait(void)
+{
+	uint32_t val;
+
+	do {
+		val = mmio_read_32(GXBB_HIU_MAILBOX_STAT_0);
+	} while (val == 0);
+
+	return val;
+}
+
+void mhu_secure_message_end(void)
+{
+	mmio_write_32(GXBB_HIU_MAILBOX_CLR_0, 0xFFFFFFFF);
+
+	bakery_lock_release(&mhu_lock);
+}
+
+void mhu_secure_init(void)
+{
+	bakery_lock_init(&mhu_lock);
+
+	mmio_write_32(GXBB_HIU_MAILBOX_CLR_3, 0xFFFFFFFF);
+}
diff --git a/plat/meson/gxbb/gxbb_pm.c b/plat/meson/gxbb/gxbb_pm.c
new file mode 100644
index 0000000..930b5e1
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_pm.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <errno.h>
+#include <gicv2.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <psci.h>
+
+#include "gxbb_private.h"
+
+#define SCPI_POWER_ON		0
+#define SCPI_POWER_RETENTION	1
+#define SCPI_POWER_OFF		3
+
+#define SCPI_SYSTEM_SHUTDOWN	0
+#define SCPI_SYSTEM_REBOOT	1
+
+static uintptr_t gxbb_sec_entrypoint;
+static volatile uint32_t gxbb_cpu0_go;
+
+static void gxbb_program_mailbox(u_register_t mpidr, uint64_t value)
+{
+	unsigned int core = plat_gxbb_calc_core_pos(mpidr);
+	uintptr_t cpu_mailbox_addr = GXBB_PSCI_MAILBOX_BASE + (core << 4);
+
+	mmio_write_64(cpu_mailbox_addr, value);
+	flush_dcache_range(cpu_mailbox_addr, sizeof(uint64_t));
+}
+
+static void __dead2 gxbb_system_reset(void)
+{
+	INFO("BL31: PSCI_SYSTEM_RESET\n");
+
+	uint32_t status = mmio_read_32(GXBB_AO_RTI_STATUS_REG3);
+
+	NOTICE("BL31: Reboot reason: 0x%x\n", status);
+
+	status &= 0xFFFF0FF0;
+
+	console_flush();
+
+	mmio_write_32(GXBB_AO_RTI_STATUS_REG3, status);
+
+	int ret = scpi_sys_power_state(SCPI_SYSTEM_REBOOT);
+
+	if (ret != 0) {
+		ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %u\n", ret);
+		panic();
+	}
+
+	wfi();
+
+	ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n");
+	panic();
+}
+
+static void __dead2 gxbb_system_off(void)
+{
+	INFO("BL31: PSCI_SYSTEM_OFF\n");
+
+	unsigned int ret = scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN);
+
+	if (ret != 0) {
+		ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %u\n", ret);
+		panic();
+	}
+
+	gxbb_program_mailbox(read_mpidr_el1(), 0);
+
+	wfi();
+
+	ERROR("BL31: PSCI_SYSTEM_OFF: Operation not handled\n");
+	panic();
+}
+
+static int32_t gxbb_pwr_domain_on(u_register_t mpidr)
+{
+	unsigned int core = plat_gxbb_calc_core_pos(mpidr);
+
+	/* CPU0 can't be turned OFF, emulate it with a WFE loop */
+	if (core == GXBB_PRIMARY_CPU) {
+		VERBOSE("BL31: Releasing CPU0 from wait loop...\n");
+
+		gxbb_cpu0_go = 1;
+		flush_dcache_range((uintptr_t)&gxbb_cpu0_go, sizeof(gxbb_cpu0_go));
+		dsb();
+		isb();
+
+		sev();
+
+		return PSCI_E_SUCCESS;
+	}
+
+	gxbb_program_mailbox(mpidr, gxbb_sec_entrypoint);
+	scpi_set_css_power_state(mpidr,
+				 SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON);
+	dmbsy();
+	sev();
+
+	return PSCI_E_SUCCESS;
+}
+
+static void gxbb_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	unsigned int core = plat_gxbb_calc_core_pos(read_mpidr_el1());
+
+	assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+					PLAT_LOCAL_STATE_OFF);
+
+	if (core == GXBB_PRIMARY_CPU) {
+		gxbb_cpu0_go = 0;
+		flush_dcache_range((uintptr_t)&gxbb_cpu0_go, sizeof(gxbb_cpu0_go));
+		dsb();
+		isb();
+	}
+
+	gicv2_pcpu_distif_init();
+	gicv2_cpuif_enable();
+}
+
+static void gxbb_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	u_register_t mpidr = read_mpidr_el1();
+	unsigned int core = plat_gxbb_calc_core_pos(mpidr);
+	uintptr_t addr = GXBB_PSCI_MAILBOX_BASE + 8 + (core << 4);
+
+	mmio_write_32(addr, 0xFFFFFFFF);
+	flush_dcache_range(addr, sizeof(uint32_t));
+
+	gicv2_cpuif_disable();
+
+	/* CPU0 can't be turned OFF, emulate it with a WFE loop */
+	if (core == GXBB_PRIMARY_CPU)
+		return;
+
+	scpi_set_css_power_state(mpidr,
+				 SCPI_POWER_OFF, SCPI_POWER_ON, SCPI_POWER_ON);
+}
+
+static void __dead2 gxbb_pwr_domain_pwr_down_wfi(const psci_power_state_t
+						 *target_state)
+{
+	unsigned int core = plat_gxbb_calc_core_pos(read_mpidr_el1());
+
+	/* CPU0 can't be turned OFF, emulate it with a WFE loop */
+	if (core == GXBB_PRIMARY_CPU) {
+		VERBOSE("BL31: CPU0 entering wait loop...\n");
+
+		while (gxbb_cpu0_go == 0)
+			wfe();
+
+		VERBOSE("BL31: CPU0 resumed.\n");
+
+		write_rmr_el3(RMR_EL3_RR_BIT | RMR_EL3_AA64_BIT);
+	}
+
+	dsbsy();
+
+	for (;;)
+		wfi();
+}
+
+/*******************************************************************************
+ * Platform handlers and setup function.
+ ******************************************************************************/
+static const plat_psci_ops_t gxbb_ops = {
+	.pwr_domain_on			= gxbb_pwr_domain_on,
+	.pwr_domain_on_finish		= gxbb_pwr_domain_on_finish,
+	.pwr_domain_off			= gxbb_pwr_domain_off,
+	.pwr_domain_pwr_down_wfi	= gxbb_pwr_domain_pwr_down_wfi,
+	.system_off			= gxbb_system_off,
+	.system_reset			= gxbb_system_reset,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	gxbb_sec_entrypoint = sec_entrypoint;
+	*psci_ops = &gxbb_ops;
+	gxbb_cpu0_go = 0;
+	return 0;
+}
diff --git a/plat/meson/gxbb/gxbb_private.h b/plat/meson/gxbb/gxbb_private.h
new file mode 100644
index 0000000..910a42c
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_private.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GXBB_PRIVATE_H
+#define GXBB_PRIVATE_H
+
+#include <stdint.h>
+
+/* Utility functions */
+unsigned int plat_gxbb_calc_core_pos(u_register_t mpidr);
+void gxbb_console_init(void);
+void gxbb_setup_page_tables(void);
+
+/* MHU functions */
+void mhu_secure_message_start(void);
+void mhu_secure_message_send(uint32_t msg);
+uint32_t mhu_secure_message_wait(void);
+void mhu_secure_message_end(void);
+void mhu_secure_init(void);
+
+/* SCPI functions */
+void scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state,
+			      uint32_t cluster_state, uint32_t css_state);
+uint32_t scpi_sys_power_state(uint64_t system_state);
+void scpi_jtag_set_state(uint32_t state, uint8_t select);
+uint32_t scpi_efuse_read(void *dst, uint32_t base, uint32_t size);
+void scpi_unknown_thermal(uint32_t arg0, uint32_t arg1,
+			  uint32_t arg2, uint32_t arg3);
+
+/* Peripherals */
+void gxbb_thermal_unknown(void);
+uint64_t gxbb_efuse_read(void *dst, uint32_t offset, uint32_t size);
+uint64_t gxbb_efuse_user_max(void);
+
+#endif /* GXBB_PRIVATE_H */
diff --git a/plat/meson/gxbb/gxbb_scpi.c b/plat/meson/gxbb/gxbb_scpi.c
new file mode 100644
index 0000000..2390bca
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_scpi.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+
+#include "gxbb_private.h"
+
+#define SIZE_SHIFT	20
+#define SIZE_MASK	0x1FF
+
+/*
+ * Note: The Amlogic SCP firmware uses the legacy SCPI protocol.
+ */
+#define SCPI_CMD_SET_CSS_POWER_STATE	0x04
+#define SCPI_CMD_SET_SYS_POWER_STATE	0x08
+
+#define SCPI_CMD_JTAG_SET_STATE		0xC0
+#define SCPI_CMD_EFUSE_READ		0xC2
+
+static inline uint32_t scpi_cmd(uint32_t command, uint32_t size)
+{
+	return command | (size << SIZE_SHIFT);
+}
+
+void scpi_secure_message_send(uint32_t command, uint32_t size)
+{
+	mhu_secure_message_send(scpi_cmd(command, size));
+}
+
+uint32_t scpi_secure_message_receive(void **message_out, size_t *size_out)
+{
+	uint32_t response = mhu_secure_message_wait();
+
+	size_t size = (response >> SIZE_SHIFT) & SIZE_MASK;
+
+	response &= ~(SIZE_MASK << SIZE_SHIFT);
+
+	if (size_out != NULL)
+		*size_out = size;
+
+	if (message_out != NULL)
+		*message_out = (void *)GXBB_MHU_SECURE_SCP_TO_AP_PAYLOAD;
+
+	return response;
+}
+
+void scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state,
+			      uint32_t cluster_state, uint32_t css_state)
+{
+	uint32_t state = (mpidr & 0x0F) | /* CPU ID */
+			 ((mpidr & 0xF00) >> 4) | /* Cluster ID */
+			 (cpu_state << 8) |
+			 (cluster_state << 12) |
+			 (css_state << 16);
+
+	mhu_secure_message_start();
+	mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, state);
+	mhu_secure_message_send(scpi_cmd(SCPI_CMD_SET_CSS_POWER_STATE, 4));
+	mhu_secure_message_wait();
+	mhu_secure_message_end();
+}
+
+uint32_t scpi_sys_power_state(uint64_t system_state)
+{
+	uint32_t *response;
+	size_t size;
+
+	mhu_secure_message_start();
+	mmio_write_8(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, system_state);
+	mhu_secure_message_send(scpi_cmd(SCPI_CMD_SET_SYS_POWER_STATE, 1));
+	scpi_secure_message_receive((void *)&response, &size);
+	mhu_secure_message_end();
+
+	return *response;
+}
+
+void scpi_jtag_set_state(uint32_t state, uint8_t select)
+{
+	assert(state <= GXBB_JTAG_STATE_OFF);
+
+	if (select > GXBB_JTAG_A53_EE) {
+		WARN("BL31: Invalid JTAG select (0x%x).\n", select);
+		return;
+	}
+
+	mhu_secure_message_start();
+	mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD,
+		      (state << 8) | (uint32_t)select);
+	mhu_secure_message_send(scpi_cmd(SCPI_CMD_JTAG_SET_STATE, 4));
+	mhu_secure_message_wait();
+	mhu_secure_message_end();
+}
+
+uint32_t scpi_efuse_read(void *dst, uint32_t base, uint32_t size)
+{
+	uint32_t *response;
+	size_t resp_size;
+
+	if (size > 0x1FC)
+		return 0;
+
+	mhu_secure_message_start();
+	mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, base);
+	mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 4, size);
+	mhu_secure_message_send(scpi_cmd(SCPI_CMD_EFUSE_READ, 8));
+	scpi_secure_message_receive((void *)&response, &resp_size);
+	mhu_secure_message_end();
+
+	/*
+	 * response[0] is the size of the response message.
+	 * response[1 ... N] are the contents.
+	 */
+	if (*response != 0)
+		memcpy(dst, response + 1, *response);
+
+	return *response;
+}
+
+void scpi_unknown_thermal(uint32_t arg0, uint32_t arg1,
+			  uint32_t arg2, uint32_t arg3)
+{
+	mhu_secure_message_start();
+	mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x0, arg0);
+	mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x4, arg1);
+	mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x8, arg2);
+	mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0xC, arg3);
+	mhu_secure_message_send(scpi_cmd(0xC3, 16));
+	mhu_secure_message_wait();
+	mhu_secure_message_end();
+}
diff --git a/plat/meson/gxbb/gxbb_sip_svc.c b/plat/meson/gxbb/gxbb_sip_svc.c
new file mode 100644
index 0000000..82ed449
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_sip_svc.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 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 <runtime_svc.h>
+#include <stdint.h>
+
+#include "gxbb_private.h"
+
+/*******************************************************************************
+ * This function is responsible for handling all SiP calls
+ ******************************************************************************/
+static uintptr_t gxbb_sip_handler(uint32_t smc_fid,
+				  u_register_t x1, u_register_t x2,
+				  u_register_t x3, u_register_t x4,
+				  void *cookie, void *handle,
+				  u_register_t flags)
+{
+	switch (smc_fid) {
+
+	case GXBB_SM_GET_SHARE_MEM_INPUT_BASE:
+		SMC_RET1(handle, GXBB_SHARE_MEM_INPUT_BASE);
+
+	case GXBB_SM_GET_SHARE_MEM_OUTPUT_BASE:
+		SMC_RET1(handle, GXBB_SHARE_MEM_OUTPUT_BASE);
+
+	case GXBB_SM_EFUSE_READ:
+	{
+		void *dst = (void *)GXBB_SHARE_MEM_OUTPUT_BASE;
+		uint64_t ret = gxbb_efuse_read(dst, (uint32_t)x1, x2);
+
+		SMC_RET1(handle, ret);
+	}
+	case GXBB_SM_EFUSE_USER_MAX:
+		SMC_RET1(handle,  gxbb_efuse_user_max());
+
+	case GXBB_SM_JTAG_ON:
+		scpi_jtag_set_state(GXBB_JTAG_STATE_ON, x1);
+		SMC_RET1(handle, 0);
+
+	case GXBB_SM_JTAG_OFF:
+		scpi_jtag_set_state(GXBB_JTAG_STATE_OFF, x1);
+		SMC_RET1(handle, 0);
+
+	default:
+		ERROR("BL31: Unhandled SIP SMC: 0x%08x\n", smc_fid);
+		break;
+	}
+
+	SMC_RET1(handle, SMC_UNK);
+}
+
+DECLARE_RT_SVC(
+	gxbb_sip_handler,
+
+	OEN_SIP_START,
+	OEN_SIP_END,
+	SMC_TYPE_FAST,
+	NULL,
+	gxbb_sip_handler
+);
diff --git a/plat/meson/gxbb/gxbb_thermal.c b/plat/meson/gxbb/gxbb_thermal.c
new file mode 100644
index 0000000..b6048ee
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_thermal.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include "gxbb_private.h"
+
+static int32_t modules_initialized = -1;
+
+/*******************************************************************************
+ * Unknown commands related to something thermal-related
+ ******************************************************************************/
+void gxbb_thermal_unknown(void)
+{
+	uint16_t ret;
+
+	if (modules_initialized == -1) {
+		scpi_efuse_read(&ret, 0, 2);
+		modules_initialized = ret;
+	}
+
+	scpi_unknown_thermal(10, 2,  /* thermal */
+			     13, 1); /* thermalver */
+}
diff --git a/plat/meson/gxbb/gxbb_topology.c b/plat/meson/gxbb/gxbb_topology.c
new file mode 100644
index 0000000..49bb2dc
--- /dev/null
+++ b/plat/meson/gxbb/gxbb_topology.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <platform_def.h>
+#include <stdint.h>
+
+#include "gxbb_private.h"
+
+/* The power domain tree descriptor */
+static unsigned char power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first node */
+	PLATFORM_CLUSTER0_CORE_COUNT
+};
+
+/*******************************************************************************
+ * This function returns the ARM default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
+		return -1;
+
+	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT)
+		return -1;
+
+	if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
+		return -1;
+
+	return plat_gxbb_calc_core_pos(mpidr);
+}
diff --git a/plat/meson/gxbb/include/plat_macros.S b/plat/meson/gxbb/include/plat_macros.S
new file mode 100644
index 0000000..948b5f9
--- /dev/null
+++ b/plat/meson/gxbb/include/plat_macros.S
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
+
+#include <gicv2.h>
+#include <platform_def.h>
+
+.section .rodata.gic_reg_name, "aS"
+
+gicc_regs:
+	.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+gicd_pend_reg:
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
+newline:
+	.asciz "\n"
+spacer:
+	.asciz ":\t\t0x"
+
+	/* ---------------------------------------------
+	 * 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
+
+	/* GICC registers */
+
+	mov_imm	x17, GXBB_GICC_BASE
+
+	adr	x6, gicc_regs
+	ldr	w8, [x17, #GICC_HPPIR]
+	ldr	w9, [x17, #GICC_AHPPIR]
+	ldr	w10, [x17, #GICC_CTLR]
+	bl	str_in_crash_buf_print
+
+	/* GICD registers */
+
+	mov_imm	x16, GXBB_GICD_BASE
+
+	add	x7, x16, #GICD_ISPENDR
+	adr	x4, gicd_pend_reg
+	bl	asm_print_str
+
+gicd_ispendr_loop:
+	sub	x4, x7, x16
+	cmp	x4, #0x280
+	b.eq	exit_print_gic_regs
+	bl	asm_print_hex
+
+	adr	x4, spacer
+	bl	asm_print_str
+
+	ldr	x4, [x7], #8
+	bl	asm_print_hex
+
+	adr	x4, newline
+	bl	asm_print_str
+	b	gicd_ispendr_loop
+exit_print_gic_regs:
+
+	.endm
+
+#endif /* PLAT_MACROS_S */
diff --git a/plat/meson/gxbb/include/platform_def.h b/plat/meson/gxbb/include/platform_def.h
new file mode 100644
index 0000000..a85637f
--- /dev/null
+++ b/plat/meson/gxbb/include/platform_def.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <utils_def.h>
+
+#include "../gxbb_def.h"
+
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define GXBB_BL31_PLAT_PARAM_VAL	ULL(0x0F1E2D3C4B5A6978)
+
+#define PLATFORM_STACK_SIZE		UL(0x1000)
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(4)
+#define PLATFORM_CLUSTER_COUNT		U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
+#define PLATFORM_CORE_COUNT		PLATFORM_CLUSTER0_CORE_COUNT
+
+#define GXBB_PRIMARY_CPU		U(0)
+
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL1
+#define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN		U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET		U(1)
+/* Local power state for power-down. Valid for CPU and cluster power domains. */
+#define PLAT_LOCAL_STATE_OFF		U(2)
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH		U(4)
+#define PLAT_LOCAL_PSTATE_MASK		((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_SHIFT		U(6)
+#define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
+
+/* Memory-related defines */
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 32)
+
+#define MAX_MMAP_REGIONS		12
+#define MAX_XLAT_TABLES			5
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/meson/gxbb/platform.mk b/plat/meson/gxbb/platform.mk
new file mode 100644
index 0000000..e6f5ae4
--- /dev/null
+++ b/plat/meson/gxbb/platform.mk
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_INCLUDES		:=	-Iinclude/drivers/meson/		\
+				-Iplat/meson/gxbb/include
+
+GXBB_GIC_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
+				drivers/arm/gic/v2/gicv2_main.c		\
+				drivers/arm/gic/v2/gicv2_helpers.c	\
+				plat/common/plat_gicv2.c
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/console/aarch64/multi_console.S	\
+				drivers/meson/console/aarch64/meson_console.S \
+				plat/meson/gxbb/gxbb_common.c		\
+				plat/meson/gxbb/gxbb_topology.c		\
+				${XLAT_TABLES_LIB_SRCS}
+
+BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
+				plat/common/plat_psci_common.c		\
+				plat/meson/gxbb/aarch64/gxbb_helpers.S	\
+				plat/meson/gxbb/gxbb_bl31_setup.c	\
+				plat/meson/gxbb/gxbb_efuse.c		\
+				plat/meson/gxbb/gxbb_mhu.c		\
+				plat/meson/gxbb/gxbb_pm.c		\
+				plat/meson/gxbb/gxbb_scpi.c		\
+				plat/meson/gxbb/gxbb_sip_svc.c		\
+				plat/meson/gxbb/gxbb_thermal.c		\
+				${GXBB_GIC_SOURCES}
+
+# Tune compiler for Cortex-A53
+ifeq ($(notdir $(CC)),armclang)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
+else
+    TF_CFLAGS_aarch64	+=	-mtune=cortex-a53
+endif
+
+# Build config flags
+# ------------------
+
+# Enable all errata workarounds for Cortex-A53
+ERRATA_A53_826319		:= 1
+ERRATA_A53_835769		:= 1
+ERRATA_A53_836870		:= 1
+ERRATA_A53_843419		:= 1
+ERRATA_A53_855873		:= 1
+
+WORKAROUND_CVE_2017_5715	:= 0
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA	:= 1
+
+# Use Coherent memory
+USE_COHERENT_MEM		:= 1
+
+# Use multi console API
+MULTI_CONSOLE_API		:= 1
+
+# Verify build config
+# -------------------
+
+ifneq (${MULTI_CONSOLE_API}, 1)
+  $(error Error: gxbb needs MULTI_CONSOLE_API=1)
+endif
+
+ifneq (${RESET_TO_BL31}, 0)
+  $(error Error: gxbb needs RESET_TO_BL31=0)
+endif
+
+ifeq (${ARCH},aarch32)
+  $(error Error: AArch32 not supported on gxbb)
+endif
diff --git a/plat/qemu/platform.mk b/plat/qemu/platform.mk
index 9167c9f..982886a 100644
--- a/plat/qemu/platform.mk
+++ b/plat/qemu/platform.mk
@@ -38,24 +38,12 @@
 PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/${ARCH}
 endif
 
-# Use translation tables library v2 by default
-ARM_XLAT_TABLES_LIB_V1		:=	0
-$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
-$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
-
-
 PLAT_BL_COMMON_SOURCES	:=	plat/qemu/qemu_common.c			  \
 				plat/qemu/qemu_console.c		  \
 				drivers/arm/pl011/${ARCH}/pl011_console.S \
 
-ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
-PLAT_BL_COMMON_SOURCES	+=	lib/xlat_tables/xlat_tables_common.c		\
-				lib/xlat_tables/${ARCH}/xlat_tables.c
-else
 include lib/xlat_tables_v2/xlat_tables.mk
-
 PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
-endif
 
 ifneq (${TRUSTED_BOARD_BOOT},0)
 
diff --git a/plat/qemu/qemu_common.c b/plat/qemu/qemu_common.c
index 376ff2f..43a3f70 100644
--- a/plat/qemu/qemu_common.c
+++ b/plat/qemu/qemu_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,8 @@
 #include <arch_helpers.h>
 #include <bl_common.h>
 #include <platform_def.h>
-#include <arm_xlat_tables.h>
+#include <xlat_tables_v2.h>
+
 #include "qemu_private.h"
 
 #define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index f84b9d4..e438dc3 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -108,7 +108,7 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 	enable_mmu_el3(0);
 }
 
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index a14388f..0163450 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -193,6 +193,6 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 	enable_mmu_el3(0);
 }
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 33859ee..35c8983 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -16,10 +16,6 @@
 
 WORKAROUND_CVE_2017_5715	:=	0
 
-ARM_XLAT_TABLES_LIB_V1		:=	1
-$(eval $(call assert_boolean,ARM_XLAT_TABLES_LIB_V1))
-$(eval $(call add_define,ARM_XLAT_TABLES_LIB_V1))
-
 ifdef ZYNQMP_ATF_MEM_BASE
     $(eval $(call add_define,ZYNQMP_ATF_MEM_BASE))
 
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 52d4bf8..a27f34b 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -57,6 +57,6 @@
 		{0}
 	};
 
-	arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+	setup_page_tables(bl_regions, plat_arm_get_mmap());
 	enable_mmu_el1(0);
 }
diff --git a/readme.rst b/readme.rst
index f2a7a00..e7fbfb4 100644
--- a/readme.rst
+++ b/readme.rst
@@ -193,6 +193,7 @@
 This release also contains the following platform support:
 
 -  Allwinner sun50i_64 and sun50i_h6
+-  Amlogic Meson S905 (GXBB)
 -  ARM SGI-575 and SGM-775
 -  HiKey, HiKey960 and Poplar boards
 -  Marvell Armada 8K
diff --git a/services/std_svc/sdei/sdei_private.h b/services/std_svc/sdei/sdei_private.h
index f5197c6..8212667 100644
--- a/services/std_svc/sdei/sdei_private.h
+++ b/services/std_svc/sdei/sdei_private.h
@@ -8,6 +8,7 @@
 #define SDEI_PRIVATE_H
 
 #include <arch_helpers.h>
+#include <context.h>
 #include <context_mgmt.h>
 #include <debug.h>
 #include <errno.h>