:: commit 39936f5929dc7d0ee20131cc1403918fe9a917bb

mintsuki <mintsuki@protonmail.com> — 2021-03-15 01:56

parents: 6bbc31f232

fb: Improve fallback resolution logic

diff --git a/stage23/drivers/gop.c b/stage23/drivers/gop.c
index 6a29d790..a68266d5 100644
--- a/stage23/drivers/gop.c
+++ b/stage23/drivers/gop.c
@@ -37,28 +37,6 @@ bool init_gop(struct fb_info *ret,
               uint16_t target_width, uint16_t target_height, uint16_t target_bpp) {
     EFI_STATUS status;
 
-    if (!target_width || !target_height || !target_bpp) {
-        target_width  = 1024;
-        target_height = 768;
-        target_bpp    = 32;
-        struct edid_info_struct *edid_info = get_edid_info();
-        if (edid_info != NULL) {
-            int edid_width   = (int)edid_info->det_timing_desc1[2];
-                edid_width  += ((int)edid_info->det_timing_desc1[4] & 0xf0) << 4;
-            int edid_height  = (int)edid_info->det_timing_desc1[5];
-                edid_height += ((int)edid_info->det_timing_desc1[7] & 0xf0) << 4;
-            if (edid_width && edid_height) {
-                target_width  = edid_width;
-                target_height = edid_height;
-                print("gop: EDID detected screen resolution of %ux%u\n",
-                      target_width, target_height);
-            }
-        }
-    } else {
-        print("gop: Requested resolution of %ux%ux%u\n",
-              target_width, target_height, target_bpp);
-    }
-
     EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
     EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
 
@@ -79,10 +57,50 @@ bool init_gop(struct fb_info *ret,
         panic("gop: Initialisation failed");
     }
 
+    struct resolution fallback_resolutions[] = {
+        { 0,    0,   0  },   // Overwritten by preset resolution
+        { 1024, 768, 32 },
+        { 800,  600, 32 },
+        { 640,  480, 32 }
+    };
+
+    uefi_call_wrapper(gop->QueryMode, 4,
+        gop, gop->Mode->Mode, &mode_info_size, &mode_info);
+
+    fallback_resolutions[0].width  = mode_info->HorizontalResolution;
+    fallback_resolutions[0].height = mode_info->VerticalResolution;
+    fallback_resolutions[0].bpp    = linear_masks_to_bpp(
+                        mode_info->PixelInformation.RedMask,
+                        mode_info->PixelInformation.GreenMask,
+                        mode_info->PixelInformation.BlueMask,
+                        mode_info->PixelInformation.ReservedMask);
+
     UINTN modes_count = gop->Mode->MaxMode;
 
     size_t current_fallback = 0;
 
+    if (!target_width || !target_height || !target_bpp) {
+        struct edid_info_struct *edid_info = get_edid_info();
+        if (edid_info != NULL) {
+            int edid_width   = (int)edid_info->det_timing_desc1[2];
+                edid_width  += ((int)edid_info->det_timing_desc1[4] & 0xf0) << 4;
+            int edid_height  = (int)edid_info->det_timing_desc1[5];
+                edid_height += ((int)edid_info->det_timing_desc1[7] & 0xf0) << 4;
+            if (edid_width && edid_height) {
+                target_width  = edid_width;
+                target_height = edid_height;
+                target_bpp    = 32;
+                print("gop: EDID detected screen resolution of %ux%u\n",
+                      target_width, target_height);
+            }
+        } else {
+            goto fallback;
+        }
+    } else {
+        print("gop: Requested resolution of %ux%ux%u\n",
+              target_width, target_height, target_bpp);
+    }
+
 retry:
     for (size_t i = 0; i < modes_count; i++) {
         status = uefi_call_wrapper(gop->QueryMode, 4,
@@ -153,6 +171,7 @@ retry:
         return true;
     }
 
+fallback:
     if (current_fallback < SIZEOF_ARRAY(fallback_resolutions)) {
         target_width  = fallback_resolutions[current_fallback].width;
         target_height = fallback_resolutions[current_fallback].height;
diff --git a/stage23/drivers/vbe.c b/stage23/drivers/vbe.c
index 669e6511..46a8ed5e 100644
--- a/stage23/drivers/vbe.c
+++ b/stage23/drivers/vbe.c
@@ -130,10 +130,16 @@ bool init_vbe(struct fb_info *ret,
     print("vbe: Product name: %s\n", (char *)rm_desegment(vbe_info.prod_name_seg, vbe_info.prod_name_off));
     print("vbe: Product revision: %s\n", (char *)rm_desegment(vbe_info.prod_rev_seg, vbe_info.prod_rev_off));
 
+    uint16_t *vid_modes = (uint16_t *)rm_desegment(vbe_info.vid_modes_seg,
+                                                   vbe_info.vid_modes_off);
+
+    struct resolution fallback_resolutions[] = {
+        { 1024, 768, 32 },
+        { 800,  600, 32 },
+        { 640,  480, 32 }
+    };
+
     if (!target_width || !target_height || !target_bpp) {
-        target_width  = 1024;
-        target_height = 768;
-        target_bpp    = 32;
         struct edid_info_struct *edid_info = get_edid_info();
         if (edid_info != NULL) {
             int edid_width   = (int)edid_info->det_timing_desc1[2];
@@ -146,15 +152,14 @@ bool init_vbe(struct fb_info *ret,
                 print("vbe: EDID detected screen resolution of %ux%u\n",
                       target_width, target_height);
             }
+        } else {
+            goto fallback;
         }
     } else {
         print("vbe: Requested resolution of %ux%ux%u\n",
               target_width, target_height, target_bpp);
     }
 
-    uint16_t *vid_modes = (uint16_t *)rm_desegment(vbe_info.vid_modes_seg,
-                                                   vbe_info.vid_modes_off);
-
 retry:
     for (size_t i = 0; vid_modes[i] != 0xffff; i++) {
         struct vbe_mode_info_struct vbe_mode_info;
@@ -200,6 +205,7 @@ retry:
         }
     }
 
+fallback:
     if (current_fallback < SIZEOF_ARRAY(fallback_resolutions)) {
         target_width  = fallback_resolutions[current_fallback].width;
         target_height = fallback_resolutions[current_fallback].height;
diff --git a/stage23/lib/fb.h b/stage23/lib/fb.h
index 66641269..9699dc36 100644
--- a/stage23/lib/fb.h
+++ b/stage23/lib/fb.h
@@ -9,13 +9,6 @@ struct resolution {
     uint16_t bpp;
 };
 
-__attribute__((unused))
-static struct resolution fallback_resolutions[] = {
-    { 1024, 768, 32 },
-    { 800,  600, 32 },
-    { 640,  480, 32 }
-};
-
 struct fb_info {
     uint8_t  memory_model;
     uint32_t framebuffer_addr;
tab: 248 wrap: offon