dump the cbmem console */
| 733 | |
| 734 | /* dump the cbmem console */ |
| 735 | static void dump_console(enum console_print_type type, int max_loglevel, int print_unknown_logs) |
| 736 | { |
| 737 | const struct cbmem_console *console_p; |
| 738 | char *console_c; |
| 739 | size_t size, cursor, previous; |
| 740 | |
| 741 | if (!cbmem_drv_get_cbmem_entry(CBMEM_ID_CONSOLE, (uint8_t **)&console_p, NULL, NULL)) |
| 742 | die("CBMEM console not found.\n"); |
| 743 | |
| 744 | cursor = console_p->cursor & CBMC_CURSOR_MASK; |
| 745 | if (!(console_p->cursor & CBMC_OVERFLOW) && cursor < console_p->size) |
| 746 | size = cursor; |
| 747 | else |
| 748 | size = console_p->size; |
| 749 | |
| 750 | console_c = malloc(size + 1); |
| 751 | if (!console_c) { |
| 752 | free((uint8_t *)console_p); |
| 753 | die("Not enough memory for console.\n"); |
| 754 | } |
| 755 | console_c[size] = '\0'; |
| 756 | |
| 757 | if (console_p->cursor & CBMC_OVERFLOW) { |
| 758 | if (cursor >= size) { |
| 759 | printf("cbmem: ERROR: CBMEM console struct is illegal, " |
| 760 | "output may be corrupt or out of order!\n\n"); |
| 761 | cursor = 0; |
| 762 | } |
| 763 | memcpy(console_c, console_p->body + cursor, size - cursor); |
| 764 | memcpy(console_c + size - cursor, console_p->body, cursor); |
| 765 | } else { |
| 766 | memcpy(console_c, console_p->body, size); |
| 767 | } |
| 768 | |
| 769 | /* Slight memory corruption may occur between reboots and give us a few |
| 770 | unprintable characters like '\0'. Replace them with '?' on output. */ |
| 771 | for (cursor = 0; cursor < size; cursor++) |
| 772 | if (!isprint(console_c[cursor]) && !isspace(console_c[cursor]) |
| 773 | && !BIOS_LOG_IS_MARKER(console_c[cursor])) |
| 774 | console_c[cursor] = '?'; |
| 775 | |
| 776 | /* We detect the reboot cutoff by looking for a bootblock, romstage or |
| 777 | ramstage banner, in that order (to account for platforms without |
| 778 | CONFIG_BOOTBLOCK_CONSOLE and/or CONFIG_EARLY_CONSOLE). Once we find |
| 779 | a banner, store the last two matches for that stage and stop. */ |
| 780 | cursor = previous = 0; |
| 781 | if (type != CONSOLE_PRINT_FULL) { |
| 782 | #define BANNER_REGEX(stage) \ |
| 783 | "\n\n.?coreboot-[^\n]* " stage " starting.*\\.\\.\\.\n" |
| 784 | #define OVERFLOW_REGEX(stage) "\n.?\\*\\*\\* Pre-CBMEM " stage " console overflow" |
| 785 | const char *regex[] = { BANNER_REGEX("verstage-before-bootblock"), |
| 786 | BANNER_REGEX("bootblock"), |
| 787 | BANNER_REGEX("verstage"), |
| 788 | OVERFLOW_REGEX("romstage"), |
| 789 | BANNER_REGEX("romstage"), |
| 790 | OVERFLOW_REGEX("ramstage"), |
| 791 | BANNER_REGEX("ramstage") }; |
| 792 |
no test coverage detected