From 8de8788d21826457ac3bfd1629d0e280f67c7b5f Mon Sep 17 00:00:00 2001 From: Arvind Sankar Date: Tue, 24 Dec 2019 16:10:04 +0100 Subject: [PATCH] efi/gop: Unify 32/64-bit functions Use efi_table_attr macro to deal with 32/64-bit firmware using the same source code. Signed-off-by: Arvind Sankar Signed-off-by: Ard Biesheuvel Cc: Borislav Petkov Cc: James Morse Cc: Matt Fleming Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: https://lkml.kernel.org/r/20191224151025.32482-5-ardb@kernel.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/libstub/gop.c | 134 +++++-------------------------------- 1 file changed, 18 insertions(+), 116 deletions(-) diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c index a0c1ef6..94045ab 100644 --- a/drivers/firmware/efi/libstub/gop.c +++ b/drivers/firmware/efi/libstub/gop.c @@ -83,108 +83,14 @@ setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line, } } -static efi_status_t -setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, - efi_guid_t *proto, unsigned long size, void **gop_handle) -{ - efi_graphics_output_protocol_32_t *gop32, *first_gop; - unsigned long nr_gops; - u16 width, height; - u32 pixels_per_scan_line; - u32 ext_lfb_base; - efi_physical_addr_t fb_base; - efi_pixel_bitmask_t pixel_info; - int pixel_format; - efi_status_t status; - u32 *handles = (u32 *)(unsigned long)gop_handle; - int i; - - first_gop = NULL; - gop32 = NULL; - - nr_gops = size / sizeof(u32); - for (i = 0; i < nr_gops; i++) { - efi_graphics_output_protocol_mode_32_t *mode; - efi_graphics_output_mode_info_t *info = NULL; - efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; - bool conout_found = false; - void *dummy = NULL; - efi_handle_t h = (efi_handle_t)(unsigned long)handles[i]; - efi_physical_addr_t current_fb_base; - - status = efi_call_early(handle_protocol, h, - proto, (void **)&gop32); - if (status != EFI_SUCCESS) - continue; - - status = efi_call_early(handle_protocol, h, - &conout_proto, &dummy); - if (status == EFI_SUCCESS) - conout_found = true; - - mode = (void *)(unsigned long)gop32->mode; - info = (void *)(unsigned long)mode->info; - current_fb_base = mode->frame_buffer_base; - - if ((!first_gop || conout_found) && - info->pixel_format != PIXEL_BLT_ONLY) { - /* - * Systems that use the UEFI Console Splitter may - * provide multiple GOP devices, not all of which are - * backed by real hardware. The workaround is to search - * for a GOP implementing the ConOut protocol, and if - * one isn't found, to just fall back to the first GOP. - */ - width = info->horizontal_resolution; - height = info->vertical_resolution; - pixel_format = info->pixel_format; - pixel_info = info->pixel_information; - pixels_per_scan_line = info->pixels_per_scan_line; - fb_base = current_fb_base; - - /* - * Once we've found a GOP supporting ConOut, - * don't bother looking any further. - */ - first_gop = gop32; - if (conout_found) - break; - } - } - - /* Did we find any GOPs? */ - if (!first_gop) - return EFI_NOT_FOUND; - - /* EFI framebuffer */ - si->orig_video_isVGA = VIDEO_TYPE_EFI; - - si->lfb_width = width; - si->lfb_height = height; - si->lfb_base = fb_base; - - ext_lfb_base = (u64)(unsigned long)fb_base >> 32; - if (ext_lfb_base) { - si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE; - si->ext_lfb_base = ext_lfb_base; - } - - si->pages = 1; - - setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format); - - si->lfb_size = si->lfb_linelength * si->lfb_height; - - si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; - - return EFI_SUCCESS; -} +#define efi_gop_attr(table, attr, instance) \ + (efi_table_attr(efi_graphics_output_protocol##table, attr, instance)) static efi_status_t -setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, - efi_guid_t *proto, unsigned long size, void **gop_handle) +setup_gop(efi_system_table_t *sys_table_arg, struct screen_info *si, + efi_guid_t *proto, unsigned long size, void **handles) { - efi_graphics_output_protocol_64_t *gop64, *first_gop; + efi_graphics_output_protocol_t *gop, *first_gop; unsigned long nr_gops; u16 width, height; u32 pixels_per_scan_line; @@ -193,24 +99,26 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, efi_pixel_bitmask_t pixel_info; int pixel_format; efi_status_t status; - u64 *handles = (u64 *)(unsigned long)gop_handle; int i; + bool is64 = efi_is_64bit(); first_gop = NULL; - gop64 = NULL; + gop = NULL; - nr_gops = size / sizeof(u64); + nr_gops = size / (is64 ? sizeof(u64) : sizeof(u32)); for (i = 0; i < nr_gops; i++) { - efi_graphics_output_protocol_mode_64_t *mode; + efi_graphics_output_protocol_mode_t *mode; efi_graphics_output_mode_info_t *info = NULL; efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; bool conout_found = false; void *dummy = NULL; - efi_handle_t h = (efi_handle_t)(unsigned long)handles[i]; + efi_handle_t h = (efi_handle_t)(unsigned long) + (is64 ? ((u64 *)handles)[i] + : ((u32 *)handles)[i]); efi_physical_addr_t current_fb_base; status = efi_call_early(handle_protocol, h, - proto, (void **)&gop64); + proto, (void **)&gop); if (status != EFI_SUCCESS) continue; @@ -219,9 +127,9 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, if (status == EFI_SUCCESS) conout_found = true; - mode = (void *)(unsigned long)gop64->mode; - info = (void *)(unsigned long)mode->info; - current_fb_base = mode->frame_buffer_base; + mode = (void *)(unsigned long)efi_gop_attr(, mode, gop); + info = (void *)(unsigned long)efi_gop_attr(_mode, info, mode); + current_fb_base = efi_gop_attr(_mode, frame_buffer_base, mode); if ((!first_gop || conout_found) && info->pixel_format != PIXEL_BLT_ONLY) { @@ -243,7 +151,7 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, * Once we've found a GOP supporting ConOut, * don't bother looking any further. */ - first_gop = gop64; + first_gop = gop; if (conout_found) break; } @@ -298,13 +206,7 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg, if (status != EFI_SUCCESS) goto free_handle; - if (efi_is_64bit()) { - status = setup_gop64(sys_table_arg, si, proto, size, - gop_handle); - } else { - status = setup_gop32(sys_table_arg, si, proto, size, - gop_handle); - } + status = setup_gop(sys_table_arg, si, proto, size, gop_handle); free_handle: efi_call_early(free_pool, gop_handle); -- 2.7.4