Merge pull request #1704 from marex/arm/master/memsize-passing-v1

Arm/master/memsize passing v1
diff --git a/Makefile b/Makefile
index c79264b..eed7c7a 100644
--- a/Makefile
+++ b/Makefile
@@ -214,6 +214,7 @@
 BL_COMMON_SOURCES	+=	common/bl_common.c			\
 				common/tf_log.c				\
 				common/${ARCH}/debug.S			\
+				drivers/console/multi_console.c		\
 				lib/${ARCH}/cache_helpers.S		\
 				lib/${ARCH}/misc_helpers.S		\
 				plat/common/plat_bl_common.c		\
diff --git a/acknowledgements.rst b/acknowledgements.rst
index 4d527f4..095b5ad 100644
--- a/acknowledgements.rst
+++ b/acknowledgements.rst
@@ -1,3 +1,9 @@
+**Note: This file is only relevant for legacy contributions, to acknowledge the
+specific contributors referred to in "Arm Limited and Contributors" copyright
+notices. As contributors are now encouraged to put their name or company name
+directly into the copyright notices, this file is not relevant for new
+contributions.**
+
 Contributor Acknowledgements
 ============================
 
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 54db681..77bd63e 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -356,24 +356,8 @@
 	 * We already have x0-x4 in place. x5 will point to a cookie (not used
 	 * now). x6 will point to the context structure (SP_EL3) and x7 will
 	 * contain flags we need to pass to the handler.
-	 *
-	 * Save x4-x29 and sp_el0.
 	 */
-	stp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
-	stp	x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
-	stp	x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
-	stp	x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
-	stp	x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
-	stp	x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
-	stp	x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
-	stp	x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]
-	stp	x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]
-	stp	x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]
-	stp	x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]
-	stp	x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]
-	stp	x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
-	mrs	x18, sp_el0
-	str	x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0]
+	bl	save_gp_registers
 
 	mov	x5, xzr
 	mov	x6, sp
diff --git a/contributing.rst b/contributing.rst
index 5ab7f09..d98d5b9 100644
--- a/contributing.rst
+++ b/contributing.rst
@@ -50,19 +50,19 @@
       other in-source documentation needs updating.
    -  Ensure that each changed file has the correct copyright and license
       information. Files that entirely consist of contributions to this
-      project should have the copyright notice and BSD-3-Clause SPDX license
-      identifier as shown in `license.rst`_. Files that contain
-      changes to imported Third Party IP should contain a notice as follows,
-      with the original copyright and license text retained:
+      project should have a copyright notice and BSD-3-Clause SPDX license
+      identifier of the form as shown in `license.rst`_. Files that contain
+      changes to imported Third Party IP files should retain their original
+      copyright and license notices. For significant contributions you may
+      add your own copyright notice in following format:
 
       ::
 
-          Portions copyright (c) [XXXX-]YYYY, Arm Limited and Contributors. All rights reserved.
+          Portions copyright (c) [XXXX-]YYYY, <OWNER>. All rights reserved.
 
       where XXXX is the year of first contribution (if different to YYYY) and
-      YYYY is the year of most recent contribution.
-   -  If not done previously, you may add your name or your company name to
-      the `Acknowledgements`_ file.
+      YYYY is the year of most recent contribution. <OWNER> is your name or
+      your company name.
    -  If you are submitting new files that you intend to be the technical
       sub-maintainer for (for example, a new platform port), then also update
       the `Maintainers`_ file.
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 4f1638a..f1a26f4 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2550,9 +2550,6 @@
 Crash Reporting mechanism (in BL31)
 -----------------------------------
 
-NOTE: This section assumes that your platform is enabling the MULTI_CONSOLE_API
-flag in its platform.mk. Not using this flag is deprecated for new platforms.
-
 BL31 implements a crash reporting mechanism which prints the various registers
 of the CPU to enable quick crash analysis and debugging. This mechanism relies
 on the platform implementating ``plat_crash_console_init``,
@@ -2564,15 +2561,18 @@
 output to be routed over the normal console infrastructure and get printed on
 consoles configured to output in crash state. ``console_set_scope()`` can be
 used to control whether a console is used for crash output.
+NOTE: Platforms are responsible for making sure that they only mark consoles for
+use in the crash scope that are able to support this, i.e. that are written in
+assembly and conform with the register clobber rules for putc() (x0-x2, x16-x17)
+and flush() (x0-x3, x16-x17) crash callbacks.
 
 In some cases (such as debugging very early crashes that happen before the
 normal boot console can be set up), platforms may want to control crash output
-more explicitly. For these, the following functions can be overridden by
-platform code. They are executed outside of a C environment and without a stack.
-
-If this behaviour is not desirable, the platform may implement functions that
-redirect the prints to the console driver (``console_xxx_core_init``, etc). Most
-platforms (including Arm platforms) do this and they can be used as an example.
+more explicitly. These platforms may instead provide custom implementations for
+these. They are executed outside of a C environment and without a stack. Many
+console drivers provide functions named ``console_xxx_core_init/putc/flush``
+that are designed to be used by these functions. See Arm platforms (like juno)
+for an example of this.
 
 Function : plat\_crash\_console\_init [mandatory]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2586,28 +2586,6 @@
 console. It must only use the general purpose registers x0 through x7 to do the
 initialization and returns 1 on success.
 
-When using the sample implementation, if you are trying to debug crashes before
-the console driver would normally get registered, you can use this to register a
-driver from assembly with hardcoded parameters. For example, you could register
-the 16550 driver like this:
-
-::
-
-    .section .data.crash_console      /* Reserve space for console structure */
-    crash_console:
-    .zero 6 * 8                       /* console_16550_t has 6 8-byte words */
-    func plat_crash_console_init
-        ldr     x0, =YOUR_16550_BASE_ADDR
-        ldr     x1, =YOUR_16550_SRCCLK_IN_HZ
-        ldr     x2, =YOUR_16550_TARGET_BAUD_RATE
-        adrp    x3, crash_console
-        add     x3, x3, :lo12:crash_console
-        b       console_16550_register  /* tail call, returns 1 on success */
-    endfunc plat_crash_console_init
-
-If you're trying to debug crashes in BL1, you can call the
-``console_xxx_core_init`` function exported by some console drivers from here.
-
 Function : plat\_crash\_console\_putc [mandatory]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2621,12 +2599,6 @@
 x2 to do its work. The parameter and the return value are in general purpose
 register x0.
 
-If you have registered a normal console driver in ``plat_crash_console_init``,
-you can keep the sample implementation here (which calls ``console_putc()``).
-
-If you're trying to debug crashes in BL1, you can call the
-``console_xxx_core_putc`` function exported by some console drivers from here.
-
 Function : plat\_crash\_console\_flush [mandatory]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -2640,12 +2612,6 @@
 registers x0 through x5 to do its work. The return value is 0 on successful
 completion; otherwise the return value is -1.
 
-If you have registered a normal console driver in ``plat_crash_console_init``,
-you can keep the sample implementation here (which calls ``console_flush()``).
-
-If you're trying to debug crashes in BL1, you can call the console_xx_core_flush
-function exported by some console drivers from here.
-
 External Abort handling and RAS Support
 ---------------------------------------
 
diff --git a/drivers/arm/pl011/aarch32/pl011_console.S b/drivers/arm/pl011/aarch32/pl011_console.S
index 46ff225..5d6b95f 100644
--- a/drivers/arm/pl011/aarch32/pl011_console.S
+++ b/drivers/arm/pl011/aarch32/pl011_console.S
@@ -10,11 +10,13 @@
 #include <console_macros.S>
 #include <pl011.h>
 
+#if !MULTI_CONSOLE_API
 /*
  * Pull in generic functions to provide backwards compatibility for
  * platform makefiles
  */
 #include "../../../console/aarch32/console.S"
+#endif
 
 	/*
 	 * "core" functions are low-level implementations that don't require
diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S
index 3886f3b..7fec090 100644
--- a/drivers/arm/pl011/aarch64/pl011_console.S
+++ b/drivers/arm/pl011/aarch64/pl011_console.S
@@ -10,11 +10,13 @@
 #include <console_macros.S>
 #include <pl011.h>
 
+#if !MULTI_CONSOLE_API
 /*
  * Pull in generic functions to provide backwards compatibility for
  * platform makefiles
  */
 #include "../../../console/aarch64/console.S"
