This patch allows the OpenBSD bootloader to recognize the framebuffer initialized by U-Boot and hand it over to the kernel. You also need to put "set tty fb0" into /etc/boot.conf for the kernel to actually select the framebuffer device to be used as the console. Many thanks and all credits to Tomasz Bielecki for sharing this patch with me, which I am publishing (with his permission) unchanged. Index: sys/arch/arm64/stand/efiboot/efiboot.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/efiboot.c,v retrieving revision 1.38 diff -u -p -r1.38 efiboot.c --- sys/arch/arm64/stand/efiboot/efiboot.c 15 Dec 2021 00:37:21 -0000 1.38 +++ sys/arch/arm64/stand/efiboot/efiboot.c 18 Feb 2022 20:25:43 -0000 @@ -43,6 +43,16 @@ #include "efiboot.h" #include "fdt.h" +struct efi_fb_format { + char* name; + uint32_t bytes_per_pixel; + EFI_PIXEL_BITMASK pixel_bitmask; +}; + +struct efi_fb_format efi_fb_formats[] = { + { "r5g6b5", 2, { 0x1f << 11, 0x3f << 5, 0x1f, 0 } }, +}; + EFI_SYSTEM_TABLE *ST; EFI_BOOT_SERVICES *BS; EFI_RUNTIME_SERVICES *RS; @@ -351,13 +361,16 @@ efi_framebuffer(void) { EFI_GRAPHICS_OUTPUT *gop; EFI_STATUS status; + EFI_PIXEL_BITMASK tmp_mask; void *node, *child; uint32_t acells, scells; uint64_t base, size; uint32_t reg[4]; + uint32_t bytes_per_pixel; uint32_t width, height, stride; char *format; char *prop; + int i; /* * Don't create a "simple-framebuffer" node if we already have @@ -401,13 +414,31 @@ efi_framebuffer(void) if (gop == NULL || gop->Mode == NULL || gop->Mode->Info == NULL) return; - /* We only support 32-bit pixel modes for now. */ switch (gop->Mode->Info->PixelFormat) { case PixelRedGreenBlueReserved8BitPerColor: format = "x8b8g8r8"; + bytes_per_pixel = 4; break; case PixelBlueGreenRedReserved8BitPerColor: format = "x8r8g8b8"; + bytes_per_pixel = 4; + break; + case PixelBitMask: + format = NULL; + tmp_mask = gop->Mode->Info->PixelInformation; + for (i = 0; i < nitems(efi_fb_formats); i++) { + if (tmp_mask.RedMask == efi_fb_formats[i].pixel_bitmask.RedMask && + tmp_mask.GreenMask == efi_fb_formats[i].pixel_bitmask.GreenMask && + tmp_mask.BlueMask == efi_fb_formats[i].pixel_bitmask.BlueMask && + tmp_mask.ReservedMask == efi_fb_formats[i].pixel_bitmask.ReservedMask) + { + format = efi_fb_formats[i].name; + bytes_per_pixel = efi_fb_formats[i].bytes_per_pixel; + break; + } + } + if (format == NULL) + return; break; default: return; @@ -417,7 +448,7 @@ efi_framebuffer(void) size = gop->Mode->FrameBufferSize; width = htobe32(gop->Mode->Info->HorizontalResolution); height = htobe32(gop->Mode->Info->VerticalResolution); - stride = htobe32(gop->Mode->Info->PixelsPerScanLine * 4); + stride = htobe32(gop->Mode->Info->PixelsPerScanLine * bytes_per_pixel); node = fdt_find_node("/"); if (fdt_node_property_int(node, "#address-cells", &acells) != 1)