> Date: Sun, 23 Feb 2020 18:50:54 +0900 (JST)
> From: YASUOKA Masahiko <[email protected]>
>
> On Sat, 22 Feb 2020 13:02:48 +1100
> Jonathan Gray <[email protected]> wrote:
> > On Fri, Feb 21, 2020 at 02:09:07PM +0900, YASUOKA Masahiko wrote:
> >> When efiboot starts the kernel, the video display becomes distorted
> >> and never recovered until CPU reset.
> >>
> >> Our kernel tries to initialized console twice, first trial is done
> >> before getting boot info and second trial is done after getting boot
> >> info. Since EFI framebuffer needs "boot info", it is initialized on
> >> second trial.
> >>
> >> On HPE DL20 Gen10, probing vga is succeeded on first trial, the kernel
> >> selects vga for the console, but actually it is broken. On usual
> >> machines which boot with EFI, the problem doesn't happen since they
> >> have no vga.
> >>
> >> The diff following fixes the problem by initializing efifb console
> >> even if the VGA is probed.
> >>
> >> # Also, HP DL20 Gen10 has "UEFI optimized boot" setting on BIOS and
> >> # disabling the setting avoids the problem happening. But since the
> >> # setting seems to be for old Windows, I think we should fix our
> >> # kernel.
> >>
> >> comment? ok?
> >
> > Is there a way to detect efi or bios before boot info is set?
> > Ideally vga_cnattach() would never be called when booting via efi.
>
> Yes. I've tried to find such the way, I found 2 ways.
>
> 1) ACPI has FADT_NO_VGA flag which indicate the system has VGA, but
> reading ACPI table at early of kernel boot is not good and difficult
Reading it in efiboot would be fairly simple though.
> 2) Pass a flag from efiboot. A diff for this is attached.
So the EFI bootloader could pass a BAPIV_NOVGA fairly trivially. In
that case we probably should add the check for the flag in
wscn_video_init().
> > Should the cninit() before the boot args are parsed be removed and just
> > have cninit() unconditionally after? This would make the debug printfs
> > in boot arg passing useless, but they already wouldn't work when booting
> > via efi.
>
> I think this is a straight way and no downside for efi. For a system
> booting via BIOS, there is a downside that panic or debug string isn't
> shown at very early part of kernel boot.
>
> * * *
>
> Index: sys/arch/amd64/stand/efiboot/exec_i386.c
> ===================================================================
> RCS file: /disk/cvs/openbsd/src/sys/arch/amd64/stand/efiboot/exec_i386.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 exec_i386.c
> --- sys/arch/amd64/stand/efiboot/exec_i386.c 12 Dec 2019 13:09:35 -0000
> 1.3
> +++ sys/arch/amd64/stand/efiboot/exec_i386.c 23 Feb 2020 09:49:48 -0000
> @@ -163,11 +163,11 @@ run_loadfile(uint64_t *marks, int howto)
> marks[i] += delta;
>
> #ifdef __amd64__
> - (*run_i386)((u_long)run_i386, entry, howto, bootdev, BOOTARG_APIVER,
> + (*run_i386)((u_long)run_i386, entry, howto, bootdev, BOOTARG_APIVER |
> BAPIV_EFI,
> marks[MARK_END], extmem, cnvmem, ac, (intptr_t)av);
> #else
> /* stack and the gung is ok at this point, so, no need for asm setup */
> - (*(startfuncp)entry)(howto, bootdev, BOOTARG_APIVER, marks[MARK_END],
> + (*(startfuncp)entry)(howto, bootdev, BOOTARG_APIVER | BAPIV_EFI,
> marks[MARK_END],
> extmem, cnvmem, ac, (int)av);
> #endif
> /* not reached */
> Index: sys/arch/amd64/amd64/machdep.c
> ===================================================================
> RCS file: /disk/cvs/openbsd/src/sys/arch/amd64/amd64/machdep.c,v
> retrieving revision 1.261
> diff -u -p -r1.261 machdep.c
> --- sys/arch/amd64/amd64/machdep.c 24 Jan 2020 05:27:31 -0000 1.261
> +++ sys/arch/amd64/amd64/machdep.c 23 Feb 2020 09:50:02 -0000
> @@ -1396,7 +1396,8 @@ init_x86_64(paddr_t first_avail)
> /*
> * Attach the glass console early in case we need to display a panic.
> */
> - cninit();
> + if (!ISSET(bootapiver, BAPIV_EFI))
> + cninit();
>
> /*
> * Initialize PAGE_SIZE-dependent variables.
> @@ -1420,6 +1421,9 @@ init_x86_64(paddr_t first_avail)
> } else
> panic("invalid /boot");
>
> + /* EFI: bootinfo is required to initialize efifb */
> + if (ISSET(bootapiver, BAPIV_EFI))
> + cninit();
> /*
> * Memory on the AMD64 port is described by three different things.
> *
> Index: sys/stand/boot/bootarg.h
> ===================================================================
> RCS file: /disk/cvs/openbsd/src/sys/stand/boot/bootarg.h,v
> retrieving revision 1.15
> diff -u -p -r1.15 bootarg.h
> --- sys/stand/boot/bootarg.h 8 Apr 2018 13:24:36 -0000 1.15
> +++ sys/stand/boot/bootarg.h 23 Feb 2020 09:50:02 -0000
> @@ -32,6 +32,7 @@
> #define BAPIV_VECTOR 0x00000002 /* MI vector of MD structures
> passed */
> #define BAPIV_ENV 0x00000004 /* MI environment vars vector */
> #define BAPIV_BMEMMAP 0x00000008 /* MI memory map passed is in
> bytes */
> +#define BAPIV_EFI 0x00000010 /* MI booted from EFI */
>
> typedef struct _boot_args {
> int ba_type;
>
>
>