aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/common/aarch64/console_macros.S43
-rw-r--r--include/drivers/console.h63
-rw-r--r--include/drivers/console_assertions.h30
3 files changed, 132 insertions, 4 deletions
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 <console.h>
+
+/*
+ * 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 <stdint.h>
+#include <utils_def.h>
-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 <types.h>
+
+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 <console_assertions.h> /* 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 <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);
+/* 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_<driver>_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 <cassert.h>
+
+/*
+ * This file contains some separate assertions about console_t, moved here to
+ * keep them out of the way. Should only be included from <console.h>.
+ */
+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__ */
+