Blame SOURCES/0018-fallback-For-HD-device-paths-use-just-the-media-node.patch

4210fa
From dfd6c73a212f8cf6b32ce74807de9a08a87f0b79 Mon Sep 17 00:00:00 2001
4210fa
From: Peter Jones <pjones@redhat.com>
4210fa
Date: Fri, 31 Jan 2014 10:30:24 -0500
4210fa
Subject: [PATCH 18/74] [fallback] For HD() device paths, use just the media
4210fa
 node and later.
4210fa
4210fa
UEFI 2.x section 3.1.2 provides for "short-form device path", where the
4210fa
first element specified is a "hard drive media device path", so that you
4210fa
can move a disk around on different buses without invalidating your
4210fa
device path.  Fallback has not been using this option, though in most
4210fa
cases efibootmgr has.
4210fa
4210fa
Note that we still keep the full device path, because LoadImage()
4210fa
isn't necessarily the layer where HD() works - one some systems BDS is
4210fa
responsible for resolving the full path and passes that to LoadImage()
4210fa
instead.  So we have to do LoadImage() with the full path.
4210fa
---
4210fa
 fallback.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++---------------
4210fa
 1 file changed, 78 insertions(+), 25 deletions(-)
4210fa
4210fa
diff --git a/fallback.c b/fallback.c
4210fa
index ba864ee..a12bb74 100644
4210fa
--- a/fallback.c
4210fa
+++ b/fallback.c
4210fa
@@ -15,6 +15,27 @@
4210fa
 EFI_LOADED_IMAGE *this_image = NULL;
4210fa
 
4210fa
 static EFI_STATUS
4210fa
+FindSubDevicePath(EFI_DEVICE_PATH *In, UINT8 Type, UINT8 SubType,
4210fa
+		  EFI_DEVICE_PATH **Out)
4210fa
+{
4210fa
+	EFI_DEVICE_PATH *dp = In;
4210fa
+	if (!In || !Out)
4210fa
+		return EFI_INVALID_PARAMETER;
4210fa
+
4210fa
+	for (dp = In; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
4210fa
+		if (DevicePathType(dp) == Type &&
4210fa
+				DevicePathSubType(dp) == SubType) {
4210fa
+			*Out = DuplicateDevicePath(dp);
4210fa
+			if (!*Out)
4210fa
+				return EFI_OUT_OF_RESOURCES;
4210fa
+			return EFI_SUCCESS;
4210fa
+		}
4210fa
+	}
4210fa
+	*Out = NULL;
4210fa
+	return EFI_NOT_FOUND;
4210fa
+}
4210fa
+
4210fa
+static EFI_STATUS
4210fa
 get_file_size(EFI_FILE_HANDLE fh, UINTN *retsize)
