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(¶ms);
+ if (stm32_sdmmc2_mmc_init(¶ms) != 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 \