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
2) Pass a flag from efiboot. A diff for this is attached.
> 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;