Skip to content

Commit fc37206

Browse files
Ard BiesheuvelIngo Molnar
authored andcommitted
efi/libstub: Move Graphics Output Protocol handling to generic code
The Graphics Output Protocol code executes in the stub, so create a generic version based on the x86 version in libstub so that we can move other archs to it in subsequent patches. The new source file gop.c is added to the libstub build for all architectures, but only wired up for x86. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk> Cc: Borislav Petkov <bp@alien8.de> Cc: David Herrmann <dh.herrmann@gmail.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Peter Jones <pjones@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Will Deacon <will.deacon@arm.com> Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1461614832-17633-18-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 2c23b73 commit fc37206

File tree

7 files changed

+441
-400
lines changed

7 files changed

+441
-400
lines changed

arch/arm/include/asm/efi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ void efi_virtmap_unload(void);
6060

6161
/* arch specific definitions used by the stub code */
6262

63-
#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
63+
#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
64+
#define __efi_call_early(f, ...) f(__VA_ARGS__)
65+
#define efi_is_64bit() (false)
6466

6567
/*
6668
* A reasonable upper bound for the uncompressed kernel size is 32 MBytes,

arch/arm64/include/asm/efi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
5252
#define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */
5353
#define MAX_FDT_OFFSET SZ_512M
5454

55-
#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
55+
#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
56+
#define __efi_call_early(f, ...) f(__VA_ARGS__)
57+
#define efi_is_64bit() (true)
5658

5759
#define EFI_ALLOC_ALIGN SZ_64K
5860

arch/x86/boot/compressed/eboot.c

Lines changed: 0 additions & 318 deletions
Original file line numberDiff line numberDiff line change
@@ -571,324 +571,6 @@ static void setup_efi_pci(struct boot_params *params)
571571
efi_call_early(free_pool, pci_handle);
572572
}
573573

