From 155a10068ac6feefcc783b7b023fc90390e5cc44 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Tue, 12 Dec 2017 14:23:26 -0800 Subject: utils_def: Add REGSZ and make BIT() assembly-compatible In assembly code it can be useful to have a constant for the width of a register in the current architecture, so this patch adds one to and replaces the existing custom one in crash_reporting.S with that. It also fixes up the BIT() macro in the same file so that it can be safely used in assembly code. Change-Id: I10513a311f3379e767396e6ddfbae8d2d8201464 Signed-off-by: Julius Werner --- include/lib/utils_def.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h index 185a1c129..bda3b0735 100644 --- a/include/lib/utils_def.h +++ b/include/lib/utils_def.h @@ -16,7 +16,7 @@ #define SIZE_FROM_LOG2_WORDS(n) (4 << (n)) -#define BIT(nr) (1ULL << (nr)) +#define BIT(nr) (ULL(1) << (nr)) /* * This variant of div_round_up can be used in macro definition but should not @@ -84,6 +84,13 @@ # define ULL(_x) (_x##ull) #endif +/* Register size of the current architecture. */ +#ifdef AARCH32 +#define REGSZ U(4) +#else +#define REGSZ U(8) +#endif + /* * Test for the current architecture version to be at least the version * expected. -- cgit v1.2.3 From 9536bae6df5638772a1e8b1c8cf8e321f4ab5452 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 31 Jul 2017 18:15:11 -0700 Subject: Add new function-pointer-based console API This patch overhauls the console API to allow for multiple console instances of different drivers that are active at the same time. Instead of binding to well-known function names (like console_core_init), consoles now provide a register function (e.g. console_16550_register()) that will hook them into the list of active consoles. All console operations will be dispatched to all consoles currently in the list. The new API will be selected by the build-time option MULTI_CONSOLE_API, which defaults to ${ERROR_DEPRECATED} for now. The old console API code will be retained to stay backwards-compatible to older platforms, but should no longer be used for any newly added platforms and can hopefully be removed at some point in the future. The new console API is intended to be used for both normal (bootup) and crash use cases, freeing platforms of the need to set up the crash console separately. Consoles can be individually configured to be active active at boot (until first handoff to EL2), at runtime (after first handoff to EL2), and/or after a crash. Console drivers should set a sane default upon registration that can be overridden with the console_set_scope() call. Code to hook up the crash reporting mechanism to this framework will be added with a later patch. This patch only affects AArch64, but the new API could easily be ported to AArch32 as well if desired. Change-Id: I35c5aa2cb3f719cfddd15565eb13c7cde4162549 Signed-off-by: Julius Werner --- include/common/aarch64/console_macros.S | 43 ++++++++++++++++++++++ include/drivers/console.h | 63 ++++++++++++++++++++++++++++++--- include/drivers/console_assertions.h | 30 ++++++++++++++++ 3 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 include/common/aarch64/console_macros.S create mode 100644 include/drivers/console_assertions.h (limited to 'include') diff --git a/include/common/aarch64/console_macros.S b/include/common/aarch64/console_macros.S new file mode 100644 index 000000000..0ebea2c1b --- /dev/null +++ b/include/common/aarch64/console_macros.S @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __CONSOLE_MACROS_S__ +#define __CONSOLE_MACROS_S__ + +#include + +/* + * This macro encapsulates the common setup that has to be done at the end of + * a console driver's register function. It will register all of the driver's + * callbacks in the console_t structure and initialize the flags field (by + * default consoles are enabled for the "boot" and "crash" states, this can be + * changed after registration with the console_set_scope() function). It ends + * with a tail call that will include return to the caller. + * REQUIRES console_t pointer in x0 and a valid return address in x30. + */ + .macro finish_console_register _driver + /* + * Add these weak definitions so we will automatically write a 0 if the + * function doesn't exist. I'd rather use .ifdef but that only works if + * the function was defined (not just declared .global) above this point + * in the file, which we can't guarantee. + */ + .weak console_\_driver\()_putc + .weak console_\_driver\()_getc + .weak console_\_driver\()_flush + + /* Don't use adrp on weak funcs! See GNU ld bugzilla issue 22589. */ + ldr x1, =console_\_driver\()_putc + str x1, [x0, #CONSOLE_T_PUTC] + ldr x1, =console_\_driver\()_getc + str x1, [x0, #CONSOLE_T_GETC] + ldr x1, =console_\_driver\()_flush + str x1, [x0, #CONSOLE_T_FLUSH] + mov x1, #(CONSOLE_FLAG_BOOT | CONSOLE_FLAG_CRASH) + str x1, [x0, #CONSOLE_T_FLAGS] + b console_register + .endm + +#endif /* __CONSOLE_MACROS_S__ */ diff --git a/include/drivers/console.h b/include/drivers/console.h index da5cb8f7b..0629f5717 100644 --- a/include/drivers/console.h +++ b/include/drivers/console.h @@ -7,14 +7,69 @@ #ifndef __CONSOLE_H__ #define __CONSOLE_H__ -#include +#include -int console_init(uintptr_t base_addr, - unsigned int uart_clk, unsigned int baud_rate); -void console_uninit(void); +#define CONSOLE_T_NEXT (U(0) * REGSZ) +#define CONSOLE_T_FLAGS (U(1) * REGSZ) +#define CONSOLE_T_PUTC (U(2) * REGSZ) +#define CONSOLE_T_GETC (U(3) * REGSZ) +#define CONSOLE_T_FLUSH (U(4) * REGSZ) +#define CONSOLE_T_DRVDATA (U(5) * REGSZ) + +#define CONSOLE_FLAG_BOOT BIT(0) +#define CONSOLE_FLAG_RUNTIME BIT(1) +#define CONSOLE_FLAG_CRASH BIT(2) +/* Bits 3 to 7 reserved for additional scopes in future expansion. */ +#define CONSOLE_FLAG_SCOPE_MASK ((U(1) << 8) - 1) +/* Bits 8 to 31 reserved for non-scope use in future expansion. */ + +/* Returned by getc callbacks when receive FIFO is empty. */ +#define ERROR_NO_PENDING_CHAR (-1) +/* Returned by console_xxx() if no registered console implements xxx. */ +#define ERROR_NO_VALID_CONSOLE (-128) + +#ifndef __ASSEMBLY__ + +#include + +typedef struct console { + struct console *next; + u_register_t flags; + int (*putc)(int character, struct console *console); + int (*getc)(struct console *console); + int (*flush)(struct console *console); + /* Additional private driver data may follow here. */ +} console_t; +#include /* offset macro assertions for console_t */ + +/* + * NOTE: There is no publicly accessible console_register() function. Consoles + * are registered by directly calling the register function of a specific + * implementation, e.g. console_16550_register() from . 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); +/* Set scope mask of a console that determines in what states it is active. */ +void console_set_scope(console_t *console, unsigned int scope); + +/* Switch to a new global console state (CONSOLE_FLAG_BOOT/RUNTIME/CRASH). */ +void console_switch_state(unsigned int new_state); +/* Output a character on all consoles registered for the current state. */ int console_putc(int c); +/* Read a character (blocking) from any console registered for current state. */ int console_getc(void); +/* Flush all consoles registered for the current state. */ int console_flush(void); +#if !MULTI_CONSOLE_API +/* DEPRECATED on AArch64 -- use console__register() instead! */ +int console_init(uintptr_t base_addr, + unsigned int uart_clk, unsigned int baud_rate) __deprecated; +void console_uninit(void) __deprecated; +#endif + +#endif /* __ASSEMBLY__ */ + #endif /* __CONSOLE_H__ */ diff --git a/include/drivers/console_assertions.h b/include/drivers/console_assertions.h new file mode 100644 index 000000000..cedce8679 --- /dev/null +++ b/include/drivers/console_assertions.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __CONSOLE_ASSERTIONS_H__ +#define __CONSOLE_ASSERTIONS_H__ + +#include + +/* + * This file contains some separate assertions about console_t, moved here to + * keep them out of the way. Should only be included from . + */ +CASSERT(CONSOLE_T_NEXT == __builtin_offsetof(console_t, next), + assert_console_t_next_offset_mismatch); +CASSERT(CONSOLE_T_FLAGS == __builtin_offsetof(console_t, flags), + assert_console_t_flags_offset_mismatch); +CASSERT(CONSOLE_T_PUTC == __builtin_offsetof(console_t, putc), + assert_console_t_putc_offset_mismatch); +CASSERT(CONSOLE_T_GETC == __builtin_offsetof(console_t, getc), + assert_console_t_getc_offset_mismatch); +CASSERT(CONSOLE_T_FLUSH == __builtin_offsetof(console_t, flush), + assert_console_t_flush_offset_mismatch); +CASSERT(CONSOLE_T_DRVDATA == sizeof(console_t), + assert_console_t_drvdata_offset_mismatch); + +#endif /* __CONSOLE_ASSERTIONS_H__ */ + -- cgit v1.2.3 From 36c42ca111ea44e10d3589e93fa18a2b8162b6a3 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 18 Sep 2017 16:57:51 -0700 Subject: drivers: ti: uart: Update 16550 UART driver to support MULTI_CONSOLE_API This patch updates the TI 16550 console driver to support the new console API. The driver will continue to support the old API as well by checking the MULTI_CONSOLE_API compile-time flag. Change-Id: I60a44b7ba3c35c74561824c04b8dbe3e3039324c Signed-off-by: Julius Werner --- include/drivers/ti/uart/uart_16550.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include') diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h index f258d45bd..9eba41aa6 100644 --- a/include/drivers/ti/uart/uart_16550.h +++ b/include/drivers/ti/uart/uart_16550.h @@ -7,6 +7,8 @@ #ifndef __UART_16550_H__ #define __UART_16550_H__ +#include + /* UART16550 Registers */ #define UARTTX 0x0 #define UARTRX 0x0 @@ -67,4 +69,26 @@ #define UARTLSR_RDR_BIT (0) /* Rx Data Ready Bit */ #define UARTLSR_RDR (1 << UARTLSR_RDR_BIT) /* Rx Data Ready */ +#define CONSOLE_T_16550_BASE CONSOLE_T_DRVDATA + +#ifndef __ASSEMBLY__ + +#include + +typedef struct { + console_t console; + uintptr_t base; +} console_16550_t; + +/* + * Initialize a new 16550 console instance and register it with the console + * framework. The |console| pointer must point to storage that will be valid + * for the lifetime of the console, such as a global or static local variable. + * Its contents will be reinitialized from scratch. + */ +int console_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, + console_16550_t *console); + +#endif /*__ASSEMBLY__*/ + #endif /* __UART_16550_H__ */ -- cgit v1.2.3 From 4a0c45716df6b0e9c1142c768bb2578ad87ce8c7 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 18 Sep 2017 16:59:43 -0700 Subject: drivers: arm: pl011: Update PL011 driver to support MULTI_CONSOLE_API This patch updates the ARM PL011 console driver to support the new console API. The driver will continue to support the old API as well by checking the MULTI_CONSOLE_API compile-time flag. Change-Id: Ic34e4158addbb0c5fae500c9cff899c05a4f4206 Signed-off-by: Julius Werner --- include/drivers/arm/pl011.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include') diff --git a/include/drivers/arm/pl011.h b/include/drivers/arm/pl011.h index cd259c5e1..06d754353 100644 --- a/include/drivers/arm/pl011.h +++ b/include/drivers/arm/pl011.h @@ -7,6 +7,8 @@ #ifndef __PL011_H__ #define __PL011_H__ +#include + /* PL011 Registers */ #define UARTDR 0x000 #define UARTRSR 0x004 @@ -79,4 +81,26 @@ #endif /* !PL011_GENERIC_UART */ +#define CONSOLE_T_PL011_BASE CONSOLE_T_DRVDATA + +#ifndef __ASSEMBLY__ + +#include + +typedef struct { + console_t console; + uintptr_t base; +} console_pl011_t; + +/* + * Initialize a new PL011 console instance and register it with the console + * framework. The |console| pointer must point to storage that will be valid + * for the lifetime of the console, such as a global or static local variable. + * Its contents will be reinitialized from scratch. + */ +int console_pl011_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, + console_pl011_t *console); + +#endif /*__ASSEMBLY__*/ + #endif /* __PL011_H__ */ -- cgit v1.2.3 From 38ba8e9327a3911e8a24ada75346c0765ffffba1 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 18 Sep 2017 17:01:06 -0700 Subject: drivers: cadence: cdns: Update CDNS driver to support MULTI_CONSOLE_API This patch updates the Cadence CDNS console driver to support the new console API. The driver will continue to support the old API as well by checking the MULTI_CONSOLE_API compile-time flag. Change-Id: I2ef8fb0d6ab72696997db1e0243a533499569d6b Signed-off-by: Julius Werner --- include/drivers/cadence/cdns_uart.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include') diff --git a/include/drivers/cadence/cdns_uart.h b/include/drivers/cadence/cdns_uart.h index 3aadde32e..7ab6df047 100644 --- a/include/drivers/cadence/cdns_uart.h +++ b/include/drivers/cadence/cdns_uart.h @@ -7,6 +7,8 @@ #ifndef __CADENCE_UART_H__ #define __CADENCE_UART_H__ +#include + /* This is very minimalistic and will only work in QEMU. */ /* CADENCE Registers */ @@ -23,4 +25,26 @@ #define R_UART_TX 0x30 #define R_UART_RX 0x30 +#define CONSOLE_T_CDNS_BASE CONSOLE_T_DRVDATA + +#ifndef __ASSEMBLY__ + +#include + +typedef struct { + console_t console; + uintptr_t base; +} console_cdns_t; + +/* + * Initialize a new Cadence console instance and register it with the console + * framework. The |console| pointer must point to storage that will be valid + * for the lifetime of the console, such as a global or static local variable. + * Its contents will be reinitialized from scratch. + */ +int console_cdns_register(uint64_t baseaddr, uint32_t clock, uint32_t baud, + console_cdns_t *console); + +#endif /*__ASSEMBLY__*/ + #endif -- cgit v1.2.3 From 3429c77ab09b69eef4ed752c2d641ed724e72110 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 9 Jun 2017 15:17:15 -0700 Subject: Add platform-independent coreboot support library This patch adds the foundation for a platform-independent coreboot support library that can be shared by all platforms that boot BL31 from coreboot (acting as BL2). It adds code to parse the "coreboot table", a data structure that coreboot uses to communicate different kinds of information to later-stage firmware and certain OS drivers. As a first small use case for this information, allow platforms to access the serial console configuration used by coreboot, removing the need to hardcode base address and divisors and allowing Trusted Firmware to benefit from coreboot's user configuration (e.g. which UART to pick and which baud rate to use). Change-Id: I2bfb39cd2609ce6640b844ab68df6c9ae3f28e9e Signed-off-by: Julius Werner --- include/lib/coreboot.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 include/lib/coreboot.h (limited to 'include') diff --git a/include/lib/coreboot.h b/include/lib/coreboot.h new file mode 100644 index 000000000..4b1f200a2 --- /dev/null +++ b/include/lib/coreboot.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __COREBOOT_H__ +#define __COREBOOT_H__ + +#include + +typedef struct { + uint32_t type; /* always 2 (memory-mapped) on ARM */ + uint32_t baseaddr; + uint32_t baud; + uint32_t regwidth; /* in bytes, i.e. usually 4 */ + uint32_t input_hertz; + uint32_t uart_pci_addr; /* unused on current ARM systems */ +} coreboot_serial_t; +extern coreboot_serial_t coreboot_serial; + +void coreboot_table_setup(void *base); + +#endif /* __COREBOOT_H__ */ -- cgit v1.2.3 From 1c5f5031f38ed77688298d419727a6f0930e0673 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Tue, 13 Jun 2017 15:53:45 -0700 Subject: coreboot: Add support for CBMEM console coreboot supports an in-memory console to store firmware logs even when no serial console is available. It is widely supported by coreboot-compatible bootloaders (including SeaBIOS and GRUB) and can be read by the Linux kernel. This patch allows BL31 to add its own log messages to this console. The driver will be registered automatically if coreboot support is compiled in and detects the presence of a console buffer in the coreboot tables. Change-Id: I31254dfa0c2fdeb7454634134b5707b4b4154907 Signed-off-by: Julius Werner --- include/drivers/coreboot/cbmem_console.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 include/drivers/coreboot/cbmem_console.h (limited to 'include') diff --git a/include/drivers/coreboot/cbmem_console.h b/include/drivers/coreboot/cbmem_console.h new file mode 100644 index 000000000..4fca36f61 --- /dev/null +++ b/include/drivers/coreboot/cbmem_console.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __CBMEM_CONSOLE_H__ +#define __CBMEM_CONSOLE_H__ + +#include + +#define CONSOLE_T_CBMC_BASE CONSOLE_T_DRVDATA +#define CONSOLE_T_CBMC_SIZE (CONSOLE_T_DRVDATA + REGSZ) + +#ifndef __ASSEMBLER__ + +typedef struct { + console_t console; + uintptr_t base; + uint32_t size; +} console_cbmc_t; + +int console_cbmc_register(uintptr_t base, console_cbmc_t *console); + +#endif /* __ASSEMBLER__ */ + +#endif /* __CBMEM_CONSOLE_H__ */ -- cgit v1.2.3