Merge pull request #1681 from Andre-ARM/allwinner/fixes

allwinner: clock / power fixes
diff --git a/Makefile b/Makefile
index 74d5180..c79264b 100644
--- a/Makefile
+++ b/Makefile
@@ -108,13 +108,6 @@
         LOG_LEVEL	:=	20
 endif
 
-# Enable backtrace by default in DEBUG AArch64 builds
-ifeq (${ARCH},aarch32)
-        ENABLE_BACKTRACE 	:=	0
-else
-        ENABLE_BACKTRACE 	:=	${DEBUG}
-endif
-
 # Default build string (git branch and commit)
 ifeq (${BUILD_STRING},)
         BUILD_STRING	:=	$(shell git describe --always --dirty --tags 2> /dev/null)
@@ -206,11 +199,6 @@
 
 GCC_V_OUTPUT		:=	$(shell $(CC) -v 2>&1)
 
-# Force the compiler to include the frame pointer
-ifeq (${ENABLE_BACKTRACE},1)
-TF_CFLAGS		+=	-fno-omit-frame-pointer
-endif
-
 TF_LDFLAGS		+=	--fatal-warnings -O1
 TF_LDFLAGS		+=	--gc-sections
 TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
@@ -238,10 +226,6 @@
 BL_COMMON_SOURCES	+=	lib/${ARCH}/armclang_printf.S
 endif
 
-ifeq (${ENABLE_BACKTRACE},1)
-BL_COMMON_SOURCES	+=	common/backtrace.c
-endif
-
 INCLUDES		+=	-Iinclude				\
 				-Iinclude/bl1				\
 				-Iinclude/bl2				\
@@ -270,6 +254,8 @@
 				${SPD_INCLUDES}				\
 				-Iinclude/tools_share
 
+include common/backtrace/backtrace.mk
+
 ################################################################################
 # Generic definitions
 ################################################################################
@@ -369,15 +355,6 @@
 # Check incompatible options
 ################################################################################
 
-ifeq (${ARCH},aarch32)
-        ifeq (${ENABLE_BACKTRACE},1)
-                ifneq (${AARCH32_INSTRUCTION_SET},A32)
-                        $(error Error: AARCH32_INSTRUCTION_SET=A32 is needed \
-                        for ENABLE_BACKTRACE when compiling for AArch32.)
-                endif
-        endif
-endif
-
 ifdef EL3_PAYLOAD_BASE
         ifdef PRELOADED_BL33_BASE
                 $(warning "PRELOADED_BL33_BASE and EL3_PAYLOAD_BASE are \
@@ -568,7 +545,6 @@
 $(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
 $(eval $(call assert_boolean,ENABLE_AMU))
 $(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))
@@ -619,7 +595,6 @@
 $(eval $(call add_define,EL3_EXCEPTION_HANDLING))
 $(eval $(call add_define,ENABLE_AMU))
 $(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))
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 7777954..019a19e 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -8,6 +8,9 @@
 # Include SPM Makefile
 ################################################################################
 ifeq (${ENABLE_SPM},1)
+ifeq (${EL3_EXCEPTION_HANDLING},0)
+  $(error EL3_EXCEPTION_HANDLING must be 1 for SPM support)
+endif
 $(info Including SPM makefile)
 include services/std_svc/spm/spm.mk
 endif
diff --git a/common/backtrace.c b/common/backtrace/backtrace.c
similarity index 100%
rename from common/backtrace.c
rename to common/backtrace/backtrace.c
diff --git a/common/backtrace/backtrace.mk b/common/backtrace/backtrace.mk
new file mode 100644
index 0000000..e669331
--- /dev/null
+++ b/common/backtrace/backtrace.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Enable backtrace by default in DEBUG AArch64 builds
+ifeq (${ARCH},aarch32)
+        ENABLE_BACKTRACE 	:=	0
+else
+        ENABLE_BACKTRACE 	:=	${DEBUG}
+endif
+
+ifeq (${ENABLE_BACKTRACE},1)
+        # Force the compiler to include the frame pointer
+        TF_CFLAGS		+=	-fno-omit-frame-pointer
+
+        BL_COMMON_SOURCES	+=	common/backtrace/backtrace.c
+endif
+
+ifeq (${ARCH},aarch32)
+        ifeq (${ENABLE_BACKTRACE},1)
+                ifneq (${AARCH32_INSTRUCTION_SET},A32)
+                        $(error Error: AARCH32_INSTRUCTION_SET=A32 is needed \
+                        for ENABLE_BACKTRACE when compiling for AArch32.)
+                endif
+        endif
+endif
+
+$(eval $(call assert_boolean,ENABLE_BACKTRACE))
+$(eval $(call add_define,ENABLE_BACKTRACE))
diff --git a/docs/plat/rpi3.rst b/docs/plat/rpi3.rst
index db47564..a22bfc6 100644
--- a/docs/plat/rpi3.rst
+++ b/docs/plat/rpi3.rst
@@ -231,6 +231,44 @@
   ``RPI3_DIRECT_LINUX_BOOT=1``. This option allows to specify the location of a
   DTB in memory.
 
+- ``RPI3_RUNTIME_UART``: Indicates whether the UART should be used at runtime
+  or disabled. ``-1`` (default) disables the runtime UART. Any other value
+  enables the default UART (currently UART1) for runtime messages.
+
+- ``RPI3_USE_UEFI_MAP``: Set to 1 to build ATF with the altername memory
+  mapping required for an UEFI firmware payload. These changes are needed
+  to be able to run Windows on ARM64. This option, which is disabled by
+  default, results in the following memory mappings:
+
+::
+
+    0x00000000 +-----------------+
+               |       ROM       | BL1
+    0x00010000 +-----------------+
+               |       DTB       | (Loaded by the VideoCore)
+    0x00020000 +-----------------+
+               |       FIP       |
+    0x00030000 +-----------------+
+               |                 |
+               |  UEFI PAYLOAD   |
+               |                 |
+    0x00200000 +-----------------+
+               |   Secure SRAM   | BL2, BL31
+    0x00300000 +-----------------+
+               |   Secure DRAM   | BL32 (Secure payload)
+    0x00400000 +-----------------+
+               |                 |
+               |                 |
+               | Non-secure DRAM | BL33
+               |                 |
+               |                 |
+    0x01000000 +-----------------+
+               |                 |
+               |       ...       |
+               |                 |
+    0x3F000000 +-----------------+
+               |       I/O       |
+
 - ``BL32``: This port can load and run OP-TEE. The OP-TEE image is optional.
   Please use the code from `here <https://github.com/OP-TEE/optee_os>`__.
   Build the Trusted Firmware with option ``BL32=tee-header_v2.bin
diff --git a/docs/secure-partition-manager-design.rst b/docs/secure-partition-manager-design.rst
index fec7c00..73406b2 100644
--- a/docs/secure-partition-manager-design.rst
+++ b/docs/secure-partition-manager-design.rst
@@ -125,8 +125,9 @@
 the rest of this document.
 
 To enable SPM support in TF-A, the source code must be compiled with the build
-flag ``ENABLE_SPM=1``. On Arm platforms the build option ``ARM_BL31_IN_DRAM``
-must be set to 1. Also, the location of the binary that contains the BL32 image
+flag ``ENABLE_SPM=1``, along with ``EL3_EXCEPTION_HANDLING=1``. On Arm
+platforms the build option ``ARM_BL31_IN_DRAM`` must be set to 1. Also, the
+location of the binary that contains the BL32 image
 (``BL32=path/to/image.bin``) must be specified.
 
 First, build the Standalone MM Secure Partition. To build it, refer to the
