diff options
-rw-r--r-- | sys/arch/armv7/stand/efiboot/conf.c | 4 | ||||
-rw-r--r-- | sys/arch/armv7/stand/efiboot/efiboot.c | 68 |
2 files changed, 49 insertions, 23 deletions
diff --git a/sys/arch/armv7/stand/efiboot/conf.c b/sys/arch/armv7/stand/efiboot/conf.c index d95ff7633c3..7cac47de852 100644 --- a/sys/arch/armv7/stand/efiboot/conf.c +++ b/sys/arch/armv7/stand/efiboot/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.6 2016/10/23 19:06:08 kettenis Exp $ */ +/* $OpenBSD: conf.c,v 1.7 2017/07/24 11:15:34 patrick Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -35,7 +35,7 @@ #include "efiboot.h" #include "efidev.h" -const char version[] = "0.5"; +const char version[] = "0.6"; int debug = 0; struct fs_ops file_system[] = { diff --git a/sys/arch/armv7/stand/efiboot/efiboot.c b/sys/arch/armv7/stand/efiboot/efiboot.c index 9b3c1431b15..f28c8749cb9 100644 --- a/sys/arch/armv7/stand/efiboot/efiboot.c +++ b/sys/arch/armv7/stand/efiboot/efiboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: efiboot.c,v 1.14 2017/03/11 09:09:14 jsg Exp $ */ +/* $OpenBSD: efiboot.c,v 1.15 2017/07/24 11:15:34 patrick Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net> @@ -46,6 +46,8 @@ static EFI_GUID imgp_guid = LOADED_IMAGE_PROTOCOL; static EFI_GUID blkio_guid = BLOCK_IO_PROTOCOL; static EFI_GUID devp_guid = DEVICE_PATH_PROTOCOL; +static int efi_device_path_depth(EFI_DEVICE_PATH *dp, int); +static int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int); static void efi_timer_init(void); static void efi_timer_cleanup(void); @@ -163,13 +165,13 @@ EFI_BLOCK_IO *disk; void efi_diskprobe(void) { - int i, bootdev; + int i, depth = -1; UINTN sz; EFI_STATUS status; EFI_HANDLE *handles = NULL; EFI_BLOCK_IO *blkio; EFI_BLOCK_IO_MEDIA *media; - EFI_DEVICE_PATH *dp, *bp; + EFI_DEVICE_PATH *dp; sz = 0; status = EFI_CALL(BS->LocateHandle, ByProtocol, &blkio_guid, 0, &sz, 0); @@ -181,8 +183,10 @@ efi_diskprobe(void) if (handles == NULL || EFI_ERROR(status)) panic("BS->LocateHandle() returns %d", status); + if (efi_bootdp != NULL) + depth = efi_device_path_depth(efi_bootdp, MEDIA_DEVICE_PATH); + for (i = 0; i < sz / sizeof(EFI_HANDLE); i++) { - bootdev = 0; status = EFI_CALL(BS->HandleProtocol, handles[i], &blkio_guid, (void **)&blkio); if (EFI_ERROR(status)) @@ -192,26 +196,13 @@ efi_diskprobe(void) if (media->LogicalPartition || !media->MediaPresent) continue; - if (efi_bootdp == NULL) - goto next; + if (efi_bootdp == NULL || depth == -1) + continue; status = EFI_CALL(BS->HandleProtocol, handles[i], &devp_guid, (void **)&dp); if (EFI_ERROR(status)) - goto next; - bp = efi_bootdp; - while (1) { - if (IsDevicePathEnd(dp)) { - bootdev = 1; - break; - } - if (memcmp(dp, bp, sizeof(EFI_DEVICE_PATH)) != 0 || - memcmp(dp, bp, DevicePathNodeLength(dp)) != 0) - break; - dp = NextDevicePathNode(dp); - bp = NextDevicePathNode(bp); - } -next: - if (bootdev) { + continue; + if (efi_device_path_ncmp(efi_bootdp, dp, depth) == 0) { disk = blkio; break; } @@ -220,6 +211,41 @@ next: free(handles, sz); } +static int +efi_device_path_depth(EFI_DEVICE_PATH *dp, int dptype) +{ + int i; + + for (i = 0; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp), i++) { + if (DevicePathType(dp) == dptype) + return (i); + } + + return (-1); +} + +static int +efi_device_path_ncmp(EFI_DEVICE_PATH *dpa, EFI_DEVICE_PATH *dpb, int deptn) +{ + int i, cmp; + + for (i = 0; i < deptn; i++) { + if (IsDevicePathEnd(dpa) || IsDevicePathEnd(dpb)) + return ((IsDevicePathEnd(dpa) && IsDevicePathEnd(dpb)) + ? 0 : (IsDevicePathEnd(dpa))? -1 : 1); + cmp = DevicePathNodeLength(dpa) - DevicePathNodeLength(dpb); + if (cmp) + return (cmp); + cmp = memcmp(dpa, dpb, DevicePathNodeLength(dpa)); + if (cmp) + return (cmp); + dpa = NextDevicePathNode(dpa); + dpb = NextDevicePathNode(dpb); + } + + return (0); +} + struct board_id { const char *name; uint32_t board_id; |