Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/stand/efiboot Fix a few bugs related to the fr...



details:   https://anonhg.NetBSD.org/src/rev/7fb9df72031e
branches:  trunk
changeset: 848766:7fb9df72031e
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sat Feb 08 14:35:47 2020 +0000

description:
Fix a few bugs related to the framebuffer:
 - If a GOP mode wasn't explicitly requested, the bootloader was passing
   fb info to the kernel even if the console was in text mode! This
   results in garbled console output on at least ThinkPad T420 and
   likely many others. If a mode isn't specified, default to 800x600.
 - The "gop" command was incorrectly parsing video modes in the form
   WxHxD as WxWxD.
 - Allow a short form WxH for the "gop" command to select any mode with
   the target dimensions.

diffstat:

 sys/arch/i386/stand/efiboot/eficons.c |  74 ++++++++++++++++++----------------
 1 files changed, 40 insertions(+), 34 deletions(-)

diffs (125 lines):

diff -r 95bd91799d0d -r 7fb9df72031e sys/arch/i386/stand/efiboot/eficons.c
--- a/sys/arch/i386/stand/efiboot/eficons.c     Sat Feb 08 14:17:30 2020 +0000
+++ b/sys/arch/i386/stand/efiboot/eficons.c     Sat Feb 08 14:35:47 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: eficons.c,v 1.7 2019/09/13 02:19:45 manu Exp $ */
+/*     $NetBSD: eficons.c,v 1.8 2020/02/08 14:35:47 jmcneill Exp $     */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -34,6 +34,10 @@
 #include "bootinfo.h"
 #include "vbe.h"
 
+#ifndef DEFAULT_GOP_MODE
+#define DEFAULT_GOP_MODE       "800x600"
+#endif
+
 extern struct x86_boot_params boot_params;
 
 struct btinfo_console btinfo_console;
@@ -71,6 +75,8 @@
 static int efi_com_status(int);
 static int efi_com_waitforinputevent(uint64_t);
 
+static int efi_find_gop_mode(char *);
+
 static int iodev;
 static int (*internal_getchar)(void) = efi_cons_getc;
 static int (*internal_putchar)(int) = efi_cons_putc;
@@ -415,46 +421,36 @@
        EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
        struct btinfo_framebuffer fb;
        INT32 bestmode = -1;
+       UINTN sz;
 
-       if (efi_gop == NULL) {
-               framebuffer_configure(NULL);
-               return;
-       }
+       if (efi_gop == NULL)
+               goto nofb;
 
        if (efi_gop_mode >= 0) {
                bestmode = efi_gop_mode;
        } else {
-#if 0
-               UINT64 res, bestres = 0;
-               UINTN sz;
-               UINT32 i;
-
-               /* XXX EDID? EFI_EDID_DISCOVERED_PROTOCOL */
-               for (i = 0; i < efi_gop->Mode->MaxMode; i++) {
-                       status = uefi_call_wrapper(efi_gop->QueryMode, 4,
-                           efi_gop, i, &sz, &info);
-                       if (EFI_ERROR(status))
-                               continue;
+               /* If a mode has not been selected, choose a default */
+               bestmode = efi_find_gop_mode(DEFAULT_GOP_MODE);
+       }
+       if (bestmode == -1)
+               goto nofb;
 
-                       res = (UINT64)info->HorizontalResolution *
-                           (UINT64)info->VerticalResolution *
-                           (UINT64)getdepth(info);
-                       if (res > bestres) {
-                               bestmode = i;
-                               bestres = res;
-                       }
-               }
-#endif
-       }
-       if (bestmode >= 0) {
-               status = uefi_call_wrapper(efi_gop->SetMode, 2, efi_gop,
-                   bestmode);
-               if (EFI_ERROR(status) || efi_gop->Mode->Mode != bestmode)
-                       printf("GOP setmode failed: %" PRIxMAX "\n",
-                           (uintmax_t)status);
+       status = uefi_call_wrapper(efi_gop->SetMode, 2, efi_gop,
+           bestmode);
+       if (EFI_ERROR(status) || efi_gop->Mode->Mode != bestmode) {
+               printf("GOP setmode failed: %" PRIxMAX "\n",
+                   (uintmax_t)status);
+               goto nofb;
        }
 
-       info = efi_gop->Mode->Info;
+       status = uefi_call_wrapper(efi_gop->QueryMode, 4,
+           efi_gop, bestmode, &sz, &info);
+       if (EFI_ERROR(status)) {
+               printf("GOP querymode failed: %" PRIxMAX "\n",
+                   (uintmax_t)status);
+               goto nofb;
+       }
+
        memset(&fb, 0, sizeof(fb));
        fb.physaddr = efi_gop->Mode->FrameBufferBase;
        fb.flags = 0;
@@ -499,6 +495,10 @@
        }
 
        framebuffer_configure(&fb);
+       return;
+
+nofb:
+       framebuffer_configure(NULL);
 }
 
 int
@@ -658,8 +658,14 @@
 
                snprintf(mode, sizeof(mode), "%lux%lux%u",
                    (long)info->HorizontalResolution,
+                   (long)info->VerticalResolution,
+                   depth);
+               if (strcmp(arg, mode) == 0)
+                       return i;
+
+               snprintf(mode, sizeof(mode), "%lux%lu",
                    (long)info->HorizontalResolution,
-                   depth);
+                   (long)info->VerticalResolution);
                if (strcmp(arg, mode) == 0)
                        return i;
        }



Home | Main Index | Thread Index | Old Index