util/cbmem: Add -2/--2ndtolast option to print second-to-last boot log
On some platforms, runtime firmware crashes write logs to the CBMEM
console. For those, since a crash reboots the system, by the time we
have a chance to run `cbmem` again the boot where the crash happened
will be the one before the "last" (current) boot. So cbmem -1 doesn't
show the interesting part, and cbmem -c potentially shows a lot that is
cumbersome to dig through. This patch introduces a new option cbmem -2
to explicitly show only the boot cycle before the last one.
Signed-off-by: Julius Werner <jwerner@chromium.org>
Change-Id: I6725698f4c9ae07011cbacf0928544cebb4ad6f8
Reviewed-on: https://review.coreboot.org/c/coreboot/+/57510
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c
index 3a94f3e..085e004 100644
--- a/util/cbmem/cbmem.c
+++ b/util/cbmem/cbmem.c
@@ -715,12 +715,18 @@
#define CBMC_CURSOR_MASK ((1 << 28) - 1)
#define CBMC_OVERFLOW (1 << 31)
+enum console_print_type {
+ CONSOLE_PRINT_FULL = 0,
+ CONSOLE_PRINT_LAST,
+ CONSOLE_PRINT_PREVIOUS,
+};
+
/* dump the cbmem console */
-static void dump_console(int one_boot_only)
+static void dump_console(enum console_print_type type)
{
const struct cbmem_console *console_p;
char *console_c;
- size_t size, cursor;
+ size_t size, cursor, previous;
struct mapping console_mapping;
if (console.tag != LB_TAG_CBMEM_CONSOLE) {
@@ -773,12 +779,12 @@
if (!isprint(console_c[cursor]) && !isspace(console_c[cursor]))
console_c[cursor] = '?';
- /* We detect the last boot by looking for a bootblock, romstage or
+ /* We detect the reboot cutoff by looking for a bootblock, romstage or
ramstage banner, in that order (to account for platforms without
CONFIG_BOOTBLOCK_CONSOLE and/or CONFIG_EARLY_CONSOLE). Once we find
- a banner, store the last match for that stage in cursor and stop. */
- cursor = 0;
- if (one_boot_only) {
+ a banner, store the last two matches for that stage and stop. */
+ cursor = previous = 0;
+ if (type != CONSOLE_PRINT_FULL) {
#define BANNER_REGEX(stage) \
"\n\ncoreboot-[^\n]* " stage " starting.*\\.\\.\\.\n"
#define OVERFLOW_REGEX(stage) "\n\\*\\*\\* Pre-CBMEM " stage " console overflow"
@@ -796,12 +802,19 @@
assert(!regcomp(&re, regex[i], 0));
/* Keep looking for matches so we find the last one. */
- while (!regexec(&re, console_c + cursor, 1, &match, 0))
+ while (!regexec(&re, console_c + cursor, 1, &match, 0)) {
+ previous = cursor;
cursor += match.rm_so + 1;
+ }
regfree(&re);
}
}
+ if (type == CONSOLE_PRINT_PREVIOUS) {
+ console_c[cursor] = '\0';
+ cursor = previous;
+ }
+
puts(console_c + cursor);
free(console_c);
unmap_memory(&console_mapping);
@@ -1087,6 +1100,7 @@
printf("\n"
" -c | --console: print cbmem console\n"
" -1 | --oneboot: print cbmem console for last boot only\n"
+ " -2 | --2ndtolast: print cbmem console for the boot that came before the last one only\n"
" -C | --coverage: dump coverage information\n"
" -l | --list: print cbmem table of contents\n"
" -x | --hexdump: print hexdump of cbmem area\n"
@@ -1227,13 +1241,14 @@
int print_timestamps = 0;
int print_tcpa_log = 0;
int machine_readable_timestamps = 0;
- int one_boot_only = 0;
+ enum console_print_type console_type = CONSOLE_PRINT_FULL;
unsigned int rawdump_id = 0;
int opt, option_index = 0;
static struct option long_options[] = {
{"console", 0, 0, 'c'},
{"oneboot", 0, 0, '1'},
+ {"2ndtolast", 0, 0, '2'},
{"coverage", 0, 0, 'C'},
{"list", 0, 0, 'l'},
{"tcpa-log", 0, 0, 'L'},
@@ -1246,7 +1261,7 @@
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
- while ((opt = getopt_long(argc, argv, "c1CltTLxVvh?r:",
+ while ((opt = getopt_long(argc, argv, "c12CltTLxVvh?r:",
long_options, &option_index)) != EOF) {
switch (opt) {
case 'c':
@@ -1255,7 +1270,12 @@
break;
case '1':
print_console = 1;
- one_boot_only = 1;
+ console_type = CONSOLE_PRINT_LAST;
+ print_defaults = 0;
+ break;
+ case '2':
+ print_console = 1;
+ console_type = CONSOLE_PRINT_PREVIOUS;
print_defaults = 0;
break;
case 'C':
@@ -1383,7 +1403,7 @@
die("Table not found.\n");
if (print_console)
- dump_console(one_boot_only);
+ dump_console(console_type);
if (print_coverage)
dump_coverage();