:: commit 6e110b5b74fa9798168206c020e5be21da6fd3dc

Mintsuki <mintsuki@protonmail.com> — 2026-05-13 06:42

parents: 0a0540aec8

lib/term: Move framebuffer clear into term_notready to keep WC active

diff --git a/common/drivers/gop.c b/common/drivers/gop.c
index 59a19043..57f82869 100644
--- a/common/drivers/gop.c
+++ b/common/drivers/gop.c
@@ -126,8 +126,7 @@ bool gop_force_16 = false;
 
 static bool try_mode(struct fb_info *ret, EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
                      size_t mode, uint64_t width, uint64_t height, int bpp,
-                     struct fb_info *fbs, size_t fbs_count,
-                     bool preserve_screen) {
+                     struct fb_info *fbs, size_t fbs_count) {
     EFI_STATUS status;
 
     if (!mode_to_fb_info(ret, gop, mode)) {
@@ -179,10 +178,6 @@ static bool try_mode(struct fb_info *ret, EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
 
     ret->framebuffer_addr = gop->Mode->FrameBufferBase;
 
-    if (!preserve_screen) {
-        fb_clear(ret);
-    }
-
     return true;
 }
 
@@ -213,8 +208,7 @@ no_unwind static int preset_modes[MAX_PRESET_MODES];
 no_unwind static bool preset_modes_initialised = false;
 
 void init_gop(struct fb_info **ret, size_t *_fbs_count,
-              uint64_t target_width, uint64_t target_height, uint16_t target_bpp,
-              bool preserve_screen) {
+              uint64_t target_width, uint64_t target_height, uint16_t target_bpp) {
     if (preset_modes_initialised == false) {
         for (size_t i = 0; i < MAX_PRESET_MODES; i++) {
             preset_modes[i] = -1;
@@ -321,7 +315,7 @@ void init_gop(struct fb_info **ret, size_t *_fbs_count,
 
 retry:
         for (size_t j = 0; j < modes_count; j++) {
-            if (try_mode(fb, gop, j, _target_width, _target_height, _target_bpp, *ret, fbs_count, preserve_screen)) {
+            if (try_mode(fb, gop, j, _target_width, _target_height, _target_bpp, *ret, fbs_count)) {
                 goto success;
             }
         }
@@ -348,7 +342,7 @@ fallback:
         if (current_fallback == 1) {
             current_fallback++;
 
-            if (try_mode(fb, gop, preset_modes[i], 0, 0, 0, *ret, fbs_count, preserve_screen)) {
+            if (try_mode(fb, gop, preset_modes[i], 0, 0, 0, *ret, fbs_count)) {
                 goto success;
             }
         }
diff --git a/common/drivers/gop.h b/common/drivers/gop.h
index bf0c41de..24a463ab 100644
--- a/common/drivers/gop.h
+++ b/common/drivers/gop.h
@@ -9,8 +9,7 @@
 #include <lib/fb.h>
 
 void init_gop(struct fb_info **ret, size_t *_fbs_count,
-              uint64_t target_width, uint64_t target_height, uint16_t target_bpp,
-              bool preserve_screen);
+              uint64_t target_width, uint64_t target_height, uint16_t target_bpp);
 
 extern bool gop_force_16;
 
diff --git a/common/drivers/vbe.c b/common/drivers/vbe.c
index 4c7c4dbc..d71bf0a8 100644
--- a/common/drivers/vbe.c
+++ b/common/drivers/vbe.c
@@ -231,8 +231,7 @@ struct fb_info *vbe_get_mode_list(size_t *count) {
 }
 
 bool init_vbe(struct fb_info *ret,
-              uint16_t target_width, uint16_t target_height, uint16_t target_bpp,
-              bool preserve_screen) {
+              uint16_t target_width, uint16_t target_height, uint16_t target_bpp) {
     printv("vbe: Initialising...\n");
 
     size_t current_fallback = 0;
@@ -344,10 +343,6 @@ retry:
                 continue;
             }
 
-            if (!preserve_screen) {
-                fb_clear(ret);
-            }
-
             return true;
         }
     }
diff --git a/common/drivers/vbe.h b/common/drivers/vbe.h
index fbbdf937..f5da1f88 100644
--- a/common/drivers/vbe.h
+++ b/common/drivers/vbe.h
@@ -7,8 +7,7 @@
 #include <lib/fb.h>
 
 bool init_vbe(struct fb_info *ret,
-              uint16_t target_width, uint16_t target_height, uint16_t target_bpp,
-              bool preserve_screen);
+              uint16_t target_width, uint16_t target_height, uint16_t target_bpp);
 
 struct fb_info *vbe_get_mode_list(size_t *count);
 
diff --git a/common/drivers/vga_textmode.c b/common/drivers/vga_textmode.c
index 0a5c5961..66a80367 100644
--- a/common/drivers/vga_textmode.c
+++ b/common/drivers/vga_textmode.c
@@ -267,7 +267,7 @@ static void text_deinit(struct flanterm_context *_ctx, void (*_free)(void *, siz
 }
 
 void vga_textmode_init(bool managed) {
-    term_notready();
+    term_notready(true);
 
     if (quiet) {
         return;
diff --git a/common/entry.s3.c b/common/entry.s3.c
index d6b86ebb..ddf2d6e4 100644
--- a/common/entry.s3.c
+++ b/common/entry.s3.c
@@ -211,7 +211,7 @@ noreturn void stage3_common(void) {
 #endif
 #endif
 
-    term_notready();
+    term_notready(true);
 
 #if defined (UEFI)
     init_bli();
diff --git a/common/lib/fb.c b/common/lib/fb.c
index 7d489747..12f779c1 100644
--- a/common/lib/fb.c
+++ b/common/lib/fb.c
@@ -12,15 +12,10 @@ struct fb_info *fb_fbs;
 size_t fb_fbs_count = 0;
 
 void fb_init(struct fb_info **ret, size_t *_fbs_count,
-             uint64_t target_width, uint64_t target_height, uint16_t target_bpp,
-             bool preserve_screen) {
-    if (quiet) {
-        preserve_screen = true;
-    }
-
+             uint64_t target_width, uint64_t target_height, uint16_t target_bpp) {
 #if defined (BIOS)
     *ret = ext_mem_alloc(sizeof(struct fb_info));
-    if (init_vbe(*ret, target_width, target_height, target_bpp, preserve_screen)) {
+    if (init_vbe(*ret, target_width, target_height, target_bpp)) {
         *_fbs_count = 1;
 
         (*ret)->edid = get_edid_info();
@@ -32,7 +27,7 @@ void fb_init(struct fb_info **ret, size_t *_fbs_count,
         pmm_free(*ret, sizeof(struct fb_info));
     }
 #elif defined (UEFI)
-    init_gop(ret, _fbs_count, target_width, target_height, target_bpp, preserve_screen);
+    init_gop(ret, _fbs_count, target_width, target_height, target_bpp);
 #endif
 
     fb_fbs = *ret;
diff --git a/common/lib/fb.h b/common/lib/fb.h
index fd46ff59..bb55b8d2 100644
--- a/common/lib/fb.h
+++ b/common/lib/fb.h
@@ -37,8 +37,7 @@ extern struct fb_info *fb_fbs;
 extern size_t fb_fbs_count;
 
 void fb_init(struct fb_info **ret, size_t *_fbs_count,
-             uint64_t target_width, uint64_t target_height, uint16_t target_bpp,
-             bool preserve_screen);
+             uint64_t target_width, uint64_t target_height, uint16_t target_bpp);
 
 void fb_clear(struct fb_info *fb);
 
diff --git a/common/lib/gterm.c b/common/lib/gterm.c
index e9027eaf..0e59f514 100644
--- a/common/lib/gterm.c
+++ b/common/lib/gterm.c
@@ -783,7 +783,7 @@ bool gterm_init(struct fb_info **_fbs, size_t *_fbs_count,
     prev_valid = false;
 
     if (quiet) {
-        term_notready();
+        term_notready(true);
         return false;
     }
 
@@ -794,10 +794,10 @@ bool gterm_init(struct fb_info **_fbs, size_t *_fbs_count,
     }
 #endif
 
-    term_notready();
+    term_notready(true);
 
     // We force bpp to 32
-    fb_init(&fbs, &fbs_count, width, height, 32, true);
+    fb_init(&fbs, &fbs_count, width, height, 32);
 
     if (_fbs != NULL) {
         *_fbs = fbs;
diff --git a/common/lib/panic.s2.c b/common/lib/panic.s2.c
index 91753fb6..bdd32220 100644
--- a/common/lib/panic.s2.c
+++ b/common/lib/panic.s2.c
@@ -67,7 +67,7 @@ noreturn void panic(bool allow_menu, const char *fmt, ...) {
         getchar();
 
         // This fixes a crash
-        term_notready();
+        term_notready(true);
 
         menu(false);
 /*
diff --git a/common/lib/term.c b/common/lib/term.c
index 4b85cb33..99c5b1c1 100644
--- a/common/lib/term.c
+++ b/common/lib/term.c
@@ -19,7 +19,19 @@ size_t terms_i = 0;
 
 int term_backend = _NOT_READY;
 
-void term_notready(void) {
+void term_notready(bool preserve_screen) {
+    if (quiet) {
+        preserve_screen = true;
+    }
+
+    if (!preserve_screen) {
+        for (size_t i = 0; i < fb_fbs_count; i++) {
+            if (fb_fbs[i].framebuffer_bpp == 32) {
+                fb_clear(&fb_fbs[i]);
+            }
+        }
+    }
+
 #if defined (__i386__) || defined (__x86_64__)
     mtrr_wc_clear_fb_ranges();
 #endif
@@ -234,7 +246,7 @@ void term_fallback(void) {
     int prev_backend = term_backend;
 #endif
 
-    term_notready();
+    term_notready(true);
 
     terms = ext_mem_alloc(sizeof(void *));
     terms_i = 1;
diff --git a/common/lib/term.h b/common/lib/term.h
index 18fd4ddd..2940aae4 100644
--- a/common/lib/term.h
+++ b/common/lib/term.h
@@ -3,6 +3,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <lib/print.h>
 #include <flanterm.h>
 
@@ -52,7 +53,7 @@ static inline void set_cursor_pos_helper(size_t x, size_t y) {
     print("\e[%u;%uH", (int)y + 1, (int)x + 1);
 }
 
-void term_notready(void);
+void term_notready(bool preserve_screen);
 void term_fallback(void);
 void _term_write(struct flanterm_context *term, uint64_t buf, uint64_t count);
 
diff --git a/common/protos/chainload.c b/common/protos/chainload.c
index b92a5b60..a51315eb 100644
--- a/common/protos/chainload.c
+++ b/common/protos/chainload.c
@@ -295,7 +295,7 @@ noreturn void chainload(char *config, char *cmdline) {
     EFI_DEVICE_PATH_PROTOCOL *efi_file_path = build_relative_efi_file_path(image);
 
     fclose(image);
-    term_notready();
+    term_notready(false);
 
     size_t req_width = 0, req_height = 0, req_bpp = 0;
 
@@ -305,7 +305,7 @@ noreturn void chainload(char *config, char *cmdline) {
 
     struct fb_info *fbinfo;
     size_t fb_count;
-    fb_init(&fbinfo, &fb_count, req_width, req_height, req_bpp, false);
+    fb_init(&fbinfo, &fb_count, req_width, req_height, req_bpp);
 
     size_t cmdline_len = strlen(cmdline);
     CHAR16 *new_cmdline;
diff --git a/common/protos/limine.c b/common/protos/limine.c
index ee5ba24f..8c6eb6ed 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -1374,10 +1374,11 @@ FEAT_END
     struct fb_info *fbs;
     size_t fbs_count;
 
-    term_notready();
-
     bool preserve_screen = get_request(LIMINE_FLANTERM_FB_INIT_PARAMS_REQUEST_ID) != NULL;
-    fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp, preserve_screen);
+
+    term_notready(preserve_screen);
+
+    fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp);
     if (fbs_count == 0) {
         goto no_fb;
     }
diff --git a/common/protos/linux_risc.c b/common/protos/linux_risc.c
index 892fab45..b33f0566 100644
--- a/common/protos/linux_risc.c
+++ b/common/protos/linux_risc.c
@@ -275,9 +275,9 @@ static void prepare_efi_tables(struct boot_param *p, char *config) {
         struct fb_info *fbs;
         size_t fbs_count;
 
-        term_notready();
+        term_notready(false);
 
-        fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp, false);
+        fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp);
 
         // TODO(qookie): Let the user pick a framebuffer if there's > 1
         if (fbs_count > 0) {
diff --git a/common/protos/linux_x86.c b/common/protos/linux_x86.c
index 9fed6999..def4c088 100644
--- a/common/protos/linux_x86.c
+++ b/common/protos/linux_x86.c
@@ -544,7 +544,7 @@ no_modules:;
     // Video
     ///////////////////////////////////////
 
-    term_notready();
+    term_notready(false);
 
     struct screen_info *screen_info = &boot_params->screen_info;
 
@@ -569,7 +569,7 @@ no_modules:;
 #if defined (UEFI)
     gop_force_16 = true;
 #endif
-    fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp, false);
+    fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp);
     if (fbs_count == 0) {
 #if defined (UEFI)
         goto no_fb;
diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c
index a3c79cf0..c856bf0f 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -405,7 +405,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
     multiboot1_info->bootloader_name = (uint32_t)(size_t)lowmem_bootname - mb1_info_slide;
     multiboot1_info->flags |= (1 << 9);
 
-    term_notready();
+    term_notready(false);
 
     size_t req_width = 0;
     size_t req_height = 0;
@@ -436,7 +436,7 @@ modeset:;
 
             struct fb_info *fbs;
             size_t fbs_count;
-            fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp, false);
+            fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp);
             if (fbs_count == 0) {
 #if defined (UEFI)
                 goto skip_modeset;
diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index 46fb6886..fd16103b 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -757,7 +757,7 @@ reloc_fail:
 
         tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
 
-        term_notready();
+        term_notready(false);
 
         size_t req_width = 0;
         size_t req_height = 0;
@@ -786,7 +786,7 @@ modeset:;
 
             struct fb_info *fbs;
             size_t fbs_count;
-            fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp, false);
+            fb_init(&fbs, &fbs_count, req_width, req_height, req_bpp);
             if (fbs_count == 0) {
 #if defined (BIOS)
 textmode:
tab: 248 wrap: offon