Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/stand/efiboot Add support for simple framebuffers when b...



details:   https://anonhg.NetBSD.org/src/rev/6b617839031b
branches:  trunk
changeset: 457908:6b617839031b
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Wed Jul 24 11:40:36 2019 +0000

description:
Add support for simple framebuffers when booting in ACPI mode.

diffstat:

 sys/stand/efiboot/efifdt.c |  84 ++++++++++++++++++++++++++++++++++++++++++++-
 sys/stand/efiboot/efifdt.h |   3 +-
 sys/stand/efiboot/exec.c   |   6 ++-
 sys/stand/efiboot/version  |   3 +-
 4 files changed, 91 insertions(+), 5 deletions(-)

diffs (177 lines):

diff -r 9a9a36fc61bb -r 6b617839031b sys/stand/efiboot/efifdt.c
--- a/sys/stand/efiboot/efifdt.c        Wed Jul 24 11:34:55 2019 +0000
+++ b/sys/stand/efiboot/efifdt.c        Wed Jul 24 11:40:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.c,v 1.15 2019/04/21 22:30:41 thorpej Exp $ */
+/* $NetBSD: efifdt.c,v 1.16 2019/07/24 11:40:36 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 Jason R. Thorpe
@@ -185,7 +185,7 @@
        EFI_MEMORY_DESCRIPTOR *md, *memmap;
        UINT32 descver;
        UINT64 phys_start, phys_size;
-       int n, memory;
+       int n, memory, chosen;
 
        memory = fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH);
        if (memory < 0)
@@ -193,6 +193,12 @@
        if (memory < 0)
                panic("FDT: Failed to create " FDT_MEMORY_NODE_PATH " node");
 
+       chosen = fdt_path_offset(fdt_data, FDT_CHOSEN_NODE_PATH);
+       if (chosen < 0)
+               chosen = fdt_add_subnode(fdt_data, fdt_path_offset(fdt_data, "/"), FDT_CHOSEN_NODE_NAME);
+       if (chosen < 0)
+               panic("FDT: Failed to create " FDT_CHOSEN_NODE_PATH " node");
+
        fdt_delprop(fdt_data, memory, "reg");
 
        const int address_cells = fdt_address_cells(fdt_data, fdt_path_offset(fdt_data, "/"));
@@ -202,6 +208,12 @@
        for (n = 0, md = memmap; n < nentries; n++, md = NextMemoryDescriptor(md, descsize)) {
                if ((md->Attribute & EFI_MEMORY_RUNTIME) != 0)
                        continue;
+
+               fdt_appendprop_u32(fdt_data, chosen, "netbsd,uefi-memory-map", md->Type);
+               fdt_appendprop_u64(fdt_data, chosen, "netbsd,uefi-memory-map", md->PhysicalStart);
+               fdt_appendprop_u64(fdt_data, chosen, "netbsd,uefi-memory-map", md->NumberOfPages);
+               fdt_appendprop_u64(fdt_data, chosen, "netbsd,uefi-memory-map", md->Attribute);
+
                if ((md->Attribute & EFI_MEMORY_WB) == 0)
                        continue;
                if (!FDT_MEMORY_USABLE(md))
@@ -239,6 +251,70 @@
 }
 
 void
+efi_fdt_gop(void)
+{
+       EFI_STATUS status;
+       EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
+       EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *mode;
+       EFI_HANDLE *gop_handle;
+       UINTN ngop_handle, n;
+       char buf[48];
+       int fb;
+
+       status = LibLocateHandle(ByProtocol, &GraphicsOutputProtocol, NULL, &ngop_handle, &gop_handle);
+       if (EFI_ERROR(status) || ngop_handle == 0)
+               return;
+
+       for (n = 0; n < ngop_handle; n++) {
+               status = uefi_call_wrapper(BS->HandleProtocol, 3, gop_handle[n], &GraphicsOutputProtocol, (void **)&gop);
+               if (EFI_ERROR(status))
+                       continue;
+
+               mode = gop->Mode;
+               if (mode == NULL)
+                       continue;
+
+#ifdef EFIBOOT_DEBUG
+               printf("GOP: FB @ 0x%lx size 0x%lx\n", mode->FrameBufferBase, mode->FrameBufferSize);
+               printf("GOP: Version %d\n", mode->Info->Version);
+               printf("GOP: HRes %d VRes %d\n", mode->Info->HorizontalResolution, mode->Info->VerticalResolution);
+               printf("GOP: PixelFormat %d\n", mode->Info->PixelFormat);
+               printf("GOP: PixelBitmask R 0x%x G 0x%x B 0x%x Res 0x%x\n",
+                   mode->Info->PixelInformation.RedMask,
+                   mode->Info->PixelInformation.GreenMask,
+                   mode->Info->PixelInformation.BlueMask,
+                   mode->Info->PixelInformation.ReservedMask);
+               printf("GOP: Pixels per scanline %d\n", mode->Info->PixelsPerScanLine);
+#endif
+
+               if (mode->Info->PixelFormat == PixelBltOnly) {
+                       printf("GOP: PixelBltOnly pixel format not supported\n");
+                       continue;
+               }
+
+               snprintf(buf, sizeof(buf), "framebuffer@%lx", mode->FrameBufferBase);
+               fb = fdt_add_subnode(fdt_data, fdt_path_offset(fdt_data, "/chosen"), buf);
+               if (fb < 0)
+                       panic("FDT: Failed to create framebuffer node");
+
+               fdt_appendprop_string(fdt_data, fb, "compatible", "simple-framebuffer");
+               fdt_appendprop_string(fdt_data, fb, "status", "okay");
+               fdt_appendprop_u64(fdt_data, fb, "reg", mode->FrameBufferBase);
+               fdt_appendprop_u64(fdt_data, fb, "reg", mode->FrameBufferSize);
+               fdt_appendprop_u32(fdt_data, fb, "width", mode->Info->HorizontalResolution);
+               fdt_appendprop_u32(fdt_data, fb, "height", mode->Info->VerticalResolution);
+               fdt_appendprop_u32(fdt_data, fb, "stride", mode->Info->PixelsPerScanLine * 4);  /* XXX */
+               fdt_appendprop_string(fdt_data, fb, "format", "a8b8g8r8");
+
+               snprintf(buf, sizeof(buf), "/chosen/framebuffer@%lx", mode->FrameBufferBase);
+               fdt_setprop_string(fdt_data, fdt_path_offset(fdt_data, FDT_CHOSEN_NODE_PATH),
+                   "stdout-path", buf);
+
+               return;
+       }
+}
+
+void
 efi_fdt_bootargs(const char *bootargs)
 {
        struct efi_block_part *bpart = efi_block_boot_part();
@@ -251,6 +327,10 @@
        if (chosen < 0)
                panic("FDT: Failed to create " FDT_CHOSEN_NODE_PATH " node");
 
+       fdt_setprop_u32(fdt_data, chosen, "#address-cells", 2);
+       fdt_setprop_u32(fdt_data, chosen, "#size-cells", 2);
+       fdt_setprop_empty(fdt_data, chosen, "ranges");
+
        if (*bootargs)
                fdt_setprop_string(fdt_data, chosen, "bootargs", bootargs);
 
diff -r 9a9a36fc61bb -r 6b617839031b sys/stand/efiboot/efifdt.h
--- a/sys/stand/efiboot/efifdt.h        Wed Jul 24 11:34:55 2019 +0000
+++ b/sys/stand/efiboot/efifdt.h        Wed Jul 24 11:40:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.h,v 1.5 2019/04/21 22:30:41 thorpej Exp $ */
+/* $NetBSD: efifdt.h,v 1.6 2019/07/24 11:40:36 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -28,6 +28,7 @@
 
 int efi_fdt_probe(void);
 void efi_fdt_memory_map(void);
+void efi_fdt_gop(void);
 int efi_fdt_set_data(void *);
 void *efi_fdt_data(void);
 int efi_fdt_size(void);
diff -r 9a9a36fc61bb -r 6b617839031b sys/stand/efiboot/exec.c
--- a/sys/stand/efiboot/exec.c  Wed Jul 24 11:34:55 2019 +0000
+++ b/sys/stand/efiboot/exec.c  Wed Jul 24 11:40:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.c,v 1.10 2019/04/21 22:30:41 thorpej Exp $ */
+/* $NetBSD: exec.c,v 1.11 2019/07/24 11:40:36 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 Jason R. Thorpe
@@ -330,6 +330,10 @@
                load_fdt_overlays();
                efi_fdt_initrd(initrd_addr, initrd_size);
                efi_fdt_bootargs(args);
+#ifdef EFIBOOT_ACPI
+               if (efi_acpi_available())
+                       efi_fdt_gop();
+#endif
                efi_fdt_memory_map();
        }
 
diff -r 9a9a36fc61bb -r 6b617839031b sys/stand/efiboot/version
--- a/sys/stand/efiboot/version Wed Jul 24 11:34:55 2019 +0000
+++ b/sys/stand/efiboot/version Wed Jul 24 11:40:36 2019 +0000
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.10 2019/04/21 22:30:41 thorpej Exp $
+$NetBSD: version,v 1.11 2019/07/24 11:40:36 jmcneill Exp $
 
 NOTE ANY CHANGES YOU MAKE TO THE EFI BOOTLOADER HERE.  The format of this
 file is important - make sure the entries are appended on end, last item
@@ -14,3 +14,4 @@
 1.7:   Add NFS support.
 1.8:   Add support for "bootargs" environment variable.
 1.9:   Add support for efiboot.plist and loading device tree overlays.
+1.10:  Add support for EFI GOP framebuffers in ACPI mode.



Home | Main Index | Thread Index | Old Index