[v5,2/7] cmd: efidebug: add devices command

Message ID 20190121074923.29959-3-takahiro.akashi@linaro.org
State New
Headers show
Series
  • cmd: add efidebug for efi environment
Related show

Commit Message

AKASHI Takahiro Jan. 21, 2019, 7:49 a.m.
"devices" command prints all the uefi variables on the system.

=> efi devices
Scanning disk ahci_scsi.id0lun0...
Scanning disk ahci_scsi.id1lun0...
Found 4 disks
D
e
v                Device Path

Comments

Alexander Graf Jan. 21, 2019, 1:34 p.m. | #1
On 01/21/2019 08:49 AM, AKASHI Takahiro wrote:
> "devices" command prints all the uefi variables on the system.
>
> => efi devices
> Scanning disk ahci_scsi.id0lun0...
> Scanning disk ahci_scsi.id1lun0...
> Found 4 disks
> D
> e
> v                Device Path

Why the weird formatting of "Dev"?

Alex
AKASHI Takahiro Jan. 22, 2019, 1:38 a.m. | #2
Alex,

On Mon, Jan 21, 2019 at 02:34:43PM +0100, Alexander Graf wrote:
> On 01/21/2019 08:49 AM, AKASHI Takahiro wrote:
> >"devices" command prints all the uefi variables on the system.
> >
> >=> efi devices
> >Scanning disk ahci_scsi.id0lun0...
> >Scanning disk ahci_scsi.id1lun0...
> >Found 4 disks
> >D
> >e
> >v                Device Path
> 
> Why the weird formatting of "Dev"?

Good question :)
The format mimics a EDK2's shell.
The purpose is that we will be able to add some *narrow* data fields
later without spilling out a line length.

But I admit that we don't have to do so because we have an enough width,
16 digits, for ID (or address of efi object in this case).

=== From EDK2 UEFI Shell output ===
Shell> drivers
            T   D
D           Y C I
e           P F A
V  VERSION  E G G #D #C DRIVER NAME                         IMAGE NAME
== ======== = = = == == =================================== ==========
6E 0000000A D - -  1  - Platform Console Management Driver  ConPlatformDxe
   ...
Shell> devices
     T   D
     Y C I
     P F A
CTRL E G G #P #D #C  Device Name
==== = = = == == === =========================================================
  15 R - -  0  1   1 VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(38400,8,N,1)
     ...

Thanks,
-Takahiro Akashi

> Alex
>
Alexander Graf Jan. 22, 2019, 9:19 a.m. | #3
On 22.01.19 02:38, AKASHI Takahiro wrote:
> Alex,
> 
> On Mon, Jan 21, 2019 at 02:34:43PM +0100, Alexander Graf wrote:
>> On 01/21/2019 08:49 AM, AKASHI Takahiro wrote:
>>> "devices" command prints all the uefi variables on the system.
>>>
>>> => efi devices
>>> Scanning disk ahci_scsi.id0lun0...
>>> Scanning disk ahci_scsi.id1lun0...
>>> Found 4 disks
>>> D
>>> e
>>> v                Device Path
>>
>> Why the weird formatting of "Dev"?
> 
> Good question :)
> The format mimics a EDK2's shell.
> The purpose is that we will be able to add some *narrow* data fields
> later without spilling out a line length.
> 
> But I admit that we don't have to do so because we have an enough width,
> 16 digits, for ID (or address of efi object in this case).
> 
> === From EDK2 UEFI Shell output ===
> Shell> drivers
>             T   D
> D           Y C I
> e           P F A
> V  VERSION  E G G #D #C DRIVER NAME                         IMAGE NAME
> == ======== = = = == == =================================== ==========
> 6E 0000000A D - -  1  - Platform Console Management Driver  ConPlatformDxe

Ah, yes, in this output it makes sense. We don't have the table header
size problem though, so let's please not pull that ugly header in :).


Alex

Patch

================ ====================
        7ef3bfa0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)
        7ef3cca0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Scsi(0,0)
        7ef3d070 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Scsi(1,0)
        7ef3d1b0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Scsi(1,0)/HD(1,MBR,0x086246ba,0x800,0x40000)
        7ef3d3e0 /VenHw(e61d73b9-a384-4acc-aeab-82e828f3628b)/Scsi(1,0)/HD(2,MBR,0x086246ba,0x40800,0x3f800)

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 cmd/efidebug.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 98 insertions(+), 1 deletion(-)

diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index c54fb6cfa101..0c7b51364753 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -18,6 +18,8 @@ 
 #include <linux/ctype.h>
 #include <asm/global_data.h>
 
+#define BS systab.boottime
+
 static void dump_var_data(char *data, unsigned long len)
 {
 	char *start, *end, *p;
@@ -301,6 +303,97 @@  int do_efi_set_var_ext(cmd_tbl_t *cmdtp, int flag,
 }
 
 #ifdef CONFIG_CMD_EFIDEBUG
+static int efi_get_handles_by_proto(efi_guid_t *guid, efi_handle_t **handlesp,
+				    int *num)
+{
+	efi_handle_t *handles = NULL;
+	efi_uintn_t size = 0;
+	efi_status_t ret;
+
+	if (guid) {
+		ret = BS->locate_handle(BY_PROTOCOL, guid, NULL, &size,
+					handles);
+		if (ret == EFI_BUFFER_TOO_SMALL) {
+			handles = calloc(1, size);
+			if (!handles)
+				return -1;
+
+			ret = BS->locate_handle(BY_PROTOCOL, guid, NULL, &size,
+						handles);
+		}
+		if (ret != EFI_SUCCESS) {
+			free(handles);
+			return -1;
+		}
+	} else {
+		ret = BS->locate_handle(ALL_HANDLES, NULL, NULL, &size, NULL);
+		if (ret == EFI_BUFFER_TOO_SMALL) {
+			handles = calloc(1, size);
+			if (!handles)
+				return -1;
+
+			ret = BS->locate_handle(ALL_HANDLES, NULL, NULL, &size,
+						handles);
+		}
+		if (ret != EFI_SUCCESS) {
+			free(handles);
+			return -1;
+		}
+	}
+
+	*handlesp = handles;
+	*num = size / sizeof(efi_handle_t);
+
+	return 0;
+}
+
+static int efi_get_device_handle_info(efi_handle_t handle, u16 **dev_path_text)
+{
+	struct efi_device_path *dp;
+	efi_status_t ret;
+
+	ret = BS->open_protocol(handle, &efi_guid_device_path,
+				(void **)&dp, NULL /* FIXME */, NULL,
+				EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+	if (ret == EFI_SUCCESS) {
+		*dev_path_text = efi_dp_str(dp);
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+static int do_efi_show_devices(cmd_tbl_t *cmdtp, int flag,
+			       int argc, char * const argv[])
+{
+	efi_handle_t *handles;
+	u16 *dev_path_text;
+	int num, i;
+
+	handles = NULL;
+	num = 0;
+	if (efi_get_handles_by_proto(NULL, &handles, &num))
+		return CMD_RET_FAILURE;
+
+	if (!num)
+		return CMD_RET_SUCCESS;
+
+	printf("D\n");
+	printf("e\n");
+	printf("v                Device Path\n");
+	printf("================ ====================\n");
+	for (i = 0; i < num; i++) {
+		if (!efi_get_device_handle_info(handles[i], &dev_path_text)) {
+			printf("%16p %ls\n", handles[i], dev_path_text);
+			efi_free_pool(dev_path_text);
+		}
+	}
+
+	free(handles);
+
+	return CMD_RET_SUCCESS;
+}
+
 static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag,
 			   int argc, char * const argv[])
 {
@@ -694,6 +787,8 @@  static cmd_tbl_t cmd_efidebug_sub[] = {
 	U_BOOT_CMD_MKENT(dumpvar, CONFIG_SYS_MAXARGS, 1, do_efi_dump_var,
 			 "", ""),
 	U_BOOT_CMD_MKENT(setvar, CONFIG_SYS_MAXARGS, 1, do_efi_set_var, "", ""),
+	U_BOOT_CMD_MKENT(devices, CONFIG_SYS_MAXARGS, 1, do_efi_show_devices,
+			 "", ""),
 };
 
 /* Interpreter command to configure UEFI environment */
@@ -744,7 +839,9 @@  static char efidebug_help_text[] =
 	"  - show UEFI variable's value\n"
 	"efidebug setvar <name> [<value>]\n"
 	"  - set/delete uefi variable's value\n"
-	"    <value> may be \"=\"...\"\", \"=0x...\", \"=H...\", (set) or \"=\" (delete)\n";
+	"    <value> may be \"=\"...\"\", \"=0x...\", \"=H...\", (set) or \"=\" (delete)\n"
+	"efidebug devices\n"
+	"  - show uefi devices\n";
 #endif
 
 U_BOOT_CMD(