diff --git a/drivers/arm/tzc/tzc_dmc620.c b/drivers/arm/tzc/tzc_dmc620.c
new file mode 100644
index 0000000..4abd080
--- /dev/null
+++ b/drivers/arm/tzc/tzc_dmc620.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <mmio.h>
+#include <tzc_dmc620.h>
+
+/* Mask to extract bit 31 to 16 */
+#define MASK_31_16 UINT64_C(0x0000ffff0000)
+/* Mask to extract bit 47 to 32 */
+#define MASK_47_32 UINT64_C(0xffff00000000)
+
+/* Helper macro for getting dmc_base addr of a dmc_inst */
+#define DMC_BASE(plat_data, dmc_inst) \
+	((uintptr_t)(plat_data->dmc_base[dmc_inst]))
+
+/* Pointer to the tzc_dmc620_config_data structure populated by the platform */
+static const tzc_dmc620_config_data_t *g_plat_config_data;
+
+#if ENABLE_ASSERTIONS
+/*
+ * Helper function to check if the DMC-620 instance is present at the
+ * base address provided by the platform and also check if at least
+ * one dmc instance is present.
+ */
+static void tzc_dmc620_validate_plat_driver_data(
+			const tzc_dmc620_driver_data_t *plat_driver_data)
+{
+	uint8_t dmc_inst, dmc_count;
+	unsigned int dmc_id;
+	uintptr_t base;
+
+	assert(plat_driver_data != NULL);
+
+	dmc_count = plat_driver_data->dmc_count;
+	assert(dmc_count > 0U);
+
+	for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
+		base = DMC_BASE(plat_driver_data, dmc_inst);
+		dmc_id = mmio_read_32(base + DMC620_PERIPHERAL_ID_0);
+		assert(dmc_id == DMC620_PERIPHERAL_ID_0_VALUE);
+	}
+}
+#endif
+
+/*
+ * Program a region with region base and region top addresses of all
+ * DMC-620 instances.
+ */
+static void tzc_dmc620_configure_region(int region_no,
+					unsigned long long region_base,
+					unsigned long long region_top,
+					unsigned int sec_attr)
+{
+	uint32_t min_31_00, min_47_32;
+	uint32_t max_31_00, max_47_32;
+	uint8_t dmc_inst, dmc_count;
+	uintptr_t base;
+	const tzc_dmc620_driver_data_t *plat_driver_data;
+
+	plat_driver_data = g_plat_config_data->plat_drv_data;
+	assert(plat_driver_data != NULL);
+
+	/* Do range checks on regions. */
+	assert((region_no >= 0U) && (region_no <= DMC620_ACC_ADDR_COUNT));
+
+	/* region_base and (region_top + 1) must be 4KB aligned */
+	assert(((region_base | (region_top + 1U)) & (4096U - 1U)) == 0U);
+
+	dmc_count = plat_driver_data->dmc_count;
+	for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
+		min_31_00 = (region_base & MASK_31_16) | sec_attr;
+		min_47_32 = (region_base & MASK_47_32)
+				>> DMC620_ACC_ADDR_WIDTH;
+		max_31_00 = (region_top  & MASK_31_16);
+		max_47_32 = (region_top  & MASK_47_32)
+				>> DMC620_ACC_ADDR_WIDTH;
+
+		/* Extract the base address of the DMC-620 instance */
+		base = DMC_BASE(plat_driver_data, dmc_inst);
+		/* Configure access address region registers */
+		mmio_write_32(base + DMC620_ACC_ADDR_MIN_31_00_NEXT(region_no),
+				min_31_00);
+		mmio_write_32(base + DMC620_ACC_ADDR_MIN_47_32_NEXT(region_no),
+				min_47_32);
+		mmio_write_32(base + DMC620_ACC_ADDR_MAX_31_00_NEXT(region_no),
+				max_31_00);
+		mmio_write_32(base + DMC620_ACC_ADDR_MAX_47_32_NEXT(region_no),
+				max_47_32);
+	}
+}
+
+/*
+ * Set the action value for all the DMC-620 instances.
+ */
+static void tzc_dmc620_set_action(void)
+{
+	uint8_t dmc_inst, dmc_count;
+	uintptr_t base;
+	const tzc_dmc620_driver_data_t *plat_driver_data;
+
+	plat_driver_data = g_plat_config_data->plat_drv_data;
+	dmc_count = plat_driver_data->dmc_count;
+	for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
+		/* Extract the base address of the DMC-620 instance */
+		base = DMC_BASE(plat_driver_data, dmc_inst);
+		/* Switch to READY */
+		mmio_write_32(base + DMC620_MEMC_CMD, DMC620_MEMC_CMD_GO);
+		mmio_write_32(base + DMC620_MEMC_CMD, DMC620_MEMC_CMD_EXECUTE);
+	}
+}
+
+/*
+ * Verify whether the DMC-620 configuration is complete by reading back
+ * configuration registers and comparing it with the configured value. If
+ * configuration is incomplete, loop till the configured value is reflected in
+ * the register.
+ */
+static void tzc_dmc620_verify_complete(void)
+{
+	uint8_t dmc_inst, dmc_count;
+	uintptr_t base;
+	const tzc_dmc620_driver_data_t *plat_driver_data;
+
+	plat_driver_data = g_plat_config_data->plat_drv_data;
+	dmc_count = plat_driver_data->dmc_count;
+	for (dmc_inst = 0U; dmc_inst < dmc_count; dmc_inst++) {
+		/* Extract the base address of the DMC-620 instance */
+		base = DMC_BASE(plat_driver_data, dmc_inst);
+		while ((mmio_read_32(base + DMC620_MEMC_STATUS) &
+				DMC620_MEMC_CMD_MASK) != DMC620_MEMC_CMD_GO)
+			continue;
+	}
+}
+
+/*
+ * Initialize the DMC-620 TrustZone Controller using the region configuration
+ * supplied by the platform. The DMC620 controller should be enabled elsewhere
+ * before invoking this function.
+ */
+void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data)
+{
+	int i;
+
+	/* Check if valid pointer is passed */
+	assert(plat_config_data != NULL);
+
+	/*
+	 * Check if access address count passed by the platform is less than or
+	 * equal to DMC620's access address count
+	 */
+	assert(plat_config_data->acc_addr_count <= DMC620_ACC_ADDR_COUNT);
+
+#if ENABLE_ASSERTIONS
+	/* Validates the information passed by platform */
+	tzc_dmc620_validate_plat_driver_data(plat_config_data->plat_drv_data);
+#endif
+
+	g_plat_config_data = plat_config_data;
+
+	INFO("Configuring DMC-620 TZC settings\n");
+	for (i = 0U; i < g_plat_config_data->acc_addr_count; i++)
+		tzc_dmc620_configure_region(i,
+			g_plat_config_data->plat_acc_addr_data[i].region_base,
+			g_plat_config_data->plat_acc_addr_data[i].region_top,
+			g_plat_config_data->plat_acc_addr_data[i].sec_attr);
+
+	tzc_dmc620_set_action();
+	tzc_dmc620_verify_complete();
+	INFO("DMC-620 TZC setup completed\n");
+}
diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S
index 6575af4..25c21cf 100644
--- a/drivers/marvell/uart/a3700_console.S
+++ b/drivers/marvell/uart/a3700_console.S
@@ -5,16 +5,27 @@
  * https://spdx.org/licenses
  */
 
+#include <arch.h>
 #include <asm_macros.S>
 #include <a3700_console.h>
+#define USE_FINISH_CONSOLE_REG_2
+#include <console_macros.S>
 
-	.globl	console_core_init
-	.globl	console_core_putc
-	.globl	console_core_getc
-	.globl	console_core_flush
+	/*
+	 * "core" functions are low-level implementations that don't require
+	 * writable memory and are thus safe to call in BL1 crash context.
+	 */
+	.globl console_a3700_core_putc
+	.globl console_a3700_core_init
+	.globl console_a3700_core_getc
+	.globl console_a3700_core_flush
+
+	.globl console_a3700_putc
+	.globl console_a3700_getc
+	.globl console_a3700_flush
 
 	/* -----------------------------------------------
-	 * int console_core_init(unsigned long base_addr,
+	 * int console_a3700_core_init(unsigned long base_addr,
 	 * unsigned int uart_clk, unsigned int baud_rate)
 	 * Function to initialize the console without a
 	 * C Runtime to print debug information. This
@@ -27,7 +38,7 @@
 	 * Clobber list : x1, x2, x3
 	 * -----------------------------------------------
 	 */
-func console_core_init
+func console_a3700_core_init
 	/* Check the input base address */
 	cbz	x0, init_fail
 	/* Check baud rate and uart clock for sanity */
@@ -95,10 +106,43 @@
 init_fail:
 	mov	w0, #0
 	ret