+#endif
 
 	/*
 	 * "core" functions are low-level implementations that don't require
diff --git a/drivers/console/aarch32/console.S b/drivers/console/aarch32/console.S
index f909609..1c38094 100644
--- a/drivers/console/aarch32/console.S
+++ b/drivers/console/aarch32/console.S
@@ -5,7 +5,9 @@
  */
 
  #if MULTI_CONSOLE_API
- #include "multi_console.S"
+ #if ERROR_DEPRECATED
+ #error "console.S is deprecated, platforms should no longer link it explicitly"
+ #endif
  #else
  #include "deprecated_console.S"
  #endif
diff --git a/drivers/console/aarch32/multi_console.S b/drivers/console/aarch32/multi_console.S
deleted file mode 100644
index e23b20e..0000000
--- a/drivers/console/aarch32/multi_console.S
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <asm_macros.S>
-#include <assert_macros.S>
-#include <console.h>
-
-	.globl	console_register
-	.globl	console_unregister
-	.globl	console_is_registered
-	.globl	console_set_scope
-	.globl	console_switch_state
-	.globl	console_putc
-	.globl	console_getc
-	.globl	console_flush
-
-	/*
-	 *  The console list pointer is in the data section and not in
-	 *  .bss even though it is zero-init. In particular, this allows
-	 *  the console functions to start using this variable before
-	 *  the runtime memory is initialized for images which do not
-	 *  need to copy the .data section from ROM to RAM.
-	 */
-.section .data.console_list ; .align 2
-	console_list: .word 0x0
-.section .data.console_state ; .align 0
-	console_state: .byte CONSOLE_FLAG_BOOT
-
-	/* -----------------------------------------------
-	 * int console_register(console_t *console)
-	 * Function to insert a new console structure into
-	 * the console list. Should usually be called by
-	 * console_<driver>_register implementations. The
-	 * data structure passed will be taken over by the
-	 * console framework and *MUST* be allocated in
-	 * persistent memory (e.g. the data section).
-	 * In : r0 - address of console_t structure
-	 * Out: r0 - Always 1 (for easier tail calling)
-	 * Clobber list: r0, r1
-	 * -----------------------------------------------
-	 */
-func console_register
-	push	{r6,  lr}
-#if ENABLE_ASSERTIONS
-	/* Assert that r0 isn't a NULL pointer */
-	cmp	r0, #0
-	ASM_ASSERT(ne)
-	/* Assert that the struct isn't in the stack */
-	ldr	r1, =__STACKS_START__
-	cmp	r0, r1
-	blo	not_on_stack
-	ldr	r1, =__STACKS_END__
-	cmp	r0, r1
-	ASM_ASSERT(hs)
-not_on_stack:
-	/* Assert that this struct isn't in the list */
-	mov	r1, r0 /* Preserve r0 and lr */
-	bl	console_is_registered
-	cmp	r0, #0
-	ASM_ASSERT(eq)
-	mov	r0, r1
-#endif /* ENABLE_ASSERTIONS */
-	ldr	r6, =console_list
-	ldr	r1, [r6]	/* R1 = first struct in list */
-	str	r0, [r6]	/* list head = new console */
-	str	r1, [r0, #CONSOLE_T_NEXT]	/* new console next ptr = R1 */
-	mov	r0, #1
-	pop	{r6, pc}
-endfunc console_register
-
-	/* -----------------------------------------------
-	 * int console_unregister(console_t *console)
-	 * Function to find a specific console in the list
-	 * of currently active consoles and remove it.
-	 * In: r0 - address of console_t struct to remove
-	 * Out: r0 - removed address, or NULL if not found
-	 * Clobber list: r0, r1
-	 * -----------------------------------------------
-	 */
-func console_unregister
-#if ENABLE_ASSERTIONS
-	/* Assert that r0 isn't a NULL pointer */
-	cmp	r0, #0
-	ASM_ASSERT(ne)
-#endif /* ENABLE_ASSERTIONS */
-	push	{r6}
-	ldr	r6, =console_list		/* R6 = ptr to first struct */
-	ldr	r1, [r6]			/* R1 = first struct */
-
-unregister_loop:
-	cmp	r1, #0
-	beq	unregister_not_found
-	cmp	r0, r1
-	beq	unregister_found
-	ldr	r6, [r6]			/* R6 = next ptr of struct */
-	ldr	r1, [r6]			/* R1 = next struct */
-	b	unregister_loop
-
-unregister_found:
-	ldr	r1, [r1]			/* R1 = next struct */
-	str	r1, [r6]			/* prev->next = cur->next */
-	pop	{r6}
-	bx	lr
-
-unregister_not_found:
-	mov	r0, #0				/* return NULL if not found */
-	pop	{r6}
-	bx	lr
-endfunc console_unregister
-
-	/* -----------------------------------------------
-	 * int console_is_registered(console_t *console)
-	 * Function to detect if a specific console is
-	 * registered or not.
-	 * In: r0 - address of console_t struct to remove
-	 * Out: r0 - 1 if it is registered, 0 if not.
-	 * Clobber list: r0
-	 * -----------------------------------------------
-	 */
-func console_is_registered
-#if ENABLE_ASSERTIONS
-	/* Assert that r0 isn't a NULL pointer */
-	cmp	r0, #0
-	ASM_ASSERT(ne)
-#endif /* ENABLE_ASSERTIONS */
-	push	{r6}
-	ldr	r6, =console_list
-	ldr	r6, [r6]	/* R6 = first console struct */
-check_registered_loop:
-	cmp	r6, #0			/* Check if end of list */
-	beq	console_not_registered
-	cmp	r0, r6		/* Check if the pointers are different */
-	beq	console_registered
-	ldr	r6, [r6, #CONSOLE_T_NEXT]	/* Get pointer to next struct */
-	b	check_registered_loop
-console_not_registered:
-	mov	r0, #0
-	pop	{r6}
-	bx	lr
-console_registered:
-	mov	r0, #1
-	pop	{r6}
-	bx	lr
-endfunc console_is_registered
-
-	/* -----------------------------------------------
-	 * void console_switch_state(unsigned int new_state)
-	 * Function to switch the current console state.
-	 * The console state determines which of the
-	 * registered consoles are actually used at a time.
-	 * In : r0 - global console state to move to
-	 * Clobber list: r0, r1
-	 * -----------------------------------------------
-	 */
-func console_switch_state
-	ldr	r1, =console_state
-	strb	r0, [r1]
-	bx	lr
-endfunc console_switch_state
-
-	/* -----------------------------------------------
-	 * void console_set_scope(console_t *console,
-	 *                       unsigned int scope)
-	 * Function to update the states that a given console
-	 * may be active in.
-	 * In : r0 - pointer to console_t struct
-	 *    : r1 - new active state mask
-	 * Clobber list: r0, r1, r2
-	 * -----------------------------------------------
-	 */
-func console_set_scope
-#if ENABLE_ASSERTIONS
-	ands	r2, r1, #~CONSOLE_FLAG_SCOPE_MASK
-	ASM_ASSERT(eq)
-#endif /* ENABLE_ASSERTIONS */
-	ldr	r2, [r0, #CONSOLE_T_FLAGS]
-	and	r2, r2, #~CONSOLE_FLAG_SCOPE_MASK
-	orr	r2, r2, r1
-	str	r2, [r0, #CONSOLE_T_FLAGS]
-	bx	lr
-endfunc console_set_scope
-
-	/* ---------------------------------------------
-	 * int console_putc(int c)
-	 * Function to output a character. Calls all
-	 * active console's putc() handlers in succession.
-	 * In : r0 - character to be printed
-	 * Out: r0 - printed character on success, or < 0
-	             if at least one console had an error
-	 * Clobber list : r0, r1, r2
-	 * ---------------------------------------------
-	 */
-func console_putc
-	push	{r4-r6, lr}
-	mov	r5, #ERROR_NO_VALID_CONSOLE	/* R5 = current return value */
-	mov	r4, r0				/* R4 = character to print */
-	ldr	r6, =console_list
-	ldr	r6, [r6]	/* R6 = first console struct */
-
-putc_loop:
-	cmp	r6, #0
-	beq	putc_done
-	ldr	r1, =console_state
-	ldrb	r1, [r1]
-	ldr	r2, [r6, #CONSOLE_T_FLAGS]
-	tst	r1, r2
-	beq	putc_continue
-	ldr	r2, [r6, #CONSOLE_T_PUTC]
-	cmp	r2, #0
-	beq	putc_continue
-	mov	r0, r4
-	mov	r1, r6
-	blx	r2
-	cmp	r5, #ERROR_NO_VALID_CONSOLE	/* update R5 if it's NOVALID */
-	cmpne	r0, #0				/* else update it if R0 < 0 */
-	movlt	r5, r0
-putc_continue:
-	ldr	r6, [r6]			/* R6 = next struct */
-	b	putc_loop
-
-putc_done:
-	mov	r0, r5
-	pop	{r4-r6, pc}
-endfunc console_putc
-
-	/* ---------------------------------------------
-	 * int console_getc(void)
-	 * Function to get a character from any console.
-	 * Keeps looping through all consoles' getc()
-	 * handlers until one of them returns a
-	 * character, then stops iterating and returns
-	 * that character to the caller. Will stop looping
-	 * if all active consoles report real errors
-	 * (other than just not having a char available).
-	 * Out : r0 - read character, or < 0 on error
-	 * Clobber list : r0, r1
-	 * ---------------------------------------------
-	 */
-func console_getc
-	push	{r5-r6, lr}
-getc_try_again:
-	mov	r5, #ERROR_NO_VALID_CONSOLE	/* R5 = current return value */
-	ldr	r6, =console_list
-	ldr	r6, [r6]			/* R6 = first console struct */
-	cmp	r6, #0
-	bne	getc_loop
-	mov	r0, r5				/* If no consoles registered */
-	pop	{r5-r6, pc}			/* return immediately. */
-
-getc_loop:
-	ldr	r0, =console_state
-	ldrb	r0, [r0]
-	ldr	r1, [r6, #CONSOLE_T_FLAGS]
-	tst	r0, r1
-	beq	getc_continue
-	ldr	r1, [r6, #CONSOLE_T_GETC]
-	cmp	r1, #0
-	beq	getc_continue
-	mov	r0, r6
-	blx	r1
-	cmp	r0, #0				/* if R0 >= 0: return */
-	bge	getc_found
-	cmp	r5, #ERROR_NO_PENDING_CHAR	/* may update R5 (NOCHAR has */
-	movne	r5, r0				/* precedence vs real errors) */
-getc_continue:
-	ldr	r6, [r6]			/* R6 = next struct */
-	cmp	r6, #0
-	bne	getc_loop
-	cmp	r5, #ERROR_NO_PENDING_CHAR	/* Keep scanning if at least */
-	beq	getc_try_again			/* one console returns NOCHAR */
-	mov	r0, r5
-
-getc_found:
-	pop	{r5-r6, pc}
-endfunc console_getc
-
-	/* ---------------------------------------------
-	 * int console_flush(void)
-	 * Function to force a write of all buffered
-	 * data that hasn't been output. Calls all
-	 * console's flush() handlers in succession.
-	 * Out: r0 - 0 on success, < 0 if at least one error
-	 * Clobber list : r0, r1, r2
-	 * ---------------------------------------------
-	 */
-func console_flush
-	push	{r5-r6, lr}
-	mov	r5, #ERROR_NO_VALID_CONSOLE	/* R5 = current return value */
-	ldr	r6, =console_list
-	ldr	r6, [r6]			/* R6 = first console struct */
-
-flush_loop:
-	cmp	r6, #0
-	beq	flush_done
-	ldr	r1, =console_state
-	ldrb	r1, [r1]
-	ldr	r2, [r6, #CONSOLE_T_FLAGS]
-	tst	r1, r2
-	beq	flush_continue
-	ldr	r1, [r6, #CONSOLE_T_FLUSH]
-	cmp	r1, #0
-	beq	flush_continue
-	mov	r0, r6
-	blx	r1
-	cmp	r5, #ERROR_NO_VALID_CONSOLE	/* update R5 if it's NOVALID */
-	cmpne	r0, #0				/* else update it if R0 < 0 */
-	movlt	r5, r0
-flush_continue:
-	ldr	r6, [r6]			/* R6 = next struct */
-	b	flush_loop
-
-flush_done:
-	mov	r0, r5
-	pop	{r5-r6, pc}
-endfunc console_flush
diff --git a/drivers/console/aarch64/console.S b/drivers/console/aarch64/console.S
index f847ed5..669b31a 100644
--- a/drivers/console/aarch64/console.S
+++ b/drivers/console/aarch64/console.S
@@ -5,7 +5,9 @@
  */
 
 #if MULTI_CONSOLE_API
-#include "multi_console.S"
+#if ERROR_DEPRECATED
+#error "console.S is deprecated, platforms should no longer link it explicitly"
+#endif
 #else
 #include "deprecated_console.S"
 #endif
diff --git a/drivers/console/aarch64/multi_console.S b/drivers/console/aarch64/multi_console.S
deleted file mode 100644
index 7f076c6..0000000
--- a/drivers/console/aarch64/multi_console.S
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <asm_macros.S>
-#include <assert_macros.S>
-#include <console.h>
-
-	.globl	console_register
-	.globl	console_unregister
-	.globl	console_is_registered
-	.globl	console_set_scope
-	.globl	console_switch_state
-	.globl	console_putc
-	.globl	console_getc
-	.globl	console_flush
-
-	/*
-	 *  The console list pointer is in the data section and not in
-	 *  .bss even though it is zero-init. In particular, this allows
-	 *  the console functions to start using this variable before
-	 *  the runtime memory is initialized for images which do not
-	 *  need to copy the .data section from ROM to RAM.
-	 */
-.section .data.console_list ; .align 3
-	console_list: .quad 0x0
-.section .data.console_state ; .align 0
-	console_state: .byte CONSOLE_FLAG_BOOT
-
-	/* -----------------------------------------------
-	 * int console_register(console_t *console)
-	 * Function to insert a new console structure into
-	 * the console list. Should usually be called by
-	 * console_<driver>_register implementations. The
-	 * data structure passed will be taken over by the
-	 * console framework and *MUST* be allocated in
-	 * persistent memory (e.g. the data section).
-	 * In : x0 - address of console_t structure
-	 * Out: x0 - Always 1 (for easier tail calling)
-	 * Clobber list: x0, x1
-	 * -----------------------------------------------
-	 */
-func console_register
-	stp	x21, x30, [sp, #-16]!
-#if ENABLE_ASSERTIONS
-	/* Assert that x0 isn't a NULL pointer */
-	cmp	x0, #0
-	ASM_ASSERT(ne)
-	/* Assert that the struct isn't in the stack */
-	adrp	x1, __STACKS_START__
-	add	x1, x1, :lo12:__STACKS_START__
-	cmp	x0, x1
-	b.lo	not_on_stack
-	adrp	x1, __STACKS_END__
-	add	x1, x1, :lo12:__STACKS_END__
-	cmp	x0, x1
-	ASM_ASSERT(hs)
-not_on_stack:
-	/* Assert that this struct isn't in the list */
-	mov	x1, x0 /* Preserve x0 and x30 */
-	bl	console_is_registered
-	cmp	x0, #0
-	ASM_ASSERT(eq)
-	mov	x0, x1
-#endif /* ENABLE_ASSERTIONS */
-	adrp	x21, console_list
-	ldr	x1, [x21, :lo12:console_list]	/* X1 = first struct in list */
-	str	x0, [x21, :lo12:console_list]	/* list head = new console */
-	str	x1, [x0, #CONSOLE_T_NEXT]	/* new console next ptr = X1 */
-	mov	x0, #1
-	ldp	x21, x30, [sp], #16
-	ret
-endfunc console_register
-
-	/* -----------------------------------------------
-	 * int console_unregister(console_t *console)
-	 * Function to find a specific console in the list
-	 * of currently active consoles and remove it.
-	 * In: x0 - address of console_t struct to remove
-	 * Out: x0 - removed address, or NULL if not found
-	 * Clobber list: x0, x1
-	 * -----------------------------------------------
-	 */
-func console_unregister
-#if ENABLE_ASSERTIONS
-	/* Assert that x0 isn't a NULL pointer */
-	cmp	x0, #0
-	ASM_ASSERT(ne)
-#endif /* ENABLE_ASSERTIONS */
-	stp	x21, xzr, [sp, #-16]!
-	adrp	x21, console_list
-	add	x21, x21, :lo12:console_list	/* X21 = ptr to first struct */
-	ldr	x1, [x21]			/* X1 = first struct */
-
-unregister_loop:
-	cbz	x1, unregister_not_found
-	cmp	x0, x1
-	b.eq	unregister_found
-	ldr	x21, [x21]			/* X21 = next ptr of struct */
-	ldr	x1, [x21]			/* X1 = next struct */
-	b	unregister_loop
-
-unregister_found:
-	ldr	x1, [x1]			/* X1 = next struct */
-	str	x1, [x21]			/* prev->next = cur->next */
-	ldp	x21, xzr, [sp], #16
-	ret
-
-unregister_not_found:
-	mov	x0, #0				/* return NULL if not found */
-	ldp	x21, xzr, [sp], #16
-	ret
-endfunc console_unregister
-
-	/* -----------------------------------------------
-	 * int console_is_registered(console_t *console)
-	 * Function to detect if a specific console is
-	 * registered or not.
-	 * In: x0 - address of console_t struct to remove
-	 * Out: x0 - 1 if it is registered, 0 if not.
-	 * Clobber list: x0
-	 * -----------------------------------------------
-	 */
-func console_is_registered
-#if ENABLE_ASSERTIONS
-	/* Assert that x0 isn't a NULL pointer */
-	cmp	x0, #0
-	ASM_ASSERT(ne)
-#endif /* ENABLE_ASSERTIONS */
-	stp	x21, xzr, [sp, #-16]!
-	adrp	x21, console_list
-	ldr	x21, [x21, :lo12:console_list]	/* X21 = first console struct */
-check_registered_loop:
-	cbz	x21, console_not_registered /* Check if end of list */
-	cmp	x0, x21		/* Check if the pointers are different */
-	b.eq	console_registered
-	ldr	x21, [x21, #CONSOLE_T_NEXT]	/* Get pointer to next struct */
-	b	check_registered_loop
-console_not_registered:
-	mov	x0, #0
-	ldp	x21, xzr, [sp], #16
-	ret
-console_registered:
-	mov	x0, #1
-	ldp	x21, xzr, [sp], #16
-	ret
-endfunc console_is_registered
-
-	/* -----------------------------------------------
-	 * void console_switch_state(unsigned int new_state)
-	 * Function to switch the current console state.
-	 * The console state determines which of the
-	 * registered consoles are actually used at a time.
-	 * In : w0 - global console state to move to
-	 * Clobber list: x0, x1
-	 * -----------------------------------------------
-	 */
-func console_switch_state
-	adrp	x1, console_state
-	strb	w0, [x1, :lo12:console_state]
-	ret
-endfunc console_switch_state
-
-	/* -----------------------------------------------
-	 * void console_set_scope(console_t *console,
-	 *                       unsigned int scope)
-	 * Function to update the states that a given console
-	 * may be active in.
-	 * In : x0 - pointer to console_t struct
-	 *    : w1 - new active state mask
-	 * Clobber list: x0, x1, x2
-	 * -----------------------------------------------
-	 */
-func console_set_scope
-#if ENABLE_ASSERTIONS
-	tst	w1, #~CONSOLE_FLAG_SCOPE_MASK
-	ASM_ASSERT(eq)
-#endif /* ENABLE_ASSERTIONS */
-	ldr	w2, [x0, #CONSOLE_T_FLAGS]
-	and	w2, w2, #~CONSOLE_FLAG_SCOPE_MASK
-	orr	w2, w2, w1
-	str	w2, [x0, #CONSOLE_T_FLAGS]
-	ret
-endfunc console_set_scope
-
-	/* ---------------------------------------------
-	 * int console_putc(int c)
-	 * Function to output a character. Calls all
-	 * active console's putc() handlers in succession.
-	 * In : x0 - character to be printed
-	 * Out: x0 - printed character on success, or < 0
-	             if at least one console had an error
-	 * Clobber list : x0, x1, x2
-	 * ---------------------------------------------
-	 */
-func console_putc
-	stp	x21, x30, [sp, #-16]!
-	stp	x19, x20, [sp, #-16]!
-	mov	w20, #ERROR_NO_VALID_CONSOLE	/* W20 = current return value */
-	mov	w19, w0				/* W19 = character to print */
-	adrp	x21, console_list
-	ldr	x21, [x21, :lo12:console_list]	/* X21 = first console struct */
-
-putc_loop:
-	cbz	x21, putc_done
-	adrp	x1, console_state
-	ldrb	w1, [x1, :lo12:console_state]
-	ldr	w2, [x21, #CONSOLE_T_FLAGS]
-	tst	w1, w2
-	b.eq	putc_continue
-	ldr	x2, [x21, #CONSOLE_T_PUTC]
-	cbz	x2, putc_continue
-	mov	w0, w19
-	mov	x1, x21
-	blr	x2
-	cmp	w20, #ERROR_NO_VALID_CONSOLE	/* update W20 if it's NOVALID */
-	ccmp	w0, #0, #0x8, ne		/* else update it if W0 < 0 */
-	csel	w20, w0, w20, lt
-putc_continue:
-	ldr	x21, [x21]			/* X21 = next struct */
-	b	putc_loop
-
-putc_done:
-	mov	w0, w20
-	ldp	x19, x20, [sp], #16
-	ldp	x21, x30, [sp], #16
-	ret
-endfunc console_putc
-
-	/* ---------------------------------------------
-	 * int console_getc(void)
-	 * Function to get a character from any console.
-	 * Keeps looping through all consoles' getc()
-	 * handlers until one of them returns a
-	 * character, then stops iterating and returns
-	 * that character to the caller. Will stop looping
-	 * if all active consoles report real errors
-	 * (other than just not having a char available).
-	 * Out : x0 - read character, or < 0 on error
-	 * Clobber list : x0, x1
-	 * ---------------------------------------------
-	 */
-func console_getc
-	stp	x30, xzr, [sp, #-16]!
-	stp	x20, x21, [sp, #-16]!
-getc_try_again:
-	mov	w20, #ERROR_NO_VALID_CONSOLE	/* W20 = current return value */
-	adrp	x21, console_list
-	ldr	x21, [x21, :lo12:console_list]	/* X21 = first console struct */
-	cbnz	x21, getc_loop
-	mov	w0, w20				/* If no consoles registered */
-	ldp	x20, x21, [sp], #16
-	ldp	x30, xzr, [sp], #16
-	ret					/* return immediately. */
-
-getc_loop:
-	adrp	x0, console_state
-	ldrb	w0, [x0, :lo12:console_state]
-	ldr	w1, [x21, #CONSOLE_T_FLAGS]
-	tst	w0, w1
-	b.eq	getc_continue
-	ldr	x1, [x21, #CONSOLE_T_GETC]
-	cbz	x1, getc_continue
-	mov	x0, x21
-	blr	x1
-	cmp	w0, #0				/* if X0 >= 0: return */
-	b.ge	getc_found
-	cmp	w20, #ERROR_NO_PENDING_CHAR	/* may update W20 (NOCHAR has */
-	csel	w20, w20, w0, eq		/* precedence vs real errors) */
-getc_continue:
-	ldr	x21, [x21]			/* X21 = next struct */
-	cbnz	x21, getc_loop
-	cmp	w20, #ERROR_NO_PENDING_CHAR	/* Keep scanning if at least */
-	b.eq	getc_try_again			/* one console returns NOCHAR */
-	mov	w0, w20
-
-getc_found:
-	ldp	x20, x21, [sp], #16
-	ldp	x30, xzr, [sp], #16
-	ret
-endfunc console_getc
-
-	/* ---------------------------------------------
-	 * int console_flush(void)
-	 * Function to force a write of all buffered
-	 * data that hasn't been output. Calls all
-	 * console's flush() handlers in succession.
-	 * Out: x0 - 0 on success, < 0 if at least one error
-	 * Clobber list : x0, x1, x2
-	 * ---------------------------------------------
-	 */
-func console_flush
-	stp	x30, xzr, [sp, #-16]!
-	stp	x20, x21, [sp, #-16]!
-	mov	w20, #ERROR_NO_VALID_CONSOLE	/* W20 = current return value */
-	adrp	x21, console_list
-	ldr	x21, [x21, :lo12:console_list]	/* X21 = first console struct */
-
-flush_loop:
-	cbz	x21, flush_done
-	adrp	x1, console_state
-	ldrb	w1, [x1, :lo12:console_state]
-	ldr	w2, [x21, #CONSOLE_T_FLAGS]
-	tst	w1, w2
-	b.eq	flush_continue
-	ldr	x1, [x21, #CONSOLE_T_FLUSH]
-	cbz	x1, flush_continue
-	mov	x0, x21
-	blr	x1
-	cmp	w20, #ERROR_NO_VALID_CONSOLE	/* update W20 if it's NOVALID */
-	ccmp	w0, #0, #0x8, ne		/* else update it if W0 < 0 */
-	csel	w20, w0, w20, lt
-flush_continue:
-	ldr	x21, [x21]			/* X21 = next struct */
-	b	flush_loop
-
-flush_done:
-	mov	w0, w20
-	ldp	x20, x21, [sp], #16
-	ldp	x30, xzr, [sp], #16
-	ret
-endfunc console_flush
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
new file mode 100644
index 0000000..c678de0
--- /dev/null
+++ b/drivers/console/multi_console.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if MULTI_CONSOLE_API
+
+#include <assert.h>
+#include <drivers/console.h>
+
+console_t *console_list;
+uint8_t console_state = CONSOLE_FLAG_BOOT;
+
+int console_register(console_t *console)
+{
+	IMPORT_SYM(console_t *, __STACKS_START__, stacks_start)
+	IMPORT_SYM(console_t *, __STACKS_END__, stacks_end)
+
+	/* Assert that the struct is not on the stack (common mistake). */
+	assert((console < stacks_start) || (console >= stacks_end));
+	/* Assert that we won't make a circle in the list. */
+	assert(!console_is_registered(console));
+
+	console->next = console_list;
+	console_list = console;
+
+	/* Return 1 for convenient tail-calling from console_xxx_register(). */
+	return 1;
+}
+
+console_t *console_unregister(console_t *to_be_deleted)
+{
+	console_t **ptr;
+
+	assert(to_be_deleted != NULL);
+
+	for (ptr = &console_list; *ptr != NULL; ptr = &(*ptr)->next)
+		if (*ptr == to_be_deleted) {
+			*ptr = (*ptr)->next;
+			return to_be_deleted;
+		}
+
+	return NULL;
+}
+
+int console_is_registered(console_t *to_find)
+{
+	console_t *console;
+
+	assert(to_find != NULL);
+
+	for (console = console_list; console != NULL; console = console->next)
+		if (console == to_find)
+			return 1;
+
+	return 0;
+}
+
+void console_switch_state(unsigned int new_state)
+{
+	console_state = new_state;
+}
+
+void console_set_scope(console_t *console, unsigned int scope)
+{
+	assert(console != NULL);
+
+	console->flags = (console->flags & ~CONSOLE_FLAG_SCOPE_MASK) | scope;
+}
+
+int console_putc(int c)
+{
+	int err = ERROR_NO_VALID_CONSOLE;
+	console_t *console;
+
+	for (console = console_list; console != NULL; console = console->next)
+		if (console->flags & console_state) {
+			int ret = console->putc(c, console);
+			if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
+				err = ret;
+		}
+
+	return err;
+}
+
+int console_getc(void)
+{
+	int err = ERROR_NO_VALID_CONSOLE;
+	console_t *console;
+
+	do {	/* Keep polling while at least one console works correctly. */
+		for (console = console_list; console != NULL;
+		     console = console->next)
+			if (console->flags & console_state) {
+				int ret = console->getc(console);
+				if (ret >= 0)
+					return ret;
+				if (err != ERROR_NO_PENDING_CHAR)
+					err = ret;
+			}
+	} while (err == ERROR_NO_PENDING_CHAR);
+
+	return err;
+}
+
+int console_flush(void)
+{
+	int err = ERROR_NO_VALID_CONSOLE;
+	console_t *console;
+
+	for (console = console_list; console != NULL; console = console->next)
+		if (console->flags & console_state) {
+			int ret = console->flush(console);
+			if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
+				err = ret;
+		}
+
+	return err;
+}
+
+#endif	/* MULTI_CONSOLE_API */
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 02bf770..4160003 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -386,7 +386,10 @@
 	int ret, n;
 	unsigned int resp_data[4];
 
-	mmc_reset_to_idle();
+	ret = mmc_reset_to_idle();
+	if (ret != 0) {
+		return ret;
+	};
 
 	for (n = 0; n < SEND_OP_COND_MAX_RETRIES; n++) {
 		ret = mmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
@@ -416,7 +419,10 @@
 
 	ops->init();
 
-	mmc_reset_to_idle();
+	ret = mmc_reset_to_idle();
+	if (ret != 0) {
+		return ret;
+	};
 
 	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
 		ret = mmc_send_op_cond();
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index 633a425..db51581 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -97,7 +97,7 @@
 #define SDMMC_STAR_CMDSENT		BIT(7)
 #define SDMMC_STAR_DATAEND		BIT(8)
 #define SDMMC_STAR_DBCKEND		BIT(10)
-#define SDMMC_STAR_DPSMACT		BIT(11)
+#define SDMMC_STAR_DPSMACT		BIT(12)
 #define SDMMC_STAR_RXFIFOHF		BIT(15)
 #define SDMMC_STAR_RXFIFOE		BIT(19)
 #define SDMMC_STAR_IDMATE		BIT(27)
@@ -266,21 +266,22 @@
 
 	mmio_write_32(base + SDMMC_CMDR, cmd_reg);
 
-	start = get_timer(0);
+	status = mmio_read_32(base + SDMMC_STAR);
 
-	do {
-		status = mmio_read_32(base + SDMMC_STAR);
+	start = get_timer(0);
 
+	while ((status & flags_cmd) == 0U) {
 		if (get_timer(start) > TIMEOUT_10_MS) {
 			err = -ETIMEDOUT;
 			ERROR("%s: timeout 10ms (cmd = %d,status = %x)\n",
 			      __func__, cmd->cmd_idx, status);
-			break;
+			goto err_exit;
 		}
-	} while ((status & flags_cmd) == 0U);
 
-	if (((status & (SDMMC_STAR_CTIMEOUT | SDMMC_STAR_CCRCFAIL)) != 0U) &&
-	    (err == 0)) {
+		status = mmio_read_32(base + SDMMC_STAR);
+	}
+
+	if ((status & (SDMMC_STAR_CTIMEOUT | SDMMC_STAR_CCRCFAIL)) != 0U) {
 		if ((status & SDMMC_STAR_CTIMEOUT) != 0U) {
 			err = -ETIMEDOUT;
 			/*
@@ -300,9 +301,11 @@
 			ERROR("%s: CRCFAIL (cmd = %d,status = %x)\n",
 			      __func__, cmd->cmd_idx, status);
 		}
+
+		goto err_exit;
 	}
 
-	if (((cmd_reg & SDMMC_CMDR_WAITRESP) != 0U) && (err == 0)) {
+	if ((cmd_reg & SDMMC_CMDR_WAITRESP) != 0U) {
 		if ((cmd->cmd_idx == MMC_CMD(9)) &&
 		    ((cmd_reg & SDMMC_CMDR_WAITRESP) == SDMMC_CMDR_WAITRESP)) {
 			/* Need to invert response to match CSD structure */
@@ -324,32 +327,26 @@
 		}
 	}
 
-	if ((flags_data == 0U) || (err != 0)) {
-		if (flags_data != 0U) {
-			mmio_clrbits_32(base + SDMMC_CMDR, SDMMC_CMDR_CMDTRANS);
-		}
-
+	if (flags_data == 0U) {
 		mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS);
 
-		if ((err != 0) && (flags_data != 0U)) {
-			return stm32_sdmmc2_stop_transfer();
-		}
-
-		return err;
+		return 0;
 	}
 
-	start = get_timer(0);
+	status = mmio_read_32(base + SDMMC_STAR);
 
-	do {
-		status = mmio_read_32(base + SDMMC_STAR);
+	start = get_timer(0);
 
+	while ((status & flags_data) == 0U) {
 		if (get_timer(start) > TIMEOUT_10_MS) {
 			ERROR("%s: timeout 10ms (cmd = %d,status = %x)\n",
 			      __func__, cmd->cmd_idx, status);
 			err = -ETIMEDOUT;
-			break;
+			goto err_exit;
 		}
-	} while ((status & flags_data) == 0U);
+
+		status = mmio_read_32(base + SDMMC_STAR);
+	};
 
 	if ((status & (SDMMC_STAR_DTIMEOUT | SDMMC_STAR_DCRCFAIL |
 		       SDMMC_STAR_TXUNDERR | SDMMC_STAR_RXOVERR |
@@ -359,11 +356,16 @@
 		err = -EIO;
 	}
 
+err_exit:
 	mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS);
 	mmio_clrbits_32(base + SDMMC_CMDR, SDMMC_CMDR_CMDTRANS);
 
 	if (err != 0) {
-		return stm32_sdmmc2_stop_transfer();
+		int ret_stop = stm32_sdmmc2_stop_transfer();
+
+		if (ret_stop != 0) {
+			return ret_stop;
+		}
 	}
 
 	return err;
diff --git a/include/drivers/console.h b/include/drivers/console.h
index 2375466..02f2f8a 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -52,8 +52,9 @@
  * implementation, e.g. console_16550_register() from <uart_16550.h>. Consoles
  * registered that way can be unregistered/reconfigured with below functions.
  */
-/* Remove a single console_t instance from the console list. */
-int console_unregister(console_t *console);
+/* Remove a single console_t instance from the console list. Return a pointer to
+ * the console that was removed if it was found, or NULL if not. */
+console_t *console_unregister(console_t *console);
 /* Returns 1 if this console is already registered, 0 if not */
 int console_is_registered(console_t *console);
 /*
diff --git a/license.rst b/license.rst
index a4464d9..29bdf56 100644
--- a/license.rst
+++ b/license.rst
@@ -1,4 +1,4 @@
-Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
+Copyright (c) [XXXX-]YYYY, <OWNER>. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without modification,
 are permitted provided that the following conditions are met:
diff --git a/maintainers.rst b/maintainers.rst
index 3122ecd..e807f18 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -48,6 +48,23 @@
 :F: plat/arm/board/sgi575/
 :F: plat/arm/board/sgm775/
 
+Console API framework
+---------------------
+:M: Julius Werner <jwerner@chromium.org>
+:G: `jwerner-chromium`_
+:F: drivers/console/
+:F: include/drivers/console.h
+:F: plat/common/aarch64/crash_console_helpers.S
+
+coreboot support libraries
+--------------------------
+:M: Julius Werner <jwerner@chromium.org>
+:G: `jwerner-chromium`_
+:F: drivers/coreboot/
+:F: include/drivers/coreboot/
+:F: include/lib/coreboot.h
+:F: lib/coreboot/
+
 eMMC/UFS drivers
 ----------------
 :M: Haojian Zhuang <haojian.zhuang@linaro.org>
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 2dc058f..f20f515 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -15,8 +15,7 @@
 
 include lib/libfdt/libfdt.mk
 
-PLAT_BL_COMMON_SOURCES	:=	drivers/console/${ARCH}/console.S	\
-				drivers/ti/uart/${ARCH}/16550_console.S	\
+PLAT_BL_COMMON_SOURCES	:=	drivers/ti/uart/${ARCH}/16550_console.S	\
 				${XLAT_TABLES_LIB_SRCS}			\
 				${AW_PLAT}/common/plat_helpers.S	\
 				${AW_PLAT}/common/sunxi_common.c
diff --git a/plat/arm/board/sgi575/fdts/sgi575.dts b/plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
similarity index 100%
rename from plat/arm/board/sgi575/fdts/sgi575.dts
rename to plat/arm/board/sgi575/fdts/sgi575_nt_fw_config.dts
diff --git a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
index 315fa69..b14d7ad 100644
--- a/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
+++ b/plat/arm/board/sgi575/fdts/sgi575_tb_fw_config.dts
@@ -9,8 +9,8 @@
 / {
 	/* Platform Config */
 	compatible = "arm,tb_fw";
-	hw_config_addr = <0x0 0xFEF00000>;
-	hw_config_max_size = <0x0100000>;
+	nt_fw_config_addr = <0x0 0xFEF00000>;
+	nt_fw_config_max_size = <0x0100000>;
 	/*
 	 * The following two entries are placeholders for Mbed TLS
 	 * heap information. The default values don't matter since
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index f31a8b7..e72225d 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -33,8 +33,8 @@
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
 
-FDT_SOURCES		+=	${SGI575_BASE}/fdts/${PLAT}.dts
-HW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}.dtb
+FDT_SOURCES		+=	${SGI575_BASE}/fdts/${PLAT}_nt_fw_config.dts
+NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
-# Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
diff --git a/plat/arm/board/sgiclarka/fdts/sgiclarka.dts b/plat/arm/board/sgiclarka/fdts/sgiclarka_nt_fw_config.dts
similarity index 100%
rename from plat/arm/board/sgiclarka/fdts/sgiclarka.dts
rename to plat/arm/board/sgiclarka/fdts/sgiclarka_nt_fw_config.dts
diff --git a/plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts b/plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts
index 315fa69..b14d7ad 100644
--- a/plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts
+++ b/plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts
@@ -9,8 +9,8 @@
 / {
 	/* Platform Config */
 	compatible = "arm,tb_fw";
-	hw_config_addr = <0x0 0xFEF00000>;
-	hw_config_max_size = <0x0100000>;
+	nt_fw_config_addr = <0x0 0xFEF00000>;
+	nt_fw_config_max_size = <0x0100000>;
 	/*
 	 * The following two entries are placeholders for Mbed TLS
 	 * heap information. The default values don't matter since
diff --git a/plat/arm/board/sgiclarka/platform.mk b/plat/arm/board/sgiclarka/platform.mk
index 0773be5..1a8b157 100644
--- a/plat/arm/board/sgiclarka/platform.mk
+++ b/plat/arm/board/sgiclarka/platform.mk
@@ -33,10 +33,10 @@
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config))
 
-FDT_SOURCES		+=	${SGICLARKA_BASE}/fdts/${PLAT}.dts
-HW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}.dtb
+FDT_SOURCES		+=	${SGICLARKA_BASE}/fdts/${PLAT}_nt_fw_config.dts
+NT_FW_CONFIG		:=	${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
 
-# Add the HW_CONFIG to FIP and specify the same to certtool
-$(eval $(call TOOL_ADD_PAYLOAD,${HW_CONFIG},--hw-config))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
 
 override CTX_INCLUDE_AARCH32_REGS	:= 0
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c
index 39069ca..e078bd2 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/css/sgi/sgi_image_load.c
@@ -25,9 +25,9 @@
 	int nodeoffset, err;
 	unsigned int platid = 0, platcfg = 0;
 
-	mem_params = get_bl_mem_params_node(HW_CONFIG_ID);
+	mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
 	if (mem_params == NULL) {
-		ERROR("HW CONFIG base address is NULL");
+		ERROR("NT_FW CONFIG base address is NULL");
 		return -1;
 	}
 
@@ -35,7 +35,7 @@
 
 	/* Check the validity of the fdt */
 	if (fdt_check_header(fdt) != 0) {
-		ERROR("Invalid HW_CONFIG DTB passed\n");
+		ERROR("Invalid NT_FW_CONFIG DTB passed\n");
 		return -1;
 	}
 
diff --git a/plat/common/aarch64/crash_console_helpers.S b/plat/common/aarch64/crash_console_helpers.S
index 5af8db2..8f8ca11 100644
--- a/plat/common/aarch64/crash_console_helpers.S
+++ b/plat/common/aarch64/crash_console_helpers.S
@@ -16,77 +16,167 @@
 	.globl	plat_crash_console_putc
 	.globl	plat_crash_console_flush
 
-#if MULTI_CONSOLE_API
+#if !MULTI_CONSOLE_API
+#error "This crash console implementation only works with the MULTI_CONSOLE_API!"
+#endif
 
-	/* -----------------------------------------------------
-	 * int plat_crash_console_init(void)
-	 * Use normal console by default. Switch it to crash
-	 * mode so serial consoles become active again.
-	 * NOTE: This default implementation will only work for
-	 * crashes that occur after a normal console (marked
-	 * valid for the crash state) has been registered with
-	 * the console framework. To debug crashes that occur
-	 * earlier, the platform has to override these functions
-	 * with an implementation that initializes a console
-	 * driver with hardcoded parameters. See
-	 * docs/porting-guide.rst for more information.
-	 * -----------------------------------------------------
-	 */
-func plat_crash_console_init
-#if defined(IMAGE_BL1)
 	/*
-	 * BL1 code can possibly crash so early that the data segment is not yet
-	 * accessible. Don't risk undefined behavior by trying to run the normal
-	 * console framework. Platforms that want to debug BL1 will need to
-	 * override this with custom functions that can run from registers only.
+	 * Spinlock to syncronize access to crash_console_triggered. We cannot
+	 * acquire spinlocks when the cache is disabled, so in some cases (like
+	 * late during CPU suspend) some risk remains.
 	 */
-	mov	x0, #0
-	ret
-#else	/* IMAGE_BL1 */
-	mov	x3, x30
-	mov	x0, #CONSOLE_FLAG_CRASH
-	bl	console_switch_state
-	mov	x0, #1
-	ret	x3
-#endif
-endfunc plat_crash_console_init
+.section .data.crash_console_spinlock
+	define_asm_spinlock crash_console_spinlock
 
-	/* -----------------------------------------------------
-	 * void plat_crash_console_putc(int character)
-	 * Output through the normal console by default.
-	 * -----------------------------------------------------
+	/*
+	 * Flag to make sure that only one CPU can write a crash dump even if
+	 * multiple crash at the same time. Interleaving crash dumps on the same
+	 * console would just make the output unreadable, so it's better to only
+	 * get a single but uncorrupted dump. This also means that we don't have
+	 * to duplicate the reg_stash below for each CPU.
 	 */
-func plat_crash_console_putc
-	b	console_putc
-endfunc plat_crash_console_putc
+.section .data.crash_console_triggered
+	crash_console_triggered: .byte 0
 
-	/* -----------------------------------------------------
-	 * void plat_crash_console_flush(void)
-	 * Flush normal console by default.
-	 * -----------------------------------------------------
+	/*
+	 * Space to stash away some register values while we're calling into
+	 * console drivers and don't have a real stack available. We need x14,
+	 * x15 and x30 for bookkeeping within the plat_crash_console functions
+	 * themselves, and some console drivers use x16 and x17 as additional
+	 * scratch space that is not preserved by the main crash reporting
+	 * framework. (Note that x16 and x17 should really never be expected to
+	 * retain their values across any function call, even between carefully
+	 * designed assembly functions, since the linker is always free to
+	 * insert a function call veneer that uses these registers as scratch
+	 * space at any time. The current crash reporting framework doesn't
+	 * really respect that, but since TF is usually linked as a single
+	 * contiguous binary of less than 128MB, it seems to work in practice.)
 	 */
-func plat_crash_console_flush
-	b	console_flush
-endfunc plat_crash_console_flush
-
-#else	/* MULTI_CONSOLE_API */
+.section .data.crash_console_reg_stash
+	.align 3
+	crash_console_reg_stash: .quad 0, 0, 0, 0, 0
 
-	/* -----------------------------------------------------
-	 * In the old API these are all no-op stubs that need to
-	 * be overridden by the platform to be useful.
-	 * -----------------------------------------------------
+	/* --------------------------------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Takes the crash console spinlock (if possible) and checks the trigger
+	 * flag to make sure we're the first CPU to dump. If not, return an
+	 * error (so crash dumping will fail but the CPU will still call
+	 * plat_panic_handler() which may do important platform-specific tasks
+	 * that may be needed on all crashing CPUs). In either case, the lock
+	 * will be released so other CPUs can make forward progress on this.
+	 * Clobbers: x0 - x4, x30
+	 * --------------------------------------------------------------------
 	 */
 func plat_crash_console_init
-	mov	x0, #0
+#if defined(IMAGE_BL31)
+	mov	x4, x30		/* x3 and x4 are not clobbered by spin_lock() */
+	mov	x3, #0		/* return value */
+
+	mrs	x1, sctlr_el3
+	tst	x1, #SCTLR_C_BIT
+	beq	skip_spinlock	/* can't synchronize when cache disabled */
+
+	adrp	x0, crash_console_spinlock
+	add	x0, x0, :lo12:crash_console_spinlock
+	bl	spin_lock
+
+skip_spinlock:
+	adrp	x1, crash_console_triggered
+	add	x1, x1, :lo12:crash_console_triggered
+	ldarb	w2, [x1]
+	cmp	w2, #0
+	bne	init_error
+
+	mov	x3, #1		/* set return value to success */
+	stlrb	w3, [x1]
+
+init_error:
+	bl	spin_unlock	/* harmless if we didn't acquire the lock */
+	mov	x0, x3
+	ret	x4
+#else	/* Only one CPU in BL1/BL2, no need to synchronize anything */
+	mov	x0, #1
 	ret
+#endif
 endfunc plat_crash_console_init
 
+	/* --------------------------------------------------------------------
+	 * int plat_crash_console_putc(char c)
+	 * Prints the character on all consoles registered with the console
+	 * framework that have CONSOLE_FLAG_CRASH set. Note that this is only
+	 * helpful for crashes that occur after the platform intialization code
+	 * has registered a console. Platforms using this implementation need to
+	 * ensure that all console drivers they use that have the CRASH flag set
+	 * support this (i.e. are written in assembly and comply to the register
+	 * clobber requirements of plat_crash_console_putc().
+	 * --------------------------------------------------------------------
+	 */
 func plat_crash_console_putc
+	adrp	x1, crash_console_reg_stash
+	add	x1, x1, :lo12:crash_console_reg_stash
+	stp	x14, x15, [x1]
+	stp	x16, x17, [x1, #16]
+	str	x30, [x1, #32]
+
+	mov	w14, w0				/* W14 = character to print */
+	adrp	x15, console_list
+	ldr	x15, [x15, :lo12:console_list]	/* X15 = first console struct */
+
+putc_loop:
+	cbz	x15, putc_done
+	ldr	w1, [x15, #CONSOLE_T_FLAGS]
+	tst	w1, #CONSOLE_FLAG_CRASH
+	b.eq	putc_continue
+	ldr	x2, [x15, #CONSOLE_T_PUTC]
+	cbz	x2, putc_continue
+	mov	x1, x15
+	blr	x2
+	mov	w0, w14
+putc_continue:
+	ldr	x15, [x15]			/* X15 = next struct */
+	b	putc_loop
+
+putc_done:
+	adrp	x1, crash_console_reg_stash
+	add	x1, x1, :lo12:crash_console_reg_stash
+	ldp	x14, x15, [x1]
+	ldp	x16, x17, [x1, #16]
+	ldr	x30, [x1, #32]
 	ret
 endfunc plat_crash_console_putc
 
+	/* --------------------------------------------------------------------
+	 * int plat_crash_console_flush(char c)
+	 * Flushes all consoles registered with the console framework that have
+	 * CONSOLE_FLAG_CRASH set. Same requirements as putc().
+	 * --------------------------------------------------------------------
+	 */
 func plat_crash_console_flush
+	adrp	x1, crash_console_reg_stash
+	add	x1, x1, :lo12:crash_console_reg_stash
+	stp	x30, x15, [x1]
+	stp	x16, x17, [x1, #16]
+
+	adrp	x15, console_list
+	ldr	x15, [x15, :lo12:console_list]	/* X15 = first console struct */
+
+flush_loop:
+	cbz	x15, flush_done
+	ldr	w1, [x15, #CONSOLE_T_FLAGS]
+	tst	w1, #CONSOLE_FLAG_CRASH
+	b.eq	flush_continue
+	ldr	x2, [x15, #CONSOLE_T_FLUSH]
+	cbz	x2, flush_continue
+	mov	x0, x15
+	blr	x2
+flush_continue:
+	ldr	x15, [x15]			/* X15 = next struct */
+	b	flush_loop
+
+flush_done:
+	adrp	x1, crash_console_reg_stash
+	add	x1, x1, :lo12:crash_console_reg_stash
+	ldp	x30, x15, [x1]
+	ldp	x16, x17, [x1, #16]
 	ret
 endfunc plat_crash_console_flush
-
-#endif
diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S
index d3ffcaf..8952319 100644
--- a/plat/common/aarch64/platform_helpers.S
+++ b/plat/common/aarch64/platform_helpers.S
@@ -40,70 +40,11 @@
 endfunc plat_report_exception
 
 #if !ERROR_DEPRECATED
-#if MULTI_CONSOLE_API
-	/* -----------------------------------------------------
-	 * int plat_crash_console_init(void)
-	 * Use normal console by default. Switch it to crash
-	 * mode so serial consoles become active again.
-	 * NOTE: This default implementation will only work for
-	 * crashes that occur after a normal console (marked
-	 * valid for the crash state) has been registered with
-	 * the console framework. To debug crashes that occur
-	 * earlier, the platform has to override these functions
-	 * with an implementation that initializes a console
-	 * driver with hardcoded parameters. See
-	 * docs/porting-guide.rst for more information.
-	 * -----------------------------------------------------
-	 */
 func plat_crash_console_init
-#if defined(IMAGE_BL1)
-	/*
-	 * BL1 code can possibly crash so early that the data segment is not yet
-	 * accessible. Don't risk undefined behavior by trying to run the normal
-	 * console framework. Platforms that want to debug BL1 will need to
-	 * override this with custom functions that can run from registers only.
-	 */
 	mov	x0, #0
 	ret
-#else	/* IMAGE_BL1 */
-	mov	x3, x30
-	mov	x0, #CONSOLE_FLAG_CRASH
-	bl	console_switch_state
-	mov	x0, #1
-	ret	x3
-#endif
 endfunc plat_crash_console_init
 
-	/* -----------------------------------------------------
-	 * void plat_crash_console_putc(int character)
-	 * Output through the normal console by default.
-	 * -----------------------------------------------------
-	 */
-func plat_crash_console_putc
-	b	console_putc
-endfunc plat_crash_console_putc
-
-	/* -----------------------------------------------------
-	 * void plat_crash_console_flush(void)
-	 * Flush normal console by default.
-	 * -----------------------------------------------------
-	 */
-func plat_crash_console_flush
-	b	console_flush
-endfunc plat_crash_console_flush
-
-#else	/* MULTI_CONSOLE_API */
-
-	/* -----------------------------------------------------
-	 * In the old API these are all no-op stubs that need to
-	 * be overridden by the platform to be useful.
-	 * -----------------------------------------------------
-	 */
-func plat_crash_console_init
-	mov	x0, #0
-	ret
-endfunc plat_crash_console_init
-
 func plat_crash_console_putc
 	ret
 endfunc plat_crash_console_putc
@@ -111,7 +52,6 @@
 func plat_crash_console_flush
 	ret
 endfunc plat_crash_console_flush
-#endif
 #endif /* ERROR_DEPRECATED */
 
 	/* -----------------------------------------------------
diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk
index ce84e2b..dc45e90 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -26,7 +26,6 @@
 				lib/xlat_tables/xlat_tables_common.c		\
 				lib/cpus/aarch64/cortex_a53.S			\
 				lib/cpus/aarch64/cortex_a72.S			\
-				drivers/console/aarch64/console.S		\
 				drivers/arm/cci/cci.c				\
 				${IMX_GIC_SOURCES}				\
 
diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk
index 02559b4..a831bf2 100644
--- a/plat/imx/imx8qx/platform.mk
+++ b/plat/imx/imx8qx/platform.mk
@@ -25,7 +25,6 @@
 				lib/xlat_tables/xlat_tables_common.c	\
 				lib/xlat_tables/aarch64/xlat_tables.c	\
 				lib/cpus/aarch64/cortex_a35.S		\
-				drivers/console/aarch64/console.S	\
 				${IMX_GIC_SOURCES}			\
 
 include plat/imx/common/sci/sci_api.mk
diff --git a/plat/layerscape/board/ls1043/platform.mk b/plat/layerscape/board/ls1043/platform.mk
index 678205c..795d924 100644
--- a/plat/layerscape/board/ls1043/platform.mk
+++ b/plat/layerscape/board/ls1043/platform.mk
@@ -28,8 +28,7 @@
 					-Iinclude/drivers/io
 
 
-PLAT_BL_COMMON_SOURCES		:=	drivers/console/aarch64/console.S	\
-					plat/layerscape/common/aarch64/ls_console.S
+PLAT_BL_COMMON_SOURCES		:=	plat/layerscape/common/aarch64/ls_console.S
 
 LS1043_CPU_LIBS			:=	lib/cpus/${ARCH}/aem_generic.S
 
diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk
index 3983c70..e2ac97f 100644
--- a/plat/marvell/a3700/common/a3700_common.mk
+++ b/plat/marvell/a3700/common/a3700_common.mk
@@ -96,7 +96,6 @@
 				$(ATF_INCLUDES)
 
 PLAT_BL_COMMON_SOURCES	:=	$(PLAT_COMMON_BASE)/aarch64/a3700_common.c \
-				drivers/console/aarch64/console.S	   \
 				$(MARVELL_COMMON_BASE)/marvell_cci.c	   \
 				$(MARVELL_DRV_BASE)/uart/a3700_console.S
 
diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk
index 88d9311..e350d6a 100644
--- a/plat/marvell/a8k/common/a8k_common.mk
+++ b/plat/marvell/a8k/common/a8k_common.mk
@@ -55,7 +55,6 @@
 				$(ATF_INCLUDES)
 
 PLAT_BL_COMMON_SOURCES	:=	$(PLAT_COMMON_BASE)/aarch64/a8k_common.c \
-				drivers/console/aarch64/console.S	 \
 				drivers/ti/uart/aarch64/16550_console.S
 
 BLE_PORTING_SOURCES	:=	$(PLAT_FAMILY_BASE)/$(PLAT)/board/dram_port.c \
diff --git a/plat/meson/gxbb/platform.mk b/plat/meson/gxbb/platform.mk
index e6f5ae4..68ff400 100644
--- a/plat/meson/gxbb/platform.mk
+++ b/plat/meson/gxbb/platform.mk
@@ -14,8 +14,7 @@
 				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_BL_COMMON_SOURCES	:=	drivers/meson/console/aarch64/meson_console.S \
 				plat/meson/gxbb/gxbb_common.c		\
 				plat/meson/gxbb/gxbb_topology.c		\
 				${XLAT_TABLES_LIB_SRCS}
diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk
index 785f640..2b2ac51 100644
--- a/plat/rockchip/rk3328/platform.mk
+++ b/plat/rockchip/rk3328/platform.mk
@@ -34,7 +34,6 @@
 
 BL31_SOURCES		+=	${RK_GIC_SOURCES}				\
 				drivers/arm/cci/cci.c				\
-				drivers/console/aarch64/console.S		\
 				drivers/ti/uart/aarch64/16550_console.S		\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
diff --git a/plat/rockchip/rk3368/platform.mk b/plat/rockchip/rk3368/platform.mk
index a3e593e..c0164c1 100644
--- a/plat/rockchip/rk3368/platform.mk
+++ b/plat/rockchip/rk3368/platform.mk
@@ -31,7 +31,6 @@
 
 BL31_SOURCES		+=	${RK_GIC_SOURCES}				\
 				drivers/arm/cci/cci.c				\
-				drivers/console/aarch64/console.S		\
 				drivers/ti/uart/aarch64/16550_console.S		\
 				drivers/delay_timer/delay_timer.c		\
 				drivers/delay_timer/generic_delay_timer.c	\
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index eccf1cc..b624717 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -37,7 +37,6 @@
 
 BL31_SOURCES	+=	${RK_GIC_SOURCES}				\
 			drivers/arm/cci/cci.c				\
-			drivers/console/aarch64/console.S		\
 			drivers/ti/uart/aarch64/16550_console.S		\
 			drivers/delay_timer/delay_timer.c		\
 			drivers/delay_timer/generic_delay_timer.c	\
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
index db96de8..46c139e 100644
--- a/plat/rpi3/platform.mk
+++ b/plat/rpi3/platform.mk
@@ -10,8 +10,7 @@
 PLAT_INCLUDES		:=	-Iinclude/common/tbbr			\
 				-Iplat/rpi3/include
 
-PLAT_BL_COMMON_SOURCES	:=	drivers/console/aarch64/console.S	\
-				drivers/ti/uart/aarch64/16550_console.S	\
+PLAT_BL_COMMON_SOURCES	:=	drivers/ti/uart/aarch64/16550_console.S	\
 				plat/rpi3/rpi3_common.c			\
 				${XLAT_TABLES_LIB_SRCS}
 
diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c
index fdbd4bf..b1125d1 100644
--- a/plat/st/stm32mp1/bl2_io_storage.c
+++ b/plat/st/stm32mp1/bl2_io_storage.c
@@ -282,7 +282,11 @@
 		}
 
 		params.device_info = &device_info;
-		stm32_sdmmc2_mmc_init(&params);
+		if (stm32_sdmmc2_mmc_init(&params) != 0) {
+			ERROR("SDMMC%u init failed\n",
+			      boot_context->boot_interface_instance);
+			panic();
+		}
 
 		/* Open MMC as a block device to read GPT table */
 		io_result = register_io_dev_block(&mmc_dev_con);
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index f4a0ca4..545b140 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -35,8 +35,7 @@
 
 PLAT_BL_COMMON_SOURCES	:=	plat/st/stm32mp1/stm32mp1_common.c
 
-PLAT_BL_COMMON_SOURCES	+=	drivers/console/aarch32/console.S			\
-				drivers/st/uart/aarch32/stm32_console.S
+PLAT_BL_COMMON_SOURCES	+=	drivers/st/uart/aarch32/stm32_console.S
 
 ifneq (${ENABLE_STACK_PROTECTOR},0)
 PLAT_BL_COMMON_SOURCES	+=	plat/st/stm32mp1/stm32mp1_stack_protector.c
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index fbd79b4..9b3e7d8 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -39,7 +39,6 @@
 				-I${PLAT_PATH}/common/drivers/ti_sci	\
 
 K3_CONSOLE_SOURCES	+=	\
-				drivers/console/aarch64/console.S	\
 				drivers/ti/uart/aarch64/16550_console.S	\
 				${PLAT_PATH}/common/k3_console.c	\