:: commit 35bd9ee9338f78efca498ff41e2eb621554d9879

mintsuki <mintsuki@protonmail.com> — 2022-09-17 08:40

parents: 99187cd837

misc: Improve printing effectively on panics and errors

diff --git a/common/entry.s3.c b/common/entry.s3.c
index 6c83d02d..44ca8c1b 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();
 
     init_gdt();
@@ -62,9 +60,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");
 
@@ -92,8 +87,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");
         }
@@ -110,8 +106,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;
     }
@@ -119,8 +116,6 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 #endif
 
 noreturn void stage3_common(void) {
-    term_notready();
-
     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 8f869682..b062bd2b 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 35487fce..f43c1fe0 100644
--- a/common/lib/print.s2.c
+++ b/common/lib/print.s2.c
@@ -11,29 +11,6 @@
 #include <sys/cpu.h>
 #include <drivers/serial.h>
 
-#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 (;;) {
@@ -199,21 +180,13 @@ 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 (E9_OUTPUT) {
             outb(0xe9, print_buf[i]);
         }
-        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 97e222ab..9a5b2528 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 <lib/misc.h>
 #include <lib/real.h>
 
-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 dbb43f06..84767cfc 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
@@ -893,5 +888,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 c0e43fb2..9da5bb2e 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -535,6 +535,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 f5092d9b..f0ecc62b 100644
--- a/common/protos/linux.c
+++ b/common/protos/linux.c
@@ -494,6 +494,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 f006d570..2915b4d4 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -298,6 +298,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 b0d5ce59..64f53708 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -493,6 +493,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;
diff --git a/common/protos/stivale.c b/common/protos/stivale.c
index b91fba00..9adf5a09 100644
--- a/common/protos/stivale.c
+++ b/common/protos/stivale.c
@@ -309,6 +309,7 @@ noreturn void stivale_load(char *config, char *cmdline) {
     printv("stivale: Current epoch: %U\n", stivale_struct->epoch);
 
     term_deinit();
+    quiet = true;
 
     if (stivale_hdr.flags & (1 << 0)) {
         size_t req_width  = stivale_hdr.framebuffer_width;
diff --git a/common/protos/stivale2.c b/common/protos/stivale2.c
index fb8d7ee6..33fc6f30 100644
--- a/common/protos/stivale2.c
+++ b/common/protos/stivale2.c
@@ -629,6 +629,7 @@ failed_to_load_header_section:
     }
 
     term_deinit();
+    quiet = true;
 
     if (hdrtag != NULL
 #if defined (UEFI)
@@ -636,6 +637,7 @@ failed_to_load_header_section:
 #endif
      || (avtag != NULL && preference == 0)) {
         term_deinit();
+        quiet = true;
 
 #if defined (UEFI)
         gop_force_16 = true;
tab: 248 wrap: offon