diff mbox series

[3/4] cmd: efidebug: add RAM disk mount command

Message ID 20230707040045.485790-4-masahisa.kojima@linaro.org
State Superseded
Headers show
Series introduce EFI_RAM_DISK_PROTOCOL | expand

Commit Message

Masahisa Kojima July 7, 2023, 4 a.m. UTC
This commit implements the test commands for EFI_RAM_DISK_PROTOCOL.
With the disk load/unload commands, user can mount the
ISO image in the volatile memory through EFI_RAM_DISK_PROTOCOL.

Currently the load command can load only one image at a time
even if UEFI specification does not limit the number of images.
Anyway one image is enough for testing.

Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
---
 cmd/efidebug.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)
diff mbox series

Patch

diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 9622430c47..3466ae7e32 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -1421,6 +1421,113 @@  static int do_efi_query_info(struct cmd_tbl *cmdtp, int flag,
 	return CMD_RET_SUCCESS;
 }
 
+#ifdef CONFIG_EFI_RAM_DISK_PROTOCOL
+static struct efi_device_path *ram_disk_dp;
+static efi_guid_t virtual_cd_guid = EFI_VIRTUAL_CD_GUID;
+
+static int do_efi_disk_load(struct cmd_tbl *cmdtp, int flag, int argc,
+			    char *const argv[])
+{
+	u64 addr, size;
+	efi_status_t ret;
+	struct efi_ram_disk_protocol *ram_disk = NULL;
+
+	if (ram_disk_dp) {
+		printf("Only one image can be loaded\n");
+		return CMD_RET_FAILURE;
+	}
+
+	argc--;
+	argv++;
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	addr = hextoul(argv[0], NULL);
+	size = hextoul(argv[1], NULL);
+
+	ret = EFI_CALL(BS->locate_protocol(&efi_guid_ram_disk_protocol, NULL,
+					   (void **)&ram_disk));
+	if (ret != EFI_SUCCESS || !ram_disk) {
+		printf("No EFI_RAM_DISK_PROTOCOL found(ret = %lu)\n",
+		       ret & ~EFI_ERROR_MASK);
+		return CMD_RET_FAILURE;
+	}
+
+	ret = EFI_CALL(ram_disk->disk_register(addr, size, &virtual_cd_guid, NULL,
+					       &ram_disk_dp));
+	if (ret != EFI_SUCCESS || !ram_disk_dp) {
+		printf("RAM DISK register failed(ret = %lu)\n",
+		       ret & ~EFI_ERROR_MASK);
+		return CMD_RET_FAILURE;
+	}
+
+	return CMD_RET_SUCCESS;
+}
+
+static int do_efi_disk_unload(struct cmd_tbl *cmdtp, int flag, int argc,
+			      char *const argv[])
+{
+	efi_status_t ret;
+	struct efi_ram_disk_protocol *ram_disk = NULL;
+
+	ret = EFI_CALL(BS->locate_protocol(&efi_guid_ram_disk_protocol, NULL,
+					   (void **)&ram_disk));
+	if (ret != EFI_SUCCESS || !ram_disk) {
+		printf("No EFI_RAM_DISK_PROTOCOL found(ret = %lu)\n",
+		       ret & ~EFI_ERROR_MASK);
+		return CMD_RET_FAILURE;
+	}
+
+	ret = EFI_CALL(ram_disk->unregister(ram_disk_dp));
+	if (ret != EFI_SUCCESS) {
+		printf("RAM DISK unregister failed(ret = %lu)\n",
+		       ret & ~EFI_ERROR_MASK);
+		return CMD_RET_FAILURE;
+	}
+
+	ram_disk_dp = NULL;
+
+	return CMD_RET_SUCCESS;
+}
+
+static struct cmd_tbl cmd_efidebug_disk_sub[] = {
+	U_BOOT_CMD_MKENT(load, CONFIG_SYS_MAXARGS, 1, do_efi_disk_load, "", ""),
+	U_BOOT_CMD_MKENT(unload, CONFIG_SYS_MAXARGS, 1, do_efi_disk_unload, "", ""),
+};
+
+/**
+ * do_efi_disk() - manage UEFI ram disk device
+ *
+ * @cmdtp:	Command table
+ * @flag:	Command flag
+ * @argc:	Number of arguments
+ * @argv:	Argument array
+ * Return:	CMD_RET_SUCCESS on success,
+ *		CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
+ *
+ * Implement efidebug "disk" sub-command.
+ */
+static int do_efi_disk(struct cmd_tbl *cmdtp, int flag, int argc,
+		       char *const argv[])
+{
+	struct cmd_tbl *cp;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	argc--;
+	argv++;
+
+	cp = find_cmd_tbl(argv[0], cmd_efidebug_disk_sub,
+			  ARRAY_SIZE(cmd_efidebug_disk_sub));
+	if (!cp)
+		return CMD_RET_USAGE;
+
+	return cp->cmd(cmdtp, flag, argc, argv);
+}
+#endif
+
 static struct cmd_tbl cmd_efidebug_sub[] = {
 	U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""),
 #ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT
@@ -1441,6 +1548,10 @@  static struct cmd_tbl cmd_efidebug_sub[] = {
 			 "", ""),
 	U_BOOT_CMD_MKENT(query, CONFIG_SYS_MAXARGS, 1, do_efi_query_info,
 			 "", ""),
+#ifdef CONFIG_EFI_RAM_DISK_PROTOCOL
+	U_BOOT_CMD_MKENT(disk, CONFIG_SYS_MAXARGS, 1, do_efi_disk,
+			 "", ""),
+#endif
 };
 
 /**
@@ -1526,6 +1637,12 @@  static char efidebug_help_text[] =
 	"  - show UEFI memory map\n"
 	"efidebug tables\n"
 	"  - show UEFI configuration tables\n"
+#ifdef CONFIG_EFI_RAM_DISK_PROTOCOL
+	"efidebug disk load <address> <size>\n"
+	"  - load ISO image\n"
+	"efidebug disk unload\n"
+	"  - unload ISO image\n"
+#endif
 #ifdef CONFIG_CMD_BOOTEFI_BOOTMGR
 	"efidebug test bootmgr\n"
 	"  - run simple bootmgr for test\n"