574-
static void
575-
setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line,
576-
struct efi_pixel_bitmask pixel_info, int pixel_format)
577-
{
578-
if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) {
579-
si->lfb_depth = 32;
580-
si->lfb_linelength = pixels_per_scan_line * 4;
581-
si->red_size = 8;
582-
si->red_pos = 0;
583-
si->green_size = 8;
584-
si->green_pos = 8;
585-
si->blue_size = 8;
586-
si->blue_pos = 16;
587-
si->rsvd_size = 8;
588-
si->rsvd_pos = 24;
589-
} else if (pixel_format == PIXEL_BGR_RESERVED_8BIT_PER_COLOR) {
590-
si->lfb_depth = 32;
591-
si->lfb_linelength = pixels_per_scan_line * 4;
592-
si->red_size = 8;
593-
si->red_pos = 16;
594-
si->green_size = 8;
595-
si->green_pos = 8;
596-
si->blue_size = 8;
597-
si->blue_pos = 0;
598-
si->rsvd_size = 8;
599-
si->rsvd_pos = 24;
600-
} else if (pixel_format == PIXEL_BIT_MASK) {
601-
find_bits(pixel_info.red_mask, &si->red_pos, &si->red_size);
602-
find_bits(pixel_info.green_mask, &si->green_pos,
603-
&si->green_size);
604-
find_bits(pixel_info.blue_mask, &si->blue_pos, &si->blue_size);
605-
find_bits(pixel_info.reserved_mask, &si->rsvd_pos,
606-
&si->rsvd_size);
607-
si->lfb_depth = si->red_size + si->green_size +
608-
si->blue_size + si->rsvd_size;
609-
si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) / 8;
610-
} else {
611-
si->lfb_depth = 4;
612-
si->lfb_linelength = si->lfb_width / 2;
613-
si->red_size = 0;
614-
si->red_pos = 0;
615-
si->green_size = 0;
616-
si->green_pos = 0;
617-
si->blue_size = 0;
618-
si->blue_pos = 0;
619-
si->rsvd_size = 0;
620-
si->rsvd_pos = 0;
621-
}
622-
}
623-
624-
static efi_status_t
625-
__gop_query32(efi_system_table_t *sys_table_arg,
626-
struct efi_graphics_output_protocol_32 *gop32,
627-
struct efi_graphics_output_mode_info **info,
628-
unsigned long *size, u64 *fb_base)
629-
{
630-
struct efi_graphics_output_protocol_mode_32 *mode;
631-
efi_graphics_output_protocol_query_mode query_mode;
632-
efi_status_t status;
633-
unsigned long m;
634-
635-
m = gop32->mode;
636-
mode = (struct efi_graphics_output_protocol_mode_32 *)m;
637-
query_mode = (void *)(unsigned long)gop32->query_mode;
638-
639-
status = __efi_call_early(query_mode, (void *)gop32, mode->mode, size,
640-
info);
641-
if (status != EFI_SUCCESS)
642-
return status;
643-
644-
*fb_base = mode->frame_buffer_base;
645-
return status;
646-
}
647-
648-
static efi_status_t
649-
setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si,
650-
efi_guid_t *proto, unsigned long size, void **gop_handle)
651-
{
652-
struct efi_graphics_output_protocol_32 *gop32, *first_gop;
653-
unsigned long nr_gops;
654-
u16 width, height;
655-
u32 pixels_per_scan_line;
656-
u32 ext_lfb_base;
657-
u64 fb_base;
658-
struct efi_pixel_bitmask pixel_info;
659-
int pixel_format;
660-
efi_status_t status = EFI_NOT_FOUND;
661-
u32 *handles = (u32 *)(unsigned long)gop_handle;
662-
int i;
663-
664-
first_gop = NULL;
665-
gop32 = NULL;
666-
667-
nr_gops = size / sizeof(u32);
668-
for (i = 0; i < nr_gops; i++) {
669-
struct efi_graphics_output_mode_info *info = NULL;
670-
efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
671-
bool conout_found = false;
672-
void *dummy = NULL;
673-
efi_handle_t h = (efi_handle_t)(unsigned long)handles[i];
674-
u64 current_fb_base;
675-
676-
status = efi_call_early(handle_protocol, h,
677-
proto, (void **)&gop32);
678-
if (status != EFI_SUCCESS)
679-
continue;
680-
681-
status = efi_call_early(handle_protocol, h,
682-
&conout_proto, &dummy);
683-
if (status == EFI_SUCCESS)
684-
conout_found = true;
685-
686-
status = __gop_query32(sys_table_arg, gop32, &info, &size,
687-
&current_fb_base);
688-
if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
689-
/*
690-
* Systems that use the UEFI Console Splitter may
691-
* provide multiple GOP devices, not all of which are
692-
* backed by real hardware. The workaround is to search
693-
* for a GOP implementing the ConOut protocol, and if
694-
* one isn't found, to just fall back to the first GOP.
695-
*/
696-
width = info->horizontal_resolution;
697-
height = info->vertical_resolution;
698-
pixel_format = info->pixel_format;
699-
pixel_info = info->pixel_information;
700-
pixels_per_scan_line = info->pixels_per_scan_line;
701-
fb_base = current_fb_base;
702-
703-
/*
704-
* Once we've found a GOP supporting ConOut,
705-
* don't bother looking any further.
706-
*/
707-
first_gop = gop32;
708-
if (conout_found)
709-
break;
710-
}
711-
}
712-
713-
/* Did we find any GOPs? */
714-
if (!first_gop)
715-
goto out;
716-
717-
/* EFI framebuffer */
718-
si->orig_video_isVGA = VIDEO_TYPE_EFI;
719-
720-
si->lfb_width = width;
721-
si->lfb_height = height;
722-
si->lfb_base = fb_base;
723-
724-
ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
725-
if (ext_lfb_base) {
726-
si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
727-
si->ext_lfb_base = ext_lfb_base;
728-
}
729-
730-
si->pages = 1;
731-
732-
setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
733-
734-
si->lfb_size = si->lfb_linelength * si->lfb_height;
735-
736-
si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
737-
out:
738-
return status;
739-
}
740-
741-
static efi_status_t
742-
__gop_query64(efi_system_table_t *sys_table_arg,
743-
struct efi_graphics_output_protocol_64 *gop64,
744-
struct efi_graphics_output_mode_info **info,
745-
unsigned long *size, u64 *fb_base)
746-
{
747-
struct efi_graphics_output_protocol_mode_64 *mode;
748-
efi_graphics_output_protocol_query_mode query_mode;
749-
efi_status_t status;
750-
unsigned long m;
751-
752-
m = gop64->mode;
753-
mode = (struct efi_graphics_output_protocol_mode_64 *)m;
754-
query_mode = (void *)(unsigned long)gop64->query_mode;
755-
756-
status = __efi_call_early(query_mode, (void *)gop64, mode->mode, size,
757-
info);
758-
if (status != EFI_SUCCESS)
759-
return status;
760-
761-
*fb_base = mode->frame_buffer_base;
762-
return status;
763-
}
764-
765-
static efi_status_t
766-
setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si,
767-
efi_guid_t *proto, unsigned long size, void **gop_handle)
768-
{
769-
struct efi_graphics_output_protocol_64 *gop64, *first_gop;
770-
unsigned long nr_gops;
771-
u16 width, height;
772-
u32 pixels_per_scan_line;
773-
u32 ext_lfb_base;
774-
u64 fb_base;
775-
struct efi_pixel_bitmask pixel_info;
776-
int pixel_format;
777-
efi_status_t status = EFI_NOT_FOUND;
778-
u64 *handles = (u64 *)(unsigned long)gop_handle;
779-
int i;
780-
781-
first_gop = NULL;
782-
gop64 = NULL;
783-
784-
nr_gops = size / sizeof(u64);
785-
for (i = 0; i < nr_gops; i++) {
786-
struct efi_graphics_output_mode_info *info = NULL;
787-
efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
788-
bool conout_found = false;
789-
void *dummy = NULL;
790-
efi_handle_t h = (efi_handle_t)(unsigned long)handles[i];
791-
u64 current_fb_base;
792-
793-
status = efi_call_early(handle_protocol, h,
794-
proto, (void **)&gop64);
795-
if (status != EFI_SUCCESS)
796-
continue;
797-
798-
status = efi_call_early(handle_protocol, h,
799-
&conout_proto, &dummy);
800-
if (status == EFI_SUCCESS)
801-
conout_found = true;
802-
803-
status = __gop_query64(sys_table_arg, gop64, &info, &size,
804-
&current_fb_base);
805-
if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
806-
/*
807-
* Systems that use the UEFI Console Splitter may
808-
* provide multiple GOP devices, not all of which are
809-
* backed by real hardware. The workaround is to search
810-
* for a GOP implementing the ConOut protocol, and if
811-
* one isn't found, to just fall back to the first GOP.
812-
*/
813-
width = info->horizontal_resolution;
814-
height = info->vertical_resolution;
815-
pixel_format = info->pixel_format;
816-
pixel_info = info->pixel_information;
817-
pixels_per_scan_line = info->pixels_per_scan_line;
818-
fb_base = current_fb_base;
819-
820-
/*
821-
* Once we've found a GOP supporting ConOut,
822-
* don't bother looking any further.
823-
*/
824-
first_gop = gop64;
825-
if (conout_found)
826-
break;
827-
}
828-
}
829-
830-
/* Did we find any GOPs? */
831-
if (!first_gop)
832-
goto out;
833-
834-
/* EFI framebuffer */
835-
si->orig_video_isVGA = VIDEO_TYPE_EFI;
836-
837-
si->lfb_width = width;
838-
si->lfb_height = height;
839-
si->lfb_base = fb_base;
840-
841-
ext_lfb_base = (u64)(unsigned long)fb_base >> 32;
842-
if (ext_lfb_base) {
843-
si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
844-
si->ext_lfb_base = ext_lfb_base;
845-
}
846-
847-
si->pages = 1;
848-
849-
setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format);
850-
851-
si->lfb_size = si->lfb_linelength * si->lfb_height;
852-
853-
si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
854-
out:
855-
return status;
856-
}
857-
858-
/*
859-
* See if we have Graphics Output Protocol
860-
*/
861-
efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
862-
struct screen_info *si, efi_guid_t *proto,
863-
unsigned long size)
864-
{
865-
efi_status_t status;
866-
void **gop_handle = NULL;
867-
868-
status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
869-
size, (void **)&gop_handle);
870-
if (status != EFI_SUCCESS)
871-
return status;
872-
873-
status = efi_call_early(locate_handle,
874-
EFI_LOCATE_BY_PROTOCOL,
875-
proto, NULL, &size, gop_handle);
876-
if (status != EFI_SUCCESS)
877-
goto free_handle;
878-
879-
if (efi_is_64bit()) {
880-
status = setup_gop64(sys_table_arg, si, proto, size,
881-
gop_handle);
882-
} else {
883-
status = setup_gop32(sys_table_arg, si, proto, size,
884-
gop_handle);
885-
}
886-
887-
free_handle:
888-
efi_call_early(free_pool, gop_handle);
889-
return status;
890-
}
891-
892574
static efi_status_t
893575
setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
894576
{

0 commit comments

Comments
 (0)