> Date: Thu, 16 Jun 2022 23:49:05 +0900 (JST)
> From: YASUOKA Masahiko <[email protected]>
>
> On Thu, 16 Jun 2022 15:52:41 +0300
> Nick Henderson <[email protected]> wrote:
> > Any updates on this patch? Would love to see it included in the next
> > release.
>
> Yes.
>
> I'll commit this this weekend even if I don't get no ok.
>
> ok?
Sorry. I forgot about this diff.
> Index: sys/arch/amd64/stand/efiboot/efiboot.c
> ===================================================================
> RCS file: /disk/cvs/openbsd/src/sys/arch/amd64/stand/efiboot/efiboot.c,v
> retrieving revision 1.38
> diff -u -p -r1.38 efiboot.c
> --- sys/arch/amd64/stand/efiboot/efiboot.c 7 Jun 2021 00:04:20 -0000
> 1.38
> +++ sys/arch/amd64/stand/efiboot/efiboot.c 2 May 2022 07:53:38 -0000
> @@ -424,8 +424,9 @@ efi_memprobe_internal(void)
> /***********************************************************************
> * Console
> ***********************************************************************/
> -static SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
> -static SIMPLE_INPUT_INTERFACE *conin;
> +static SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
> +static SIMPLE_INPUT_INTERFACE *conin;
> +static EFI_GRAPHICS_OUTPUT *gop = NULL;
> static EFI_GUID con_guid
> = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
> static EFI_GUID gop_guid
> @@ -444,6 +445,30 @@ efi_video_init(void)
> int i, mode80x25, mode100x31;
> UINTN cols, rows;
> EFI_STATUS status;
> + EFI_HANDLE *handles;
> + UINTN nhandles;
> + EFI_GRAPHICS_OUTPUT *first_gop = NULL;
> + EFI_DEVICE_PATH *devp_test = NULL;
> +
> + status = BS->LocateHandleBuffer(ByProtocol, &gop_guid, NULL, &nhandles,
> + &handles);
> + if (status != EFI_SUCCESS)
> + panic("BS->LocateHandleBuffer() returns %d", status);
What about headless machines? I suspect that most x86 machines
without a GPU of some sorts will still provide a framebuffer of some
sorts in their UEFI implementations. But maybe some machines don't?
If there are no GOP protocol handles, LocateHandleBuffer() seems to
return EFI_NOT_FOUND, which would result in a panic, which wouldn't be
very helpful.
> + for (i = 0; i < nhandles; i++) {
> + status = BS->HandleProtocol(handles[i], &gop_guid,
> + (void **)&gop);
> + if (first_gop == NULL)
> + first_gop = gop;
> + status = BS->HandleProtocol(handles[i], &devp_guid,
> + (void **)&devp_test);
> + if (status == EFI_SUCCESS)
> + break;
> + }
> + if (status != EFI_SUCCESS)
> + gop = first_gop;
> + if (gop == NULL)
> + panic("no gop found");
> + BS->FreePool(handles);
>
> conout = ST->ConOut;
> status = BS->LocateProtocol(&con_guid, NULL, (void **)&conctrl);
> @@ -808,7 +833,6 @@ efi_com_putc(dev_t dev, int c)
> */
> static EFI_GUID acpi_guid = ACPI_20_TABLE_GUID;
> static EFI_GUID smbios_guid = SMBIOS_TABLE_GUID;
> -static EFI_GRAPHICS_OUTPUT *gop;
> static int gopmode = -1;
>
> #define efi_guidcmp(_a, _b) memcmp((_a), (_b), sizeof(EFI_GUID))
> @@ -853,57 +877,54 @@ efi_makebootargs(void)
> /*
> * Frame buffer
> */
> - status = BS->LocateProtocol(&gop_guid, NULL, (void **)&gop);
> - if (!EFI_ERROR(status)) {
> - if (gopmode < 0) {
> - for (i = 0; i < gop->Mode->MaxMode; i++) {
> - status = gop->QueryMode(gop, i, &sz, &gopi);
> - if (EFI_ERROR(status))
> - continue;
> - gopsiz = gopi->HorizontalResolution *
> - gopi->VerticalResolution;
> - if (gopsiz > bestsiz) {
> - gopmode = i;
> - bestsiz = gopsiz;
> - }
> + if (gopmode < 0) {
> + for (i = 0; i < gop->Mode->MaxMode; i++) {
> + status = gop->QueryMode(gop, i, &sz, &gopi);
> + if (EFI_ERROR(status))
> + continue;
> + gopsiz = gopi->HorizontalResolution *
> + gopi->VerticalResolution;
> + if (gopsiz > bestsiz) {
> + gopmode = i;
> + bestsiz = gopsiz;
> }
> }
> - if (gopmode >= 0 && gopmode != gop->Mode->Mode) {
> - curmode = gop->Mode->Mode;
> - if (efi_gop_setmode(gopmode) != EFI_SUCCESS)
> - (void)efi_gop_setmode(curmode);
> - }
> -
> - gopi = gop->Mode->Info;
> - switch (gopi->PixelFormat) {
> - case PixelBlueGreenRedReserved8BitPerColor:
> - ei->fb_red_mask = 0x00ff0000;
> - ei->fb_green_mask = 0x0000ff00;
> - ei->fb_blue_mask = 0x000000ff;
> - ei->fb_reserved_mask = 0xff000000;
> - break;
> - case PixelRedGreenBlueReserved8BitPerColor:
> - ei->fb_red_mask = 0x000000ff;
> - ei->fb_green_mask = 0x0000ff00;
> - ei->fb_blue_mask = 0x00ff0000;
> - ei->fb_reserved_mask = 0xff000000;
> - break;
> - case PixelBitMask:
> - ei->fb_red_mask = gopi->PixelInformation.RedMask;
> - ei->fb_green_mask = gopi->PixelInformation.GreenMask;
> - ei->fb_blue_mask = gopi->PixelInformation.BlueMask;
> - ei->fb_reserved_mask =
> - gopi->PixelInformation.ReservedMask;
> - break;
> - default:
> - break;
> - }
> - ei->fb_addr = gop->Mode->FrameBufferBase;
> - ei->fb_size = gop->Mode->FrameBufferSize;
> - ei->fb_height = gopi->VerticalResolution;
> - ei->fb_width = gopi->HorizontalResolution;
> - ei->fb_pixpsl = gopi->PixelsPerScanLine;
> }
> + if (gopmode >= 0 && gopmode != gop->Mode->Mode) {
> + curmode = gop->Mode->Mode;
> + if (efi_gop_setmode(gopmode) != EFI_SUCCESS)
> + (void)efi_gop_setmode(curmode);
> + }
> +
> + gopi = gop->Mode->Info;
> + switch (gopi->PixelFormat) {
> + case PixelBlueGreenRedReserved8BitPerColor:
> + ei->fb_red_mask = 0x00ff0000;
> + ei->fb_green_mask = 0x0000ff00;
> + ei->fb_blue_mask = 0x000000ff;
> + ei->fb_reserved_mask = 0xff000000;
> + break;
> + case PixelRedGreenBlueReserved8BitPerColor:
> + ei->fb_red_mask = 0x000000ff;
> + ei->fb_green_mask = 0x0000ff00;
> + ei->fb_blue_mask = 0x00ff0000;
> + ei->fb_reserved_mask = 0xff000000;
> + break;
> + case PixelBitMask:
> + ei->fb_red_mask = gopi->PixelInformation.RedMask;
> + ei->fb_green_mask = gopi->PixelInformation.GreenMask;
> + ei->fb_blue_mask = gopi->PixelInformation.BlueMask;
> + ei->fb_reserved_mask =
> + gopi->PixelInformation.ReservedMask;
> + break;
> + default:
> + break;
> + }
> + ei->fb_addr = gop->Mode->FrameBufferBase;
> + ei->fb_size = gop->Mode->FrameBufferSize;
> + ei->fb_height = gopi->VerticalResolution;
> + ei->fb_width = gopi->HorizontalResolution;
> + ei->fb_pixpsl = gopi->PixelsPerScanLine;
>
> /*
> * EFI system table
> @@ -1029,10 +1050,6 @@ Xgop_efi(void)
> UINTN sz;
> EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
> *gopi;
> -
> - status = BS->LocateProtocol(&gop_guid, NULL, (void **)&gop);
> - if (EFI_ERROR(status))
> - return (0);
>
> if (cmd.argc >= 2) {
> mode = strtol(cmd.argv[1], NULL, 10);
>
>