summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/armv7/stand/efiboot/conf.c4
-rw-r--r--sys/arch/armv7/stand/efiboot/efiboot.c68
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;