4210fa
 {
4210fa
 	EFI_STATUS rc;
4210fa
@@ -93,7 +114,9 @@ make_full_path(CHAR16 *dirname, CHAR16 *filename, CHAR16 **out, UINT64 *outlen)
4210fa
 {
4210fa
 	UINT64 len;
4210fa
 	
4210fa
-	len = StrLen(dirname) + StrLen(filename) + StrLen(L"\\EFI\\\\") + 2;
4210fa
+	len = StrLen(L"\\EFI\\") + StrLen(dirname)
4210fa
+	    + StrLen(L"\\") + StrLen(filename)
4210fa
+	    + 2;
4210fa
 
4210fa
 	CHAR16 *fullpath = AllocateZeroPool(len*sizeof(CHAR16));
4210fa
 	if (!fullpath) {
4210fa
@@ -119,7 +142,8 @@ VOID *first_new_option_args = NULL;
4210fa
 UINTN first_new_option_size = 0;
4210fa
 
4210fa
 EFI_STATUS
4210fa
-add_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, CHAR16 *arguments)
4210fa
+add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp,
4210fa
+		CHAR16 *filename, CHAR16 *label, CHAR16 *arguments)
4210fa
 {
4210fa
 	static int i = 0;
4210fa
 	CHAR16 varname[] = L"Boot0000";
4210fa
@@ -136,24 +160,31 @@ add_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, CHAR16 *ar
4210fa
 		void *var = LibGetVariable(varname, &global);
4210fa
 		if (!var) {
4210fa
 			int size = sizeof(UINT32) + sizeof (UINT16) +
4210fa
-				StrLen(label)*2 + 2 + DevicePathSize(dp) +
4210fa
-				StrLen(arguments) * 2 + 2;
4210fa
+				StrLen(label)*2 + 2 + DevicePathSize(hddp) +
4210fa
+				StrLen(arguments) * 2;
4210fa
 
4210fa
 			CHAR8 *data = AllocateZeroPool(size);
4210fa
 			CHAR8 *cursor = data;
4210fa
 			*(UINT32 *)cursor = LOAD_OPTION_ACTIVE;
4210fa
 			cursor += sizeof (UINT32);
4210fa
-			*(UINT16 *)cursor = DevicePathSize(dp);
4210fa
+			*(UINT16 *)cursor = DevicePathSize(hddp);
4210fa
 			cursor += sizeof (UINT16);
4210fa
 			StrCpy((CHAR16 *)cursor, label);
4210fa
 			cursor += StrLen(label)*2 + 2;
4210fa
-			CopyMem(cursor, dp, DevicePathSize(dp));
4210fa
-			cursor += DevicePathSize(dp);
4210fa
+			CopyMem(cursor, hddp, DevicePathSize(hddp));
4210fa
+			cursor += DevicePathSize(hddp);
4210fa
 			StrCpy((CHAR16 *)cursor, arguments);
4210fa
 
4210fa
 			Print(L"Creating boot entry \"%s\" with label \"%s\" "
4210fa
 					L"for file \"%s\"\n",
4210fa
 				varname, label, filename);
4210fa
+
4210fa
+			if (!first_new_option) {
4210fa
+				first_new_option = DuplicateDevicePath(fulldp);
4210fa
+				first_new_option_args = arguments;
4210fa
+				first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
4210fa
+			}
4210fa
+
4210fa
 			rc = uefi_call_wrapper(RT->SetVariable, 5, varname,
4210fa
 				&global, EFI_VARIABLE_NON_VOLATILE |
4210fa
 					 EFI_VARIABLE_BOOTSERVICE_ACCESS |
4210fa
@@ -254,7 +285,10 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *
4210fa
 	if (EFI_ERROR(rc))
4210fa
 		return rc;
4210fa
 	
4210fa
-	EFI_DEVICE_PATH *dph = NULL, *dpf = NULL, *dp = NULL;
4210fa
+	EFI_DEVICE_PATH *dph = NULL;
4210fa
+	EFI_DEVICE_PATH *file = NULL;
4210fa
+	EFI_DEVICE_PATH *full_device_path = NULL;
4210fa
+	EFI_DEVICE_PATH *dp = NULL;
4210fa
 	
4210fa
 	dph = DevicePathFromHandle(this_image->DeviceHandle);
4210fa
 	if (!dph) {
4210fa
@@ -262,19 +296,31 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *
4210fa
 		goto err;
4210fa
 	}
4210fa
 
4210fa
-	dpf = FileDevicePath(fh, fullpath);
4210fa
-	if (!dpf) {
4210fa
+	file = FileDevicePath(fh, fullpath);
4210fa
+	if (!file) {
4210fa
 		rc = EFI_OUT_OF_RESOURCES;
4210fa
 		goto err;
4210fa
 	}
4210fa
 
4210fa
-	dp = AppendDevicePath(dph, dpf);
4210fa
-	if (!dp) {
4210fa
+	full_device_path = AppendDevicePath(dph, file);
4210fa
+	if (!full_device_path) {
4210fa
 		rc = EFI_OUT_OF_RESOURCES;
4210fa
 		goto err;
4210fa
 	}
4210fa
 
4210fa
+	rc = FindSubDevicePath(full_device_path,
4210fa
+				MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, &dp;;
4210fa
+	if (EFI_ERROR(rc)) {
4210fa
+		if (rc == EFI_NOT_FOUND) {
4210fa
+			dp = full_device_path;
4210fa
+		} else {
4210fa
+			rc = EFI_OUT_OF_RESOURCES;
4210fa
+			goto err;
4210fa
+		}
4210fa
+	}
4210fa
+
4210fa
 #ifdef DEBUG_FALLBACK
4210fa
+	{
4210fa
 	UINTN s = DevicePathSize(dp);
4210fa
 	int i;
4210fa
 	UINT8 *dpv = (void *)dp;
4210fa
@@ -287,20 +333,16 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *
4210fa
 
4210fa
 	CHAR16 *dps = DevicePathToStr(dp);
4210fa
 	Print(L"device path: \"%s\"\n", dps);
4210fa
-#endif
4210fa
-	if (!first_new_option) {
4210fa
-		CHAR16 *dps = DevicePathToStr(dp);
4210fa
-		Print(L"device path: \"%s\"\n", dps);
4210fa
-		first_new_option = DuplicateDevicePath(dp);
4210fa
-		first_new_option_args = arguments;
4210fa
-		first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
4210fa
 	}
4210fa
+#endif
4210fa
 
4210fa
-	add_boot_option(dp, fullpath, label, arguments);
4210fa
+	add_boot_option(dp, full_device_path, fullpath, label, arguments);
4210fa
 
4210fa
 err:
4210fa
-	if (dpf)
4210fa
-		FreePool(dpf);
4210fa
+	if (file)
4210fa
+		FreePool(file);
4210fa
+	if (full_device_path)
4210fa
+		FreePool(full_device_path);
4210fa
 	if (dp)
4210fa
 		FreePool(dp);
4210fa
 	if (fullpath)
4210fa
@@ -629,8 +671,19 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
4210fa
 			       first_new_option, NULL, 0,
4210fa
 			       &image_handle);
4210fa
 	if (EFI_ERROR(rc)) {
4210fa
-		Print(L"LoadImage failed: %d\n", rc);
4210fa
-		uefi_call_wrapper(BS->Stall, 1, 2000000);
4210fa
+		CHAR16 *dps = DevicePathToStr(first_new_option);
4210fa
+		UINTN s = DevicePathSize(first_new_option);
4210fa
+		int i;
4210fa
+		UINT8 *dpv = (void *)first_new_option;
4210fa
+		Print(L"LoadImage failed: %d\nDevice path: \"%s\"\n", rc, dps);
4210fa
+		for (i = 0; i < s; i++) {
4210fa
+			if (i > 0 && i % 16 == 0)
4210fa
+				Print(L"\n");
4210fa
+			Print(L"%02x ", dpv[i]);
4210fa
+		}
4210fa
+		Print(L"\n");
4210fa
+
4210fa
+		uefi_call_wrapper(BS->Stall, 1, 500000000);
4210fa
 		return rc;
4210fa
 	}
4210fa
 
4210fa
@@ -644,7 +697,7 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
4210fa
 	rc = uefi_call_wrapper(BS->StartImage, 3, image_handle, NULL, NULL);
4210fa
 	if (EFI_ERROR(rc)) {
4210fa
 		Print(L"StartImage failed: %d\n", rc);
4210fa
-		uefi_call_wrapper(BS->Stall, 1, 2000000);
4210fa
+		uefi_call_wrapper(BS->Stall, 1, 500000000);
4210fa
 	}
4210fa
 	return rc;
4210fa
 }
4210fa
-- 
4210fa
1.9.3
4210fa