diff mbox

[U-Boot,4/4] efi_loader: use efi_devpath to get correct boot device-path

Message ID 20170721184339.3042-5-robdclark@gmail.com
State Deferred
Delegated to: Alexander Graf
Headers show

Commit Message

Rob Clark July 21, 2017, 6:43 p.m. UTC
This way grub can properly match up the loaded_image device-path to a
partition device object, so it can locate it's grub.cfg.

Signed-off-by: Rob Clark <robdclark@gmail.com>
---
 cmd/bootefi.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 5030b7bd86..ea0d5dbc79 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -41,6 +41,11 @@  static struct efi_device_path_file_path bootefi_image_path[] = {
 	}
 };
 
+/* if we have CONFIG_DM we construct a proper device-path from the
+ * boot device, otherwise fallback to using bootefi_device_path.
+ */
+static struct efi_device_path *real_bootefi_device_path;
+
 static struct efi_device_path_file_path bootefi_device_path[] = {
 	{
 		.dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE,
@@ -58,13 +63,12 @@  static efi_status_t EFIAPI bootefi_open_dp(void *handle, efi_guid_t *protocol,
 			void **protocol_interface, void *agent_handle,
 			void *controller_handle, uint32_t attributes)
 {
-	*protocol_interface = bootefi_device_path;
+	*protocol_interface = real_bootefi_device_path;
 	return EFI_SUCCESS;
 }
 
 /* The EFI loaded_image interface for the image executed via "bootefi" */
 static struct efi_loaded_image loaded_image_info = {
-	.device_handle = bootefi_device_path,
 	.file_path = bootefi_image_path,
 };
 
@@ -93,7 +97,6 @@  static struct efi_object loaded_image_info_obj = {
 
 /* The EFI object struct for the device the "bootefi" image was loaded from */
 static struct efi_object bootefi_device_obj = {
-	.handle = bootefi_device_path,
 	.protocols = {
 		{
 			/* When asking for the device path interface, return
@@ -239,8 +242,6 @@  static unsigned long do_bootefi_exec(void *efi, void *fdt)
 
 	if (!memcmp(bootefi_device_path[0].str, "N\0e\0t", 6))
 		loaded_image_info.device_handle = nethandle;
-	else
-		loaded_image_info.device_handle = bootefi_device_path;
 #endif
 #ifdef CONFIG_GENERATE_SMBIOS_TABLE
 	efi_smbios_register();
@@ -339,6 +340,18 @@  U_BOOT_CMD(
 	bootefi_help_text
 );
 
+#ifdef CONFIG_DM
+static int parse_partnum(const char *devnr)
+{
+	const char *str = strchr(devnr, ':');
+	if (str) {
+		str++;
+		return simple_strtoul(str, NULL, 16);
+	}
+	return 0;
+}
+#endif
+
 void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
 {
 	__maybe_unused struct blk_desc *desc;
@@ -376,9 +389,14 @@  void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
 	if (colon)
 		*colon = '\0';
 
+#ifdef CONFIG_DM
+	real_bootefi_device_path = efi_dp_from_part(desc, parse_partnum(devnr));
+#else
 	/* Patch bootefi_device_path to the target device */
+	real_bootefi_device_path = bootefi_device_path;
 	memset(bootefi_device_path[0].str, 0, sizeof(bootefi_device_path[0].str));
 	ascii2unicode(bootefi_device_path[0].str, devname);
+#endif
 
 	/* Patch bootefi_image_path to the target file path */
 	memset(bootefi_image_path[0].str, 0, sizeof(bootefi_image_path[0].str));
@@ -389,4 +407,7 @@  void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
 		snprintf(devname, sizeof(devname), "%s", path);
 	}
 	ascii2unicode(bootefi_image_path[0].str, devname);
+
+	loaded_image_info.device_handle = real_bootefi_device_path;
+	bootefi_device_obj.handle = real_bootefi_device_path;
 }