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>
This commit is contained in:
parent
2c59a3884d
commit
8202fc42d4
|
@ -715,12 +715,18 @@ struct cbmem_console {
|
||||||
#define CBMC_CURSOR_MASK ((1 << 28) - 1)
|
#define CBMC_CURSOR_MASK ((1 << 28) - 1)
|
||||||
#define CBMC_OVERFLOW (1 << 31)
|
#define CBMC_OVERFLOW (1 << 31)
|
||||||
|
|
||||||
|
enum console_print_type {
|
||||||
|
CONSOLE_PRINT_FULL = 0,
|
||||||
|
CONSOLE_PRINT_LAST,
|
||||||
|
CONSOLE_PRINT_PREVIOUS,
|
||||||
|
};
|
||||||
|
|
||||||
/* dump the cbmem console */
|
/* 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;
|
const struct cbmem_console *console_p;
|
||||||
char *console_c;
|
char *console_c;
|
||||||
size_t size, cursor;
|
size_t size, cursor, previous;
|
||||||
struct mapping console_mapping;
|
struct mapping console_mapping;
|
||||||
|
|
||||||
if (console.tag != LB_TAG_CBMEM_CONSOLE) {
|
if (console.tag != LB_TAG_CBMEM_CONSOLE) {
|
||||||
|
@ -773,12 +779,12 @@ static void dump_console(int one_boot_only)
|
||||||
if (!isprint(console_c[cursor]) && !isspace(console_c[cursor]))
|
if (!isprint(console_c[cursor]) && !isspace(console_c[cursor]))
|
||||||
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
|
ramstage banner, in that order (to account for platforms without
|
||||||
CONFIG_BOOTBLOCK_CONSOLE and/or CONFIG_EARLY_CONSOLE). Once we find
|
CONFIG_BOOTBLOCK_CONSOLE and/or CONFIG_EARLY_CONSOLE). Once we find
|
||||||
a banner, store the last match for that stage in cursor and stop. */
|
a banner, store the last two matches for that stage and stop. */
|
||||||
cursor = 0;
|
cursor = previous = 0;
|
||||||
if (one_boot_only) {
|
if (type != CONSOLE_PRINT_FULL) {
|
||||||
#define BANNER_REGEX(stage) \
|
#define BANNER_REGEX(stage) \
|
||||||
"\n\ncoreboot-[^\n]* " stage " starting.*\\.\\.\\.\n"
|
"\n\ncoreboot-[^\n]* " stage " starting.*\\.\\.\\.\n"
|
||||||
#define OVERFLOW_REGEX(stage) "\n\\*\\*\\* Pre-CBMEM " stage " console overflow"
|
#define OVERFLOW_REGEX(stage) "\n\\*\\*\\* Pre-CBMEM " stage " console overflow"
|
||||||
|
@ -796,12 +802,19 @@ static void dump_console(int one_boot_only)
|
||||||
assert(!regcomp(&re, regex[i], 0));
|
assert(!regcomp(&re, regex[i], 0));
|
||||||
|
|
||||||
/* Keep looking for matches so we find the last one. */
|
/* 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;
|
cursor += match.rm_so + 1;
|
||||||
|
}
|
||||||
regfree(&re);
|
regfree(&re);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == CONSOLE_PRINT_PREVIOUS) {
|
||||||
|
console_c[cursor] = '\0';
|
||||||
|
cursor = previous;
|
||||||
|
}
|
||||||
|
|
||||||
puts(console_c + cursor);
|
puts(console_c + cursor);
|
||||||
free(console_c);
|
free(console_c);
|
||||||
unmap_memory(&console_mapping);
|
unmap_memory(&console_mapping);
|
||||||
|
@ -1087,6 +1100,7 @@ static void print_usage(const char *name, int exit_code)
|
||||||
printf("\n"
|
printf("\n"
|
||||||
" -c | --console: print cbmem console\n"
|
" -c | --console: print cbmem console\n"
|
||||||
" -1 | --oneboot: print cbmem console for last boot only\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"
|
" -C | --coverage: dump coverage information\n"
|
||||||
" -l | --list: print cbmem table of contents\n"
|
" -l | --list: print cbmem table of contents\n"
|
||||||
" -x | --hexdump: print hexdump of cbmem area\n"
|
" -x | --hexdump: print hexdump of cbmem area\n"
|
||||||
|
@ -1227,13 +1241,14 @@ int main(int argc, char** argv)
|
||||||
int print_timestamps = 0;
|
int print_timestamps = 0;
|
||||||
int print_tcpa_log = 0;
|
int print_tcpa_log = 0;
|
||||||
int machine_readable_timestamps = 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;
|
unsigned int rawdump_id = 0;
|
||||||
|
|
||||||
int opt, option_index = 0;
|
int opt, option_index = 0;
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"console", 0, 0, 'c'},
|
{"console", 0, 0, 'c'},
|
||||||
{"oneboot", 0, 0, '1'},
|
{"oneboot", 0, 0, '1'},
|
||||||
|
{"2ndtolast", 0, 0, '2'},
|
||||||
{"coverage", 0, 0, 'C'},
|
{"coverage", 0, 0, 'C'},
|
||||||
{"list", 0, 0, 'l'},
|
{"list", 0, 0, 'l'},
|
||||||
{"tcpa-log", 0, 0, 'L'},
|
{"tcpa-log", 0, 0, 'L'},
|
||||||
|
@ -1246,7 +1261,7 @@ int main(int argc, char** argv)
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
{0, 0, 0, 0}
|
{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) {
|
long_options, &option_index)) != EOF) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'c':
|
case 'c':
|
||||||
|
@ -1255,7 +1270,12 @@ int main(int argc, char** argv)
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
print_console = 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;
|
print_defaults = 0;
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
|
@ -1383,7 +1403,7 @@ int main(int argc, char** argv)
|
||||||
die("Table not found.\n");
|
die("Table not found.\n");
|
||||||
|
|
||||||
if (print_console)
|
if (print_console)
|
||||||
dump_console(one_boot_only);
|
dump_console(console_type);
|
||||||
|
|
||||||
if (print_coverage)
|
if (print_coverage)
|
||||||
dump_coverage();
|
dump_coverage();
|
||||||
|
|
Loading…
Reference in New Issue