To use the EFI firmware update "UX Capsule" extension, we need to know what the GOP video mode number was during boot. This patch adds it to the efi-framebuffer.N devices in sysfs and adds the various files in /sys/bus/platform/drivers/efi-framebuffer/efi-framebuffer.N/ to the sysfs documentation. Signed-off-by: Peter Jones <pjones@xxxxxxxxxx> --- drivers/firmware/efi/libstub/gop.c | 16 ++++++++++++---- drivers/video/fbdev/efifb.c | 11 +++++++++++ include/uapi/linux/screen_info.h | 4 ++-- Documentation/ABI/testing/sysfs-firmware-efi | 15 +++++++++++++++ 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c index 24c461dea7a..f9e174acb0b 100644 --- a/drivers/firmware/efi/libstub/gop.c +++ b/drivers/firmware/efi/libstub/gop.c @@ -89,7 +89,7 @@ static efi_status_t __gop_query32(efi_system_table_t *sys_table_arg, struct efi_graphics_output_protocol_32 *gop32, struct efi_graphics_output_mode_info **info, - unsigned long *size, u64 *fb_base) + unsigned long *size, u64 *fb_base, u32 *mode_num) { struct efi_graphics_output_protocol_mode_32 *mode; efi_graphics_output_protocol_query_mode query_mode; @@ -106,6 +106,7 @@ __gop_query32(efi_system_table_t *sys_table_arg, return status; *fb_base = mode->frame_buffer_base; + *mode_num = mode->mode; return status; } @@ -115,6 +116,7 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, { struct efi_graphics_output_protocol_32 *gop32, *first_gop; unsigned long nr_gops; + u32 mode_num; u16 width, height; u32 pixels_per_scan_line; u32 ext_lfb_base; @@ -148,7 +150,7 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, conout_found = true; status = __gop_query32(sys_table_arg, gop32, &info, &size, - ¤t_fb_base); + ¤t_fb_base, &mode_num); if (status == EFI_SUCCESS && (!first_gop || conout_found) && info->pixel_format != PIXEL_BLT_ONLY) { /* @@ -182,6 +184,8 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, /* EFI framebuffer */ si->orig_video_isVGA = VIDEO_TYPE_EFI; + si->efi_gop_mode_high = (mode_num & 0xff00) >> 16; + si->efi_gop_mode_low = (mode_num & 0xff); si->lfb_width = width; si->lfb_height = height; si->lfb_base = fb_base; @@ -207,7 +211,7 @@ static efi_status_t __gop_query64(efi_system_table_t *sys_table_arg, struct efi_graphics_output_protocol_64 *gop64, struct efi_graphics_output_mode_info **info, - unsigned long *size, u64 *fb_base) + unsigned long *size, u64 *fb_base, u32 *mode_num) { struct efi_graphics_output_protocol_mode_64 *mode; efi_graphics_output_protocol_query_mode query_mode; @@ -224,6 +228,7 @@ __gop_query64(efi_system_table_t *sys_table_arg, return status; *fb_base = mode->frame_buffer_base; + *mode_num = mode->mode; return status; } @@ -233,6 +238,7 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, { struct efi_graphics_output_protocol_64 *gop64, *first_gop; unsigned long nr_gops; + u32 mode_num; u16 width, height; u32 pixels_per_scan_line; u32 ext_lfb_base; @@ -266,7 +272,7 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, conout_found = true; status = __gop_query64(sys_table_arg, gop64, &info, &size, - ¤t_fb_base); + ¤t_fb_base, &mode_num); if (status == EFI_SUCCESS && (!first_gop || conout_found) && info->pixel_format != PIXEL_BLT_ONLY) { /* @@ -300,6 +306,8 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si, /* EFI framebuffer */ si->orig_video_isVGA = VIDEO_TYPE_EFI; + si->efi_gop_mode_high = (mode_num & 0xff00) >> 16; + si->efi_gop_mode_low = (mode_num & 0xff); si->lfb_width = width; si->lfb_height = height; si->lfb_base = fb_base; diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index ba906876cc4..3250f3f9152 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -331,12 +331,23 @@ efifb_attr_decl(height, "%u"); efifb_attr_decl(width, "%u"); efifb_attr_decl(depth, "%u"); +static ssize_t gop_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "0x%04hx%04hx\n", + screen_info.efi_gop_mode_high, + screen_info.efi_gop_mode_low); +} +static DEVICE_ATTR_RO(gop_mode); + static struct attribute *efifb_attrs[] = { &dev_attr_base.attr, &dev_attr_linelength.attr, &dev_attr_width.attr, &dev_attr_height.attr, &dev_attr_depth.attr, + &dev_attr_gop_mode.attr, NULL }; ATTRIBUTE_GROUPS(efifb); diff --git a/include/uapi/linux/screen_info.h b/include/uapi/linux/screen_info.h index 87e5c086938..a8eb2d76167 100644 --- a/include/uapi/linux/screen_info.h +++ b/include/uapi/linux/screen_info.h @@ -18,7 +18,7 @@ struct screen_info { __u8 flags; /* 0x08 */ __u8 unused2; /* 0x09 */ __u16 orig_video_ega_bx;/* 0x0a */ - __u16 unused3; /* 0x0c */ + __u16 efi_gop_mode_low; /* 0x0c */ __u8 orig_video_lines; /* 0x0e */ __u8 orig_video_isVGA; /* 0x0f */ __u16 orig_video_points;/* 0x10 */ @@ -45,7 +45,7 @@ struct screen_info { __u16 vesa_attributes; /* 0x34 */ __u32 capabilities; /* 0x36 */ __u32 ext_lfb_base; /* 0x3a */ - __u8 _reserved[2]; /* 0x3e */ + __u16 efi_gop_mode_high;/* 0x3e */ } __attribute__((packed)); #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ diff --git a/Documentation/ABI/testing/sysfs-firmware-efi b/Documentation/ABI/testing/sysfs-firmware-efi index e794eac32a9..6c169599863 100644 --- a/Documentation/ABI/testing/sysfs-firmware-efi +++ b/Documentation/ABI/testing/sysfs-firmware-efi @@ -28,3 +28,18 @@ Description: Displays the physical addresses of all EFI Configuration versions are always printed first, i.e. ACPI20 comes before ACPI. Users: dmidecode + +What: /sys/bus/platform/drivers/efi-framebuffer/efi-framebuffer.N/ +Date: October 2016 +Contact: linux-efi@xxxxxxxxxxxxxxx +Description: The characteristics of the EFI GOP framebuffer device. + + base: The physical address of the framebuffer memory. + depth: The color depth of the framebuffer, in bits. + height: The height of the displayed frame in pixels. + linelength: The size of one line (i.e. the stride) of the + framebuffer memory, in bytes. + width: The width of the displayed frame in pixels. + gop_mode: The index into the EFI GOP mode table for the mode in + use during boot-up. +Users: fwupd -- 2.20.1