All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arvind Sankar <nivedita@alum.mit.edu>
To: Ard Biesheuvel <ardb@kernel.org>
Cc: linux-efi@vger.kernel.org
Subject: [PATCH 19/24] efi/gop: Add an option to list out the available GOP modes
Date: Mon, 18 May 2020 15:07:11 -0400	[thread overview]
Message-ID: <20200518190716.751506-20-nivedita@alum.mit.edu> (raw)
In-Reply-To: <20200518190716.751506-1-nivedita@alum.mit.edu>

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

Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
---
 Documentation/fb/efifb.rst                    |  5 +
 .../firmware/efi/libstub/efi-stub-helper.c    | 35 +++++++
 drivers/firmware/efi/libstub/efistub.h        |  2 +
 drivers/firmware/efi/libstub/gop.c            | 97 ++++++++++++++++++-
 include/linux/efi.h                           |  1 +
 5 files changed, 139 insertions(+), 1 deletion(-)

diff --git a/Documentation/fb/efifb.rst b/Documentation/fb/efifb.rst
index 519550517fd4..6badff64756f 100644
--- a/Documentation/fb/efifb.rst
+++ b/Documentation/fb/efifb.rst
@@ -63,4 +63,9 @@ auto
         with the highest resolution, it will choose one with the highest color
         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>
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index c0278a8063b7..a36f3af6e130 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -463,3 +463,38 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image,
 
 	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;
+}
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index c7c03099367f..ad7e0406d0ba 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -323,6 +323,8 @@ union efi_simple_text_input_protocol {
 	} mixed_mode;
 };
 
+efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key);
+
 union efi_simple_text_output_protocol {
 	struct {
 		void *reset;
diff --git a/drivers/firmware/efi/libstub/gop.c b/drivers/firmware/efi/libstub/gop.c
index 34c0cba2c8bf..ea5da307d542 100644
--- a/drivers/firmware/efi/libstub/gop.c
+++ b/drivers/firmware/efi/libstub/gop.c
@@ -19,7 +19,8 @@ enum efi_cmdline_option {
 	EFI_CMDLINE_NONE,
 	EFI_CMDLINE_MODE_NUM,
 	EFI_CMDLINE_RES,
-	EFI_CMDLINE_AUTO
+	EFI_CMDLINE_AUTO,
+	EFI_CMDLINE_LIST
 };
 
 static struct {
@@ -100,6 +101,19 @@ static bool parse_auto(char *option, char **next)
 	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)
 {
 	while (*option) {
@@ -109,6 +123,8 @@ void efi_parse_option_graphics(char *option)
 			continue;
 		if (parse_auto(option, &option))
 			continue;
+		if (parse_list(option, &option))
+			continue;
 
 		while (*option && *option++ != ',')
 			;
@@ -290,6 +306,82 @@ static u32 choose_mode_auto(efi_graphics_output_protocol_t *gop)
 	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)
 {
 	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:
 		new_mode = choose_mode_auto(gop);
 		break;
+	case EFI_CMDLINE_LIST:
+		new_mode = choose_mode_list(gop);
+		break;
 	default:
 		return;
 	}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 974648db0c68..609201bd4682 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -39,6 +39,7 @@
 #define EFI_WRITE_PROTECTED	( 8 | (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_TIMEOUT		(18 | (1UL << (BITS_PER_LONG-1)))
 #define EFI_ABORTED		(21 | (1UL << (BITS_PER_LONG-1)))
 #define EFI_SECURITY_VIOLATION	(26 | (1UL << (BITS_PER_LONG-1)))
 
-- 
2.26.2


  parent reply	other threads:[~2020-05-18 19:07 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-18 19:06 [PATCH 00/24] efi/libstub: Add printf implementation Arvind Sankar
2020-05-18 19:06 ` [PATCH 01/24] efi/libstub: Include dependencies of efistub.h Arvind Sankar
2020-05-18 19:06 ` [PATCH 02/24] efi/libstub: Rename efi_[char16_]printk to efi_[char16_]puts Arvind Sankar
2020-05-18 19:06 ` [PATCH 03/24] efi/libstub: Buffer output of efi_puts Arvind Sankar
2020-05-18 19:06 ` [PATCH 04/24] efi/libstub: Add a basic printf implementation Arvind Sankar
2020-05-18 19:06 ` [PATCH 05/24] efi/libstub: Optimize for size instead of speed Arvind Sankar
2020-06-05  0:31   ` Andrey Ignatov
2020-06-05  6:33     ` Ard Biesheuvel
2020-06-05 13:14       ` Arvind Sankar
2020-06-05 13:32         ` Arvind Sankar
2020-06-05 14:53           ` Ard Biesheuvel
2020-06-05 15:10             ` Arvind Sankar
2020-06-05 15:11               ` Ard Biesheuvel
2020-06-05 15:06           ` [PATCH] efi/x86: Fix build with gcc 4 Arvind Sankar
2020-06-05 16:09             ` Andrey Ignatov
2020-06-15  9:43               ` Ard Biesheuvel
2020-06-19 16:46             ` [tip: efi/urgent] " tip-bot2 for Arvind Sankar
2020-05-18 19:06 ` [PATCH 06/24] efi/printf: Drop %n format and L qualifier Arvind Sankar
2020-05-18 19:06 ` [PATCH 07/24] efi/printf: Add 64-bit and 8-bit integer support Arvind Sankar
2020-05-18 19:07 ` [PATCH 08/24] efi/printf: Factor out flags parsing and handle '%' earlier Arvind Sankar
2020-05-18 19:07 ` [PATCH 09/24] efi/printf: Fix minor bug in precision handling Arvind Sankar
2020-05-18 19:07 ` [PATCH 10/24] efi/printf: Merge 'p' with the integer formats Arvind Sankar
2020-05-18 19:07 ` [PATCH 11/24] efi/printf: Factor out width/precision parsing Arvind Sankar
2020-05-18 19:07 ` [PATCH 12/24] efi/printf: Factor out integer argument retrieval Arvind Sankar
2020-05-18 19:07 ` [PATCH 13/24] efi/printf: Handle null string input Arvind Sankar
2020-05-18 19:07 ` [PATCH 14/24] efi/printf: Refactor code to consolidate padding and output Arvind Sankar
2020-05-18 19:07 ` [PATCH 15/24] efi/printf: Abort on invalid format Arvind Sankar
2020-05-18 19:07 ` [PATCH 16/24] efi/printf: Turn vsprintf into vsnprintf Arvind Sankar
2020-05-18 19:07 ` [PATCH 17/24] efi/libstub: Implement printk-style logging Arvind Sankar
2020-05-19  8:22   ` Ard Biesheuvel
2020-05-19 15:07     ` Arvind Sankar
2020-05-20 16:38       ` Arvind Sankar
2020-05-20 16:38         ` Ard Biesheuvel
2020-05-20 17:02           ` Arvind Sankar
2020-05-20 17:09             ` Ard Biesheuvel
2020-05-18 19:07 ` [PATCH 18/24] efi/libstub: Add definitions for console input and events Arvind Sankar
2020-05-18 19:07 ` Arvind Sankar [this message]
2020-05-18 19:07 ` [PATCH 20/24] efi/printf: Add support for wchar_t (UTF-16) Arvind Sankar
2020-05-18 19:07 ` [PATCH 21/24] efi/libstub: Add UTF-8 decoding to efi_puts Arvind Sankar
2020-05-18 19:07 ` [PATCH 22/24] efi/libstub: Use %ls for filename Arvind Sankar
2020-05-18 19:07 ` [PATCH 23/24] efi/libstub: Get the exact UTF-8 length Arvind Sankar
2020-05-18 19:07 ` [PATCH 24/24] efi/libstub: Use snprintf with %ls to convert the command line Arvind Sankar
2020-05-19  7:53 ` [PATCH 00/24] efi/libstub: Add printf implementation Ard Biesheuvel
2020-05-19 15:06   ` Arvind Sankar
2020-05-19 16:44     ` Ard Biesheuvel
2020-05-21  0:29       ` [PATCH] efi/libstub: Don't parse overlong command lines Arvind Sankar
2020-05-22 13:13         ` Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200518190716.751506-20-nivedita@alum.mit.edu \
    --to=nivedita@alum.mit.edu \
    --cc=ardb@kernel.org \
    --cc=linux-efi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.