diff options
author | Yu-Ping Wu <yupingso@chromium.org> | 2019-12-02 11:11:53 +0800 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2019-12-16 09:47:38 +0000 |
commit | 41956b574212224127ba393f6e65be88de6f3f21 (patch) | |
tree | debd4257ed82d396953a848f1a06b1e0145f91a4 | |
parent | c32ca089c97198a7f715c91d8a8be0d94c67953c (diff) |
libpayload: Implement reading from CBMEM console
To support showing CBMEM logs on recovery screen, add a function
cbmem_console_snapshot() to copy the CBMEM console to an allocated
buffer. Non-printable characters are automatically replaced with '?' to
ensure the returned string is printable.
BRANCH=none
BUG=b:146105976
TEST=emerge-nami libpayload
Change-Id: Ie324055f5fd8276f1d833fc9d04f60a792dbb9f6
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/37667
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
-rw-r--r-- | payloads/libpayload/drivers/cbmem_console.c | 46 | ||||
-rw-r--r-- | payloads/libpayload/include/libpayload.h | 7 |
2 files changed, 53 insertions, 0 deletions
diff --git a/payloads/libpayload/drivers/cbmem_console.c b/payloads/libpayload/drivers/cbmem_console.c index 9435e1ca9f..62aabfb9ca 100644 --- a/payloads/libpayload/drivers/cbmem_console.c +++ b/payloads/libpayload/drivers/cbmem_console.c @@ -75,3 +75,49 @@ void cbmem_console_write(const void *buffer, size_t count) do_write(buffer, count); } + +char *cbmem_console_snapshot(void) +{ + const struct cbmem_console *console_p = cbmem_console_p; + char *console_c; + uint32_t size, cursor, overflow; + + if (!console_p) { + printf("ERROR: No cbmem console found in coreboot table\n"); + return NULL; + } + + cursor = console_p->cursor & CURSOR_MASK; + overflow = console_p->cursor & OVERFLOW; + if (!overflow && cursor < console_p->size) + size = cursor; + else + size = console_p->size; + + console_c = malloc(size + 1); + if (!console_c) { + printf("ERROR: Not enough memory for console (size = %u)\n", + size); + return NULL; + } + console_c[size] = '\0'; + + if (overflow) { + if (cursor >= size) { + printf("ERROR: CBMEM console struct is corrupted\n"); + return NULL; + } + memcpy(console_c, console_p->body + cursor, size - cursor); + memcpy(console_c + size - cursor, console_p->body, cursor); + } else { + memcpy(console_c, console_p->body, size); + } + + /* Slight memory corruption may occur between reboots and give us a few + unprintable characters like '\0'. Replace them with '?' on output. */ + for (cursor = 0; cursor < size; cursor++) + if (!isprint(console_c[cursor]) && !isspace(console_c[cursor])) + console_c[cursor] = '?'; + + return console_c; +} diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h index 934c368e5c..4b6a250f28 100644 --- a/payloads/libpayload/include/libpayload.h +++ b/payloads/libpayload/include/libpayload.h @@ -313,6 +313,13 @@ void video_printf(int foreground, int background, enum video_printf_align align, */ void cbmem_console_init(void); void cbmem_console_write(const void *buffer, size_t count); +/** + * Take a snapshot of the CBMEM memory console. This function will allocate a + * range of memory. Callers must free the returned buffer by themselves. + * + * @return The allocated buffer on success, NULL on failure. + */ +char *cbmem_console_snapshot(void); /** @} */ /* drivers/option.c */ |