[U-Boot,v2,09/13] efi: stub: Pass EFI GOP information to U-Boot payload

Message ID 1528817785-20208-10-git-send-email-bmeng.cn@gmail.com
State Accepted
Delegated to: Bin Meng
Headers show
Series
  • x86: efi: Fixes and enhancements to application and payload support
Related show

Commit Message

Bin Meng June 12, 2018, 3:36 p.m.
If UEFI BIOS has the graphics output protocol (GOP), let's pass its
information to U-Boot payload so that U-Boot can utilize it (eg:
an EFI framebuffer driver).

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 include/efi.h      | 35 +++++++++++++++++++++++++++++++++++
 lib/efi/efi_stub.c | 15 +++++++++++++++
 2 files changed, 50 insertions(+)

Comments

Bin Meng June 17, 2018, 1:18 p.m. | #1
On Tue, Jun 12, 2018 at 11:36 PM, Bin Meng <bmeng.cn@gmail.com> wrote:
> If UEFI BIOS has the graphics output protocol (GOP), let's pass its
> information to U-Boot payload so that U-Boot can utilize it (eg:
> an EFI framebuffer driver).
>
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  include/efi.h      | 35 +++++++++++++++++++++++++++++++++++
>  lib/efi/efi_stub.c | 15 +++++++++++++++
>  2 files changed, 50 insertions(+)
>

applied to u-boot-x86, thanks!

Patch

diff --git a/include/efi.h b/include/efi.h
index 5e1e8ac..639ace0 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -233,6 +233,7 @@  struct efi_open_protocol_info_entry {
 enum efi_entry_t {
 	EFIET_END,	/* Signals this is the last (empty) entry */
 	EFIET_MEMORY_MAP,
+	EFIET_GOP_MODE,
 
 	/* Number of entries */
 	EFIET_MEMORY_COUNT,
@@ -289,6 +290,40 @@  struct efi_entry_memmap {
 	struct efi_mem_desc desc[];
 };
 
+/**
+ * struct efi_entry_gopmode - a GOP mode table passed to U-Boot
+ *
+ * @fb_base:	EFI's framebuffer base address
+ * @fb_size:	EFI's framebuffer size
+ * @info_size:	GOP mode info structure size
+ * @info:	Start address of the GOP mode info structure
+ */
+struct efi_entry_gopmode {
+	efi_physical_addr_t fb_base;
+	/*
+	 * Not like the ones in 'struct efi_gop_mode' which are 'unsigned
+	 * long', @fb_size and @info_size have to be 'u64' here. As the EFI
+	 * stub codes may have different bit size from the U-Boot payload,
+	 * using 'long' will cause mismatch between the producer (stub) and
+	 * the consumer (payload).
+	 */
+	u64 fb_size;
+	u64 info_size;
+	/*
+	 * We cannot directly use 'struct efi_gop_mode_info info[]' here as
+	 * it causes compiler to complain: array type has incomplete element
+	 * type 'struct efi_gop_mode_info'.
+	 */
+	struct /* efi_gop_mode_info */ {
+		u32 version;
+		u32 width;
+		u32 height;
+		u32 pixel_format;
+		u32 pixel_bitmask[4];
+		u32 pixels_per_scanline;
+	} info[];
+};
+
 static inline struct efi_mem_desc *efi_get_next_mem_desc(
 		struct efi_entry_memmap *map, struct efi_mem_desc *desc)
 {
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
index 09023a2..4819373 100644
--- a/lib/efi/efi_stub.c
+++ b/lib/efi/efi_stub.c
@@ -274,6 +274,9 @@  efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
 	struct efi_boot_services *boot = sys_table->boottime;
 	struct efi_mem_desc *desc;
 	struct efi_entry_memmap map;
+	struct efi_gop *gop;
+	struct efi_entry_gopmode mode;
+	efi_guid_t efi_gop_guid = EFI_GOP_GUID;
 	efi_uintn_t key, desc_size, size;
 	efi_status_t ret;
 	u32 version;
@@ -312,6 +315,18 @@  efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
 	if (ret)
 		return ret;
 
+	ret = boot->locate_protocol(&efi_gop_guid, NULL, (void **)&gop);
+	if (ret) {
+		puts(" GOP unavailable\n");
+	} else {
+		mode.fb_base = gop->mode->fb_base;
+		mode.fb_size = gop->mode->fb_size;
+		mode.info_size = gop->mode->info_size;
+		add_entry_addr(priv, EFIET_GOP_MODE, &mode, sizeof(mode),
+			       gop->mode->info,
+			       sizeof(struct efi_gop_mode_info));
+	}
+
 	ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version);
 	if (ret) {
 		printhex2(ret);