Skip to content

Commit 17029cd

Browse files
tdzardbiesheuvel
authored andcommitted
efi/libstub: gop: Add support for reading EDID
Add support for EFI_EDID_DISCOVERED_PROTOCOL and EFI_EDID_ACTIVE_PROTOCOL as defined in UEFI 2.8, sec 12.9. Define GUIDs and data structures in the rsp header files. In the GOP setup function, read the EDID of the primary GOP device. First try EFI_EDID_ACTIVE_PROTOCOL, which supports user-specified EDID data. Or else try EFI_EDID_DISCOVERED_PROTOCOL, which returns the display device's native EDID. If no EDID could be retrieved, clear the storage. Rename efi_setup_gop() to efi_setup_graphics() to reflect the changes Let callers pass an optional instance of struct edid_data, if they are interested. While screen_info and edid_info come from the same device handle, they should be considered indendent data. The former refers to the graphics mode, the latter refers to the display device. GOP devices might not provide both. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent ae42b9c commit 17029cd

5 files changed

Lines changed: 69 additions & 4 deletions

File tree

drivers/firmware/efi/libstub/efi-stub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static struct screen_info *setup_graphics(void)
5656
{
5757
struct screen_info *si, tmp = {};
5858

59-
if (efi_setup_gop(&tmp) != EFI_SUCCESS)
59+
if (efi_setup_graphics(&tmp, NULL) != EFI_SUCCESS)
6060
return NULL;
6161

6262
si = alloc_screen_info();

drivers/firmware/efi/libstub/efistub.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
#define EFI_ALLOC_LIMIT ULONG_MAX
3535
#endif
3636

37+
struct edid_info;
38+
struct screen_info;
39+
3740
extern bool efi_no5lvl;
3841
extern bool efi_nochunk;
3942
extern bool efi_nokaslr;
@@ -578,6 +581,32 @@ union efi_graphics_output_protocol {
578581
} mixed_mode;
579582
};
580583

584+
typedef union efi_edid_discovered_protocol efi_edid_discovered_protocol_t;
585+
586+
union efi_edid_discovered_protocol {
587+
struct {
588+
u32 size_of_edid;
589+
u8 *edid;
590+
};
591+
struct {
592+
u32 size_of_edid;
593+
u32 edid;
594+
} mixed_mode;
595+
};
596+
597+
typedef union efi_edid_active_protocol efi_edid_active_protocol_t;
598+
599+
union efi_edid_active_protocol {
600+
struct {
601+
u32 size_of_edid;
602+
u8 *edid;
603+
};
604+
struct {
605+
u32 size_of_edid;
606+
u32 edid;
607+
} mixed_mode;
608+
};
609+
581610
typedef union {
582611
struct {
583612
u32 revision;
@@ -1085,7 +1114,7 @@ efi_status_t efi_parse_options(char const *cmdline);
10851114

10861115
void efi_parse_option_graphics(char *option);
10871116

1088-
efi_status_t efi_setup_gop(struct screen_info *si);
1117+
efi_status_t efi_setup_graphics(struct screen_info *si, struct edid_info *edid);
10891118

10901119
efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
10911120
const efi_char16_t *optstr,

drivers/firmware/efi/libstub/gop.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/string.h>
1313
#include <asm/efi.h>
1414
#include <asm/setup.h>
15+
#include <video/edid.h>
1516

1617
#include "efistub.h"
1718

@@ -413,6 +414,14 @@ static void setup_screen_info(struct screen_info *si, const efi_graphics_output_
413414
si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
414415
}
415416

417+
static void setup_edid_info(struct edid_info *edid, u32 gop_size_of_edid, u8 *gop_edid)
418+
{
419+
if (!gop_edid || gop_size_of_edid < 128)
420+
memset(edid->dummy, 0, sizeof(edid->dummy));
421+
else
422+
memcpy(edid->dummy, gop_edid, min(gop_size_of_edid, sizeof(edid->dummy)));
423+
}
424+
416425
static efi_handle_t find_handle_with_primary_gop(unsigned long num, const efi_handle_t handles[],
417426
efi_graphics_output_protocol_t **found_gop)
418427
{
@@ -469,7 +478,7 @@ static efi_handle_t find_handle_with_primary_gop(unsigned long num, const efi_ha
469478
return first_gop_handle;
470479
}
471480

472-
efi_status_t efi_setup_gop(struct screen_info *si)
481+
efi_status_t efi_setup_graphics(struct screen_info *si, struct edid_info *edid)
473482
{
474483
efi_handle_t *handles __free(efi_pool) = NULL;
475484
efi_handle_t handle;
@@ -494,5 +503,30 @@ efi_status_t efi_setup_gop(struct screen_info *si)
494503
if (si)
495504
setup_screen_info(si, gop);
496505

506+
/* Display EDID for primary GOP */
507+
if (edid) {
508+
efi_edid_discovered_protocol_t *discovered_edid;
509+
efi_edid_active_protocol_t *active_edid;
510+
u32 gop_size_of_edid = 0;
511+
u8 *gop_edid = NULL;
512+
513+
status = efi_bs_call(handle_protocol, handle, &EFI_EDID_ACTIVE_PROTOCOL_GUID,
514+
(void **)&active_edid);
515+
if (status == EFI_SUCCESS) {
516+
gop_size_of_edid = active_edid->size_of_edid;
517+
gop_edid = active_edid->edid;
518+
} else {
519+
status = efi_bs_call(handle_protocol, handle,
520+
&EFI_EDID_DISCOVERED_PROTOCOL_GUID,
521+
(void **)&discovered_edid);
522+
if (status == EFI_SUCCESS) {
523+
gop_size_of_edid = discovered_edid->size_of_edid;
524+
gop_edid = discovered_edid->edid;
525+
}
526+
}
527+
528+
setup_edid_info(edid, gop_size_of_edid, gop_edid);
529+
}
530+
497531
return EFI_SUCCESS;
498532
}

drivers/firmware/efi/libstub/x86-stub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ static void setup_graphics(struct boot_params *boot_params)
488488
{
489489
struct screen_info *si = memset(&boot_params->screen_info, 0, sizeof(*si));
490490

491-
efi_setup_gop(si);
491+
efi_setup_graphics(si, NULL);
492492
}
493493

494494
static void __noreturn efi_exit(efi_handle_t handle, efi_status_t status)

include/linux/efi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ void efi_native_runtime_setup(void);
373373
#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID EFI_GUID(0x8b843e20, 0x8132, 0x4852, 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c)
374374
#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID EFI_GUID(0x05c99a21, 0xc70f, 0x4ad2, 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e)
375375
#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a)
376+
#define EFI_EDID_DISCOVERED_PROTOCOL_GUID EFI_GUID(0x1c0c34f6, 0xd380, 0x41fa, 0xa0, 0x49, 0x8a, 0xd0, 0x6c, 0x1a, 0x66, 0xaa)
377+
#define EFI_EDID_ACTIVE_PROTOCOL_GUID EFI_GUID(0xbd8c1056, 0x9f36, 0x44ec, 0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86)
376378
#define EFI_PCI_IO_PROTOCOL_GUID EFI_GUID(0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a)
377379
#define EFI_FILE_INFO_ID EFI_GUID(0x09576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
378380
#define EFI_SYSTEM_RESOURCE_TABLE_GUID EFI_GUID(0xb122a263, 0x3661, 0x4f68, 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80)

0 commit comments

Comments
 (0)