Replace struct screen_info with struct sysfb_display_info from the kernel's sysfb_primary_display and rename functions accordingly. Transfer the it to the runtime kernel using the kernel's global state or the config-table entry LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID.
Also rename screen_info.c to primary_display.c and adapt the contained comment according to the changes. With CONFIG_FIRMWARE_EDID=y, libstub now transfers the GOP device's EDID information to the kernel. Signed-off-by: Thomas Zimmermann <[email protected]> --- drivers/firmware/efi/libstub/Makefile | 2 +- drivers/firmware/efi/libstub/efi-stub-entry.c | 11 ++-- drivers/firmware/efi/libstub/efi-stub.c | 41 +++++++++----- drivers/firmware/efi/libstub/efistub.h | 7 ++- .../firmware/efi/libstub/primary_display.c | 56 +++++++++++++++++++ drivers/firmware/efi/libstub/screen_info.c | 53 ------------------ drivers/firmware/efi/libstub/zboot.c | 4 +- 7 files changed, 93 insertions(+), 81 deletions(-) create mode 100644 drivers/firmware/efi/libstub/primary_display.c delete mode 100644 drivers/firmware/efi/libstub/screen_info.c diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 7d15a85d579f..e386ffd009b7 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -80,7 +80,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE $(call if_changed_rule,cc_o_c) lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \ - screen_info.o efi-stub-entry.o + primary_display.o efi-stub-entry.o lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c index 401ecbbdf331..aa85e910fe59 100644 --- a/drivers/firmware/efi/libstub/efi-stub-entry.c +++ b/drivers/firmware/efi/libstub/efi-stub-entry.c @@ -14,18 +14,15 @@ static void *kernel_image_addr(void *addr) return addr + kernel_image_offset; } -struct screen_info *alloc_screen_info(void) +struct sysfb_display_info *alloc_primary_display(void) { if (IS_ENABLED(CONFIG_ARM)) - return __alloc_screen_info(); + return __alloc_primary_display(); if (IS_ENABLED(CONFIG_X86) || IS_ENABLED(CONFIG_EFI_EARLYCON) || - IS_ENABLED(CONFIG_SYSFB)) { - struct sysfb_display_info *dpy = kernel_image_addr(&sysfb_primary_display); - - return &dpy->screen; - } + IS_ENABLED(CONFIG_SYSFB)) + return kernel_image_addr(&sysfb_primary_display); return NULL; } diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index 9cb814c5ba1b..42d6073bcd06 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -10,7 +10,7 @@ */ #include <linux/efi.h> -#include <linux/screen_info.h> +#include <linux/sysfb.h> #include <asm/efi.h> #include "efistub.h" @@ -48,23 +48,33 @@ static u64 virtmap_base = EFI_RT_VIRTUAL_BASE; static bool flat_va_mapping = (EFI_RT_VIRTUAL_OFFSET != 0); -void __weak free_screen_info(struct screen_info *si) -{ -} +void __weak free_primary_display(struct sysfb_display_info *dpy) +{ } -static struct screen_info *setup_graphics(void) +static struct sysfb_display_info *setup_primary_display(void) { - struct screen_info *si, tmp = {}; + struct sysfb_display_info *dpy; + struct screen_info *screen = NULL; + struct edid_info *edid = NULL; + efi_status_t status; - if (efi_setup_graphics(&tmp, NULL) != EFI_SUCCESS) + dpy = alloc_primary_display(); + if (!dpy) return NULL; + screen = &dpy->screen; +#if defined(CONFIG_FIRMWARE_EDID) + edid = &dpy->edid; +#endif - si = alloc_screen_info(); - if (!si) - return NULL; + status = efi_setup_graphics(screen, edid); + if (status != EFI_SUCCESS) + goto err_free_primary_display; - *si = tmp; - return si; + return dpy; + +err_free_primary_display: + free_primary_display(dpy); + return NULL; } static void install_memreserve_table(void) @@ -145,14 +155,14 @@ efi_status_t efi_stub_common(efi_handle_t handle, unsigned long image_addr, char *cmdline_ptr) { - struct screen_info *si; + struct sysfb_display_info *dpy; efi_status_t status; status = check_platform_features(); if (status != EFI_SUCCESS) return status; - si = setup_graphics(); + dpy = setup_primary_display(); efi_retrieve_eventlog(); @@ -172,7 +182,8 @@ efi_status_t efi_stub_common(efi_handle_t handle, status = efi_boot_kernel(handle, image, image_addr, cmdline_ptr); - free_screen_info(si); + free_primary_display(dpy); + return status; } diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index b2fb0c3fa721..979a21818cc1 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -36,6 +36,7 @@ struct edid_info; struct screen_info; +struct sysfb_display_info; extern bool efi_no5lvl; extern bool efi_nochunk; @@ -1175,9 +1176,9 @@ efi_enable_reset_attack_mitigation(void) { } void efi_retrieve_eventlog(void); -struct screen_info *alloc_screen_info(void); -struct screen_info *__alloc_screen_info(void); -void free_screen_info(struct screen_info *si); +struct sysfb_display_info *alloc_primary_display(void); +struct sysfb_display_info *__alloc_primary_display(void); +void free_primary_display(struct sysfb_display_info *dpy); void efi_cache_sync_image(unsigned long image_base, unsigned long alloc_size); diff --git a/drivers/firmware/efi/libstub/primary_display.c b/drivers/firmware/efi/libstub/primary_display.c new file mode 100644 index 000000000000..cdaebab26514 --- /dev/null +++ b/drivers/firmware/efi/libstub/primary_display.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/efi.h> +#include <linux/sysfb.h> + +#include <asm/efi.h> + +#include "efistub.h" + +/* + * There are two ways of populating the core kernel's sysfb_primary_display + * via the stub: + * + * - using a configuration table, which relies on the EFI init code to + * locate the table and copy the contents; or + * + * - by linking directly to the core kernel's copy of the global symbol. + * + * The latter is preferred because it makes the EFIFB earlycon available very + * early, but it only works if the EFI stub is part of the core kernel image + * itself. The zboot decompressor can only use the configuration table + * approach. + */ + +static efi_guid_t primary_display_guid = LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID; + +struct sysfb_display_info *__alloc_primary_display(void) +{ + struct sysfb_display_info *dpy; + efi_status_t status; + + status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, + sizeof(*dpy), (void **)&dpy); + + if (status != EFI_SUCCESS) + return NULL; + + memset(dpy, 0, sizeof(*dpy)); + + status = efi_bs_call(install_configuration_table, + &primary_display_guid, dpy); + if (status == EFI_SUCCESS) + return dpy; + + efi_bs_call(free_pool, dpy); + return NULL; +} + +void free_primary_display(struct sysfb_display_info *dpy) +{ + if (!dpy) + return; + + efi_bs_call(install_configuration_table, &primary_display_guid, NULL); + efi_bs_call(free_pool, dpy); +} diff --git a/drivers/firmware/efi/libstub/screen_info.c b/drivers/firmware/efi/libstub/screen_info.c deleted file mode 100644 index 5d3a1e32d177..000000000000 --- a/drivers/firmware/efi/libstub/screen_info.c +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include <linux/efi.h> -#include <linux/screen_info.h> - -#include <asm/efi.h> - -#include "efistub.h" - -/* - * There are two ways of populating the core kernel's struct screen_info via the stub: - * - using a configuration table, like below, which relies on the EFI init code - * to locate the table and copy the contents; - * - by linking directly to the core kernel's copy of the global symbol. - * - * The latter is preferred because it makes the EFIFB earlycon available very - * early, but it only works if the EFI stub is part of the core kernel image - * itself. The zboot decompressor can only use the configuration table - * approach. - */ - -static efi_guid_t screen_info_guid = LINUX_EFI_SCREEN_INFO_TABLE_GUID; - -struct screen_info *__alloc_screen_info(void) -{ - struct screen_info *si; - efi_status_t status; - - status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, - sizeof(*si), (void **)&si); - - if (status != EFI_SUCCESS) - return NULL; - - memset(si, 0, sizeof(*si)); - - status = efi_bs_call(install_configuration_table, - &screen_info_guid, si); - if (status == EFI_SUCCESS) - return si; - - efi_bs_call(free_pool, si); - return NULL; -} - -void free_screen_info(struct screen_info *si) -{ - if (!si) - return; - - efi_bs_call(install_configuration_table, &screen_info_guid, NULL); - efi_bs_call(free_pool, si); -} diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c index c47ace06f010..4b76f74c56da 100644 --- a/drivers/firmware/efi/libstub/zboot.c +++ b/drivers/firmware/efi/libstub/zboot.c @@ -26,9 +26,9 @@ void __weak efi_cache_sync_image(unsigned long image_base, // executable code loaded into memory to be safe for execution. } -struct screen_info *alloc_screen_info(void) +struct sysfb_display_info *alloc_primary_display(void) { - return __alloc_screen_info(); + return __alloc_primary_display(); } asmlinkage efi_status_t __efiapi -- 2.51.1
