diff --git a/src/commonlib/include/commonlib/loglevel.h b/src/commonlib/include/commonlib/loglevel.h index 68b228528c..1594465c37 100644 --- a/src/commonlib/include/commonlib/loglevel.h +++ b/src/commonlib/include/commonlib/loglevel.h @@ -178,6 +178,29 @@ static const char bios_log_prefix[BIOS_LOG_PREFIX_MAX_LEVEL + 1][5] = { [BIOS_SPEW] = "SPEW ", }; +/* + * When printing to terminals supporting ANSI escape sequences, the following + * escape sequences can be printed to highlight the respective log levels + * according to the BIOS_LOG_ESCAPE_PATTERN printf() pattern. At the end of a + * line, highlighting should be reset with the BIOS_LOG_ESCAPE_RESET seqence. + * + * The escape sequences used here set flags with the following meanings: + * 1 = bold, 4 = underlined, 5 = blinking, 7 = inverted + */ +#define BIOS_LOG_ESCAPE_PATTERN "\x1b[%sm" +#define BIOS_LOG_ESCAPE_RESET "\x1b[0m" +static const char bios_log_escape[BIOS_LOG_PREFIX_MAX_LEVEL + 1][8] = { + [BIOS_EMERG] = "1;4;5;7", + [BIOS_ALERT] = "1;4;7", + [BIOS_CRIT] = "1;7", + [BIOS_ERR] = "7", + [BIOS_WARNING] = "1;4", + [BIOS_NOTICE] = "1", + [BIOS_INFO] = "0", + [BIOS_DEBUG] = "0", + [BIOS_SPEW] = "0", +}; + #endif /* __ASSEMBLER__ */ #endif /* LOGLEVEL_H */ diff --git a/src/console/Kconfig b/src/console/Kconfig index f80d2e4972..37d8fefe96 100644 --- a/src/console/Kconfig +++ b/src/console/Kconfig @@ -395,6 +395,15 @@ config DEFAULT_CONSOLE_LOGLEVEL endif +config CONSOLE_USE_ANSI_ESCAPES + bool "Use ANSI escape sequences for console highlighting" + default y + help + If enabled, certain consoles (e.g. UART) that are meant to be read on + a terminal will use ANSI escape sequences (like `ESC [1m`) to + highlight lines based on their log level. Disable this if your + terminal does not support ANSI escape sequences. + config NO_POST bool "Don't show any POST codes" default n diff --git a/src/console/printk.c b/src/console/printk.c index ddd14c0589..93aed52377 100644 --- a/src/console/printk.c +++ b/src/console/printk.c @@ -81,16 +81,26 @@ static void line_start(union log_state state) if (state.speed == CONSOLE_LOG_FAST) return; - /* Interactive consoles get a `[DEBUG] ` style readable prefix. */ + /* Interactive consoles get a `[DEBUG] ` style readable prefix, + and potentially an escape sequence for highlighting. */ + if (CONFIG(CONSOLE_USE_ANSI_ESCAPES)) + wrap_interactive_printf(BIOS_LOG_ESCAPE_PATTERN, bios_log_escape[state.level]); wrap_interactive_printf(BIOS_LOG_PREFIX_PATTERN, bios_log_prefix[state.level]); } +static void line_end(union log_state state) +{ + if (CONFIG(CONSOLE_USE_ANSI_ESCAPES) && state.speed != CONSOLE_LOG_FAST) + wrap_interactive_printf(BIOS_LOG_ESCAPE_RESET); +} + static void wrap_putchar(unsigned char byte, void *data) { union log_state state = { .as_ptr = data }; static bool line_started = false; if (byte == '\n') { + line_end(state); line_started = false; } else if (!line_started) { line_start(state);