[RFC 1/1] cmd: add command to dump EFI block devices
Heinrich Schuchardt
heinrich.schuchardt at canonical.com
Tue Oct 4 14:33:50 CEST 2022
Provide a command to dump
* all block devices
* the protocol interfaces installed on these
* the open protocol information
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
---
When working on the EFI DM integration this command will us help to
better understand the setup.
We might want to add some of the output to efidebug in future.
---
cmd/Kconfig | 7 ++
cmd/Makefile | 1 +
cmd/blkdump.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 184 insertions(+)
create mode 100644 cmd/blkdump.c
diff --git a/cmd/Kconfig b/cmd/Kconfig
index bfa12ce12a..8c34a139fc 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1850,6 +1850,13 @@ endif
menu "Misc commands"
+config CMD_BLKDUMP
+ bool "Enable 'blkdump' command"
+ depends on EFI_LOADER
+ default y
+ help
+ Dump open protocol information for block devices
+
config CMD_BMP
bool "Enable 'bmp' command"
depends on LCD || DM_VIDEO || VIDEO
diff --git a/cmd/Makefile b/cmd/Makefile
index cf6ce1bd6f..6ec219b3bc 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_CMD_AB_SELECT) += ab_select.o
obj-$(CONFIG_CMD_ADC) += adc.o
obj-$(CONFIG_CMD_ARMFLASH) += armflash.o
obj-$(CONFIG_BLK) += blk_common.o
+obj-$(CONFIG_CMD_BLKDUMP) += blkdump.o
obj-$(CONFIG_CMD_BOOTDEV) += bootdev.o
obj-$(CONFIG_CMD_BOOTFLOW) += bootflow.o
obj-$(CONFIG_CMD_BOOTMETH) += bootmeth.o
diff --git a/cmd/blkdump.c b/cmd/blkdump.c
new file mode 100644
index 0000000000..936d92468b
--- /dev/null
+++ b/cmd/blkdump.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * The 'sbi' command displays information about the SBI implementation.
+ *
+ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk at gmx.de>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm/device.h>
+#include <efi_loader.h>
+
+/**
+ * print_handle() - print handle
+ *
+ * @handle: handle
+ */
+void print_handle(efi_handle_t handle)
+{
+ struct efi_handler *handler;
+ struct efi_device_path *dp;
+ efi_uintn_t ret;
+
+ printf("%p", handle);
+
+ if (handle->dev)
+ printf(" (%s)", handle->dev->name);
+
+ ret = efi_search_protocol(handle, &efi_guid_device_path, &handler);
+ if (ret != EFI_SUCCESS)
+ goto out;
+ dp = handler->protocol_interface;
+ printf(" - %pD", dp);
+
+out:
+ printf("\n");
+}
+
+/**
+ * print_attributes() - print attributes
+ *
+ * @val: value
+ */
+void print_attributes(u32 val)
+{
+ const char *attr_text[] = {
+ "EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL",
+ "EFI_OPEN_PROTOCOL_GET_PROTOCOL",
+ "EFI_OPEN_PROTOCOL_TEST_PROTOCOL",
+ "EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER",
+ "EFI_OPEN_PROTOCOL_BY_DRIVER",
+ "EFI_OPEN_PROTOCOL_EXCLUSIVE",
+ NULL,
+ };
+ u32 mask = 1;
+ int first = 0;
+
+ for (const char **pos = attr_text; *pos; ++pos, mask <<= 1) {
+ if (mask & val) {
+ if (first) {
+ printf(" | ");
+ ++first;
+ }
+ printf(*pos);
+ }
+ }
+ printf("\n");
+}
+
+/**
+ * print_open_protocol_information() print open protocol information
+ *
+ * @handle: handle
+ * @prot: protocol GUID
+ */
+void print_open_protocol_information(efi_handle_t handle, efi_guid_t *prot)
+{
+ efi_status_t ret;
+ struct efi_open_protocol_info_entry *buffer;
+ efi_uintn_t count;
+
+ ret = EFI_CALL(systab.boottime->open_protocol_information(
+ handle, prot, &buffer, &count));
+ if (ret == EFI_NOT_FOUND) {
+ printf("Handle doesn't support specified protocol\n");
+ return;
+ }
+ if (ret != EFI_SUCCESS) {
+ printf("Failed to get open protocol information\n");
+ return;
+ }
+
+ for (efi_uintn_t i = 0; i < count; ++i) {
+ struct efi_open_protocol_info_entry *info = &buffer[i];
+
+ printf(" AgentHandle - ");
+ print_handle(info->agent_handle);
+ printf(" ControllerHandle - ");
+ print_handle(info->controller_handle);
+ printf(" Attributes - ");
+ print_attributes(info->attributes);
+ printf(" OpenCount - %d\n", info->open_count);
+ }
+
+ if (buffer)
+ efi_free_pool(buffer);
+}
+
+/**
+ * print_handle() - print protocols installed on handle
+ *
+ * @handle: handle
+ */
+void print_protocols(efi_handle_t handle)
+{
+ efi_guid_t **buffer = NULL;
+ efi_uintn_t count;
+ efi_status_t ret;
+
+ ret = EFI_CALL(systab.boottime->protocols_per_handle(
+ handle, &buffer, &count));
+ if (ret != EFI_SUCCESS) {
+ printf("Can't get protocols\n\n");
+ return;
+ }
+ for (efi_uintn_t i = 0; i < count; ++i) {
+ efi_guid_t *prot = buffer[i];
+
+ printf(" protocol: %pUl - %pUs\n", prot, prot);
+ print_open_protocol_information(handle, prot);
+ }
+ if (buffer)
+ efi_free_pool(buffer);
+}
+
+static int do_blkdump(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ efi_handle_t *handles = NULL;
+ efi_uintn_t no_handles;
+ efi_status_t ret;
+
+ /* Initialize UEFI drivers */
+ ret = efi_init_obj_list();
+ if (ret != EFI_SUCCESS) {
+ printf("Cannot initialize UEFI sub-system");
+ return CMD_RET_FAILURE;
+ }
+
+ ret = EFI_CALL(efi_locate_handle_buffer(BY_PROTOCOL,
+ &efi_block_io_guid, NULL,
+ &no_handles, &handles));
+ if (ret != EFI_SUCCESS) {
+ printf("Could not locate handles\n");
+ return CMD_RET_FAILURE;
+ }
+ for (efi_uintn_t i = 0; i < no_handles; ++i) {
+ efi_handle_t h = handles[i];
+
+ print_handle(h);
+ print_protocols(h);
+ printf("\n");
+ }
+
+ if (handles)
+ efi_free_pool(handles);
+
+
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD_COMPLETE(
+ blkdump, 1, 0, do_blkdump,
+ "display EFI block devices",
+ NULL, NULL
+);
--
2.37.2
More information about the U-Boot
mailing list