On Wed, May 10, 2017 at 08:35:28PM +0200, Patrick Wildt wrote:
>
> I don't think this is the correct fix. It might solve your issue, but I
> don't think it's completely right. So EFI has those so called device
> paths. A path is basically a list of nodes. To compare two paths you
> need to compare the whole path and not just a single node of it. If you
> store dp instead of dp0 you will basically only save a part of the path,
> not the full path.
>
> What you can do is print the full path of efi_bootdp like..
>
> for (dp = efi_bootdp; !IsDevicePathEnd(dp);
> dp = NextDevicePathNode(dp)) {
> printf("%x %x - ", DevicePathType(dp), DevicePathSubType(dp));
> }
> printf("\n");
>
> And do the same for the DPs that are being put into the
> efi_device_path_cmp function. That will at least print the types, but
> not the content of the nodes. That's a start into figuring out why it
> does not correctly compare the paths.
>
> Maybe there's a bug in the compare code?
Sorry, only now I understood what you said... Got
2 1 - 1 1 - 1 5 - 4 1 -
(2 1) (2 1) da db cmp da db cmp diff bootdev 1
(2 1) (2 1) da db cmp da db cmp diff bootdev 1
(2 1) (2 1) da db cmp da db cmp diff bootdev 1
with the following diff
Index: efiboot/efiboot.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.c,v
retrieving revision 1.17
diff -u -p -r1.17 efiboot.c
--- efiboot/efiboot.c 3 Mar 2017 08:56:18 -0000 1.17
+++ efiboot/efiboot.c 11 May 2017 21:39:14 -0000
@@ -89,6 +89,8 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TA
if (status == EFI_SUCCESS) {
for (dp = dp0; !IsDevicePathEnd(dp);
dp = NextDevicePathNode(dp)) {
+ printf("%x %x - ", DevicePathType(dp),
+ DevicePathSubType(dp));
if (DevicePathType(dp) == MEDIA_DEVICE_PATH &&
DevicePathSubType(dp) == MEDIA_HARDDRIVE_DP) {
bios_bootdev = 0x80;
@@ -96,6 +98,7 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TA
break;
}
}
+ printf("\n");
}
#ifdef __amd64__
@@ -199,10 +202,18 @@ efi_diskprobe(void)
(void **)&dp);
if (EFI_ERROR(status))
goto next;
+ printf("(%x %x) (%x %x) ",
+ DevicePathType(efi_bootdp),
+ DevicePathSubType(efi_bootdp),
+ DevicePathType(dp),
+ DevicePathSubType(dp)
+ );
if (!efi_device_path_cmp(efi_bootdp, dp, HARDWARE_DEVICE_PATH)&&
!efi_device_path_cmp(efi_bootdp, dp, ACPI_DEVICE_PATH) &&
!efi_device_path_cmp(efi_bootdp, dp, MESSAGING_DEVICE_PATH))
bootdev = 1;
+
+ printf("bootdev %d\n", bootdev);
next:
if (bootdev)
TAILQ_INSERT_HEAD(&efi_disklist, di, list);
@@ -222,12 +233,14 @@ efi_device_path_cmp(EFI_DEVICE_PATH *dpa
for (dp = dpa; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
if (DevicePathType(dp) == dptype) {
dpt_a = dp;
+ printf("da ");
break;
}
}
for (dp = dpb; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
if (DevicePathType(dp) == dptype) {
dpt_b = dp;
+ printf("db ");
break;
}
}
@@ -236,8 +249,11 @@ efi_device_path_cmp(EFI_DEVICE_PATH *dpa
cmp = DevicePathNodeLength(dpt_a) - DevicePathNodeLength(dpt_b);
if (cmp)
return (cmp);
+ printf("cmp ");
return (memcmp(dpt_a, dpt_b, DevicePathNodeLength(dpt_a)));
}
+
+ printf("diff ");
return ((uintptr_t)dpt_a - (uintptr_t)dpt_b);
}