From 7f14f2f0d04e7d1b3a60309fd71fe052e3ed7072 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Sat, 17 Sep 2022 10:40:14 +0200 Subject: [PATCH] misc: Improve printing effectively on panics and errors --- common/entry.s3.c | 17 ++++++----------- common/lib/gterm.c | 4 ---- common/lib/panic.s2.c | 36 +---------------------------------- common/lib/print.s2.c | 39 ++++++-------------------------------- common/lib/term.c | 11 +---------- common/lib/term.h | 5 +---- common/lib/term.s2.c | 11 ++++------- common/menu.c | 27 +++++++++++++------------- common/protos/limine.c | 1 + common/protos/linux.c | 1 + common/protos/multiboot1.c | 1 + common/protos/multiboot2.c | 1 + 12 files changed, 36 insertions(+), 118 deletions(-) diff --git a/common/entry.s3.c b/common/entry.s3.c index cb41fa5c..23948237 100644 --- a/common/entry.s3.c +++ b/common/entry.s3.c @@ -36,15 +36,13 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) EFI_STATUS status; + term_fallback(); + status = gBS->SetWatchdogTimer(0, 0x10000, 0, NULL); if (status) { - term_vbe(NULL, 0, 0); - early_term = true; print("WARNING: Failed to disable watchdog timer!\n"); } - term_notready(); - init_memmap(); #if defined (__x86_64__) || defined (__i386__) @@ -64,9 +62,6 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) EFI_HANDLE current_handle = ImageHandle; for (;;) { if (current_handle == NULL) { - term_vbe(NULL, 0, 0); - early_term = true; - print("WARNING: Could not meaningfully match the boot device handle with a volume.\n"); print(" Using the first volume containing a Limine configuration!\n"); @@ -94,8 +89,9 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) break; } - if (boot_volume != NULL) + if (boot_volume != NULL) { stage3_common(); + } panic(false, "No volume contained a Limine configuration file"); } @@ -112,8 +108,9 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) boot_volume = disk_volume_from_efi_handle(loaded_image->DeviceHandle); - if (boot_volume != NULL) + if (boot_volume != NULL) { stage3_common(); + } current_handle = loaded_image->ParentHandle; } @@ -121,8 +118,6 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) #endif noreturn void stage3_common(void) { - term_notready(); - #if defined (__x86_64__) || defined (__i386__) init_flush_irqs(); init_io_apics(); diff --git a/common/lib/gterm.c b/common/lib/gterm.c index 4abad5d1..386248ab 100644 --- a/common/lib/gterm.c +++ b/common/lib/gterm.c @@ -617,7 +617,6 @@ bool gterm_init(char *config, size_t *_rows, size_t *_cols, size_t width, size_t && width == 0 && height == 0 && fbinfo.framebuffer_bpp == 32 - && !early_term && serial == last_serial && config == last_config) { *_rows = rows; @@ -633,7 +632,6 @@ bool gterm_init(char *config, size_t *_rows, size_t *_cols, size_t width, size_t && fbinfo.framebuffer_width == width && fbinfo.framebuffer_height == height && fbinfo.framebuffer_bpp == 32 - && !early_term && serial == last_serial && config == last_config) { *_rows = rows; @@ -642,8 +640,6 @@ bool gterm_init(char *config, size_t *_rows, size_t *_cols, size_t width, size_t return true; } - early_term = false; - // We force bpp to 32 if (!fb_init(&fbinfo, width, height, 32)) return false; diff --git a/common/lib/panic.s2.c b/common/lib/panic.s2.c index 564af74d..f7aaddd3 100644 --- a/common/lib/panic.s2.c +++ b/common/lib/panic.s2.c @@ -21,45 +21,11 @@ noreturn void panic(bool allow_menu, const char *fmt, ...) { quiet = false; - static bool is_nested = false; - - if (is_nested) { - goto nested; - } - - is_nested = true; - -#if defined (BIOS) - if (stage3_loaded == true && term_backend == NOT_READY) { - early_term = true; - term_vbe(NULL, 0, 0); - } -#endif - -#if defined (UEFI) - if (term_backend == NOT_READY) { - if (term_enabled_once) { - term_vbe(NULL, 0, 0); - } else { - term_fallback(); - } - } -#endif - -nested: - if (term_backend == NOT_READY) { - term_fallback(); - } - -#if defined (BIOS) - if (stage3_loaded) { -#endif + if (term_backend != FALLBACK) { print("\033[31mPANIC\033[37;1m\033[0m: "); -#if defined (BIOS) } else { print("PANIC: "); } -#endif vprint(fmt, args); va_end(args); diff --git a/common/lib/print.s2.c b/common/lib/print.s2.c index 0d728676..b157269c 100644 --- a/common/lib/print.s2.c +++ b/common/lib/print.s2.c @@ -11,29 +11,6 @@ #include #include -#if defined (BIOS) -static void s2_print(const char *s, size_t len) { - for (size_t i = 0; i < len; i++) { - struct rm_regs r = {0}; - char c = s[i]; - - switch (c) { - case '\n': - r.eax = 0x0e00 | '\r'; - rm_int(0x10, &r, &r); - r = (struct rm_regs){0}; - r.eax = 0x0e00 | '\n'; - rm_int(0x10, &r, &r); - break; - default: - r.eax = 0x0e00 | s[i]; - rm_int(0x10, &r, &r); - break; - } - } -} -#endif - static const char *base_digits = "0123456789abcdef"; #define PRINT_BUF_MAX 4096 @@ -142,6 +119,10 @@ void print(const char *fmt, ...) { static char print_buf[PRINT_BUF_MAX]; void vprint(const char *fmt, va_list args) { + if (quiet) { + return; + } + size_t print_buf_i = 0; for (;;) { @@ -218,15 +199,7 @@ void vprint(const char *fmt, va_list args) { } out: -#if defined (BIOS) - if (stage3_loaded) { -#endif - term_write((uint64_t)(uintptr_t)print_buf, print_buf_i); -#if defined (BIOS) - } else { - s2_print(print_buf, print_buf_i); - } -#endif + term_write((uint64_t)(uintptr_t)print_buf, print_buf_i); for (size_t i = 0; i < print_buf_i; i++) { #if defined (__x86_64__) || defined (__i386__) @@ -234,7 +207,7 @@ out: outb(0xe9, print_buf[i]); } #endif - if ((term_backend != NOT_READY && serial) || COM_OUTPUT) { + if (serial || COM_OUTPUT) { switch (print_buf[i]) { case '\n': serial_out('\r'); diff --git a/common/lib/term.c b/common/lib/term.c index 562f2266..7100163b 100644 --- a/common/lib/term.c +++ b/common/lib/term.c @@ -52,7 +52,7 @@ void term_deinit(void) { gterm_deinit(); } - term_notready(); + term_fallback(); } void term_vbe(char *config, size_t width, size_t height) { @@ -109,8 +109,6 @@ void term_vbe(char *config, size_t width, size_t height) { term_context_restore = gterm_context_restore; term_full_refresh = gterm_full_refresh; - term_enabled_once = true; - term_backend = VBE; } @@ -183,8 +181,6 @@ void term_textmode(void) { return; } - term_notready(); - init_vga_textmode(&term_rows, &term_cols, true); if (serial) { @@ -222,8 +218,6 @@ void term_textmode(void) { term_context_restore = text_context_restore; term_full_refresh = text_full_refresh; - term_enabled_once = true; - term_backend = TEXTMODE; } #endif @@ -260,9 +254,6 @@ static uint8_t xfer_buf[TERM_XFER_CHUNK]; bool term_autoflush = true; void term_write(uint64_t buf, uint64_t count) { - if (term_backend == NOT_READY) - return; - switch (count) { case TERM_CTX_SIZE: { uint64_t ret = context_size(); diff --git a/common/lib/term.h b/common/lib/term.h index abf39136..e40b28bb 100644 --- a/common/lib/term.h +++ b/common/lib/term.h @@ -39,7 +39,7 @@ extern struct term_context { } term_context; enum { - NOT_READY, + _NOT_READY, VBE, TEXTMODE, FALLBACK @@ -49,8 +49,6 @@ extern int current_video_mode; extern int term_backend; extern size_t term_rows, term_cols; extern bool term_runtime; -extern bool early_term; -extern bool term_enabled_once; void term_fallback(void); @@ -58,7 +56,6 @@ void term_reinit(void); void term_deinit(void); void term_vbe(char *config, size_t width, size_t height); void term_textmode(void); -void term_notready(void); void term_putchar(uint8_t c); void term_write(uint64_t buf, uint64_t count); diff --git a/common/lib/term.s2.c b/common/lib/term.s2.c index 2c6081d6..eacad011 100644 --- a/common/lib/term.s2.c +++ b/common/lib/term.s2.c @@ -5,13 +5,10 @@ #include #include -bool early_term = false; - no_unwind int current_video_mode = -1; -int term_backend = NOT_READY; +int term_backend = _NOT_READY; size_t term_rows, term_cols; bool term_runtime = false; -bool term_enabled_once = false; void (*raw_putchar)(uint8_t c); void (*clear)(bool move); @@ -139,6 +136,8 @@ static void fallback_get_cursor_pos(size_t *x, size_t *y) { } #endif +static void term_notready(void); + void term_fallback(void) { #if defined (UEFI) if (!efi_boot_services_exited) { @@ -194,9 +193,7 @@ static void notready_uint64_t(uint64_t n) { (void)n; } -void term_notready(void) { - term_backend = NOT_READY; - +static void term_notready(void) { raw_putchar = notready_raw_putchar; clear = notready_clear; enable_cursor = notready_void; diff --git a/common/menu.c b/common/menu.c index a8fa6036..a567f4cc 100644 --- a/common/menu.c +++ b/common/menu.c @@ -601,8 +601,6 @@ noreturn void _menu(bool timeout_enabled) { randomise_mem_str = config_get_value(NULL, 0, "RANDOMIZE_MEMORY"); bool randomise_mem = randomise_mem_str != NULL && strcmp(randomise_mem_str, "yes") == 0; if (randomise_mem) { - term_vbe(NULL, 0, 0); - early_term = true; pmm_randomise_memory(); } @@ -650,6 +648,7 @@ noreturn void _menu(bool timeout_enabled) { // default entry is valid. print_tree(NULL, 0, 0, selected_entry, menu_tree, &selected_menu_entry); if (selected_menu_entry == NULL || selected_menu_entry->sub != NULL) { + quiet = false; print("Default entry is not valid or directory, booting to menu.\n"); skip_timeout = true; } else { @@ -664,7 +663,6 @@ noreturn void _menu(bool timeout_enabled) { char *graphics = "yes"; #endif -reterm: if (graphics == NULL || strcmp(graphics, "no") != 0) { size_t req_width = 0, req_height = 0, req_bpp = 0; @@ -695,6 +693,7 @@ refresh: } while (menu_tree == NULL) { + quiet = false; print("Config file %s.\n\n", config_ready ? "contains no valid entries" : "not found"); print("For information on the format of Limine config entries, consult CONFIG.md in\n"); print("the root of the Limine source repository.\n\n"); @@ -765,14 +764,10 @@ refresh: term_double_buffer_flush(); if ((c = pit_sleep_and_quit_on_keypress(1))) { skip_timeout = true; - if (quiet) { - quiet = false; - goto reterm; - } else { - print("\e[2K"); - term_double_buffer_flush(); - goto timeout_aborted; - } + quiet = false; + print("\e[2K"); + term_double_buffer_flush(); + goto timeout_aborted; } } goto autoboot; @@ -826,10 +821,10 @@ timeout_aborted: selected_menu_entry->expanded = !selected_menu_entry->expanded; goto refresh; } - if (term_backend == NOT_READY) { + if (term_backend == FALLBACK) { term_vbe(NULL, 0, 0); #if defined (BIOS) - if (term_backend == NOT_READY) { + if (term_backend == FALLBACK) { term_textmode(); } #endif @@ -876,6 +871,7 @@ noreturn void boot(char *config) { } if (!strcmp(proto, "stivale1") || !strcmp(proto, "stivale") || !strcmp(proto, "stivale2")) { + quiet = false; print("The stivale and stivale2 protocols are no longer supported as of Limine 4.x\n"); print("Please notify kernel maintainers to move to the Limine boot protocol or\n"); print("roll back to Limine 3.x.\n\n"); @@ -885,18 +881,21 @@ noreturn void boot(char *config) { #if defined (__x86_64__) || defined (__i386__) linux_load(config, cmdline); #else + quiet = false; print("TODO: Linux is not available on aarch64.\n\n"); #endif } else if (!strcmp(proto, "multiboot1") || !strcmp(proto, "multiboot")) { #if defined (__x86_64__) || defined (__i386__) multiboot1_load(config, cmdline); #else + quiet = false; print("Multiboot 1 is not available on aarch64.\n\n"); #endif } else if (!strcmp(proto, "multiboot2")) { #if defined (__x86_64__) || defined (__i386__) multiboot2_load(config, cmdline); #else + quiet = false; print("Multiboot 2 is not available on aarch64.\n\n"); #endif } else if (!strcmp(proto, "chainload_next")) { @@ -905,5 +904,5 @@ noreturn void boot(char *config) { chainload(config); } - panic(true, "Incorrect protocol specified for kernel."); + panic(true, "Unsupported protocol specified for kernel."); } diff --git a/common/protos/limine.c b/common/protos/limine.c index 04310176..1e86ea7c 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -738,6 +738,7 @@ FEAT_START FEAT_END term_deinit(); + quiet = true; if (!fb_init(&fb, req_width, req_height, req_bpp)) { panic(true, "limine: Could not acquire framebuffer"); diff --git a/common/protos/linux.c b/common/protos/linux.c index 1afcf38f..049a2fb4 100644 --- a/common/protos/linux.c +++ b/common/protos/linux.c @@ -496,6 +496,7 @@ noreturn void linux_load(char *config, char *cmdline) { /////////////////////////////////////// term_deinit(); + quiet = true; struct screen_info *screen_info = &boot_params->screen_info; diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c index 6dc8946b..78da218f 100644 --- a/common/protos/multiboot1.c +++ b/common/protos/multiboot1.c @@ -303,6 +303,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) { multiboot1_info->flags |= (1 << 9); term_deinit(); + quiet = true; if (header.flags & (1 << 2)) { size_t req_width = header.fb_width; diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c index beb7f271..87131685 100644 --- a/common/protos/multiboot2.c +++ b/common/protos/multiboot2.c @@ -498,6 +498,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) { tag->common.size = sizeof(struct multiboot_tag_framebuffer); term_deinit(); + quiet = true; if (fbtag) { size_t req_width = fbtag->width;