summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu-Ping Wu <yupingso@chromium.org>2019-12-02 11:11:53 +0800
committerPatrick Georgi <pgeorgi@google.com>2019-12-16 09:47:38 +0000
commit41956b574212224127ba393f6e65be88de6f3f21 (patch)
treedebd4257ed82d396953a848f1a06b1e0145f91a4
parentc32ca089c97198a7f715c91d8a8be0d94c67953c (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.c46
-rw-r--r--payloads/libpayload/include/libpayload.h7
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 */