mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
efi/gop: Add an option to list out the available GOP modes
Add video=efifb:list option to list the modes that are available. Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Link: https://lore.kernel.org/r/20200518190716.751506-20-nivedita@alum.mit.edu Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
parent
9b47c52756
commit
14c574f35c
@ -63,4 +63,9 @@ auto
|
|||||||
with the highest resolution, it will choose one with the highest color
|
with the highest resolution, it will choose one with the highest color
|
||||||
depth.
|
depth.
|
||||||
|
|
||||||
|
list
|
||||||
|
The EFI stub will list out all the display modes that are available. A
|
||||||
|
specific mode can then be chosen using one of the above options for the
|
||||||
|
next boot.
|
||||||
|
|
||||||
Edgar Hucek <gimli@dark-green.com>
|
Edgar Hucek <gimli@dark-green.com>
|
||||||
|
@ -463,3 +463,38 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image,
|
|||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key)
|
||||||
|
{
|
||||||
|
efi_event_t events[2], timer;
|
||||||
|
unsigned long index;
|
||||||
|
efi_simple_text_input_protocol_t *con_in;
|
||||||
|
efi_status_t status;
|
||||||
|
|
||||||
|
con_in = efi_table_attr(efi_system_table, con_in);
|
||||||
|
if (!con_in)
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
efi_set_event_at(events, 0, efi_table_attr(con_in, wait_for_key));
|
||||||
|
|
||||||
|
status = efi_bs_call(create_event, EFI_EVT_TIMER, 0, NULL, NULL, &timer);
|
||||||
|
if (status != EFI_SUCCESS)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = efi_bs_call(set_timer, timer, EfiTimerRelative,
|
||||||
|
EFI_100NSEC_PER_USEC * usec);
|
||||||
|
if (status != EFI_SUCCESS)
|
||||||
|
return status;
|
||||||
|
efi_set_event_at(events, 1, timer);
|
||||||
|
|
||||||
|
status = efi_bs_call(wait_for_event, 2, events, &index);
|
||||||
|
if (status == EFI_SUCCESS) {
|
||||||
|
if (index == 0)
|
||||||
|
status = efi_call_proto(con_in, read_keystroke, key);
|
||||||
|
else
|
||||||
|
status = EFI_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
efi_bs_call(close_event, timer);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
@ -323,6 +323,8 @@ union efi_simple_text_input_protocol {
|
|||||||
} mixed_mode;
|
} mixed_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key);
|
||||||
|
|
||||||
union efi_simple_text_output_protocol {
|
union efi_simple_text_output_protocol {
|
||||||
struct {
|
struct {
|
||||||
void *reset;
|
void *reset;
|
||||||
|
@ -19,7 +19,8 @@ enum efi_cmdline_option {
|
|||||||
EFI_CMDLINE_NONE,
|
EFI_CMDLINE_NONE,
|
||||||
EFI_CMDLINE_MODE_NUM,
|
EFI_CMDLINE_MODE_NUM,
|
||||||
EFI_CMDLINE_RES,
|
EFI_CMDLINE_RES,
|
||||||
EFI_CMDLINE_AUTO
|
EFI_CMDLINE_AUTO,
|
||||||
|
EFI_CMDLINE_LIST
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
@ -100,6 +101,19 @@ static bool parse_auto(char *option, char **next)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parse_list(char *option, char **next)
|
||||||
|
{
|
||||||
|
if (!strstarts(option, "list"))
|
||||||
|
return false;
|
||||||
|
option += strlen("list");
|
||||||
|
if (*option && *option++ != ',')
|
||||||
|
return false;
|
||||||
|
cmdline.option = EFI_CMDLINE_LIST;
|
||||||
|
|
||||||
|
*next = option;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void efi_parse_option_graphics(char *option)
|
void efi_parse_option_graphics(char *option)
|
||||||
{
|
{
|
||||||
while (*option) {
|
while (*option) {
|
||||||
@ -109,6 +123,8 @@ void efi_parse_option_graphics(char *option)
|
|||||||
continue;
|
continue;
|
||||||
if (parse_auto(option, &option))
|
if (parse_auto(option, &option))
|
||||||
continue;
|
continue;
|
||||||
|
if (parse_list(option, &option))
|
||||||
|
continue;
|
||||||
|
|
||||||
while (*option && *option++ != ',')
|
while (*option && *option++ != ',')
|
||||||
;
|
;
|
||||||
@ -290,6 +306,82 @@ static u32 choose_mode_auto(efi_graphics_output_protocol_t *gop)
|
|||||||
return best_mode;
|
return best_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 choose_mode_list(efi_graphics_output_protocol_t *gop)
|
||||||
|
{
|
||||||
|
efi_status_t status;
|
||||||
|
|
||||||
|
efi_graphics_output_protocol_mode_t *mode;
|
||||||
|
efi_graphics_output_mode_info_t *info;
|
||||||
|
unsigned long info_size;
|
||||||
|
|
||||||
|
u32 max_mode, cur_mode;
|
||||||
|
int pf;
|
||||||
|
efi_pixel_bitmask_t pi;
|
||||||
|
u32 m, w, h;
|
||||||
|
u8 d;
|
||||||
|
const char *dstr;
|
||||||
|
bool valid;
|
||||||
|
efi_input_key_t key;
|
||||||
|
|
||||||
|
mode = efi_table_attr(gop, mode);
|
||||||
|
|
||||||
|
cur_mode = efi_table_attr(mode, mode);
|
||||||
|
max_mode = efi_table_attr(mode, max_mode);
|
||||||
|
|
||||||
|
efi_printk("Available graphics modes are 0-%u\n", max_mode-1);
|
||||||
|
efi_puts(" * = current mode\n"
|
||||||
|
" - = unusable mode\n");
|
||||||
|
for (m = 0; m < max_mode; m++) {
|
||||||
|
status = efi_call_proto(gop, query_mode, m,
|
||||||
|
&info_size, &info);
|
||||||
|
if (status != EFI_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pf = info->pixel_format;
|
||||||
|
pi = info->pixel_information;
|
||||||
|
w = info->horizontal_resolution;
|
||||||
|
h = info->vertical_resolution;
|
||||||
|
|
||||||
|
efi_bs_call(free_pool, info);
|
||||||
|
|
||||||
|
valid = !(pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX);
|
||||||
|
d = 0;
|
||||||
|
switch (pf) {
|
||||||
|
case PIXEL_RGB_RESERVED_8BIT_PER_COLOR:
|
||||||
|
dstr = "rgb";
|
||||||
|
break;
|
||||||
|
case PIXEL_BGR_RESERVED_8BIT_PER_COLOR:
|
||||||
|
dstr = "bgr";
|
||||||
|
break;
|
||||||
|
case PIXEL_BIT_MASK:
|
||||||
|
dstr = "";
|
||||||
|
d = pixel_bpp(pf, pi);
|
||||||
|
break;
|
||||||
|
case PIXEL_BLT_ONLY:
|
||||||
|
dstr = "blt";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dstr = "xxx";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
efi_printk("Mode %3u %c%c: Resolution %ux%u-%s%.0hhu\n",
|
||||||
|
m,
|
||||||
|
m == cur_mode ? '*' : ' ',
|
||||||
|
!valid ? '-' : ' ',
|
||||||
|
w, h, dstr, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
efi_puts("\nPress any key to continue (or wait 10 seconds)\n");
|
||||||
|
status = efi_wait_for_key(10 * EFI_USEC_PER_SEC, &key);
|
||||||
|
if (status != EFI_SUCCESS && status != EFI_TIMEOUT) {
|
||||||
|
efi_err("Unable to read key, continuing in 10 seconds\n");
|
||||||
|
efi_bs_call(stall, 10 * EFI_USEC_PER_SEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cur_mode;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_mode(efi_graphics_output_protocol_t *gop)
|
static void set_mode(efi_graphics_output_protocol_t *gop)
|
||||||
{
|
{
|
||||||
efi_graphics_output_protocol_mode_t *mode;
|
efi_graphics_output_protocol_mode_t *mode;
|
||||||
@ -305,6 +397,9 @@ static void set_mode(efi_graphics_output_protocol_t *gop)
|
|||||||
case EFI_CMDLINE_AUTO:
|
case EFI_CMDLINE_AUTO:
|
||||||
new_mode = choose_mode_auto(gop);
|
new_mode = choose_mode_auto(gop);
|
||||||
break;
|
break;
|
||||||
|
case EFI_CMDLINE_LIST:
|
||||||
|
new_mode = choose_mode_list(gop);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1)))
|
#define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1)))
|
||||||
#define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1)))
|
#define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1)))
|
||||||
#define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1)))
|
#define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1)))
|
||||||
|
#define EFI_TIMEOUT (18 | (1UL << (BITS_PER_LONG-1)))
|
||||||
#define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1)))
|
#define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1)))
|
||||||
#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))
|
#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user