-endfunc console_core_init
+endfunc console_a3700_core_init
+
+	.globl console_a3700_register
+
+	/* -----------------------------------------------
+	 * int console_a3700_register(console_16550_t *console,
+		uintptr_t base, uint32_t clk, uint32_t baud)
+	 * Function to initialize and register a new a3700
+	 * 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_a3700_t struct
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : x0, x1, x2, x6, x7, x14
+	 * -----------------------------------------------
+	 */
+func console_a3700_register
+	mov	x7, x30
+	mov	x6, x3
+	cbz	x6, register_fail
+	str	x0, [x6, #CONSOLE_T_A3700_BASE]
+
+	bl	console_a3700_core_init
+	cbz	x0, register_fail
+
+	mov	x0, x6
+	mov	x30, x7
+	finish_console_register a3700, putc=1, getc=1, flush=1
+
+register_fail:
+	ret	x7
+endfunc console_a3700_register
 
 	/* --------------------------------------------------------
-	 * int console_core_putc(int c, unsigned int base_addr)
+	 * int console_a3700_core_putc(int c, unsigned int 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
@@ -107,7 +151,7 @@
 	 * Clobber list : x2
 	 * --------------------------------------------------------
 	 */
-func console_core_putc
+func console_a3700_core_putc
 	/* Check the input parameter */
 	cbz	x1, putc_error
 
@@ -132,10 +176,25 @@
 putc_error:
 	mov	w0, #-1
 	ret
-endfunc console_core_putc
+endfunc console_a3700_core_putc
+
+	/* --------------------------------------------------------
+	 * int console_a3700_putc(int c, console_a3700_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_a3700_putc
+	ldr	x1, [x1, #CONSOLE_T_A3700_BASE]
+	b	console_a3700_core_putc
+endfunc console_a3700_putc
 
 	/* ---------------------------------------------
-	 * int console_core_getc(void)
+	 * int console_a3700_core_getc(void)
 	 * Function to get a character from the console.
 	 * It returns the character grabbed on success
 	 * or -1 on error.
@@ -144,16 +203,28 @@
 	 * Clobber list : x0, x1
 	 * ---------------------------------------------
 	 */
-func console_core_getc
-	/* Check if the receive FIFO is empty */
-	ret
-getc_error:
+func console_a3700_core_getc
 	mov	w0, #-1
 	ret
-endfunc console_core_getc
+endfunc console_a3700_core_getc
+
+	/* ---------------------------------------------
+	 * int console_a3700_getc(console_a3700_t *console)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 on 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_a3700_getc
+	ldr	x0, [x0, #CONSOLE_T_A3700_BASE]
+	b	console_a3700_core_getc
+endfunc console_a3700_getc
 
 	/* ---------------------------------------------
-	 * int console_core_flush(uintptr_t base_addr)
+	 * int console_a3700_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
@@ -161,8 +232,22 @@
 	 * Clobber list : x0, x1
 	 * ---------------------------------------------
 	 */
-func console_core_flush
-	/* Placeholder */
+func console_a3700_core_flush
 	mov	w0, #0
 	ret
-endfunc console_core_flush
+endfunc console_a3700_core_flush
+
+	/* ---------------------------------------------
+	 * int console_a3700_flush(console_a3700_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_a3700_flush
+	ldr	x0, [x0, #CONSOLE_T_A3700_BASE]
+	b	console_a3700_core_flush
+endfunc console_a3700_flush
+
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index 792703a..303d6ba 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -4,30 +4,27 @@
  * 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 <stm32_console.h>
+#include <stm32_uart_regs.h>
 
 #define USART_TIMEOUT		0x1000
 
-#define USART_CR1		0x00
-#define USART_CR1_UE		0x00000001
-#define USART_CR1_TE		0x00000008
-#define USART_CR1_FIFOEN	0x20000000
-
-#define USART_CR2		0x04
-#define USART_CR2_STOP		0x00003000
-
-#define USART_BRR		0x0C
+	/*
+	 * "core" functions are low-level implementations that don't require
+	 * writeable memory and are thus safe to call in BL1 crash context.
+	 */
+	.globl	console_stm32_core_init
+	.globl	console_stm32_core_putc
+	.globl	console_stm32_core_getc
+	.globl	console_stm32_core_flush
 
-#define USART_ISR		0x1C
-#define USART_ISR_TC		0x00000040
-#define USART_ISR_TXE		0x00000080
-#define USART_ISR_TEACK		0x00200000
+	.globl	console_stm32_putc
+	.globl	console_stm32_flush
 
-#define USART_TDR		0x28
 
-	.globl	console_core_init
-	.globl	console_core_putc
-	.globl	console_core_getc
-	.globl	console_core_flush
 
 	/* -----------------------------------------------------------------
 	 * int console_core_init(uintptr_t base_addr,
@@ -45,7 +42,7 @@
 	 * Clobber list : r1, r2, r3
 	 * -----------------------------------------------------------------
 	 */
-func console_core_init
+func console_stm32_core_init
 	/* Check the input base address */
 	cmp	r0, #0
 	beq	core_init_fail
@@ -88,7 +85,43 @@
 core_init_fail:
 	mov	r0, #0
 	bx	lr
-endfunc console_core_init
+endfunc console_stm32_core_init
+
+	.globl console_stm32_register
+
+	/* -------------------------------------------------------
+	 * int console_stm32_register(uintptr_t baseaddr,
+	 *     uint32_t clock, uint32_t baud,
+	 *     struct console_stm32 *console);
+	 * Function to initialize and register a new STM32
+	 * console. Storage passed in for the console struct
+	 * *must* be persistent (i.e. not from the stack).
+	 * In: r0 - UART register base address
+	 *     r1 - UART clock in Hz
+	 *     r2 - Baud rate
+	 *     r3 - pointer to empty console_stm32 struct
+	 * Out: return 1 on success, 0 on error
+	 * Clobber list : r0, r1, r2
+	 * -------------------------------------------------------
+	 */
+func console_stm32_register
+	push	{r4, lr}
+	mov	r4, r3
+	cmp	r4, #0
+	beq	register_fail
+	str	r0, [r4, #CONSOLE_T_STM32_BASE]
+
+	bl console_stm32_core_init
+	cmp	r0, #0
+	beq	register_fail
+
+	mov	r0, r4
+	pop	{r4, lr}
+	finish_console_register stm32 putc=1, getc=0, flush=1
+
+register_fail:
+	pop	{r4, pc}
+endfunc console_stm32_register
 
 	/* ---------------------------------------------------------------
 	 * int console_core_putc(int c, uintptr_t base_addr)
@@ -102,7 +135,7 @@
 	 * Clobber list : r2
 	 * ---------------------------------------------------------------
 	 */
-func console_core_putc
+func console_stm32_core_putc
 	/* Check the input parameter */
 	cmp	r1, #0
 	beq	putc_error
@@ -138,7 +171,26 @@
 putc_error:
 	mov	r0, #-1
 	bx	lr
-endfunc console_core_putc
+endfunc console_stm32_core_putc
+
+	/* ------------------------------------------------------------
+	 * int console_stm32_putc(int c, struct console_stm32 *console)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In: r0 - character to be printed
+	 *     r1 - pointer to console_t structure
+	 * Out : return -1 on error else return character.
+	 * Clobber list: r2
+	 * ------------------------------------------------------------
+	 */
+func console_stm32_putc
+#if ENABLE_ASSERTIONS
+	cmp	r1, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	r1, [r1, #CONSOLE_T_STM32_BASE]
+	b	console_stm32_core_putc
+endfunc console_stm32_putc
 
 	/* -----------------------------------------------------------
 	 * int console_core_getc(uintptr_t base_addr)
@@ -151,11 +203,11 @@
 	 * Clobber list : r0, r1
 	 * -----------------------------------------------------------
 	 */
-func console_core_getc
+func console_stm32_core_getc
 	/* Not supported */
 	mov	r0, #-1
 	bx	lr
-endfunc console_core_getc
+endfunc console_stm32_core_getc
 
 	/* ---------------------------------------------------------------
 	 * int console_core_flush(uintptr_t base_addr)
@@ -168,7 +220,7 @@
 	 * Clobber list : r0, r1
 	 * ---------------------------------------------------------------
 	 */
-func console_core_flush
+func console_stm32_core_flush
 	cmp	r0, #0
 	beq	flush_error
 	/* Check Transmit Data Register Empty */
@@ -181,4 +233,22 @@
 flush_error:
 	mov	r0, #-1
 	bx	lr
-endfunc console_core_flush
+endfunc console_stm32_core_flush
+
+	/* ------------------------------------------------------
+	 * int console_stm32_flush(struct console_stm32 *console)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : r0 - pointer to console_t structure
+	 * Out : return -1 on error else return 0.
+	 * Clobber list: r0, r1
+	 * ------------------------------------------------------
+	 */
+func console_stm32_flush
+#if ENABLE_ASSERTIONS
+	cmp	r0, #0
+	ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+	ldr	r0, [r0, #CONSOLE_T_STM32_BASE]
+	b	console_stm32_core_flush
+endfunc console_stm32_flush
diff --git a/include/drivers/arm/tzc_dmc620.h b/include/drivers/arm/tzc_dmc620.h
new file mode 100644
index 0000000..074bbc1
--- /dev/null
+++ b/include/drivers/arm/tzc_dmc620.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TZC_DMC620_H
+#define TZC_DMC620_H
+
+#include <utils_def.h>
+
+/* DMC-620 memc register offsets */
+#define DMC620_MEMC_STATUS	U(0x0000)
+#define DMC620_MEMC_CMD		U(0x0008)
+
+/* Mask value to check the status of memc_cmd register */
+#define DMC620_MEMC_CMD_MASK	U(0x00000007)
+
+/* memc_cmd register's action values */
+#define DMC620_MEMC_CMD_GO	U(0x00000003)
+#define DMC620_MEMC_CMD_EXECUTE	U(0x00000004)
+
+/* Address offsets of access address next region 0 registers */
+#define DMC620_ACC_ADDR_MIN_31_00_NEXT_BASE	U(0x0080)
+#define DMC620_ACC_ADDR_MIN_47_32_NEXT_BASE	U(0x0084)
+#define DMC620_ACC_ADDR_MAX_31_00_NEXT_BASE	U(0x0088)
+#define DMC620_ACC_ADDR_MAX_47_32_NEXT_BASE	U(0x008c)
+
+/* Length of one block of access address next register region */
+#define DMC620_ACC_ADDR_NEXT_SIZE		U(0x0010)
+
+/* Address offsets of access address next registers */
+#define DMC620_ACC_ADDR_MIN_31_00_NEXT(region_no)	\
+		(DMC620_ACC_ADDR_MIN_31_00_NEXT_BASE +	\
+			(region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+#define DMC620_ACC_ADDR_MIN_47_32_NEXT(region_no)	\
+		(DMC620_ACC_ADDR_MIN_47_32_NEXT_BASE +	\
+			(region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+#define DMC620_ACC_ADDR_MAX_31_00_NEXT(region_no)	\
+		(DMC620_ACC_ADDR_MAX_31_00_NEXT_BASE +	\
+			(region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+#define DMC620_ACC_ADDR_MAX_47_32_NEXT(region_no)	\
+		(DMC620_ACC_ADDR_MAX_47_32_NEXT_BASE +	\
+			(region_no * DMC620_ACC_ADDR_NEXT_SIZE))
+
+/* Number of TZC address regions in DMC-620 */
+#define DMC620_ACC_ADDR_COUNT	U(8)
+/* Width of access address registers */
+#define DMC620_ACC_ADDR_WIDTH	U(32)
+
+/* Peripheral ID registers offsets */
+#define DMC620_PERIPHERAL_ID_0		U(0x1fe0)
+
+/* Default values in id registers */
+#define DMC620_PERIPHERAL_ID_0_VALUE	U(0x00000054)
+
+/* Secure access region attributes. */
+#define TZC_DMC620_REGION_NS_RD		U(0x00000001)
+#define TZC_DMC620_REGION_NS_WR		U(0x00000002)
+#define TZC_DMC620_REGION_NS_RDWR	\
+	(TZC_DMC620_REGION_NS_RD | TZC_DMC620_REGION_NS_WR)
+#define TZC_DMC620_REGION_S_RD		U(0x00000004)
+#define TZC_DMC620_REGION_S_WR		U(0x00000008)
+#define TZC_DMC620_REGION_S_RDWR	\
+	(TZC_DMC620_REGION_S_RD | TZC_DMC620_REGION_S_WR)
+#define TZC_DMC620_REGION_S_NS_RDWR	\
+	(TZC_DMC620_REGION_NS_RDWR | TZC_DMC620_REGION_S_RDWR)
+
+/*
+ * Contains pointer to the base addresses of all the DMC-620 instances.
+ * 'dmc_count' specifies the number of DMC base addresses contained in the
+ * array pointed to by dmc_base.
+ */
+typedef struct tzc_dmc620_driver_data {
+	const uintptr_t *dmc_base;
+	const unsigned int dmc_count;
+} tzc_dmc620_driver_data_t;
+
+/*
+ * Contains region base, region top addresses and corresponding attributes
+ * for configuring TZC access region registers.
+ */
+typedef struct tzc_dmc620_acc_addr_data {
+	const unsigned long long region_base;
+	const unsigned long long region_top;
+	const unsigned int sec_attr;
+} tzc_dmc620_acc_addr_data_t;
+
+/*
+ * Contains platform specific data for configuring TZC region base and
+ * region top address. 'acc_addr_count' specifies the number of
+ * valid entries in 'plat_acc_addr_data' array.
+ */
+typedef struct tzc_dmc620_config_data {
+	const tzc_dmc620_driver_data_t *plat_drv_data;
+	const tzc_dmc620_acc_addr_data_t *plat_acc_addr_data;
+	const uint8_t acc_addr_count;
+} tzc_dmc620_config_data_t;
+
+/* Function prototypes */
+void arm_tzc_dmc620_setup(const tzc_dmc620_config_data_t *plat_config_data);
+
+#endif /* TZC_DMC620_H */
+
diff --git a/drivers/marvell/uart/a3700_console.h b/include/drivers/marvell/uart/a3700_console.h
similarity index 73%
rename from drivers/marvell/uart/a3700_console.h
rename to include/drivers/marvell/uart/a3700_console.h
index de7c4fc..01335a2 100644
--- a/drivers/marvell/uart/a3700_console.h
+++ b/include/drivers/marvell/uart/a3700_console.h
@@ -8,6 +8,8 @@
 #ifndef A3700_CONSOLE_H
 #define A3700_CONSOLE_H
 
+#include <console.h>
+
 /* MVEBU UART Registers */
 #define UART_RX_REG		0x00
 #define UART_TX_REG		0x04
@@ -52,4 +54,26 @@
 #define UART_CTRL_TXFIFO_RESET	(1 << 15)
 #define UARTLSR_TXFIFOEMPTY	(1 << 6)
 
+#define CONSOLE_T_A3700_BASE	CONSOLE_T_DRVDATA
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+typedef struct {
+	console_t console;
+	uintptr_t base;
+} console_a3700_t;
+
+/*
+ * Initialize a new a3700 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.
+ */
+int console_a3700_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+			   console_a3700_t *console);
+
+#endif /*__ASSEMBLY__*/
+
-#endif /* A3700_CONSOLE_H */
+#endif	/* A3700_CONSOLE_H */
diff --git a/include/drivers/st/stm32_console.h b/include/drivers/st/stm32_console.h
new file mode 100644
index 0000000..57e6d74
--- /dev/null
+++ b/include/drivers/st/stm32_console.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32_CONSOLE_H
+#define STM32_CONSOLE_H
+
+#include <console.h>
+
+#define CONSOLE_T_STM32_BASE	CONSOLE_T_DRVDATA
+
+#ifndef __ASSEMBLY__
+
+#include <stdint.h>
+
+struct console_stm32 {
+	console_t console;
+	uintptr_t base;
+};
+
+/*
+ * Initialize a new STM32 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.
+ */
+int console_stm32_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+			   struct console_stm32 *console);
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* STM32_CONSOLE_H */
diff --git a/include/drivers/st/stm32_uart_regs.h b/include/drivers/st/stm32_uart_regs.h
new file mode 100644
index 0000000..e78d3d4
--- /dev/null
+++ b/include/drivers/st/stm32_uart_regs.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32_UART_REGS_H
+#define STM32_UART_REGS_H
+
+#include <utils_def.h>
+
+#define USART_CR1		U(0x00)
+#define USART_CR2		U(0x04)
+#define USART_CR3		U(0x08)
+#define USART_BRR		U(0x0C)
+#define USART_GTPR		U(0x10)
+#define USART_RTOR		U(0x14)
+#define USART_RQR		U(0x18)
+#define USART_ISR		U(0x1C)
+#define USART_ICR		U(0x20)
+#define USART_RDR		U(0x24)
+#define USART_TDR		U(0x28)
+#define USART_PRESC		U(0x2C)
+
+/* USART_CR1 register fields */
+#define USART_CR1_UE		BIT(0)
+#define USART_CR1_UESM		BIT(1)
+#define USART_CR1_RE		BIT(2)
+#define USART_CR1_TE		BIT(3)
+#define USART_CR1_IDLEIE	BIT(4)
+#define USART_CR1_RXNEIE	BIT(5)
+#define USART_CR1_TCIE		BIT(6)
+#define USART_CR1_TXEIE		BIT(7)
+#define USART_CR1_PEIE		BIT(8)
+#define USART_CR1_PS		BIT(9)
+#define USART_CR1_PCE		BIT(10)
+#define USART_CR1_WAKE		BIT(11)
+#define USART_CR1_M		(BIT(28) | BIT(12))
+#define USART_CR1_M0		BIT(12)
+#define USART_CR1_MME		BIT(13)
+#define USART_CR1_CMIE		BIT(14)
+#define USART_CR1_OVER8		BIT(15)
+#define USART_CR1_DEDT		GENMASK(20, 16)
+#define USART_CR1_DEDT_0	BIT(16)
+#define USART_CR1_DEDT_1	BIT(17)
+#define USART_CR1_DEDT_2	BIT(18)
+#define USART_CR1_DEDT_3	BIT(19)
+#define USART_CR1_DEDT_4	BIT(20)
+#define USART_CR1_DEAT		GENMASK(25, 21)
+#define USART_CR1_DEAT_0	BIT(21)
+#define USART_CR1_DEAT_1	BIT(22)
+#define USART_CR1_DEAT_2	BIT(23)
+#define USART_CR1_DEAT_3	BIT(24)
+#define USART_CR1_DEAT_4	BIT(25)
+#define USART_CR1_RTOIE		BIT(26)
+#define USART_CR1_EOBIE		BIT(27)
+#define USART_CR1_M1		BIT(28)
+#define USART_CR1_FIFOEN	BIT(29)
+#define USART_CR1_TXFEIE	BIT(30)
+#define USART_CR1_RXFFIE	BIT(31)
+
+/* USART_CR2 register fields */
+#define USART_CR2_SLVEN		BIT(0)
+#define USART_CR2_DIS_NSS	BIT(3)
+#define USART_CR2_ADDM7		BIT(4)
+#define USART_CR2_LBDL		BIT(5)
+#define USART_CR2_LBDIE		BIT(6)
+#define USART_CR2_LBCL		BIT(8)
+#define USART_CR2_CPHA		BIT(9)
+#define USART_CR2_CPOL		BIT(10)
+#define USART_CR2_CLKEN		BIT(11)
+#define USART_CR2_STOP		GENMASK(13, 12)
+#define USART_CR2_STOP_0	BIT(12)
+#define USART_CR2_STOP_1	BIT(13)
+#define USART_CR2_LINEN		BIT(14)
+#define USART_CR2_SWAP		BIT(15)
+#define USART_CR2_RXINV		BIT(16)
+#define USART_CR2_TXINV		BIT(17)
+#define USART_CR2_DATAINV	BIT(18)
+#define USART_CR2_MSBFIRST	BIT(19)
+#define USART_CR2_ABREN		BIT(20)
+#define USART_CR2_ABRMODE	GENMASK(22, 21)
+#define USART_CR2_ABRMODE_0	BIT(21)
+#define USART_CR2_ABRMODE_1	BIT(22)
+#define USART_CR2_RTOEN		BIT(23)
+#define USART_CR2_ADD		GENMASK(31, 24)
+
+/* USART_CR3 register fields */
+#define USART_CR3_EIE		BIT(0)
+#define USART_CR3_IREN		BIT(1)
+#define USART_CR3_IRLP		BIT(2)
+#define USART_CR3_HDSEL		BIT(3)
+#define USART_CR3_NACK		BIT(4)
+#define USART_CR3_SCEN		BIT(5)
+#define USART_CR3_DMAR		BIT(6)
+#define USART_CR3_DMAT		BIT(7)
+#define USART_CR3_RTSE		BIT(8)
+#define USART_CR3_CTSE		BIT(9)
+#define USART_CR3_CTSIE		BIT(10)
+#define USART_CR3_ONEBIT	BIT(11)
+#define USART_CR3_OVRDIS	BIT(12)
+#define USART_CR3_DDRE		BIT(13)
+#define USART_CR3_DEM		BIT(14)
+#define USART_CR3_DEP		BIT(15)
+#define USART_CR3_SCARCNT	GENMASK(19, 17)
+#define USART_CR3_SCARCNT_0	BIT(17)
+#define USART_CR3_SCARCNT_1	BIT(18)
+#define USART_CR3_SCARCNT_2	BIT(19)
+#define USART_CR3_WUS		GENMASK(21, 20)
+#define USART_CR3_WUS_0		BIT(20)
+#define USART_CR3_WUS_1		BIT(21)
+#define USART_CR3_WUFIE		BIT(22)
+#define USART_CR3_TXFTIE	BIT(23)
+#define USART_CR3_TCBGTIE	BIT(24)
+#define USART_CR3_RXFTCFG	GENMASK(27, 25)
+#define USART_CR3_RXFTCFG_0	BIT(25)
+#define USART_CR3_RXFTCFG_1	BIT(26)
+#define USART_CR3_RXFTCFG_2	BIT(27)
+#define USART_CR3_RXFTIE	BIT(28)
+#define USART_CR3_TXFTCFG	GENMASK(31, 29)
+#define USART_CR3_TXFTCFG_0	BIT(29)
+#define USART_CR3_TXFTCFG_1	BIT(30)
+#define USART_CR3_TXFTCFG_2	BIT(31)
+
+/* USART_BRR register fields */
+#define USART_BRR_DIV_FRACTION	GENMASK(3, 0)
+#define USART_BRR_DIV_MANTISSA	GENMASK(15, 4)
+
+/* USART_GTPR register fields */
+#define USART_GTPR_PSC		GENMASK(7, 0)
+#define USART_GTPR_GT		GENMASK(15, 8)
+
+/* USART_RTOR register fields */
+#define USART_RTOR_RTO		GENMASK(23, 0)
+#define USART_RTOR_BLEN		GENMASK(31, 24)
+
+/* USART_RQR register fields */
+#define USART_RQR_ABRRQ		BIT(0)
+#define USART_RQR_SBKRQ		BIT(1)
+#define USART_RQR_MMRQ		BIT(2)
+#define USART_RQR_RXFRQ		BIT(3)
+#define USART_RQR_TXFRQ		BIT(4)
+
+/* USART_ISR register fields */
+#define USART_ISR_PE		BIT(0)
+#define USART_ISR_FE		BIT(1)
+#define USART_ISR_NE		BIT(2)
+#define USART_ISR_ORE		BIT(3)
+#define USART_ISR_IDLE		BIT(4)
+#define USART_ISR_RXNE		BIT(5)
+#define USART_ISR_TC		BIT(6)
+#define USART_ISR_TXE		BIT(7)
+#define USART_ISR_LBDF		BIT(8)
+#define USART_ISR_CTSIF		BIT(9)
+#define USART_ISR_CTS		BIT(10)
+#define USART_ISR_RTOF		BIT(11)
+#define USART_ISR_EOBF		BIT(12)
+#define USART_ISR_UDR		BIT(13)
+#define USART_ISR_ABRE		BIT(14)
+#define USART_ISR_ABRF		BIT(15)
+#define USART_ISR_BUSY		BIT(16)
+#define USART_ISR_CMF		BIT(17)
+#define USART_ISR_SBKF		BIT(18)
+#define USART_ISR_RWU		BIT(19)
+#define USART_ISR_WUF		BIT(20)
+#define USART_ISR_TEACK		BIT(21)
+#define USART_ISR_REACK		BIT(22)
+#define USART_ISR_TXFE		BIT(23)
+#define USART_ISR_RXFF		BIT(24)
+#define USART_ISR_TCBGT		BIT(25)
+#define USART_ISR_RXFT		BIT(26)
+#define USART_ISR_TXFT		BIT(27)
+
+/* USART_ICR register fields */
+#define USART_ICR_PECF		BIT(0)
+#define USART_ICR_FECF		BIT(1)
+#define USART_ICR_NCF		BIT(2)
+#define USART_ICR_ORECF		BIT(3)
+#define USART_ICR_IDLECF	BIT(4)
+#define USART_ICR_TCCF		BIT(6)
+#define USART_ICR_TCBGT		BIT(7)
+#define USART_ICR_LBDCF		BIT(8)
+#define USART_ICR_CTSCF		BIT(9)
+#define USART_ICR_RTOCF		BIT(11)
+#define USART_ICR_EOBCF		BIT(12)
+#define USART_ICR_UDRCF		BIT(13)
+#define USART_ICR_CMCF		BIT(17)
+#define USART_ICR_WUCF		BIT(20)
+
+/* USART_RDR register fields */
+#define USART_RDR_RDR		GENMASK(8, 0)
+
+/* USART_TDR register fields */
+#define USART_TDR_TDR		GENMASK(8, 0)
+
+/* USART_PRESC register fields */
+#define USART_PRESC_PRESCALER	GENMASK(3, 0)
+
+#endif /* STM32_UART_REGS_H */
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 1dd57cb..fa13caa 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -30,11 +30,19 @@
  * position @h. For example
  * GENMASK_64(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
+#if defined(__LINKER__) || defined(__ASSEMBLY__)
+#define GENMASK_32(h, l) \
+	(((0xFFFFFFFF) << (l)) & (0xFFFFFFFF >> (32 - 1 - (h))))
+
+#define GENMASK_64(h, l) \
+	((~0 << (l)) & (~0 >> (64 - 1 - (h))))
+#else
 #define GENMASK_32(h, l) \
 	(((~UINT32_C(0)) << (l)) & (~UINT32_C(0) >> (32 - 1 - (h))))
 
 #define GENMASK_64(h, l) \
 	(((~UINT64_C(0)) << (l)) & (~UINT64_C(0) >> (64 - 1 - (h))))
+#endif
 
 #ifdef AARCH32
 #define GENMASK				GENMASK_32
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 4bd0bb2..8c0a567 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -34,6 +34,12 @@
 	MAP_REGION(_adr, _adr, _sz, _attr)
 
 /*
+ * Helper macro to define entries for mmap_region_t. It allows to define 'pa'
+ * and sets 'va' to 0 for each region. To be used with mmap_add_alloc_va().
+ */
+#define MAP_REGION_ALLOC_VA(pa, sz, attr)	MAP_REGION(pa, 0, sz, attr)
+
+/*
  * Helper macro to define an mmap_region_t to map with the desired granularity
  * of translation tables.
  *
@@ -219,6 +225,21 @@
 void mmap_add(const mmap_region_t *mm);
 void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm);
 
+/*
+ * Add a region with defined base PA. Returns base VA calculated using the
+ * highest existing region in the mmap array even if it fails to allocate the
+ * region.
+ */
+void mmap_add_region_alloc_va(unsigned long long base_pa, uintptr_t *base_va,
+			      size_t size, unsigned int attr);
+void mmap_add_region_alloc_va_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
+
+/*
+ * Add an array of static regions with defined base PA, and fill the base VA
+ * field on the array of structs. This function can only be used before
+ * initializing the translation tables. The regions cannot be removed afterwards.
+ */
+void mmap_add_alloc_va(mmap_region_t *mm);
 
 #if PLAT_XLAT_TABLES_DYNAMIC
 /*
@@ -237,6 +258,21 @@
 int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
 
 /*
+ * Add a dynamic region with defined base PA. Returns base VA calculated using
+ * the highest existing region in the mmap array even if it fails to allocate
+ * the region.
+ *
+ * mmap_add_dynamic_region_alloc_va() returns the allocated VA in 'base_va'.
+ * mmap_add_dynamic_region_alloc_va_ctx() returns it in 'mm->base_va'.
+ *
+ * It returns the same error values as mmap_add_dynamic_region().
+ */
+int mmap_add_dynamic_region_alloc_va(unsigned long long base_pa,
+				     uintptr_t *base_va,
+				     size_t size, unsigned int attr);
+int mmap_add_dynamic_region_alloc_va_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
+
+/*
  * Remove a region with the specified base VA and size. Only dynamic regions can
  * be removed, and they can be removed even if the translation tables are
  * initialized.
diff --git a/include/plat/marvell/a3700/common/plat_marvell.h b/include/plat/marvell/a3700/common/plat_marvell.h
index 8c289e9..01e42c5 100644
--- a/include/plat/marvell/a3700/common/plat_marvell.h
+++ b/include/plat/marvell/a3700/common/plat_marvell.h
@@ -39,6 +39,12 @@
 #endif
 );
 
+/* Console utility functions */
+void marvell_console_boot_init(void);
+void marvell_console_boot_end(void);
+void marvell_console_runtime_init(void);
+void marvell_console_runtime_end(void);
+
 /* IO storage utility functions */
 void marvell_io_setup(void);
 
diff --git a/include/plat/marvell/a8k/common/plat_marvell.h b/include/plat/marvell/a8k/common/plat_marvell.h
index f062491..037548d 100644
--- a/include/plat/marvell/a8k/common/plat_marvell.h
+++ b/include/plat/marvell/a8k/common/plat_marvell.h
@@ -48,6 +48,12 @@
 #endif
 );
 
+/* Console utility functions */
+void marvell_console_boot_init(void);
+void marvell_console_boot_end(void);
+void marvell_console_runtime_init(void);
+void marvell_console_runtime_end(void);
+
 /* IO storage utility functions */
 void marvell_io_setup(void);
 
diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c
index f180774..b887427 100644
--- a/lib/xlat_tables_v2/xlat_tables_context.c
+++ b/lib/xlat_tables_v2/xlat_tables_context.c
@@ -38,6 +38,25 @@
 	mmap_add_ctx(&tf_xlat_ctx, mm);
 }
 
+void mmap_add_region_alloc_va(unsigned long long base_pa, uintptr_t *base_va,
+			      size_t size, unsigned int attr)
+{
+	mmap_region_t mm = MAP_REGION_ALLOC_VA(base_pa, size, attr);
+
+	mmap_add_region_alloc_va_ctx(&tf_xlat_ctx, &mm);
+
+	*base_va = mm.base_va;
+}
+
+void mmap_add_alloc_va(mmap_region_t *mm)
+{
+	while (mm->granularity != 0U) {
+		assert(mm->base_va == 0U);
+		mmap_add_region_alloc_va_ctx(&tf_xlat_ctx, mm);
+		mm++;
+	}
+}
+
 #if PLAT_XLAT_TABLES_DYNAMIC
 
 int mmap_add_dynamic_region(unsigned long long base_pa, uintptr_t base_va,
@@ -48,6 +67,20 @@
 	return mmap_add_dynamic_region_ctx(&tf_xlat_ctx, &mm);
 }
 
+int mmap_add_dynamic_region_alloc_va(unsigned long long base_pa,
+				     uintptr_t *base_va, size_t size,
+				     unsigned int attr)
+{
+	mmap_region_t mm = MAP_REGION_ALLOC_VA(base_pa, size, attr);
+
+	int rc = mmap_add_dynamic_region_alloc_va_ctx(&tf_xlat_ctx, &mm);
+
+	*base_va = mm.base_va;
+
+	return rc;
+}
+
+
 int mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
 {
 	return mmap_remove_dynamic_region_ctx(&tf_xlat_ctx,
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index 8ced76e..185473a 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -811,6 +811,80 @@
 		ctx->max_va = end_va;
 }
 
+/*
+ * Determine the table level closest to the initial lookup level that
+ * can describe this translation. Then, align base VA to the next block
+ * at the determined level.
+ */
+static void mmap_alloc_va_align_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
+{
+	/*
+	 * By or'ing the size and base PA the alignment will be the one
+	 * corresponding to the smallest boundary of the two of them.
+	 *
+	 * There are three different cases. For example (for 4 KiB page size):
+	 *
+	 * +--------------+------------------++--------------+
+	 * | PA alignment | Size multiple of || VA alignment |
+	 * +--------------+------------------++--------------+
+	 * |     2 MiB    |       2 MiB      ||     2 MiB    | (1)
+	 * |     2 MiB    |       4 KiB      ||     4 KiB    | (2)
+	 * |     4 KiB    |       2 MiB      ||     4 KiB    | (3)
+	 * +--------------+------------------++--------------+
+	 *
+	 * - In (1), it is possible to take advantage of the alignment of the PA
+	 *   and the size of the region to use a level 2 translation table
+	 *   instead of a level 3 one.
+	 *
+	 * - In (2), the size is smaller than a block entry of level 2, so it is
+	 *   needed to use a level 3 table to describe the region or the library
+	 *   will map more memory than the desired one.
+	 *
+	 * - In (3), even though the region has the size of one level 2 block
+	 *   entry, it isn't possible to describe the translation with a level 2
+	 *   block entry because of the alignment of the base PA.
+	 *
+	 *   Only bits 47:21 of a level 2 block descriptor are used by the MMU,
+	 *   bits 20:0 of the resulting address are 0 in this case. Because of
+	 *   this, the PA generated as result of this translation is aligned to
+	 *   2 MiB. The PA that was requested to be mapped is aligned to 4 KiB,
+	 *   though, which means that the resulting translation is incorrect.
+	 *   The only way to prevent this is by using a finer granularity.
+	 */
+	unsigned long long align_check;
+
+	align_check = mm->base_pa | (unsigned long long)mm->size;
+
+	/*
+	 * Assume it is always aligned to level 3. There's no need to check that
+	 * level because its block size is PAGE_SIZE. The checks to verify that
+	 * the addresses and size are aligned to PAGE_SIZE are inside
+	 * mmap_add_region.
+	 */
+	for (unsigned int level = ctx->base_level; level <= 2U; ++level) {
+
+		if ((align_check & XLAT_BLOCK_MASK(level)) != 0U)
+			continue;
+
+		mm->base_va = round_up(mm->base_va, XLAT_BLOCK_SIZE(level));
+		return;
+	}
+}
+
+void mmap_add_region_alloc_va_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
+{
+	mm->base_va = ctx->max_va + 1UL;
+
+	assert(mm->size > 0U);
+
+	mmap_alloc_va_align_ctx(ctx, mm);
+
+	/* Detect overflows. More checks are done in mmap_add_region_check(). */
+	assert(mm->base_va > ctx->max_va);
+
+	mmap_add_region_ctx(ctx, mm);
+}
+
 void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
 {
 	const mmap_region_t *mm_cursor = mm;
@@ -931,6 +1005,23 @@
 	return 0;
 }
 
+int mmap_add_dynamic_region_alloc_va_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
+{
+	mm->base_va = ctx->max_va + 1UL;
+
+	if (mm->size == 0U)
+		return 0;
+
+	mmap_alloc_va_align_ctx(ctx, mm);
+
+	/* Detect overflows. More checks are done in mmap_add_region_check(). */
+	if (mm->base_va < ctx->max_va) {
+		return -ENOMEM;
+	}
+
+	return mmap_add_dynamic_region_ctx(ctx, mm);
+}
+
 /*
  * Removes the region with given base Virtual Address and size from the given
  * context.
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 4fd4aef..58b68ab 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -268,4 +268,6 @@
 #define PLAT_ARM_SP_IMAGE_STACK_BASE	(ARM_SP_IMAGE_NS_BUF_BASE +	\
 					 ARM_SP_IMAGE_NS_BUF_SIZE)
 
+#define PLAT_SP_PRI			PLAT_RAS_PRI
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index 1870fc7..c06a0a1 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -8,11 +8,16 @@
 #define PLATFORM_DEF_H
 
 #include <sgi_base_platform_def.h>
+#include <utils_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		2
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	4
 #define CSS_SGI_MAX_PE_PER_CPU		1
 
-#define PLAT_CSS_MHU_BASE		0x45000000
+#define PLAT_CSS_MHU_BASE		UL(0x45000000)
+
+/* Base address of DMC-620 instances */
+#define SGI575_DMC620_BASE0		UL(0x4e000000)
+#define SGI575_DMC620_BASE1		UL(0x4e100000)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index 8df8b12..dd82d29 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -14,7 +14,9 @@
 
 BL1_SOURCES		+=	${SGI_CPU_SOURCES}
 
-BL2_SOURCES		+=	lib/utils/mem_region.c			\
+BL2_SOURCES		+=	${SGI575_BASE}/sgi575_security.c	\
+				drivers/arm/tzc/tzc_dmc620.c		\
+				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
 BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
diff --git a/plat/arm/board/sgi575/sgi575_security.c b/plat/arm/board/sgi575/sgi575_security.c
new file mode 100644
index 0000000..7ccc59a
--- /dev/null
+++ b/plat/arm/board/sgi575/sgi575_security.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <platform_def.h>
+#include <tzc_dmc620.h>
+
+uintptr_t sgi575_dmc_base[] = {
+	SGI575_DMC620_BASE0,
+	SGI575_DMC620_BASE1
+};
+
+static const tzc_dmc620_driver_data_t sgi575_plat_driver_data = {
+	.dmc_base = sgi575_dmc_base,
+	.dmc_count = ARRAY_SIZE(sgi575_dmc_base)
+};
+
+static const tzc_dmc620_acc_addr_data_t sgi575_acc_addr_data[] = {
+	{
+		.region_base = ARM_AP_TZC_DRAM1_BASE,
+		.region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1,
+		.sec_attr = TZC_DMC620_REGION_S_RDWR
+	}
+};
+
+static const tzc_dmc620_config_data_t sgi575_plat_config_data = {
+	.plat_drv_data = &sgi575_plat_driver_data,
+	.plat_acc_addr_data = sgi575_acc_addr_data,
+	.acc_addr_count = ARRAY_SIZE(sgi575_acc_addr_data)
+};
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+	arm_tzc_dmc620_setup(&sgi575_plat_config_data);
+}
diff --git a/plat/arm/board/sgiclarka/include/platform_def.h b/plat/arm/board/sgiclarka/include/platform_def.h
index abc48d8..ba6d043 100644
--- a/plat/arm/board/sgiclarka/include/platform_def.h
+++ b/plat/arm/board/sgiclarka/include/platform_def.h
@@ -8,11 +8,16 @@
 #define PLATFORM_DEF_H
 
 #include <sgi_base_platform_def.h>
+#include <utils_def.h>
 
 #define PLAT_ARM_CLUSTER_COUNT		2
 #define CSS_SGI_MAX_CPUS_PER_CLUSTER	4
 #define CSS_SGI_MAX_PE_PER_CPU		1
 
-#define PLAT_CSS_MHU_BASE		0x45400000
+#define PLAT_CSS_MHU_BASE		UL(0x45400000)
+
+/* Base address of DMC-620 instances */
+#define SGICLARKA_DMC620_BASE0		UL(0x4e000000)
+#define SGICLARKA_DMC620_BASE1		UL(0x4e100000)
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/sgiclarka/platform.mk b/plat/arm/board/sgiclarka/platform.mk
index fc2f766..cf02219 100644
--- a/plat/arm/board/sgiclarka/platform.mk
+++ b/plat/arm/board/sgiclarka/platform.mk
@@ -14,7 +14,9 @@
 
 BL1_SOURCES		+=	${SGI_CPU_SOURCES}
 
-BL2_SOURCES		+=	lib/utils/mem_region.c			\
+BL2_SOURCES		+=	${SGICLARKA_BASE}/sgiclarka_security.c	\
+				drivers/arm/tzc/tzc_dmc620.c		\
+				lib/utils/mem_region.c			\
 				plat/arm/common/arm_nor_psci_mem_protect.c
 
 BL31_SOURCES		+=	${SGI_CPU_SOURCES}			\
diff --git a/plat/arm/board/sgiclarka/sgiclarka_security.c b/plat/arm/board/sgiclarka/sgiclarka_security.c
new file mode 100644
index 0000000..29cd754
--- /dev/null
+++ b/plat/arm/board/sgiclarka/sgiclarka_security.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <platform_def.h>
+#include <tzc_dmc620.h>
+
+uintptr_t sgiclarka_dmc_base[] = {
+	SGICLARKA_DMC620_BASE0,
+	SGICLARKA_DMC620_BASE1
+};
+
+static const tzc_dmc620_driver_data_t sgiclarka_plat_driver_data = {
+	.dmc_base = sgiclarka_dmc_base,
+	.dmc_count = ARRAY_SIZE(sgiclarka_dmc_base)
+};
+
+static const tzc_dmc620_acc_addr_data_t sgiclarka_acc_addr_data[] = {
+	{
+		.region_base = ARM_AP_TZC_DRAM1_BASE,
+		.region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1,
+		.sec_attr = TZC_DMC620_REGION_S_RDWR
+	}
+};
+
+static const tzc_dmc620_config_data_t sgiclarka_plat_config_data = {
+	.plat_drv_data = &sgiclarka_plat_driver_data,
+	.plat_acc_addr_data = sgiclarka_acc_addr_data,
+	.acc_addr_count = ARRAY_SIZE(sgiclarka_acc_addr_data)
+};
+
+/* Initialize the secure environment */
+void plat_arm_security_setup(void)
+{
+	arm_tzc_dmc620_setup(&sgiclarka_plat_config_data);
+}
diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c
index 665871b..f313851 100644
--- a/plat/arm/common/aarch64/arm_ehf.c
+++ b/plat/arm/common/aarch64/arm_ehf.c
@@ -23,6 +23,9 @@
 	/* Normal priority SDEI */
 	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
 #endif
+#if ENABLE_SPM
+	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI),
+#endif
 };
 
 /* Plug in ARM exceptions to Exception Handling Framework. */
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index 90eb336..1395373 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -142,6 +142,8 @@
 					SOC_CSS_DEVICE_SIZE,	\
 					MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
 
+#define PLAT_SP_PRI				PLAT_RAS_PRI
+
 #if RAS_EXTENSION
 /* Allocate 128KB for CPER buffers */
 #define PLAT_SP_BUF_BASE			ULL(0x20000)
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index d6e5448..46fa7c4 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -35,8 +35,7 @@
 
 BL1_SOURCES		+=	${INTERCONNECT_SOURCES}
 
-BL2_SOURCES		+=	${CSS_ENT_BASE}/sgi_security.c		\
-				${CSS_ENT_BASE}/sgi_image_load.c
+BL2_SOURCES		+=	${CSS_ENT_BASE}/sgi_image_load.c
 
 BL31_SOURCES		+=	${INTERCONNECT_SOURCES}			\
 				${ENT_GIC_SOURCES}			\
diff --git a/plat/arm/css/sgi/sgi_security.c b/plat/arm/css/sgi/sgi_security.c
deleted file mode 100644
index 23e1a64..0000000
--- a/plat/arm/css/sgi/sgi_security.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arm_config.h>
-#include <plat_arm.h>
-
-/*
- * We assume that all security programming is done by the primary core.
- */
-void plat_arm_security_setup(void)
-{
-}
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
index 791076c..d42afe0 100644
--- a/plat/hisilicon/hikey/hikey_bl2_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -336,7 +336,7 @@
 	params.flags = MMC_FLAG_CMD23;
 	info.mmc_dev_type = MMC_IS_EMMC;
 	dw_mmc_init(&params, &info);
-	mdelay(5);
+	mdelay(20);
 
 	hikey_io_setup();
 }
diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk
index ff96394..3983c70 100644
--- a/plat/marvell/a3700/common/a3700_common.mk
+++ b/plat/marvell/a3700/common/a3700_common.mk
@@ -71,7 +71,6 @@
 				$(DDR_TOPOLOGY) 0 0 $(DOIMAGE_CFG) $(TIMNCFG) $(TIMNSIG) 0
 DOIMAGE_FLAGS		:= -r $(DOIMAGE_CFG) -v -D
 
-
 # GICV3
 $(eval $(call add_define,CONFIG_GICV3))
 
@@ -91,8 +90,8 @@
 PLAT_INCLUDES		:=	-I$(PLAT_FAMILY_BASE)/$(PLAT)		\
 				-I$(PLAT_COMMON_BASE)/include		\
 				-I$(PLAT_INCLUDE_BASE)/common		\
-				-I$(MARVELL_DRV_BASE)/uart		\
 				-I$(MARVELL_DRV_BASE)			\
+				-Iinclude/drivers/marvell/uart		\
 				-I$/drivers/arm/gic/common/		\
 				$(ATF_INCLUDES)
 
@@ -159,12 +158,12 @@
 	@truncate -s %16 $(WTMI_MULTI_IMG)
 	@openssl enc -aes-256-cbc -e -in $(WTMI_MULTI_IMG) \
 	-out $(WTMI_ENC_IMG) \
-	-K `cat $(IMAGESPATH)/aes-256.txt` -k 0 -nosalt \
+	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
 	@truncate -s %16 $(BUILD_PLAT)/$(BOOT_IMAGE);
 	@openssl enc -aes-256-cbc -e -in $(BUILD_PLAT)/$(BOOT_IMAGE) \
 	-out $(BUILD_PLAT)/$(BOOT_ENC_IMAGE) \
-	-K `cat $(IMAGESPATH)/aes-256.txt` -k 0 -nosalt \
+	-K `cat $(IMAGESPATH)/aes-256.txt` -nosalt \
 	-iv `cat $(IMAGESPATH)/iv.txt` -p
 endif
 	$(DOIMAGETOOL) $(DOIMAGE_FLAGS)
diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk
index a589004..6136a1f 100644
--- a/plat/marvell/a8k/common/a8k_common.mk
+++ b/plat/marvell/a8k/common/a8k_common.mk
@@ -25,7 +25,6 @@
 $(eval $(call add_define,PCI_EP_SUPPORT))
 $(eval $(call assert_boolean,PCI_EP_SUPPORT))
 
-
 AP_NUM			:= 1
 $(eval $(call add_define,AP_NUM))
 
diff --git a/plat/marvell/a8k/common/ble/ble.mk b/plat/marvell/a8k/common/ble/ble.mk
index a76083e..5f24ced 100644
--- a/plat/marvell/a8k/common/ble/ble.mk
+++ b/plat/marvell/a8k/common/ble/ble.mk
@@ -12,8 +12,9 @@
 
 BLE_SOURCES		+= 	$(BLE_PATH)/ble_main.c				\
 				$(BLE_PATH)/ble_mem.S				\
-				drivers/delay_timer/delay_timer.c	\
-				$(PLAT_MARVELL)/common/plat_delay_timer.c
+				drivers/delay_timer/delay_timer.c		\
+				$(PLAT_MARVELL)/common/plat_delay_timer.c	\
+				$(PLAT_MARVELL)/common/marvell_console.c
 
 PLAT_INCLUDES		+= 	-I$(MV_DDR_PATH) \
 				-I$(CURDIR)/include/ \
diff --git a/plat/marvell/a8k/common/ble/ble_main.c b/plat/marvell/a8k/common/ble/ble_main.c
index e52c738..b04e8b7 100644
--- a/plat/marvell/a8k/common/ble/ble_main.c
+++ b/plat/marvell/a8k/common/ble/ble_main.c
@@ -35,13 +35,11 @@
 	 * initialize the console and prints will be ignored
 	 */
 	if ((bootrom_flags & BR_FLAG_SILENT) == 0)
-		console_init(PLAT_MARVELL_BOOT_UART_BASE,
-			     PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-			     MARVELL_CONSOLE_BAUDRATE);
+		marvell_console_boot_init();
 
 	NOTICE("Starting binary extension\n");
 
-	/* initiliaze time (for delay functionality) */
+	/* initialize time (for delay functionality) */
 	plat_delay_timer_init();
 
 	ble_plat_setup(&skip);
diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/a8k/common/plat_pm.c
index 0c74b2f..1b68d07 100644
--- a/plat/marvell/a8k/common/plat_pm.c
+++ b/plat/marvell/a8k/common/plat_pm.c
@@ -19,7 +19,6 @@
 #include <plat_marvell.h>
 #include <platform.h>
 #include <plat_pm_trace.h>
-#include <platform.h>
 
 #define MVEBU_PRIVATE_UID_REG		0x30
 #define MVEBU_RFU_GLOBL_SW_RST		0x84
@@ -614,6 +613,8 @@
 
 		INFO("Suspending to RAM\n");
 
+		marvell_console_runtime_end();
+
 		/* Prevent interrupts from spuriously waking up this cpu */
 		gicv2_cpuif_disable();
 
@@ -687,9 +688,7 @@
 			/* Initialize the console to provide
 			 * early debug support
 			 */
-			console_init(PLAT_MARVELL_BOOT_UART_BASE,
-			PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-			MARVELL_CONSOLE_BAUDRATE);
+			marvell_console_runtime_init();
 
 			bl31_plat_arch_setup();
 			marvell_bl31_platform_setup();
diff --git a/plat/marvell/common/aarch64/marvell_helpers.S b/plat/marvell/common/aarch64/marvell_helpers.S
index 128c3ab..fbd19cb 100644
--- a/plat/marvell/common/aarch64/marvell_helpers.S
+++ b/plat/marvell/common/aarch64/marvell_helpers.S
@@ -65,7 +65,11 @@
 	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
 	mov_imm	x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ
 	mov_imm	x2, MARVELL_CONSOLE_BAUDRATE
-	b	console_core_init
+#ifdef PLAT_a3700
+	b	console_a3700_core_init
+#else
+	b	console_16550_core_init
+#endif
 endfunc plat_crash_console_init
 
 	/* ---------------------------------------------
@@ -77,7 +81,12 @@
 	 */
 func plat_crash_console_putc
 	mov_imm	x1, PLAT_MARVELL_CRASH_UART_BASE
-	b	console_core_putc
+#ifdef PLAT_a3700
+
+	b	console_a3700_core_putc
+#else
+	b	console_16550_core_putc
+#endif
 endfunc plat_crash_console_putc
 
 	/* ---------------------------------------------
@@ -85,12 +94,16 @@
 	 * Function to force a write of all buffered
 	 * data that hasn't been output.
 	 * Out : return -1 on error else return 0.
-	 * Clobber list : x0, x1
+	 * Clobber list : r0
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_flush
 	mov_imm	x0, PLAT_MARVELL_CRASH_UART_BASE
-	b	console_core_flush
+#ifdef PLAT_a3700
+	b	console_a3700_core_flush
+#else
+	b	console_16550_core_flush
+#endif
 endfunc plat_crash_console_flush
 
 	/* ---------------------------------------------------------------------
diff --git a/plat/marvell/common/marvell_bl1_setup.c b/plat/marvell/common/marvell_bl1_setup.c
index 4e1b256..c96f006 100644
--- a/plat/marvell/common/marvell_bl1_setup.c
+++ b/plat/marvell/common/marvell_bl1_setup.c
@@ -35,9 +35,7 @@
 void marvell_bl1_early_platform_setup(void)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_MARVELL_BOOT_UART_BASE,
-		     PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-		     MARVELL_CONSOLE_BAUDRATE);
+	marvell_console_boot_init();
 
 	/* Allow BL1 to see the whole Trusted RAM */
 	bl1_ram_layout.total_base = MARVELL_BL_RAM_BASE;
diff --git a/plat/marvell/common/marvell_bl2_setup.c b/plat/marvell/common/marvell_bl2_setup.c
index d33aba4..883336f 100644
--- a/plat/marvell/common/marvell_bl2_setup.c
+++ b/plat/marvell/common/marvell_bl2_setup.c
@@ -40,9 +40,7 @@
 void marvell_bl2_early_platform_setup(meminfo_t *mem_layout)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_MARVELL_BOOT_UART_BASE,
-		     PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-		     MARVELL_CONSOLE_BAUDRATE);
+	marvell_console_boot_init();
 
 	/* Setup the BL2 memory layout */
 	bl2_tzram_layout = *mem_layout;
diff --git a/plat/marvell/common/marvell_bl31_setup.c b/plat/marvell/common/marvell_bl31_setup.c
index da91b56..3b1a6f1 100644
--- a/plat/marvell/common/marvell_bl31_setup.c
+++ b/plat/marvell/common/marvell_bl31_setup.c
@@ -74,9 +74,7 @@
 				       void *plat_params_from_bl2)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PLAT_MARVELL_BOOT_UART_BASE,
-		     PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
-		     MARVELL_CONSOLE_BAUDRATE);
+	marvell_console_boot_init();
 
 #if RESET_TO_BL31
 	/* There are no parameters from BL2 if BL31 is a reset vector */
@@ -190,10 +188,10 @@
  */
 void marvell_bl31_plat_runtime_setup(void)
 {
+	console_switch_state(CONSOLE_FLAG_RUNTIME);
+
 	/* Initialize the runtime console */
-	console_init(PLAT_MARVELL_BL31_RUN_UART_BASE,
-		     PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ,
-		     MARVELL_CONSOLE_BAUDRATE);
+	marvell_console_runtime_init();
 }
 
 void bl31_platform_setup(void)
diff --git a/plat/marvell/common/marvell_common.mk b/plat/marvell/common/marvell_common.mk
index 3a6bb03..fb6fbb5 100644
--- a/plat/marvell/common/marvell_common.mk
+++ b/plat/marvell/common/marvell_common.mk
@@ -11,6 +11,8 @@
 
 VERSION_STRING			+=(Marvell-${SUBVERSION})
 
+MULTI_CONSOLE_API		:= 1
+
 SEPARATE_CODE_AND_RODATA	:= 1
 
 # flag to switch from PLL to ARO
@@ -28,7 +30,8 @@
 PLAT_BL_COMMON_SOURCES  +=      lib/xlat_tables/xlat_tables_common.c			\
 				lib/xlat_tables/aarch64/xlat_tables.c			\
 				$(MARVELL_PLAT_BASE)/common/aarch64/marvell_common.c	\
-				$(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S
+				$(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S	\
+				$(MARVELL_COMMON_BASE)/marvell_console.c
 
 BL1_SOURCES		+=	drivers/delay_timer/delay_timer.c			\
 				drivers/io/io_fip.c					\
diff --git a/plat/marvell/common/marvell_console.c b/plat/marvell/common/marvell_console.c
new file mode 100644
index 0000000..eba106d
--- /dev/null
+++ b/plat/marvell/common/marvell_console.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <plat_marvell.h>
+#include <platform_def.h>
+
+#ifdef PLAT_a3700
+#include <a3700_console.h>
+
+static console_a3700_t marvell_boot_console;
+static console_a3700_t marvell_runtime_console;
+#else
+#include <uart_16550.h>
+
+static console_16550_t marvell_boot_console;
+static console_16550_t marvell_runtime_console;
+#endif
+
+/*******************************************************************************
+ * Functions that set up the console
+ ******************************************************************************/
+
+/* Initialize the console to provide early debug support */
+void marvell_console_boot_init(void)
+{
+	int rc =
+#ifdef PLAT_a3700
+	console_a3700_register(
+#else
+	console_16550_register(
+#endif
+				PLAT_MARVELL_BOOT_UART_BASE,
+				PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+				MARVELL_CONSOLE_BAUDRATE,
+				&marvell_boot_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(&marvell_boot_console.console,
+			  CONSOLE_FLAG_BOOT);
+}
+
+void marvell_console_boot_end(void)
+{
+	(void)console_flush();
+
+	(void)console_unregister(&marvell_boot_console.console);
+}
+
+/* Initialize the runtime console */
+void marvell_console_runtime_init(void)
+{
+	int rc =
+#ifdef PLAT_a3700
+	console_a3700_register(
+#else
+	console_16550_register(
+#endif
+				PLAT_MARVELL_BOOT_UART_BASE,
+				PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+				MARVELL_CONSOLE_BAUDRATE,
+				&marvell_runtime_console);
+	if (rc == 0)
+		panic();
+
+	console_set_scope(&marvell_runtime_console.console,
+			  CONSOLE_FLAG_RUNTIME);
+}
+
+void marvell_console_runtime_end(void)
+{
+	(void)console_flush();
+
+	(void)console_unregister(&marvell_runtime_console.console);
+}
diff --git a/plat/renesas/rcar/bl2_secure_setting.c b/plat/renesas/rcar/bl2_secure_setting.c
index 35c658c..c0d49de 100644
--- a/plat/renesas/rcar/bl2_secure_setting.c
+++ b/plat/renesas/rcar/bl2_secure_setting.c
@@ -66,7 +66,9 @@
 	    /*      {SEC_SEL12,             0xFFFFFFFFU},                   */
 	    /* Bit22: RPC slave ports.                                      */
 	    /*        0: registers accessed from secure resource only.      */
-	    /* {SEC_SEL13,          0xFFBFFFFFU},*/
+#if (RCAR_RPC_HYPERFLASH_LOCKED == 1)
+	    {SEC_SEL13,          0xFFBFFFFFU},
+#endif
 	    /* Bit27: System Timer (SCMT) slave ports                       */
 	    /*        0: registers accessed from secure resource only       */
 	    /* Bit26: System Watchdog Timer (SWDT) slave ports              */
@@ -183,8 +185,10 @@
 	/** Security group 1 attribute setting for slave ports 13	*/
 	    /* Bit22: RPC slave ports.                                      */
 	    /*        SecurityGroup3                                        */
-	    /* {SEC_GRP0COND13,     0x00400000U}, */
-	    /* {SEC_GRP1COND13,     0x00400000U}, */
+#if (RCAR_RPC_HYPERFLASH_LOCKED == 1)
+	    {SEC_GRP0COND13,     0x00400000U},
+	    {SEC_GRP1COND13,     0x00400000U},
+#endif
 	/** Security group 0 attribute setting for slave ports 14	*/
 	/** Security group 1 attribute setting for slave ports 14	*/
 	    /* Bit26: System Timer (SCMT) slave ports                       */
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 95b7902..f7d6216 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -137,6 +137,13 @@
   $(eval $(call add_define,RCAR_LSI))
 endif
 
+# lock RPC HYPERFLASH access by default
+# unlock to repogram the ATF firmware from u-boot
+ifndef RCAR_RPC_HYPERFLASH_LOCKED
+RCAR_RPC_HYPERFLASH_LOCKED := 1
+endif
+$(eval $(call add_define,RCAR_RPC_HYPERFLASH_LOCKED))
+
 # Process RCAR_SECURE_BOOT flag
 ifndef RCAR_SECURE_BOOT
 RCAR_SECURE_BOOT := 1
diff --git a/plat/rpi3/include/platform_def.h b/plat/rpi3/include/platform_def.h
index 7122401..3b12c30 100644
--- a/plat/rpi3/include/platform_def.h
+++ b/plat/rpi3/include/platform_def.h
@@ -63,6 +63,25 @@
  * secure DRAM. Note that this is all actually DRAM with different names,
  * there is no Secure RAM in the Raspberry Pi 3.
  */
+#if RPI3_USE_UEFI_MAP
+#define SEC_ROM_BASE			ULL(0x00000000)
+#define SEC_ROM_SIZE			ULL(0x00010000)
+
+/* FIP placed after ROM to append it to BL1 with very little padding. */
+#define PLAT_RPI3_FIP_BASE		ULL(0x00020000)
+#define PLAT_RPI3_FIP_MAX_SIZE		ULL(0x00010000)
+
+/* Reserve 2M of secure SRAM and DRAM, starting at 2M */
+#define SEC_SRAM_BASE			ULL(0x00200000)
+#define SEC_SRAM_SIZE			ULL(0x00100000)
+
+#define SEC_DRAM0_BASE			ULL(0x00300000)
+#define SEC_DRAM0_SIZE			ULL(0x00100000)
+
+/* Windows on ARM requires some RAM at 4M */
+#define NS_DRAM0_BASE			ULL(0x00400000)
+#define NS_DRAM0_SIZE			ULL(0x00C00000)
+#else
 #define SEC_ROM_BASE			ULL(0x00000000)
 #define SEC_ROM_SIZE			ULL(0x00020000)
 
@@ -80,6 +99,7 @@
 
 #define NS_DRAM0_BASE			ULL(0x11000000)
 #define NS_DRAM0_SIZE			ULL(0x01000000)
+#endif /* RPI3_USE_UEFI_MAP */
 
 /*
  * BL33 entrypoint.
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
index 36c1ee2..db96de8 100644
--- a/plat/rpi3/platform.mk
+++ b/plat/rpi3/platform.mk
@@ -109,6 +109,13 @@
 # Assume that BL33 isn't the Linux kernel by default
 RPI3_DIRECT_LINUX_BOOT		:= 0
 
+# UART to use at runtime. -1 means the runtime UART is disabled.
+# Any other value means the default UART will be used.
+RPI3_RUNTIME_UART		:= -1
+
+# Use normal memory mapping for ROM, FIP, SRAM and DRAM
+RPI3_USE_UEFI_MAP		:= 0
+
 # BL32 location
 RPI3_BL32_RAM_LOCATION	:= tdram
 ifeq (${RPI3_BL32_RAM_LOCATION}, tsram)
@@ -126,6 +133,8 @@
 $(eval $(call add_define,RPI3_BL33_IN_AARCH32))
 $(eval $(call add_define,RPI3_DIRECT_LINUX_BOOT))
 $(eval $(call add_define,RPI3_PRELOADED_DTB_BASE))
+$(eval $(call add_define,RPI3_RUNTIME_UART))
+$(eval $(call add_define,RPI3_USE_UEFI_MAP))
 
 # Verify build config
 # -------------------
diff --git a/plat/rpi3/rpi3_common.c b/plat/rpi3/rpi3_common.c
index 18ff1c8..c7e8b3a 100644
--- a/plat/rpi3/rpi3_common.c
+++ b/plat/rpi3/rpi3_common.c
@@ -96,6 +96,10 @@
 
 void rpi3_console_init(void)
 {
+	int console_scope = CONSOLE_FLAG_BOOT;
+#if RPI3_RUNTIME_UART != -1
+	console_scope |= CONSOLE_FLAG_RUNTIME;
+#endif
 	int rc = console_16550_register(PLAT_RPI3_UART_BASE,
 					PLAT_RPI3_UART_CLK_IN_HZ,
 					PLAT_RPI3_UART_BAUDRATE,
@@ -109,8 +113,7 @@
 		panic();
 	}
 
-	console_set_scope(&rpi3_console.console,
-			  CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+	console_set_scope(&rpi3_console.console, console_scope);
 }
 
 /*******************************************************************************
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 9f2d8bd..d85ae96 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -8,7 +8,6 @@
 #include <assert.h>
 #include <bl_common.h>
 #include <boot_api.h>
-#include <console.h>
 #include <debug.h>
 #include <delay_timer.h>
 #include <desc_image_load.h>
@@ -16,11 +15,12 @@
 #include <mmio.h>
 #include <platform.h>
 #include <platform_def.h>
+#include <stm32_console.h>
 #include <stm32mp1_clk.h>
+#include <stm32mp1_context.h>
 #include <stm32mp1_dt.h>
 #include <stm32mp1_pmic.h>
 #include <stm32mp1_private.h>
-#include <stm32mp1_context.h>
 #include <stm32mp1_pwr.h>
 #include <stm32mp1_ram.h>
 #include <stm32mp1_rcc.h>
@@ -28,6 +28,8 @@
 #include <string.h>
 #include <xlat_tables_v2.h>
 
+static struct console_stm32 console;
+
 void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
 				  u_register_t arg2, u_register_t arg3)
 {
@@ -137,8 +139,8 @@
 
 	clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_dev_info.clock);
 
-	if (console_init(dt_dev_info.base, clk_rate,
-			 STM32MP1_UART_BAUDRATE) == 0) {
+	if (console_stm32_register(dt_dev_info.base, clk_rate,
+				   STM32MP1_UART_BAUDRATE, &console) == 0) {
 		panic();
 	}
 
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 678a852..f4a0ca4 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -8,6 +8,7 @@
 ARM_WITH_NEON		:=	yes
 BL2_AT_EL3		:=	1
 USE_COHERENT_MEM	:=	0
+MULTI_CONSOLE_API	:=	1
 
 STM32_TF_VERSION	?=	0
 
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index 56598c8..bd4f2ec 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -7,7 +7,6 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <bl_common.h>
-#include <console.h>
 #include <context.h>
 #include <context_mgmt.h>
 #include <debug.h>
@@ -17,6 +16,7 @@
 #include <platform.h>
 #include <platform_def.h>
 #include <platform_sp_min.h>
+#include <stm32_console.h>
 #include <stm32mp1_clk.h>
 #include <stm32mp1_dt.h>
 #include <stm32mp1_private.h>
@@ -30,6 +30,8 @@
  ******************************************************************************/
 static entry_point_info_t bl33_image_ep_info;
 
+static struct console_stm32 console;
+
 /*******************************************************************************
  * Interrupt handler for FIQ (secure IRQ)
  ******************************************************************************/
@@ -112,8 +114,9 @@
 	result = dt_get_stdout_uart_info(&dt_dev_info);
 
 	if ((result > 0) && dt_dev_info.status) {
-		if (console_init(dt_dev_info.base, 0, STM32MP1_UART_BAUDRATE)
-		    == 0) {
+		if (console_stm32_register(dt_dev_info.base, 0,
+					   STM32MP1_UART_BAUDRATE, &console) ==
+		    0) {
 			panic();
 		}
 	}
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
index b0ea0d8..673706e 100644
--- a/plat/st/stm32mp1/stm32mp1_helper.S
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -149,7 +149,7 @@
 	ldr	r0, =STM32MP1_DEBUG_USART_BASE
 	ldr	r1, =STM32MP1_HSI_CLK
 	ldr	r2, =STM32MP1_UART_BAUDRATE
-	b	console_core_init
+	b	console_stm32_core_init
 endfunc plat_crash_console_init
 
 	/* ---------------------------------------------
@@ -160,7 +160,7 @@
 	 */
 func plat_crash_console_flush
 	ldr	r1, =STM32MP1_DEBUG_USART_BASE
-	b	console_core_flush
+	b	console_stm32_core_flush
 endfunc plat_crash_console_flush
 
 	/* ---------------------------------------------
@@ -176,5 +176,5 @@
 	 */
 func plat_crash_console_putc
 	ldr	r1, =STM32MP1_DEBUG_USART_BASE
-	b	console_core_putc
+	b	console_stm32_core_putc
 endfunc plat_crash_console_putc
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index 585707d..880e86e 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -9,6 +9,7 @@
 #include <bl31.h>
 #include <context_mgmt.h>
 #include <debug.h>
+#include <ehf.h>
 #include <errno.h>
 #include <mm_svc.h>
 #include <platform.h>
@@ -233,6 +234,19 @@
 		VERBOSE("MM_COMMUNICATE: comm_size_address is not 0 as recommended.\n");
 	}
 
+	/*
+	 * The current secure partition design mandates
+	 * - at any point, only a single core can be
+	 *   executing in the secure partiton.
+	 * - a core cannot be preempted by an interrupt
+	 *   while executing in secure partition.
+	 * Raise the running priority of the core to the
+	 * interrupt level configured for secure partition
+	 * so as to block any interrupt from preempting this
+	 * core.
+	 */
+	ehf_activate_priority(PLAT_SP_PRI);
+
 	/* Save the Normal world context */
 	cm_el1_sysregs_context_save(NON_SECURE);
 
@@ -243,6 +257,12 @@
 	cm_el1_sysregs_context_restore(NON_SECURE);
 	cm_set_next_eret_context(NON_SECURE);
 
+	/*
+	 * Exited from secure partition. This core can take
+	 * interrupts now.
+	 */
+	ehf_deactivate_priority(PLAT_SP_PRI);
+
 	SMC_RET1(handle, rc);
 }