summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commonlib/include/commonlib/loglevel.h14
-rw-r--r--src/console/printk.c10
-rw-r--r--src/lib/cbmem_console.c10
-rw-r--r--util/cbmem/cbmem.c22
4 files changed, 51 insertions, 5 deletions
diff --git a/src/commonlib/include/commonlib/loglevel.h b/src/commonlib/include/commonlib/loglevel.h
index 1594465c37..34d9824179 100644
--- a/src/commonlib/include/commonlib/loglevel.h
+++ b/src/commonlib/include/commonlib/loglevel.h
@@ -201,6 +201,20 @@ static const char bios_log_escape[BIOS_LOG_PREFIX_MAX_LEVEL + 1][8] = {
[BIOS_SPEW] = "0",
};
+/*
+ * When storing console logs somewhere for later retrieval, log level prefixes
+ * and escape sequences should not be stored raw to preserve space. Instead, a
+ * non-printable control character marker is inserted into the log to indicate
+ * the log level. Decoders reading this character should translate it back into
+ * the respective escape sequence and prefix. If a decoder doesn't support this
+ * feature, the non-printable character should usually be harmless.
+ */
+#define BIOS_LOG_MARKER_START 0x10
+#define BIOS_LOG_MARKER_END (BIOS_LOG_MARKER_START + BIOS_LOG_PREFIX_MAX_LEVEL)
+#define BIOS_LOG_IS_MARKER(c) ((c) >= BIOS_LOG_MARKER_START && (c) <= BIOS_LOG_MARKER_END)
+#define BIOS_LOG_LEVEL_TO_MARKER(level) (BIOS_LOG_MARKER_START + (level))
+#define BIOS_LOG_MARKER_TO_LEVEL(c) ((c) - BIOS_LOG_MARKER_START)
+
#endif /* __ASSEMBLER__ */
#endif /* LOGLEVEL_H */
diff --git a/src/console/printk.c b/src/console/printk.c
index 93aed52377..ffa3106178 100644
--- a/src/console/printk.c
+++ b/src/console/printk.c
@@ -78,8 +78,16 @@ static void line_start(union log_state state)
{
if (state.level > BIOS_LOG_PREFIX_MAX_LEVEL)
return;
- if (state.speed == CONSOLE_LOG_FAST)
+
+ /* Stored consoles just get a single control char marker to save space. If we are in
+ LOG_FAST mode, just write the marker to CBMC and exit -- the rest of this function
+ implements the LOG_ALL case. */
+ unsigned char marker = BIOS_LOG_LEVEL_TO_MARKER(state.level);
+ if (state.speed == CONSOLE_LOG_FAST) {
+ __cbmemc_tx_byte(marker);
return;
+ }
+ console_stored_tx_byte(marker, NULL);
/* Interactive consoles get a `[DEBUG] ` style readable prefix,
and potentially an escape sequence for highlighting. */
diff --git a/src/lib/cbmem_console.c b/src/lib/cbmem_console.c
index 2faa5d5801..0c56095732 100644
--- a/src/lib/cbmem_console.c
+++ b/src/lib/cbmem_console.c
@@ -182,12 +182,16 @@ void cbmem_dump_console_to_uart(void)
if (current_console->cursor & OVERFLOW) {
for (cursor = current_console->cursor & CURSOR_MASK;
cursor < current_console->size; cursor++) {
+ if (BIOS_LOG_IS_MARKER(current_console->body[cursor]))
+ continue;
if (current_console->body[cursor] == '\n')
uart_tx_byte(console_index, '\r');
uart_tx_byte(console_index, current_console->body[cursor]);
}
}
for (cursor = 0; cursor < (current_console->cursor & CURSOR_MASK); cursor++) {
+ if (BIOS_LOG_IS_MARKER(current_console->body[cursor]))
+ continue;
if (current_console->body[cursor] == '\n')
uart_tx_byte(console_index, '\r');
uart_tx_byte(console_index, current_console->body[cursor]);
@@ -206,9 +210,11 @@ void cbmem_dump_console(void)
if (current_console->cursor & OVERFLOW)
for (cursor = current_console->cursor & CURSOR_MASK;
cursor < current_console->size; cursor++)
- do_putchar(current_console->body[cursor]);
+ if (!BIOS_LOG_IS_MARKER(current_console->body[cursor]))
+ do_putchar(current_console->body[cursor]);
for (cursor = 0; cursor < (current_console->cursor & CURSOR_MASK); cursor++)
- do_putchar(current_console->body[cursor]);
+ if (!BIOS_LOG_IS_MARKER(current_console->body[cursor]))
+ do_putchar(current_console->body[cursor]);
console_paused = false;
}
diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c
index 51b4adc80c..d5a8ae431f 100644
--- a/util/cbmem/cbmem.c
+++ b/util/cbmem/cbmem.c
@@ -18,6 +18,7 @@
#include <assert.h>
#include <regex.h>
#include <commonlib/bsd/cbmem_id.h>
+#include <commonlib/loglevel.h>
#include <commonlib/timestamp_serialized.h>
#include <commonlib/tcpa_log_serialized.h>
#include <commonlib/coreboot_tables.h>
@@ -783,7 +784,8 @@ static void dump_console(enum console_print_type type)
/* 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]))
+ if (!isprint(console_c[cursor]) && !isspace(console_c[cursor])
+ && !BIOS_LOG_IS_MARKER(console_c[cursor]))
console_c[cursor] = '?';
/* We detect the reboot cutoff by looking for a bootblock, romstage or
@@ -822,7 +824,23 @@ static void dump_console(enum console_print_type type)
cursor = previous;
}
- puts(console_c + cursor);
+ char c;
+ int tty = isatty(fileno(stdout));
+ while ((c = console_c[cursor++])) {
+ if (BIOS_LOG_IS_MARKER(c)) {
+ int lvl = BIOS_LOG_MARKER_TO_LEVEL(c);
+ if (tty)
+ printf(BIOS_LOG_ESCAPE_PATTERN, bios_log_escape[lvl]);
+ printf(BIOS_LOG_PREFIX_PATTERN, bios_log_prefix[lvl]);
+ } else {
+ putchar(c);
+ if (tty && c == '\n')
+ printf(BIOS_LOG_ESCAPE_RESET);
+ }
+ }
+ if (tty)
+ printf(BIOS_LOG_ESCAPE_RESET);
+
free(console_c);
unmap_memory(&console_mapping);
}