History

efi/gop: Add an option to list out the available GOP modes

Add video=efifb:list option to list the modes that are available.

Arvind Sankar committed 6 years ago

Commit 14c574f1 parent 9b47c525 files · +139 −1Browse files

Unified · Split

5 files
  1. Documentation/fb/efifb.rst +5 −0
  2. drivers/firmware/efi/libstub/efi-stub-helper.c +35 −0
  3. drivers/firmware/efi/libstub/efistub.h +2 −0
  4. drivers/firmware/efi/libstub/gop.c +96 −1
  5. include/linux/efi.h +1 −0
Documentation/fb/efifb.rst+5−0
@@ -63,4 +63,9 @@ auto · 62 unmodified lines
63 with the highest resolution, it will choose one with the highest color63 with the highest resolution, it will choose one with the highest color
64 depth.64 depth.
65 65
66list
67 The EFI stub will list out all the display modes that are available. A
68 specific mode can then be chosen using one of the above options for the
69 next boot.
70
66Edgar Hucek <gimli@dark-green.com>71Edgar Hucek <gimli@dark-green.com>
drivers/firmware/efi/libstub/efi-stub-helper.c+35−0
@@ -463,3 +463,38 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image, · 462 unmodified lines
463 463
464 return status;464 return status;
465}465}
466
467efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key)
468{
469 efi_event_t events[2], timer;
470 unsigned long index;
471 efi_simple_text_input_protocol_t *con_in;
472 efi_status_t status;
473
474 con_in = efi_table_attr(efi_system_table, con_in);
475 if (!con_in)
476 return EFI_UNSUPPORTED;
477 efi_set_event_at(events, 0, efi_table_attr(con_in, wait_for_key));
478
479 status = efi_bs_call(create_event, EFI_EVT_TIMER, 0, NULL, NULL, &timer);
480 if (status != EFI_SUCCESS)
481 return status;
482
483 status = efi_bs_call(set_timer, timer, EfiTimerRelative,
484 EFI_100NSEC_PER_USEC * usec);
485 if (status != EFI_SUCCESS)
486 return status;
487 efi_set_event_at(events, 1, timer);
488
489 status = efi_bs_call(wait_for_event, 2, events, &index);
490 if (status == EFI_SUCCESS) {
491 if (index == 0)
492 status = efi_call_proto(con_in, read_keystroke, key);
493 else
494 status = EFI_TIMEOUT;
495 }
496
497 efi_bs_call(close_event, timer);
498
499 return status;
500}
drivers/firmware/efi/libstub/efistub.h+2−0
@@ -323,6 +323,8 @@ union efi_simple_text_input_protocol { · 322 unmodified lines
323 } mixed_mode;323 } mixed_mode;
324};324};
325 325
326efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key);
327
326union efi_simple_text_output_protocol {328union efi_simple_text_output_protocol {
327 struct {329 struct {
328 void *reset;330 void *reset;
drivers/firmware/efi/libstub/gop.c+96−1
@@ -19,7 +19,8 @@ enum efi_cmdline_option { · 18 unmodified lines
19 EFI_CMDLINE_NONE,19 EFI_CMDLINE_NONE,
20 EFI_CMDLINE_MODE_NUM,20 EFI_CMDLINE_MODE_NUM,
21 EFI_CMDLINE_RES,21 EFI_CMDLINE_RES,
22 EFI_CMDLINE_AUTO22 EFI_CMDLINE_AUTO,
23 EFI_CMDLINE_LIST
23};24};
24 25
25static struct {26static struct {
@@ -100,6 +101,19 @@ static bool parse_auto(char *option, char **next) · 74 unmodified lines
100 return true;101 return true;
101}102}
102 103
104static bool parse_list(char *option, char **next)
105{
106 if (!strstarts(option, "list"))
107 return false;
108 option += strlen("list");
109 if (*option && *option++ != ',')
110 return false;
111 cmdline.option = EFI_CMDLINE_LIST;
112
113 *next = option;
114 return true;
115}
116
103void efi_parse_option_graphics(char *option)117void efi_parse_option_graphics(char *option)
104{118{
105 while (*option) {119 while (*option) {
@@ -109,6 +123,8 @@ void efi_parse_option_graphics(char *option) · 3 unmodified lines
109 continue;123 continue;
110 if (parse_auto(option, &option))124 if (parse_auto(option, &option))
111 continue;125 continue;
126 if (parse_list(option, &option))
127 continue;
112 128
113 while (*option && *option++ != ',')129 while (*option && *option++ != ',')
114 ;130 ;
@@ -290,6 +306,82 @@ static u32 choose_mode_auto(efi_graphics_output_protocol_t *gop) · 175 unmodified lines
290 return best_mode;306 return best_mode;
291}307}
292 308
309static u32 choose_mode_list(efi_graphics_output_protocol_t *gop)
310{
311 efi_status_t status;
312
313 efi_graphics_output_protocol_mode_t *mode;
314 efi_graphics_output_mode_info_t *info;
315 unsigned long info_size;
316
317 u32 max_mode, cur_mode;
318 int pf;
319 efi_pixel_bitmask_t pi;
320 u32 m, w, h;
321 u8 d;
322 const char *dstr;
323 bool valid;
324 efi_input_key_t key;
325
326 mode = efi_table_attr(gop, mode);
327
328 cur_mode = efi_table_attr(mode, mode);
329 max_mode = efi_table_attr(mode, max_mode);
330
331 efi_printk("Available graphics modes are 0-%u\n", max_mode-1);
332 efi_puts(" * = current mode\n"
333 " - = unusable mode\n");
334 for (m = 0; m < max_mode; m++) {
335 status = efi_call_proto(gop, query_mode, m,
336 &info_size, &info);
337 if (status != EFI_SUCCESS)
338 continue;
339
340 pf = info->pixel_format;
341 pi = info->pixel_information;
342 w = info->horizontal_resolution;
343 h = info->vertical_resolution;
344
345 efi_bs_call(free_pool, info);
346
347 valid = !(pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX);
348 d = 0;
349 switch (pf) {
350 case PIXEL_RGB_RESERVED_8BIT_PER_COLOR:
351 dstr = "rgb";
352 break;
353 case PIXEL_BGR_RESERVED_8BIT_PER_COLOR:
354 dstr = "bgr";
355 break;
356 case PIXEL_BIT_MASK:
357 dstr = "";
358 d = pixel_bpp(pf, pi);
359 break;
360 case PIXEL_BLT_ONLY:
361 dstr = "blt";
362 break;
363 default:
364 dstr = "xxx";
365 break;
366 }
367
368 efi_printk("Mode %3u %c%c: Resolution %ux%u-%s%.0hhu\n",
369 m,
370 m == cur_mode ? '*' : ' ',
371 !valid ? '-' : ' ',
372 w, h, dstr, d);
373 }
374
375 efi_puts("\nPress any key to continue (or wait 10 seconds)\n");
376 status = efi_wait_for_key(10 * EFI_USEC_PER_SEC, &key);
377 if (status != EFI_SUCCESS && status != EFI_TIMEOUT) {
378 efi_err("Unable to read key, continuing in 10 seconds\n");
379 efi_bs_call(stall, 10 * EFI_USEC_PER_SEC);
380 }
381
382 return cur_mode;
383}
384
293static void set_mode(efi_graphics_output_protocol_t *gop)385static void set_mode(efi_graphics_output_protocol_t *gop)
294{386{
295 efi_graphics_output_protocol_mode_t *mode;387 efi_graphics_output_protocol_mode_t *mode;
@@ -305,6 +397,9 @@ static void set_mode(efi_graphics_output_protocol_t *gop) · 9 unmodified lines
305 case EFI_CMDLINE_AUTO:397 case EFI_CMDLINE_AUTO:
306 new_mode = choose_mode_auto(gop);398 new_mode = choose_mode_auto(gop);
307 break;399 break;
400 case EFI_CMDLINE_LIST:
401 new_mode = choose_mode_list(gop);
402 break;
308 default:403 default:
309 return;404 return;
310 }405 }
include/linux/efi.h+1−0
@@ -39,6 +39,7 @@ · 38 unmodified lines
39#define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1)))39#define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1)))
40#define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1)))40#define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1)))
41#define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1)))41#define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1)))
42#define EFI_TIMEOUT (18 | (1UL << (BITS_PER_LONG-1)))
42#define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1)))43#define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1)))
43#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))44#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))
44 45