summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2017-07-24 12:12:10 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2017-07-24 12:12:10 +0000
commit3edd865d1dc44162bd6933343846917997721676 (patch)
tree0a0699677468cc339014941f07ae7eca8ef06d8a /sys/arch
parent7351334cabb14622c95b35ad12b9b0943f6387d6 (diff)
Port amd64's updates to the device path comparison to arm64 as well.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/arm64/stand/efiboot/conf.c4
-rw-r--r--sys/arch/arm64/stand/efiboot/efiboot.c68
2 files changed, 49 insertions, 23 deletions
diff --git a/sys/arch/arm64/stand/efiboot/conf.c b/sys/arch/arm64/stand/efiboot/conf.c
index f9d08d5dc2b..74b3bc1614b 100644
--- a/sys/arch/arm64/stand/efiboot/conf.c
+++ b/sys/arch/arm64/stand/efiboot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.3 2017/05/07 11:07:48 kettenis Exp $ */
+/* $OpenBSD: conf.c,v 1.4 2017/07/24 12:12:09 patrick Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -35,7 +35,7 @@
#include "efiboot.h"
#include "efidev.h"
-const char version[] = "0.3";
+const char version[] = "0.4";
int debug = 0;
struct fs_ops file_system[] = {
diff --git a/sys/arch/arm64/stand/efiboot/efiboot.c b/sys/arch/arm64/stand/efiboot/efiboot.c
index 2f9d031d572..25c963da222 100644
--- a/sys/arch/arm64/stand/efiboot/efiboot.c
+++ b/sys/arch/arm64/stand/efiboot/efiboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.c,v 1.7 2017/05/07 11:07:48 kettenis Exp $ */
+/* $OpenBSD: efiboot.c,v 1.8 2017/07/24 12:12:09 patrick Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -52,6 +52,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_heap_init(void);
static void efi_memprobe_internal(void);
static void efi_timer_init(void);
@@ -169,13 +171,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);
@@ -187,8 +189,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))
@@ -198,26 +202,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;
}
@@ -226,6 +217,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);
+}
+
static EFI_GUID fdt_guid = FDT_TABLE_GUID;
#define efi_guidcmp(_a, _b) memcmp((_a), (_b), sizeof(EFI_GUID))