This diff fixes missing video output when booting in UEFI mode on the
ThinkPad X121e (and possibly other boards with crappy implemenatations)
as reported earlier:

        https://marc.info/?l=openbsd-bugs&m=150407033628497&w=2

When looking for the best mode in terms of resolution, we might end up
with modes providing higher resolutions than what's possible on the
actual display. Some buggy UEFI implemenations may also fail for other
non-obvious reasons.

Either ways, current behaviour is to just proceed after a failed attempt
of setting some better mode. With this diff the currently working GOP
mode is saved and set again in case SetMode() was unsuccessful.

That way my X121e boots fine using mode 7 (640x480x32bpp) instead of
blanking out, efifb(4) comes up until radeon(4) takes over with native
resolution.

Also tested successfully/without any regressions on a Dell Latitude
E5550 as well as a Fujitsu Lifebook A Series boards both running
latest stock UEFI firmware.


Not sure yet whether this is a mistake or I'm not getting it, but
either status indicating an error or ending up with an incorrect mode
should each be enough to call it a failure.
In fact, EFI_ERROR(status) may be non-zero although gop->Mode->Mode was
indeed set and equal to bestmode as this was the case on my X121e.


Feedback? Comments?

I also have a working and tested diff for `machine fb [n]' analog to
`machine video [n]' that enables listing/and setting the GOP mode just
like FreeBSD does it with `gop list | get | set <mode>'. I'd also like to
get this in together with some other minor clean ups in case this is
the way to go.

Testers, especially with broken implemenations like the X121e are
greatly appreciated.

Index: efiboot.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.c,v
retrieving revision 1.23
diff -u -p -r1.23 efiboot.c
--- efiboot.c   7 Aug 2017 19:34:53 -0000       1.23
+++ efiboot.c   5 Sep 2017 00:29:02 -0000
@@ -702,13 +702,12 @@ static EFI_GUID smbios_guid = SMBIOS_TAB
 void
 efi_makebootargs(void)
 {
-       int                      i;
        EFI_STATUS               status;
        EFI_GRAPHICS_OUTPUT     *gop;
        EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
                                *gopi;
        bios_efiinfo_t           ei;
-       int                      bestmode = -1;
+       int                      i, curmode, bestmode = -1;
        UINTN                    sz, gopsiz, bestsiz = 0;
        EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
                                *info;
@@ -746,9 +745,12 @@ efi_makebootargs(void)
                        }
                }
                if (bestmode >= 0) {
+                       curmode = gop->Mode->Mode;
                        status = EFI_CALL(gop->SetMode, gop, bestmode);
-                       if (EFI_ERROR(status) && gop->Mode->Mode != bestmode)
+                       if (EFI_ERROR(status) || gop->Mode->Mode != bestmode) {
                                printf("GOP setmode failed(%d)\n", status);
+                               EFI_CALL(gop->SetMode, gop, curmode);
+                       }
                }
 
                gopi = gop->Mode->Info;

Reply via email to