summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authordavidcunado-arm <david.cunado@arm.com>2018-01-24 14:31:53 +0000
committerGitHub <noreply@github.com>2018-01-24 14:31:53 +0000
commit040f1e6987ab78ce459a96137a92cb985c16a136 (patch)
tree4ac8cf8073f03180de5b04373302518727a03490 /drivers
parentd2184052ec9f7055e666885d2e9f1c563bdd8d93 (diff)
parent1c5f5031f38ed77688298d419727a6f0930e0673 (diff)
Merge pull request #1193 from jwerner-chromium/JW_coreboot
New console API and coreboot support [v4]
Diffstat (limited to 'drivers')
-rw-r--r--drivers/arm/pl011/aarch64/pl011_console.S176
-rw-r--r--drivers/cadence/uart/aarch64/cdns_console.S145
-rw-r--r--drivers/console/aarch64/console.S106
-rw-r--r--drivers/console/aarch64/deprecated_console.S110
-rw-r--r--drivers/console/aarch64/multi_console.S260
-rw-r--r--drivers/console/aarch64/skeleton_console.S184
-rw-r--r--drivers/coreboot/cbmem_console/aarch64/cbmem_console.S101
-rw-r--r--drivers/ti/uart/aarch64/16550_console.S147
8 files changed, 985 insertions, 244 deletions
diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S
index 8b15d565..6f2510ad 100644
--- a/drivers/arm/pl011/aarch64/pl011_console.S
+++ b/drivers/arm/pl011/aarch64/pl011_console.S
@@ -5,6 +5,7 @@
*/
#include <arch.h>
#include <asm_macros.S>
+#include <assert_macros.S>
#include <pl011.h>
/*
@@ -13,15 +14,21 @@
*/
#include "../../../console/aarch64/console.S"
+ /*
+ * "core" functions are low-level implementations that don't require
+ * writable memory and are thus safe to call in BL1 crash context.
+ */
+ .globl console_pl011_core_init
+ .globl console_pl011_core_putc
+ .globl console_pl011_core_getc
+ .globl console_pl011_core_flush
- .globl console_core_init
- .globl console_core_putc
- .globl console_core_getc
- .globl console_core_flush
-
+ .globl console_pl011_putc
+ .globl console_pl011_getc
+ .globl console_pl011_flush
/* -----------------------------------------------
- * int console_core_init(uintptr_t base_addr,
+ * int console_pl011_core_init(uintptr_t base_addr,
* unsigned int uart_clk, unsigned int baud_rate)
* Function to initialize the console without a
* C Runtime to print debug information. This
@@ -34,7 +41,7 @@
* Clobber list : x1, x2, x3, x4
* -----------------------------------------------
*/
-func console_core_init
+func console_pl011_core_init
/* Check the input base address */
cbz x0, core_init_fail
#if !PL011_GENERIC_UART
@@ -71,10 +78,54 @@ func console_core_init
core_init_fail:
mov w0, wzr
ret
-endfunc console_core_init
+endfunc console_pl011_core_init
+
+#if MULTI_CONSOLE_API
+ .globl console_pl011_register
+
+ /* -----------------------------------------------
+ * int console_pl011_register(console_pl011_t *console,
+ uintptr_t base, uint32_t clk, uint32_t baud)
+ * Function to initialize and register a new PL011
+ * console. Storage passed in for the console struct
+ * *must* be persistent (i.e. not from the stack).
+ * In: x0 - UART register base address
+ * w1 - UART clock in Hz
+ * w2 - Baud rate
+ * x3 - pointer to empty console_pl011_t struct
+ * Out: return 1 on success, 0 on error
+ * Clobber list : x0, x1, x2, x6, x7, x14
+ * -----------------------------------------------
+ */
+func console_pl011_register
+ mov x7, x30
+ mov x6, x3
+ cbz x6, register_fail
+ str x0, [x6, #CONSOLE_T_PL011_BASE]
+
+ bl console_pl011_core_init
+ cbz x0, register_fail
+
+ mov x0, x6
+ mov x30, x7
+ finish_console_register pl011
+
+register_fail:
+ ret x7
+endfunc console_pl011_register
+#else
+ .globl console_core_init
+ .globl console_core_putc
+ .globl console_core_getc
+ .globl console_core_flush
+ .equ console_core_init,console_pl011_core_init
+ .equ console_core_putc,console_pl011_core_putc
+ .equ console_core_getc,console_pl011_core_getc
+ .equ console_core_flush,console_pl011_core_flush
+#endif
/* --------------------------------------------------------
- * int console_core_putc(int c, uintptr_t base_addr)
+ * int console_pl011_core_putc(int c, uintptr_t base_addr)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -83,9 +134,12 @@ endfunc console_core_init
* Clobber list : x2
* --------------------------------------------------------
*/
-func console_core_putc
- /* Check the input parameter */
- cbz x1, putc_error
+func console_pl011_core_putc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
/* Prepend '\r' to '\n' */
cmp w0, #0xA
b.ne 2f
@@ -101,36 +155,75 @@ func console_core_putc
tbnz w2, #PL011_UARTFR_TXFF_BIT, 2b
str w0, [x1, #UARTDR]
ret
-putc_error:
- mov w0, #-1
- ret
-endfunc console_core_putc
+endfunc console_pl011_core_putc
+
+ /* --------------------------------------------------------
+ * int console_pl011_putc(int c, console_pl011_t *console)
+ * Function to output a character over the console. It
+ * returns the character printed on success or -1 on error.
+ * In : w0 - character to be printed
+ * x1 - pointer to console_t structure
+ * Out : return -1 on error else return character.
+ * Clobber list : x2
+ * --------------------------------------------------------
+ */
+func console_pl011_putc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x1, [x1, #CONSOLE_T_PL011_BASE]
+ b console_pl011_core_putc
+endfunc console_pl011_putc
/* ---------------------------------------------
- * int console_core_getc(uintptr_t base_addr)
+ * int console_pl011_core_getc(uintptr_t base_addr)
* Function to get a character from the console.
* It returns the character grabbed on success
- * or -1 on error.
+ * or -1 if no character is available.
* In : x0 - console base address
+ * Out: w0 - character if available, else -1
* Clobber list : x0, x1
* ---------------------------------------------
*/
-func console_core_getc
- cbz x0, getc_error
-1:
+func console_pl011_core_getc
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
/* Check if the receive FIFO is empty */
ldr w1, [x0, #UARTFR]
- tbnz w1, #PL011_UARTFR_RXFE_BIT, 1b
+ tbnz w1, #PL011_UARTFR_RXFE_BIT, no_char
ldr w1, [x0, #UARTDR]
mov w0, w1
ret
-getc_error:
- mov w0, #-1
+no_char:
+ mov w0, #ERROR_NO_PENDING_CHAR
ret
-endfunc console_core_getc
+endfunc console_pl011_core_getc
+
+ /* ---------------------------------------------
+ * int console_pl011_getc(console_pl011_t *console)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 if no character is available.
+ * In : x0 - pointer to console_t structure
+ * Out: w0 - character if available, else -1
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_pl011_getc
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x0, [x0, #CONSOLE_T_PL011_BASE]
+ b console_pl011_core_getc
+endfunc console_pl011_getc
/* ---------------------------------------------
- * int console_core_flush(uintptr_t base_addr)
+ * int console_pl011_core_flush(uintptr_t base_addr)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - console base address
@@ -138,9 +231,11 @@ endfunc console_core_getc
* Clobber list : x0, x1
* ---------------------------------------------
*/
-func console_core_flush
- cbz x0, flush_error
-
+func console_pl011_core_flush
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
1:
/* Loop until the transmit FIFO is empty */
ldr w1, [x0, #UARTFR]
@@ -148,7 +243,22 @@ func console_core_flush
mov w0, #0
ret
-flush_error:
- mov w0, #-1
- ret
-endfunc console_core_flush
+endfunc console_pl011_core_flush
+
+ /* ---------------------------------------------
+ * int console_pl011_flush(console_pl011_t *console)
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * In : x0 - pointer to console_t structure
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_pl011_flush
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x0, [x0, #CONSOLE_T_PL011_BASE]
+ b console_pl011_core_flush
+endfunc console_pl011_flush
diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S
index f6a1532c..fc357f8a 100644
--- a/drivers/cadence/uart/aarch64/cdns_console.S
+++ b/drivers/cadence/uart/aarch64/cdns_console.S
@@ -5,16 +5,22 @@
*/
#include <arch.h>
#include <asm_macros.S>
+#include <assert_macros.S>
#include <cadence/cdns_uart.h>
- .globl console_core_init
- .globl console_core_putc
- .globl console_core_getc
- .globl console_core_flush
+ /*
+ * "core" functions are low-level implementations that don't require
+ * writable memory and are thus safe to call in BL1 crash context.
+ */
+ .globl console_cdns_core_init
+ .globl console_cdns_core_putc
+ .globl console_cdns_core_getc
+
+ .globl console_cdns_putc
+ .globl console_cdns_getc
/* -----------------------------------------------
- * int console_core_init(unsigned long base_addr,
- * unsigned int uart_clk, unsigned int baud_rate)
+ * int console_cdns_core_init(uintptr_t base_addr)
* Function to initialize the console without a
* C Runtime to print debug information. This
* function will be accessed by console_init and
@@ -23,18 +29,13 @@
* the HW (baud, ...) and only enable the trans-
* mitter and receiver here.
* In: x0 - console base address
- * w1 - Uart clock in Hz
- * w2 - Baud rate
* Out: return 1 on success else 0 on error
* Clobber list : x1, x2, x3
* -----------------------------------------------
*/
-func console_core_init
+func console_cdns_core_init
/* Check the input base address */
cbz x0, core_init_fail
- /* Check baud rate and uart clock for sanity */
- cbz w1, core_init_fail
- cbz w2, core_init_fail
/* RX/TX enabled & reset */
mov w3, #(R_UART_CR_TX_EN | R_UART_CR_RX_EN | R_UART_CR_TXRST | R_UART_CR_RXRST)
@@ -45,10 +46,51 @@ func console_core_init
core_init_fail:
mov w0, wzr
ret
-endfunc console_core_init
+endfunc console_cdns_core_init
+
+#if MULTI_CONSOLE_API
+ .globl console_cdns_register
+
+ /* -----------------------------------------------
+ * int console_cdns_register(console_cdns_t *console,
+ uintptr_t base, uint32_t clk, uint32_t baud)
+ * Function to initialize and register a new CDNS
+ * console. Storage passed in for the console struct
+ * *must* be persistent (i.e. not from the stack).
+ * In: x0 - UART register base address
+ * x1 - pointer to empty console_cdns_t struct
+ * Out: return 1 on success, 0 on error
+ * Clobber list : x0, x1, x2, x6, x7, x14
+ * -----------------------------------------------
+ */
+func console_cdns_register
+ mov x7, x30
+ mov x6, x1
+ cbz x6, register_fail
+ str x0, [x6, #CONSOLE_T_CDNS_BASE]
+
+ bl console_cdns_core_init
+ cbz x0, register_fail
+
+ mov x0, x6
+ mov x30, v7
+ finish_console_register cdns
+
+register_fail:
+ ret x7
+endfunc console_cdns_register
+#else
+ .globl console_core_init
+ .globl console_core_putc
+ .globl console_core_getc
+ .globl console_core_flush
+ .equ console_core_init,console_cdns_core_init
+ .equ console_core_putc,console_cdns_core_putc
+ .equ console_core_getc,console_cdns_core_getc
+#endif
/* --------------------------------------------------------
- * int console_core_putc(int c, unsigned long base_addr)
+ * int console_cdns_core_putc(int c, uintptr_t base_addr)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -57,9 +99,12 @@ endfunc console_core_init
* Clobber list : x2
* --------------------------------------------------------
*/
-func console_core_putc
- /* Check the input parameter */
- cbz x1, putc_error
+func console_cdns_core_putc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
/* Prepend '\r' to '\n' */
cmp w0, #0xA
b.ne 2f
@@ -75,36 +120,76 @@ func console_core_putc
tbnz w2, #UART_SR_INTR_TFUL_BIT, 2b
str w0, [x1, #R_UART_TX]
ret
-putc_error:
- mov w0, #-1
- ret
-endfunc console_core_putc
+endfunc console_cdns_core_putc
+
+ /* --------------------------------------------------------
+ * int console_cdns_putc(int c, console_cdns_t *cdns)
+ * Function to output a character over the console. It
+ * returns the character printed on success or -1 on error.
+ * In : w0 - character to be printed
+ * x1 - pointer to console_t structure
+ * Out : return -1 on error else return character.
+ * Clobber list : x2
+ * --------------------------------------------------------
+ */
+func console_cdns_putc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x1, [x1, #CONSOLE_T_CDNS_BASE]
+ b console_cdns_core_putc
+endfunc console_cdns_putc
/* ---------------------------------------------
- * int console_core_getc(unsigned long base_addr)
+ * int console_cdns_core_getc(uintptr_t base_addr)
* Function to get a character from the console.
* It returns the character grabbed on success
- * or -1 on error.
+ * or -1 if no character is available.
* In : x0 - console base address
+ * Out: w0 - character if available, else -1
* Clobber list : x0, x1
* ---------------------------------------------
*/
-func console_core_getc
- cbz x0, getc_error
-1:
+func console_cdns_core_getc
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
/* Check if the receive FIFO is empty */
ldr w1, [x0, #R_UART_SR]
- tbnz w1, #UART_SR_INTR_REMPTY_BIT, 1b
+ tbnz w1, #UART_SR_INTR_REMPTY_BIT, no_char
ldr w1, [x0, #R_UART_RX]
mov w0, w1
ret
-getc_error:
- mov w0, #-1
+no_char:
+ mov w0, #ERROR_NO_PENDING_CHAR
ret
-endfunc console_core_getc
+endfunc console_cdns_core_getc
+
+ /* ---------------------------------------------
+ * int console_cdns_getc(console_cdns_t *console)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 if no character is available.
+ * In : x0 - pointer to console_t structure
+ * Out: w0 - character if available, else -1
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_cdns_getc
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x0, [x0, #CONSOLE_T_CDNS_BASE]
+ b console_cdns_core_getc
+endfunc console_cdns_getc
/* ---------------------------------------------
* int console_core_flush(uintptr_t base_addr)
+ * DEPRECATED: Not used with MULTI_CONSOLE_API!
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - console base address
diff --git a/drivers/console/aarch64/console.S b/drivers/console/aarch64/console.S
index 7cc04ddd..f847ed59 100644
--- a/drivers/console/aarch64/console.S
+++ b/drivers/console/aarch64/console.S
@@ -1,105 +1,11 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <asm_macros.S>
- .globl console_init
- .globl console_uninit
- .globl console_putc
- .globl console_getc
- .globl console_flush
-
- /*
- * The console base 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_base ; .align 3
- console_base: .quad 0x0
-
- /* -----------------------------------------------
- * int console_init(uintptr_t base_addr,
- * unsigned int uart_clk, unsigned int baud_rate)
- * Function to initialize the console without a
- * C Runtime to print debug information. It saves
- * the console base to the data section.
- * In: x0 - console base address
- * w1 - Uart clock in Hz
- * w2 - Baud rate
- * out: return 1 on success else 0 on error
- * Clobber list : x1 - x4
- * -----------------------------------------------
- */
-func console_init
- /* Check the input base address */
- cbz x0, init_fail
- adrp x3, console_base
- str x0, [x3, :lo12:console_base]
- b console_core_init
-init_fail:
- ret
-endfunc console_init
-
- /* -----------------------------------------------
- * void console_uninit(void)
- * Function to finish the use of console driver.
- * It sets the console_base as NULL so that any
- * further invocation of `console_putc` or
- * `console_getc` APIs would return error.
- * -----------------------------------------------
- */
-func console_uninit
- mov x0, #0
- adrp x3, console_base
- str x0, [x3, :lo12:console_base]
- ret
-endfunc console_uninit
-
- /* ---------------------------------------------
- * int console_putc(int c)
- * Function to output a character over the
- * console. It returns the character printed on
- * success or -1 on error.
- * In : x0 - character to be printed
- * Out : return -1 on error else return character.
- * Clobber list : x1, x2
- * ---------------------------------------------
- */
-func console_putc
- adrp x2, console_base
- ldr x1, [x2, :lo12:console_base]
- b console_core_putc
-endfunc console_putc
-
- /* ---------------------------------------------
- * int console_getc(void)
- * Function to get a character from the console.
- * It returns the character grabbed on success
- * or -1 on error.
- * Clobber list : x0, x1
- * ---------------------------------------------
- */
-func console_getc
- adrp x1, console_base
- ldr x0, [x1, :lo12:console_base]
- b console_core_getc
-endfunc console_getc
-
- /* ---------------------------------------------
- * int console_flush(void)
- * Function to force a write of all buffered
- * data that hasn't been output. It returns 0
- * upon successful completion, otherwise it
- * returns -1.
- * Clobber list : x0, x1
- * ---------------------------------------------
- */
-func console_flush
- adrp x1, console_base
- ldr x0, [x1, :lo12:console_base]
- b console_core_flush
-endfunc console_flush
+#if MULTI_CONSOLE_API
+#include "multi_console.S"
+#else
+#include "deprecated_console.S"
+#endif
diff --git a/drivers/console/aarch64/deprecated_console.S b/drivers/console/aarch64/deprecated_console.S
new file mode 100644
index 00000000..c83e2467
--- /dev/null
+++ b/drivers/console/aarch64/deprecated_console.S
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_macros.S>
+
+/*
+ * This is the common console core code for the deprecated single-console API.
+ * New platforms should set MULTI_CONSOLE_API=1 and not use this file.
+ */
+
+ .globl console_init
+ .globl console_uninit
+ .globl console_putc
+ .globl console_getc
+ .globl console_flush
+
+ /*
+ * The console base 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_base ; .align 3
+ console_base: .quad 0x0
+
+ /* -----------------------------------------------
+ * int console_init(uintptr_t base_addr,
+ * unsigned int uart_clk, unsigned int baud_rate)
+ * Function to initialize the console without a
+ * C Runtime to print debug information. It saves
+ * the console base to the data section.
+ * In: x0 - console base address
+ * w1 - Uart clock in Hz
+ * w2 - Baud rate
+ * out: return 1 on success else 0 on error
+ * Clobber list : x1 - x4
+ * -----------------------------------------------
+ */
+func console_init
+ /* Check the input base address */
+ cbz x0, init_fail
+ adrp x3, console_base
+ str x0, [x3, :lo12:console_base]
+ b console_core_init
+init_fail:
+ ret
+endfunc console_init
+
+ /* -----------------------------------------------
+ * void console_uninit(void)
+ * Function to finish the use of console driver.
+ * It sets the console_base as NULL so that any
+ * further invocation of `console_putc` or
+ * `console_getc` APIs would return error.
+ * -----------------------------------------------
+ */
+func console_uninit
+ mov x0, #0
+ adrp x3, console_base
+ str x0, [x3, :lo12:console_base]
+ ret
+endfunc console_uninit
+
+ /* ---------------------------------------------
+ * int console_putc(int c)
+ * Function to output a character over the
+ * console. It returns the character printed on
+ * success or -1 on error.
+ * In : x0 - character to be printed
+ * Out : return -1 on error else return character.
+ * Clobber list : x1, x2
+ * ---------------------------------------------
+ */
+func console_putc
+ adrp x2, console_base
+ ldr x1, [x2, :lo12:console_base]
+ b console_core_putc
+endfunc console_putc
+
+ /* ---------------------------------------------
+ * int console_getc(void)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 on error.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_getc
+ adrp x1, console_base
+ ldr x0, [x1, :lo12:console_base]
+ b console_core_getc
+endfunc console_getc
+
+ /* ---------------------------------------------
+ * int console_flush(void)
+ * Function to force a write of all buffered
+ * data that hasn't been output. It returns 0
+ * upon successful completion, otherwise it
+ * returns -1.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_flush
+ adrp x1, console_base
+ ldr x0, [x1, :lo12:console_base]
+ b console_core_flush
+endfunc console_flush
diff --git a/drivers/console/aarch64/multi_console.S b/drivers/console/aarch64/multi_console.S
new file mode 100644
index 00000000..15c3ba43
--- /dev/null
+++ b/drivers/console/aarch64/multi_console.S
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2015-2017, 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_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, x14
+ * -----------------------------------------------
+ */
+func console_register
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+ 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:
+#endif /* ENABLE_ASSERTIONS */
+ adrp x14, console_list
+ ldr x1, [x14, :lo12:console_list] /* X1 = first struct in list */
+ str x0, [x14, :lo12:console_list] /* list head = new console */
+ str x1, [x0, #CONSOLE_T_NEXT] /* new console next ptr = X1 */
+ mov x0, #1
+ 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, x14
+ * -----------------------------------------------
+ */
+func console_unregister
+ adrp x14, console_list
+ add x14, x14, :lo12:console_list /* X14 = ptr to first struct */
+ ldr x1, [x14] /* X1 = first struct */
+
+unregister_loop:
+ cbz x1, unregister_not_found
+ cmp x0, x1
+ b.eq unregister_found
+ ldr x14, [x14] /* X14 = next ptr of struct */
+ ldr x1, [x14] /* X1 = next struct */
+ b unregister_loop
+
+unregister_found:
+ ldr x1, [x1] /* X1 = next struct */
+ str x1, [x14] /* prev->next = cur->next */
+ ret
+
+unregister_not_found:
+ mov x0, #0 /* return NULL if not found */
+ ret
+endfunc console_unregister
+
+ /* -----------------------------------------------
+ * 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, x12, x13, x14, x15
+ * ---------------------------------------------
+ */
+func console_putc
+ mov x15, x30
+ mov w13, #ERROR_NO_VALID_CONSOLE /* W13 = current return value */
+ mov w12, w0 /* W12 = character to print */
+ adrp x14, console_list
+ ldr x14, [x14, :lo12:console_list] /* X14 = first console struct */
+
+putc_loop:
+ cbz x14, putc_done
+ adrp x1, console_state
+ ldrb w1, [x1, :lo12:console_state]
+ ldr x2, [x14, #CONSOLE_T_FLAGS]
+ tst w1, w2
+ b.eq putc_continue
+ ldr x2, [x14, #CONSOLE_T_PUTC]
+ cbz x2, putc_continue
+ mov w0, w12
+ mov x1, x14
+ blr x2
+ cmp w13, #ERROR_NO_VALID_CONSOLE /* update W13 if it's NOVALID */
+ ccmp w0, #0, #0x8, ne /* else update it if W0 < 0 */
+ csel w13, w0, w13, lt
+putc_continue:
+ ldr x14, [x14] /* X14 = next struct */
+ b putc_loop
+
+putc_done:
+ mov w0, w13
+ ret x15
+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, x13, x14, x15
+ * ---------------------------------------------
+ */
+func console_getc
+ mov x15, x30
+getc_try_again:
+ mov w13, #ERROR_NO_VALID_CONSOLE /* W13 = current return value */
+ adrp x14, console_list
+ ldr x14, [x14, :lo12:console_list] /* X14 = first console struct */
+ cbnz x14, getc_loop
+ mov w0, w13 /* If no consoles registered */
+ ret x15 /* return immediately. */
+
+getc_loop:
+ adrp x0, console_state
+ ldrb w0, [x0, :lo12:console_state]
+ ldr x1, [x14, #CONSOLE_T_FLAGS]
+ tst w0, w1
+ b.eq getc_continue
+ ldr x1, [x14, #CONSOLE_T_GETC]
+ cbz x1, getc_continue
+ mov x0, x14
+ blr x1
+ cmp w0, #0 /* if X0 >= 0: return */
+ b.ge getc_found
+ cmp w13, #ERROR_NO_PENDING_CHAR /* may update W13 (NOCHAR has */
+ csel w13, w13, w0, eq /* precedence vs real errors) */
+getc_continue:
+ ldr x14, [x14] /* X14 = next struct */
+ cbnz x14, getc_loop
+ cmp w13, #ERROR_NO_PENDING_CHAR /* Keep scanning if at least */
+ b.eq getc_try_again /* one console returns NOCHAR */
+ mov w0, w13
+
+getc_found:
+ ret x15
+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, x3, x4, x5, x13, x14, x15
+ * ---------------------------------------------
+ */
+func console_flush
+ mov x15, x30
+ mov w13, #ERROR_NO_VALID_CONSOLE /* W13 = current return value */
+ adrp x14, console_list
+ ldr x14, [x14, :lo12:console_list] /* X14 = first console struct */
+
+flush_loop:
+ cbz x14, flush_done
+ adrp x1, console_state
+ ldrb w1, [x1, :lo12:console_state]
+ ldr x2, [x14, #CONSOLE_T_FLAGS]
+ tst w1, w2
+ b.eq flush_continue
+ ldr x1, [x14, #CONSOLE_T_FLUSH]
+ cbz x1, flush_continue
+ mov x0, x14
+ blr x1
+ cmp w13, #ERROR_NO_VALID_CONSOLE /* update W13 if it's NOVALID */
+ ccmp w0, #0, #0x8, ne /* else update it if W0 < 0 */
+ csel w13, w0, w13, lt
+flush_continue:
+ ldr x14, [x14] /* X14 = next struct */
+ b flush_loop
+
+flush_done:
+ mov w0, w13
+ ret x15
+endfunc console_flush
diff --git a/drivers/console/aarch64/skeleton_console.S b/drivers/console/aarch64/skeleton_console.S
index 9db6157d..1b5d7393 100644
--- a/drivers/console/aarch64/skeleton_console.S
+++ b/drivers/console/aarch64/skeleton_console.S
@@ -4,99 +4,171 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
+#include <console_macros.S>
/*
- * This file contains a skeleton console implementation that can
- * be used as basis for a real console implementation by platforms
- * that do not contain PL011 hardware.
+ * This file contains a skeleton console driver that can be used as
+ * basis for a real console driver. Console drivers in Trusted Firmware
+ * can be instantiated multiple times. Each instance is described by a
+ * separate console_t structure which must be registered with the common
+ * console framework via console_register(). Console drivers should
+ * define a console_xxx_register() function that initializes a new
+ * console_t structure passed in from the caller and registers it after
+ * initializing the console hardware. Drivers may define their own
+ * structures extending console_t to store private driver information.
+ * Console drivers *MUST* take care that the console callbacks they
+ * implement only change registers allowed in the clobber lists defined
+ * in this file. (Note that in addition to the explicit clobber lists,
+ * any function may always clobber the intra-procedure-call registers
+ * X16 and X17, but may never depend on them retaining their values
+ * across any function call.)
+ * Platforms using drivers based on this template need to enable
+ * MULTI_CONSOLE_API := 1 in their platform.mk.
*/
- .globl console_core_init
- .globl console_core_putc
- .globl console_core_getc
- .globl console_core_flush
+ .globl console_xxx_register
+ .globl console_xxx_putc
+ .globl console_xxx_getc
+ .globl console_xxx_flush
/* -----------------------------------------------
- * int console_core_init(uintptr_t base_addr,
- * unsigned int uart_clk, unsigned int baud_rate)
- * Function to initialize the console without a
- * C Runtime to print debug information. This
- * function will be accessed by console_init and
- * crash reporting.
- * In: x0 - console base address
- * w1 - Uart clock in Hz
- * w2 - Baud rate
- * Out: return 1 on success else 0 on error
- * Clobber list : x1, x2
+ * int console_xxx_register(console_xxx_t *console,
+ * ...additional parameters as desired...)
+ * Function to initialize and register the console.
+ * The caller needs to pass an empty console_xxx_t
+ * structure in which *MUST* be allocated in
+ * persistent memory (e.g. a global or static local
+ * variable, *NOT* on the stack).
+ * In : x0 - pointer to empty console_t structure
+ * x1 through x7: additional parameters as desired
+ * Out: x0 - 1 on success, 0 on error
+ * Clobber list : x0 - x7
* -----------------------------------------------
*/
-func console_core_init
- /* Check the input base address */
- cbz x0, core_init_fail
- /* Check baud rate and uart clock for sanity */
- cbz w1, core_init_fail
- cbz w2, core_init_fail
- /* Insert implementation here */
- mov w0, #1
- ret
-core_init_fail:
- mov w0, wzr
+func console_xxx_register
+ /*
+ * Store parameters (e.g. hardware base address) in driver-specific
+ * console_xxx_t structure field if they will need to be retrieved
+ * by later console callback (e.g. putc).
+ * Example:
+ */
+ str x1, [x0, #CONSOLE_T_XXX_BASE]
+ str x2, [x0, #CONSOLE_T_XXX_SOME_OTHER_VALUE]
+
+ /*
+ * Initialize console hardware, using x1 - x7 parameters as needed.
+ * Keep console_t pointer in x0 for later.
+ */
+
+ /* Macro to finish up registration and return (needs valid x0 + x30). */
+ finish_console_register xxx
+
+ /* Jump here if hardware init fails or parameters are invalid. */
+register_fail:
+ mov w0, #0
ret
-endfunc console_core_init
+endfunc console_xxx_register
/* --------------------------------------------------------
- * int console_core_putc(int c, uintptr_t base_addr)
+ * int console_xxx_putc(int c, console_xxx_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
- * x1 - console base address
- * Out : return -1 on error else return character.
- * Clobber list : x2
+ * x1 - pointer to console_t struct
+ * Out: w0 - printed character on success, < 0 on error.
+ * Clobber list : x0, x1, x2
* --------------------------------------------------------
*/
-func console_core_putc
- /* Check the input parameter */
- cbz x1, putc_error
- /* Insert implementation here */
+func console_xxx_putc
+ /*
+ * Retrieve values we need (e.g. hardware base address) from
+ * console_xxx_t structure pointed to by x1.
+ * Example:
+ */
+ ldr x1, [x1, #CONSOLE_T_XXX_BASE]
+
+ /*
+ * Write w0 to hardware.
+ */
+
ret
+
+ /* Jump here if output fails for any reason. */
putc_error:
mov w0, #-1
ret
-endfunc console_core_putc
+endfunc console_xxx_putc
/* ---------------------------------------------
- * int console_core_getc(uintptr_t base_addr)
+ * int console_xxx_getc(console_xxx_t *console)
* Function to get a character from the console.
- * It returns the character grabbed on success
- * or -1 on error.
- * In : x0 - console base address
+ * Even though console_getc() is blocking, this
+ * callback has to be non-blocking and always
+ * return immediately to allow polling multiple
+ * drivers concurrently.
+ * Returns the character grabbed on success,
+ * ERROR_NO_PENDING_CHAR if no character was
+ * available at this time, or any value
+ * between -2 and -127 if there was an error.
+ * In : x0 - pointer to console_t struct
+ * Out: w0 - character on success,
+ * ERROR_NO_PENDING_CHAR if no char,
+ * < -1 on error
* Clobber list : x0, x1
* ---------------------------------------------
*/
-func console_core_getc
- cbz x0, getc_error
- /* Insert implementation here */
+func console_xxx_getc
+ /*
+ * Retrieve values we need (e.g. hardware base address) from
+ * console_xxx_t structure pointed to by x0.
+ * Example:
+ */
+ ldr x1, [x0, #CONSOLE_T_XXX_BASE]
+
+ /*
+ * Try to read character into w0 from hardware.
+ */
+
ret
+
+ /* Jump here if there is no character available at this time. */
+getc_no_char:
+ mov w0, #ERROR_NO_PENDING_CHAR
+ ret
+
+ /* Jump here if there was any hardware error. */
getc_error:
- mov w0, #-1
+ mov w0, #-2 /* may pick error codes between -2 and -127 */
ret
-endfunc console_core_getc
+endfunc console_xxx_getc
/* ---------------------------------------------
- * int console_core_flush(uintptr_t base_addr)
+ * int console_xxx_flush(console_xxx_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
- * In : x0 - console base address
- * Out : return -1 on error else return 0.
- * Clobber list : x0, x1
+ * In : x0 - pointer to console_xxx_t struct
+ * Out: w0 - 0 on success, < 0 on error
+ * Clobber list : x0, x1, x2, x3, x4, x5
* ---------------------------------------------
*/
-func console_core_flush
- cbz x0, flush_error
- /* Insert implementation here */
+func console_xxx_flush
+ /*
+ * Retrieve values we need (e.g. hardware base address) from
+ * console_xxx_t structure pointed to by x0.
+ * Example:
+ */
+ ldr x1, [x0, #CONSOLE_T_XXX_BASE]
+
+ /*
+ * Flush all remaining output from hardware FIFOs. Do not return until
+ * all data has been flushed or there was an unrecoverable error.
+ */
+
mov w0, #0
ret
+
+ /* Jump here if an unrecoverable error has been encountered. */
flush_error:
mov w0, #-1
ret
-endfunc console_core_flush
+endfunc console_xxx_flush
diff --git a/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S
new file mode 100644
index 00000000..2fc06033
--- /dev/null
+++ b/drivers/coreboot/cbmem_console/aarch64/cbmem_console.S
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <cbmem_console.h>
+#include <console_macros.S>
+
+/*
+ * This driver implements access to coreboot's in-memory console
+ * (CBMEM console). For the original implementation, see
+ * <coreboot>/src/lib/cbmem_console.c.
+ */
+
+ .globl console_cbmc_register
+ .globl console_cbmc_putc
+ .globl console_cbmc_flush
+
+ /* -----------------------------------------------
+ * int console_cbmc_register(console_cbmc_t *console,
+ * uintptr_t base)
+ * Registers a new CBMEM console instance. Reads
+ * the size field from the buffer header structure
+ * and stores it in our console_cbmc_t struct, so
+ * that we keep the size in secure memory where we
+ * can trust it. A malicious EL1 could manipulate
+ * the console buffer (including the header), so we
+ * must not trust its contents after boot.
+ * In: x0 - CBMEM console base address
+ * x1 - pointer to empty console_cbmc_t struct
+ * Out: x0 - 1 to indicate success
+ * Clobber list: x0, x1, x2, x7
+ * -----------------------------------------------
+ */
+func console_cbmc_register
+ str x0, [x1, #CONSOLE_T_CBMC_BASE]
+ ldr w2, [x0]
+ str w2, [x1, #CONSOLE_T_CBMC_SIZE]
+ mov x0, x1
+ finish_console_register cbmc
+endfunc console_cbmc_register
+
+ /* -----------------------------------------------
+ * int console_cbmc_puts(int c, console_cbmc_t *console)
+ * Writes a character to the CBMEM console buffer,
+ * including overflow handling of the cursor field.
+ * The character must be preserved in x0.
+ * In: x0 - character to be stored
+ * x1 - pointer to console_cbmc_t struct
+ * Clobber list: x1, x2, x16, x17
+ * -----------------------------------------------
+ */
+func console_cbmc_putc
+ ldr w2, [x1, #CONSOLE_T_CBMC_SIZE]
+ ldr x1, [x1, #CONSOLE_T_CBMC_BASE]
+ add x1, x1, #8 /* keep address of body in x1 */
+
+ ldr w16, [x1, #-4] /* load cursor (one u32 before body) */
+ and w17, w16, #0xf0000000 /* keep flags part in w17 */
+ and w16, w16, #0x0fffffff /* keep actual cursor part in w16 */
+
+ cmp w16, w2 /* sanity check that cursor < size */
+ b.lo putc_within_bounds
+ mov w0, #-1 /* cursor >= size must be malicious */
+ ret /* so return error, don't write char */
+
+putc_within_bounds:
+ strb w0, [x1, w16, uxtw] /* body[cursor] = character */
+ add w16, w16, #1 /* cursor++ */
+ cmp w16, w2 /* if cursor < size... */
+ b.lo putc_write_back /* ...skip overflow handling */
+
+ mov w16, #0 /* on overflow, set cursor back to 0 */
+ orr w17, w17, #(1 << 31) /* and set overflow flag */
+
+putc_write_back:
+ orr w16, w16, w17 /* merge cursor and flags back */
+ str w16, [x1, #-4] /* write back cursor to memory */
+ ret
+endfunc console_cbmc_putc
+
+ /* -----------------------------------------------
+ * int console_cbmc_flush(console_cbmc_t *console)
+ * Flushes the CBMEM console by flushing the
+ * console buffer from the CPU's data cache.
+ * In: x0 - pointer to console_cbmc_t struct
+ * Out: x0 - 0 for success
+ * Clobber list: x0, x1, x2, x3, x5
+ * -----------------------------------------------
+ */
+func console_cbmc_flush
+ mov x5, x30
+ ldr x1, [x0, #CONSOLE_T_CBMC_SIZE]
+ ldr x0, [x0, #CONSOLE_T_CBMC_BASE]
+ add x1, x1, #8 /* add size of console header */
+ bl clean_dcache_range /* (clobbers x2 and x3) */
+ mov x0, #0
+ ret x5
+endfunc console_cbmc_flush
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index f9ccd577..b02209df 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -6,15 +6,24 @@
#include <arch.h>
#include <asm_macros.S>
+#include <assert_macros.S>
+#include <console_macros.S>
#include <uart_16550.h>
- .globl console_core_init
- .globl console_core_putc
- .globl console_core_getc
- .globl console_core_flush
+ /*
+ * "core" functions are low-level implementations that don't require
+ * writable memory and are thus safe to call in BL1 crash context.
+ */
+ .globl console_16550_core_init
+ .globl console_16550_core_putc
+ .globl console_16550_core_getc
+
+ .globl console_16550_putc
+ .globl console_16550_getc
+
/* -----------------------------------------------
- * int console_core_init(unsigned long base_addr,
+ * int console_16550_core_init(uintptr_t base_addr,
* unsigned int uart_clk, unsigned int baud_rate)
* Function to initialize the console without a
* C Runtime to print debug information. This
@@ -23,11 +32,11 @@
* In: x0 - console base address
* w1 - Uart clock in Hz
* w2 - Baud rate
- * Out: return 1 on success
+ * Out: return 1 on success, 0 on error
* Clobber list : x1, x2, x3
* -----------------------------------------------
*/
-func console_core_init
+func console_16550_core_init
/* Check the input base address */
cbz x0, init_fail
/* Check baud rate and uart clock for sanity */
@@ -63,12 +72,57 @@ func console_core_init
mov w3, #3
str w3, [x0, #UARTMCR]
mov w0, #1
+ ret
init_fail:
+ mov w0, #0
ret
-endfunc console_core_init
+endfunc console_16550_core_init
+
+#if MULTI_CONSOLE_API
+ .globl console_16550_register
+
+ /* -----------------------------------------------
+ * int console_16550_register(console_16550_t *console,
+ uintptr_t base, uint32_t clk, uint32_t baud)
+ * Function to initialize and register a new 16550
+ * console. Storage passed in for the console struct
+ * *must* be persistent (i.e. not from the stack).
+ * In: x0 - UART register base address
+ * w1 - UART clock in Hz
+ * w2 - Baud rate
+ * x3 - pointer to empty console_16550_t struct
+ * Out: return 1 on success, 0 on error
+ * Clobber list : x0, x1, x2, x6, x7, x14
+ * -----------------------------------------------
+ */
+func console_16550_register
+ mov x7, x30
+ mov x6, x3
+ cbz x6, register_fail
+ str x0, [x6, #CONSOLE_T_16550_BASE]
+
+ bl console_16550_core_init
+ cbz x0, register_fail
+
+ mov x0, x6
+ mov x30, x7
+ finish_console_register 16550
+
+register_fail:
+ ret x7
+endfunc console_16550_register
+#else
+ .globl console_core_init
+ .globl console_core_putc
+ .globl console_core_getc
+ .globl console_core_flush
+ .equ console_core_init,console_16550_core_init
+ .equ console_core_putc,console_16550_core_putc
+ .equ console_core_getc,console_16550_core_getc
+#endif
/* --------------------------------------------------------
- * int console_core_putc(int c, unsigned int base_addr)
+ * int console_16550_core_putc(int c, uintptr_t base_addr)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
@@ -77,9 +131,11 @@ endfunc console_core_init
* Clobber list : x2
* --------------------------------------------------------
*/
-func console_core_putc
- /* Check the input parameter */
- cbz x1, putc_error
+func console_16550_core_putc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
/* Prepend '\r' to '\n' */
cmp w0, #0xA
@@ -99,34 +155,75 @@ func console_core_putc
b.ne 2b
str w0, [x1, #UARTTX]
ret
-putc_error:
- mov w0, #-1
- ret
-endfunc console_core_putc
+endfunc console_16550_core_putc
+
+ /* --------------------------------------------------------
+ * int console_16550_putc(int c, console_16550_t *console)
+ * Function to output a character over the console. It
+ * returns the character printed on success or -1 on error.
+ * In : w0 - character to be printed
+ * x1 - pointer to console_t structure
+ * Out : return -1 on error else return character.
+ * Clobber list : x2
+ * --------------------------------------------------------
+ */
+func console_16550_putc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x1, [x1, #CONSOLE_T_16550_BASE]
+ b console_16550_core_putc
+endfunc console_16550_putc
/* ---------------------------------------------
- * int console_core_getc(void)
+ * int console_16550_core_getc(uintptr_t base_addr)
* Function to get a character from the console.
* It returns the character grabbed on success
- * or -1 on error.
- * In : w0 - console base address
- * Out : return -1 on error else return character.
+ * or -1 on if no character is available.
+ * In : x0 - console base address
+ * Out : w0 - character if available, else -1
* Clobber list : x0, x1
* ---------------------------------------------
*/
-func console_core_getc
+func console_16550_core_getc
+#if ENABLE_ASSERTIONS
+ cmp x0, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+
/* Check if the receive FIFO is empty */
1: ldr w1, [x0, #UARTLSR]
- tbz w1, #UARTLSR_RDR_BIT, 1b
+ tbz w1, #UARTLSR_RDR_BIT, no_char
ldr w0, [x0, #UARTRX]
ret
-getc_error:
- mov w0, #-1
+no_char:
+ mov w0, #ERROR_NO_PENDING_CHAR
ret
-endfunc console_core_getc
+endfunc console_16550_core_getc
+
+ /* ---------------------------------------------
+ * int console_16550_getc(console_16550_t *console)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 on if no character is available.
+ * In : x0 - pointer to console_t stucture
+ * Out : w0 - character if available, else -1
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_16550_getc
+#if ENABLE_ASSERTIONS
+ cmp x1, #0
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
+ ldr x0, [x0, #CONSOLE_T_16550_BASE]
+ b console_16550_core_getc
+endfunc console_16550_getc
/* ---------------------------------------------
* int console_core_flush(uintptr_t base_addr)
+ * DEPRECATED: Not used with MULTI_CONSOLE_API!
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - console base address