diff options
author | Julius Werner <jwerner@chromium.org> | 2018-11-27 22:10:56 -0800 |
---|---|---|
committer | Julius Werner <jwerner@chromium.org> | 2018-12-06 16:18:10 -0800 |
commit | 91b48c9f8f44db91ae73635cc543fb89d292a6f7 (patch) | |
tree | 2302ec1d9d9bed4475c1cf168759f1be1eb9b3d2 /drivers/console/multi_console.c | |
parent | 985ee0b7e8d039105de48f60c0195f391f86a625 (diff) | |
download | platform_external_arm-trusted-firmware-91b48c9f8f44db91ae73635cc543fb89d292a6f7.tar.gz platform_external_arm-trusted-firmware-91b48c9f8f44db91ae73635cc543fb89d292a6f7.tar.bz2 platform_external_arm-trusted-firmware-91b48c9f8f44db91ae73635cc543fb89d292a6f7.zip |
drivers/console: Reimplement MUTLI_CONSOLE_API framework in C
Now that we have switched to using the stack in MULTI_CONSOLE_API
framework functions and have factored all code involved in crash
reporting out into a separate file, there's really no reason to keep the
main framework code in assembly anymore. This patch rewrites it in C
which allows us to have a single implementation across aarch32/64 and
should be much easier to maintain going forward.
Change-Id: I6c85a01e89a79e8b233f3f8bee812f0dbd026221
Signed-off-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'drivers/console/multi_console.c')
-rw-r--r-- | drivers/console/multi_console.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c new file mode 100644 index 000000000..c678de098 --- /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 */ |