Module Name:    src
Committed By:   jmcneill
Date:           Wed Jul 24 11:40:37 UTC 2019

Modified Files:
        src/sys/stand/efiboot: efifdt.c efifdt.h exec.c version

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


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/sys/stand/efiboot/efifdt.c
cvs rdiff -u -r1.5 -r1.6 src/sys/stand/efiboot/efifdt.h
cvs rdiff -u -r1.10 -r1.11 src/sys/stand/efiboot/exec.c \
    src/sys/stand/efiboot/version

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/stand/efiboot/efifdt.c
diff -u src/sys/stand/efiboot/efifdt.c:1.15 src/sys/stand/efiboot/efifdt.c:1.16
--- src/sys/stand/efiboot/efifdt.c:1.15	Sun Apr 21 22:30:41 2019
+++ src/sys/stand/efiboot/efifdt.c	Wed Jul 24 11:40:36 2019
@@ -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_fdt_memory_map(void)
 	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 @@ efi_fdt_memory_map(void)
 	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 @@ efi_fdt_memory_map(void)
 	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 @@ efi_fdt_memory_map(void)
 }
 
 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 @@ efi_fdt_bootargs(const char *bootargs)
 	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);
 

Index: src/sys/stand/efiboot/efifdt.h
diff -u src/sys/stand/efiboot/efifdt.h:1.5 src/sys/stand/efiboot/efifdt.h:1.6
--- src/sys/stand/efiboot/efifdt.h:1.5	Sun Apr 21 22:30:41 2019
+++ src/sys/stand/efiboot/efifdt.h	Wed Jul 24 11:40:36 2019
@@ -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 <jmcne...@invisible.ca>
@@ -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);

Index: src/sys/stand/efiboot/exec.c
diff -u src/sys/stand/efiboot/exec.c:1.10 src/sys/stand/efiboot/exec.c:1.11
--- src/sys/stand/efiboot/exec.c:1.10	Sun Apr 21 22:30:41 2019
+++ src/sys/stand/efiboot/exec.c	Wed Jul 24 11:40:36 2019
@@ -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 @@ exec_netbsd(const char *fname, const cha
 		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();
 	}
 
Index: src/sys/stand/efiboot/version
diff -u src/sys/stand/efiboot/version:1.10 src/sys/stand/efiboot/version:1.11
--- src/sys/stand/efiboot/version:1.10	Sun Apr 21 22:30:41 2019
+++ src/sys/stand/efiboot/version	Wed Jul 24 11:40:36 2019
@@ -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 @@ is taken as the current.
 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.

Reply via email to