Tue Mar 13 14:54:52 2018 UTC ()
Pull up following revision(s) (requested by nonaka in ticket #625):
	sys/arch/i386/stand/efiboot/efidisk.c: revision 1.2
	sys/arch/i386/stand/efiboot/devopen.c: revision 1.2
	sys/arch/i386/stand/efiboot/efidisk.h: revision 1.2
	sys/arch/i386/stand/efiboot/boot.c: revision 1.6
	sys/arch/i386/stand/efiboot/efidisk_ll.c: revision 1.2
	sys/arch/i386/stand/efiboot/efidev.c: revision 1.1
	sys/arch/i386/stand/lib/biosdisk_ll.h: revision 1.16
	sys/arch/i386/stand/lib/biosdisk.h: revision 1.9
	sys/lib/libsa/cd9660.c: revision 1.31
	sys/arch/i386/stand/efiboot/efiboot.c: revision 1.5
	sys/arch/i386/stand/efiboot/efiboot.h: revision 1.6
	sys/arch/i386/stand/lib/biosdisk.c: revision 1.47
	sys/arch/i386/stand/efiboot/Makefile.efiboot: revision 1.10
	sys/arch/i386/stand/efiboot/TODO.efiboot: revision 1.4
efiboot: system can boot from CD/DVD-ROM media.

Add missed file in previous commit.


(martin)
diff -r1.9 -r1.9.2.1 src/sys/arch/i386/stand/efiboot/Makefile.efiboot
diff -r1.3 -r1.3.10.1 src/sys/arch/i386/stand/efiboot/TODO.efiboot
diff -r1.5 -r1.5.2.1 src/sys/arch/i386/stand/efiboot/boot.c
diff -r1.5 -r1.5.2.1 src/sys/arch/i386/stand/efiboot/efiboot.h
diff -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/devopen.c
diff -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/efidisk.c
diff -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/efidisk.h
diff -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/efidisk_ll.c
diff -r1.4 -r1.4.10.1 src/sys/arch/i386/stand/efiboot/efiboot.c
diff -r0 -r1.1.2.2 src/sys/arch/i386/stand/efiboot/efidev.c
diff -r1.46 -r1.46.6.1 src/sys/arch/i386/stand/lib/biosdisk.c
diff -r1.8 -r1.8.52.1 src/sys/arch/i386/stand/lib/biosdisk.h
diff -r1.15 -r1.15.90.1 src/sys/arch/i386/stand/lib/biosdisk_ll.h
diff -r1.30 -r1.30.22.1 src/sys/lib/libsa/cd9660.c

cvs diff -r1.9 -r1.9.2.1 src/sys/arch/i386/stand/efiboot/Makefile.efiboot (expand / switch to context diff)
--- src/sys/arch/i386/stand/efiboot/Makefile.efiboot 2017/04/29 00:05:35 1.9
+++ src/sys/arch/i386/stand/efiboot/Makefile.efiboot 2018/03/13 14:54:52 1.9.2.1
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.efiboot,v 1.9 2017/04/29 00:05:35 nonaka Exp $
+# $NetBSD: Makefile.efiboot,v 1.9.2.1 2018/03/13 14:54:52 martin Exp $
 
 S=		${.CURDIR}/../../../../..
 
@@ -12,8 +12,8 @@
 LIBI386SRCS= boot.c biosdisk.c bootinfo.c bootinfo_biosgeom.c
 LIBI386SRCS+= bootmenu.c diskbuf.c exec.c menuutils.c
 LIBI386SRCS+= panic.c parseutils.c pread.c
-LIBI386SRCS+= eficons.c efidelay.c efidisk.c efidisk_ll.c efigetsecs.c
-LIBI386SRCS+= efimemory.c
+LIBI386SRCS+= eficons.c efidelay.c efidev.c efidisk.c efidisk_ll.c
+LIBI386SRCS+= efigetsecs.c efimemory.c
 SRCS= ${SOURCES} ${EXTRA_SOURCES} ${LIBI386SRCS}
 
 PIE_CFLAGS=
@@ -54,9 +54,11 @@
 CPPFLAGS+= -DEFI_ALLOCATE_MAX_ADDRESS=0x100000000ULL
 CPPFLAGS+= -DHEAP_VARIABLE
 CPPFLAGS+= -DSUPPORT_CD9660
+CPPFLAGS+= -D"devb2cdb(bno)=(bno)"
 CPPFLAGS+= -DSUPPORT_DOSFS
 CPPFLAGS+= -DSUPPORT_EXT2FS
 CPPFLAGS+= -DPASS_BIOSGEOM
+CPPFLAGS+= -DBIOSDISK_DEFAULT_SECSIZE=2048	# for bootinfo_biosgeom.c
 CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
 
 EFIDIR= ${S}/external/bsd/gnu-efi/dist
@@ -66,6 +68,7 @@
 
 SAMISCCPPFLAGS+= -DLIBSA_PRINTF_LONGLONG_SUPPORT
 SAMISCCPPFLAGS+= -DLIBSA_PRINTF_WIDTH_SUPPORT
+SAMISCCPPFLAGS+= -D"cdb2devb(bno)=(bno)"
 SAMISCMAKEFLAGS+= SA_USE_CREAD=yes      # Read compressed kernels
 SAMISCMAKEFLAGS+= SA_INCLUDE_NET=no     # Netboot via TFTP, NFS
 

cvs diff -r1.3 -r1.3.10.1 src/sys/arch/i386/stand/efiboot/TODO.efiboot (expand / switch to context diff)
--- src/sys/arch/i386/stand/efiboot/TODO.efiboot 2017/03/12 06:37:41 1.3
+++ src/sys/arch/i386/stand/efiboot/TODO.efiboot 2018/03/13 14:54:52 1.3.10.1
@@ -1,6 +1,5 @@
 - efiboot
  * handle UEFI variables
- * boot from CD/DVD (bootable from CD/DVD, but root fs not found.)
  * load boot.cfg from EFI system partition (FAT32)
 
 - kernel

cvs diff -r1.5 -r1.5.2.1 src/sys/arch/i386/stand/efiboot/boot.c (expand / switch to context diff)
--- src/sys/arch/i386/stand/efiboot/boot.c 2017/05/01 13:03:01 1.5
+++ src/sys/arch/i386/stand/efiboot/boot.c 2018/03/13 14:54:52 1.5.2.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot.c,v 1.5 2017/05/01 13:03:01 nonaka Exp $	*/
+/*	$NetBSD: boot.c,v 1.5.2.1 2018/03/13 14:54:52 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -419,7 +419,7 @@
 	const char *file; /* dummy */
 
 	if (*arg == '\0') {
-		biosdisk_probe();
+		efi_disk_show();
 		printf("default %s%d%c\n", default_devname, default_unit,
 		       'a' + default_partition);
 		return;
@@ -554,6 +554,7 @@
 void
 command_version(char *arg)
 {
+	CHAR16 *path;
 
 	if (strcmp(arg, "full") == 0) {
 		printf("ImageBase: 0x%" PRIxPTR "\n",
@@ -563,6 +564,10 @@
 		    ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
 		Print(L"EFI Firmware: %s (rev %d.%02d)\n", ST->FirmwareVendor,
 		    ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
+		path = DevicePathToStr(efi_bootdp);
+		Print(L"Boot DevicePath: %d:%d:%s\n", DevicePathType(efi_bootdp),
+		    DevicePathSubType(efi_bootdp), path);
+		FreePool(path);
 	}
 
 	printf("\n"

cvs diff -r1.5 -r1.5.2.1 src/sys/arch/i386/stand/efiboot/efiboot.h (expand / switch to context diff)
--- src/sys/arch/i386/stand/efiboot/efiboot.h 2017/05/01 13:03:01 1.5
+++ src/sys/arch/i386/stand/efiboot/efiboot.h 2018/03/13 14:54:52 1.5.2.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: efiboot.h,v 1.5 2017/05/01 13:03:01 nonaka Exp $	*/
+/*	$NetBSD: efiboot.h,v 1.5.2.1 2018/03/13 14:54:52 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -46,6 +46,7 @@
 /* efiboot.c */
 extern EFI_HANDLE IH;
 extern EFI_DEVICE_PATH *efi_bootdp;
+extern int efi_bootdp_type;
 extern EFI_LOADED_IMAGE *efi_li;
 extern uintptr_t efi_main_sp;
 extern physaddr_t efi_loadaddr, efi_kernel_start;
@@ -59,8 +60,13 @@
 void command_text(char *);
 void command_gop(char *);
 
+/* efidev.c */
+int efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
+int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int);
+
 /* efidisk.c */
 void efi_disk_probe(void);
+void efi_disk_show(void);
 
 /* efimemory.c */
 void efi_memory_probe(void);

cvs diff -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/devopen.c (expand / switch to context diff)
--- src/sys/arch/i386/stand/efiboot/devopen.c 2017/01/24 11:09:14 1.1
+++ src/sys/arch/i386/stand/efiboot/devopen.c 2018/03/13 14:54:52 1.1.12.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: devopen.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $	 */
+/*	$NetBSD: devopen.c,v 1.1.12.1 2018/03/13 14:54:52 martin Exp $	 */
 
 /*-
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -66,8 +66,11 @@
 
 	if (strcmp(devname, "hd") == 0)
 		*biosdev = 0x80 + unit;
+	if (strcmp(devname, "cd") == 0)
+		*biosdev = 0x80 + get_harddrives() + unit;
 	else
 		return ENXIO;
+
 	return 0;
 }
 
@@ -76,7 +79,13 @@
 {
 
 	*unit = biosdev & 0x7f;
-	*devname = "hd";
+
+	if (biosdev >= 0x80 + get_harddrives()) {
+		*devname = "cd";
+		*unit -= get_harddrives();
+	} else
+		*devname = "hd";
+
 	*partition = biosdisk_findpartition(biosdev, sector);
 }
 

cvs diff -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/efidisk.c (expand / switch to context diff)
--- src/sys/arch/i386/stand/efiboot/efidisk.c 2017/01/24 11:09:14 1.1
+++ src/sys/arch/i386/stand/efiboot/efidisk.c 2018/03/13 14:54:52 1.1.12.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: efidisk.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $	*/
+/*	$NetBSD: efidisk.c,v 1.1.12.1 2018/03/13 14:54:52 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -26,8 +26,15 @@
  * SUCH DAMAGE.
  */
 
+#define FSTYPENAMES	/* for sys/disklabel.h */
+
 #include "efiboot.h"
 
+#include <sys/disklabel.h>
+
+#include "biosdisk.h"
+#include "biosdisk_ll.h"
+#include "devopen.h"
 #include "efidisk.h"
 
 static struct efidiskinfo_lh efi_disklist;
@@ -41,10 +48,9 @@
 	EFI_HANDLE *handles;
 	EFI_BLOCK_IO *bio;
 	EFI_BLOCK_IO_MEDIA *media;
+	EFI_DEVICE_PATH *dp;
 	struct efidiskinfo *edi;
-	EFI_DEVICE_PATH *dp, *bdp;
-	bool bootdev;
-	int dev;
+	int dev, depth = -1;
 
 	TAILQ_INIT(&efi_disklist);
 
@@ -53,6 +59,18 @@
 	if (EFI_ERROR(status))
 		Panic(L"LocateHandle(BlockIoProtocol): %r", status);
 
+	if (efi_bootdp != NULL)
+		depth = efi_device_path_depth(efi_bootdp, MEDIA_DEVICE_PATH);
+
+	/*
+	 * U-Boot incorrectly represents devices with a single
+	 * MEDIA_DEVICE_PATH component.  In that case include that
+	 * component into the matching, otherwise we'll blindly select
+	 * the first device.
+	 */
+	if (depth == 0)
+		depth = 1;
+
 	for (i = 0; i < nhandles; i++) {
 		status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i],
 		    &BlockIoProtocol, (void **)&bio);
@@ -65,43 +83,114 @@
 
 		edi = alloc(sizeof(struct efidiskinfo));
 		memset(edi, 0, sizeof(*edi));
+		edi->type = BIOSDISK_TYPE_HD;
 		edi->bio = bio;
 		edi->media_id = media->MediaId;
 
-		bootdev = false;
-		if (efi_bootdp == NULL)
-			goto next;
-
-		status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i],
-		    &DevicePathProtocol, (void **)&dp);
-		if (EFI_ERROR(status))
-			goto next;
-
-		bdp = efi_bootdp;
-		for (;;) {
-			if (IsDevicePathEnd(dp)) {
-				bootdev = true;
-				break;
+		if (efi_bootdp != NULL && depth > 0) {
+			status = uefi_call_wrapper(BS->HandleProtocol, 3,
+			    handles[i], &DevicePathProtocol, (void **)&dp);
+			if (EFI_ERROR(status))
+				goto next;
+			if (efi_device_path_ncmp(efi_bootdp, dp, depth) == 0) {
+				edi->bootdev = true;
+				TAILQ_INSERT_HEAD(&efi_disklist, edi,
+				    list);
+				continue;
 			}
-			if (memcmp(dp, bdp, sizeof(EFI_DEVICE_PATH)) != 0 ||
-			    memcmp(dp, bdp, DevicePathNodeLength(dp)) != 0)
-				break;
-			dp = NextDevicePathNode(dp);
-			bdp = NextDevicePathNode(bdp);
 		}
 next:
-		if (bootdev)
-			TAILQ_INSERT_HEAD(&efi_disklist, edi, list);
-		else
-			TAILQ_INSERT_TAIL(&efi_disklist, edi, list);
+		TAILQ_INSERT_TAIL(&efi_disklist, edi, list);
 	}
 
 	FreePool(handles);
 
+	if (efi_bootdp_type == BIOSDISK_TYPE_CD) {
+		TAILQ_FOREACH(edi, &efi_disklist, list) {
+			if (edi->bootdev) {
+				edi = TAILQ_FIRST(&efi_disklist);
+				edi->type = BIOSDISK_TYPE_CD;
+				TAILQ_REMOVE(&efi_disklist, edi, list);
+				TAILQ_INSERT_TAIL(&efi_disklist, edi, list);
+				break;
+			}
+		}
+	}
+
 	dev = 0x80;
 	TAILQ_FOREACH(edi, &efi_disklist, list) {
 		edi->dev = dev++;
-		nefidisks++;
+		if (edi->type == BIOSDISK_TYPE_HD)
+			nefidisks++;
+		if (edi->bootdev)
+			boot_biosdev = edi->dev;
+	}
+}
+
+void
+efi_disk_show(void)
+{
+	const struct efidiskinfo *edi;
+	EFI_BLOCK_IO_MEDIA *media;
+	struct biosdisk_partition *part;
+	uint64_t size;
+	int i, nparts;
+	bool first;
+
+	TAILQ_FOREACH(edi, &efi_disklist, list) {
+		media = edi->bio->Media;
+		first = true;
+		printf("disk ");
+		switch (edi->type) {
+		case BIOSDISK_TYPE_CD:
+			printf("cd0");
+			printf(" mediaId %u", media->MediaId);
+			if (edi->media_id != media->MediaId)
+				printf("(%u)", edi->media_id);
+			printf("\n");
+			printf("  cd0a\n");
+			break;
+		case BIOSDISK_TYPE_HD:
+			printf("hd%d", edi->dev & 0x7f);
+			printf(" mediaId %u", media->MediaId);
+			if (edi->media_id != media->MediaId)
+				printf("(%u)", edi->media_id);
+			printf(" size ");
+			size = (media->LastBlock + 1) * media->BlockSize;
+			if (size >= (10ULL * 1024 * 1024 * 1024))
+				printf("%"PRIu64" GB", size / (1024 * 1024 * 1024));
+			else
+				printf("%"PRIu64" MB", size / (1024 * 1024));
+			printf("\n");
+			break;
+		}
+		if (edi->type != BIOSDISK_TYPE_HD)
+			continue;
+
+		if (biosdisk_readpartition(edi->dev, &part, &nparts))
+			continue;
+
+		for (i = 0; i < nparts; i++) {
+			if (part[i].size == 0)
+				continue;
+			if (part[i].fstype == FS_UNUSED)
+				continue;
+			if (first) {
+				printf(" ");
+				first = false;
+			}
+			printf(" hd%d%c(", edi->dev & 0x7f, i + 'a');
+			if (part[i].guid != NULL)
+				printf("%s", part[i].guid->name);
+			else if (part[i].fstype < FSMAXTYPES)
+				printf("%s", fstypenames[part[i].fstype]);
+			else
+				printf("%d", part[i].fstype);
+			printf(")");
+		}
+		if (!first)
+			printf("\n");
+		dealloc(part, sizeof(*part) * nparts);
 	}
 }
 

cvs diff -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/efidisk.h (expand / switch to context diff)
--- src/sys/arch/i386/stand/efiboot/efidisk.h 2017/01/24 11:09:14 1.1
+++ src/sys/arch/i386/stand/efiboot/efidisk.h 2018/03/13 14:54:52 1.1.12.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: efidisk.h,v 1.1 2017/01/24 11:09:14 nonaka Exp $	*/
+/*	$NetBSD: efidisk.h,v 1.1.12.1 2018/03/13 14:54:52 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -32,8 +32,10 @@
 	TAILQ_ENTRY(efidiskinfo) list;
 
 	int		dev;
+	int		type;
 	EFI_BLOCK_IO	*bio;
 	UINT32		media_id;
+	bool		bootdev;
 };
 TAILQ_HEAD(efidiskinfo_lh, efidiskinfo);
 

cvs diff -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/efidisk_ll.c (expand / switch to context diff)
--- src/sys/arch/i386/stand/efiboot/efidisk_ll.c 2017/01/24 11:09:14 1.1
+++ src/sys/arch/i386/stand/efiboot/efidisk_ll.c 2018/03/13 14:54:52 1.1.12.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: efidisk_ll.c,v 1.1 2017/01/24 11:09:14 nonaka Exp $	 */
+/*	$NetBSD: efidisk_ll.c,v 1.1.12.1 2018/03/13 14:54:52 martin Exp $	 */
 /*	NetBSD: biosdisk_ll.c,v 1.31 2011/02/21 02:58:02 jakllsch Exp	 */
 
 /*-
@@ -95,14 +95,16 @@
 	media = edi->bio->Media;
 
 	d->secsize = media->BlockSize;
-	d->type = BIOSDISK_TYPE_HD;
+	d->type = edi->type;
 	d->flags = BIOSDISK_INT13EXT;
 
-	ed->totsec = media->LastBlock + 1;
-	ed->sbytes = media->BlockSize;
-	ed->flags = 0;
-	if (media->RemovableMedia)
-		ed->flags |= EXTINFO_REMOVABLE;
+	if (ed != NULL) {
+		ed->totsec = media->LastBlock + 1;
+		ed->sbytes = media->BlockSize;
+		ed->flags = 0;
+		if (media->RemovableMedia)
+			ed->flags |= EXTINFO_REMOVABLE;
+	}
 
 	return 0;
 }

cvs diff -r1.4 -r1.4.10.1 src/sys/arch/i386/stand/efiboot/efiboot.c (expand / switch to context diff)
--- src/sys/arch/i386/stand/efiboot/efiboot.c 2017/02/11 10:23:39 1.4
+++ src/sys/arch/i386/stand/efiboot/efiboot.c 2018/03/13 14:54:52 1.4.10.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: efiboot.c,v 1.4 2017/02/11 10:23:39 nonaka Exp $	*/
+/*	$NetBSD: efiboot.c,v 1.4.10.1 2018/03/13 14:54:52 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@@ -28,11 +28,13 @@
 
 #include "efiboot.h"
 
+#include "biosdisk_ll.h"
 #include "bootinfo.h"
 #include "devopen.h"
 
 EFI_HANDLE IH;
 EFI_DEVICE_PATH *efi_bootdp;
+int efi_bootdp_type = BIOSDISK_TYPE_HD;
 EFI_LOADED_IMAGE *efi_li;
 uintptr_t efi_main_sp;
 physaddr_t efi_loadaddr, efi_kernel_start;
@@ -71,15 +73,13 @@
 	    &DevicePathProtocol, (void **)&dp0);
 	if (EFI_ERROR(status))
 		Panic(L"HandleProtocol(DevicePathProtocol): %r", status);
+	efi_bootdp = dp0;
 	for (dp = dp0; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
-		if (DevicePathType(dp) == MEDIA_DEVICE_PATH)
-			continue;
-		if (DevicePathSubType(dp) == MEDIA_HARDDRIVE_DP) {
-			boot_biosdev = 0x80;
-			efi_bootdp = dp;
+		if (DevicePathType(dp) == MEDIA_DEVICE_PATH &&
+		    DevicePathSubType(dp) == MEDIA_CDROM_DP) {
+			efi_bootdp_type = BIOSDISK_TYPE_CD;
 			break;
 		}
-		break;
 	}
 
 	efi_disk_probe();

File Added: src/sys/arch/i386/stand/efiboot/efidev.c
/*	$NetBSD: efidev.c,v 1.1.2.2 2018/03/13 14:54:52 martin Exp $	*/
/*	$OpenBSD: efiboot.c,v 1.28 2017/11/25 19:02:07 patrick Exp $	*/

/*
 * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "efiboot.h"

/*
 * Determine the number of nodes up to, but not including, the first
 * node of the specified type.
 */
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);
}

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);
}

cvs diff -r1.46 -r1.46.6.1 src/sys/arch/i386/stand/lib/biosdisk.c (expand / switch to context diff)
--- src/sys/arch/i386/stand/lib/biosdisk.c 2017/01/24 11:09:14 1.46
+++ src/sys/arch/i386/stand/lib/biosdisk.c 2018/03/13 14:54:52 1.46.6.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: biosdisk.c,v 1.46 2017/01/24 11:09:14 nonaka Exp $	*/
+/*	$NetBSD: biosdisk.c,v 1.46.6.1 2018/03/13 14:54:52 martin Exp $	*/
 
 /*
  * Copyright (c) 1996, 1998
@@ -89,28 +89,19 @@
 #include "bootinfo.h"
 #endif
 
-#define BUFSIZE	2048	/* must be large enough for a CD sector */
+#ifndef BIOSDISK_BUFSIZE
+#define BIOSDISK_BUFSIZE	2048	/* must be large enough for a CD sector */
+#endif
 
 #define BIOSDISKNPART 26
 
 struct biosdisk {
 	struct biosdisk_ll ll;
 	daddr_t         boff;
-	char            buf[BUFSIZE];
+	char            buf[BIOSDISK_BUFSIZE];
 #if !defined(NO_DISKLABEL) || !defined(NO_GPT)
-	struct {
-		daddr_t offset;
-		daddr_t size;
-		int     fstype;
-#ifdef EFIBOOT
-		const struct gpt_part {
-			const struct uuid *guid;
-			const char *name;
-		} *guid;
-		uint64_t attr;
+	struct biosdisk_partition part[BIOSDISKNPART];
 #endif
-	} part[BIOSDISKNPART];
-#endif
 };
 
 #ifndef NO_GPT
@@ -178,6 +169,10 @@
 
 #define	RF_PROTECTED_SECTORS	64	/* XXX refer to <.../rf_optnames.h> */
 
+#ifndef	devb2cdb
+#define	devb2cdb(bno)	(((bno) * DEV_BSIZE) / ISO_DEFAULT_BLOCK_SIZE)
+#endif
+
 int
 biosdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size,
 		  void *buf, size_t *rsize)
@@ -191,7 +186,7 @@
 	d = (struct biosdisk *) devdata;
 
 	if (d->ll.type == BIOSDISK_TYPE_CD)
-		dblk = dblk * DEV_BSIZE / ISO_DEFAULT_BLOCK_SIZE;
+		dblk = devb2cdb(dblk);
 
 	dblk += d->boff;
 
@@ -517,7 +512,40 @@
 	return 0;
 }
 
+#if defined(EFIBOOT) && defined(SUPPORT_CD9660)
 static int
+check_cd9660(struct biosdisk *d)
+{
+	struct biosdisk_extinfo ed;
+	struct iso_primary_descriptor *vd;
+	daddr_t bno;
+
+	for (bno = 16;; bno++) {
+		if (readsects(&d->ll, bno, 1, d->buf, 0))
+			return -1;
+		vd = (struct iso_primary_descriptor *)d->buf;
+		if (memcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0)
+			return -1;
+		if (isonum_711(vd->type) == ISO_VD_END)
+			return -1;
+		if (isonum_711(vd->type) == ISO_VD_PRIMARY)
+			break;
+	}
+	if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE)
+		return -1;
+
+	if (set_geometry(&d->ll, &ed))
+		return -1;
+
+	memset(d->part, 0, sizeof(d->part));
+	d->part[0].fstype = FS_ISO9660;
+	d->part[0].offset = 0;
+	d->part[0].size = ed.totsec;
+	return 0;
+}
+#endif
+
+static int
 read_label(struct biosdisk *d)
 {
 	struct disklabel dflt_lbl;
@@ -624,6 +652,13 @@
 	if (error >= 0)
 		return error;
 
+#if defined(EFIBOOT) && defined(SUPPORT_CD9660)
+	/* Check CD/DVD */
+	error = check_cd9660(d);
+	if (error >= 0)
+		return error;
+#endif
+
 	/*
 	 * Nothing at start of disk, return info from mbr partitions.
 	 */
@@ -774,6 +809,7 @@
 				case FS_RAID:
 				case FS_CCD:
 				case FS_CGD:
+				case FS_ISO9660:
 					break;
 
 				default:
@@ -795,6 +831,43 @@
 
 	dealloc(d, sizeof(*d));
 	return partition;
+#endif /* NO_DISKLABEL && NO_GPT */
+}
+
+int
+biosdisk_readpartition(int biosdev, struct biosdisk_partition **partpp,
+    int *rnum)
+{
+#if defined(NO_DISKLABEL) && defined(NO_GPT)
+	return ENOTSUP;
+#else
+	struct biosdisk *d;
+	struct biosdisk_partition *part;
+	int rv;
+
+	/* Look for netbsd partition that is the dos boot one */
+	d = alloc_biosdisk(biosdev);
+	if (d == NULL)
+		return ENOMEM;
+
+	if (read_partitions(d)) {
+		rv = EINVAL;
+		goto out;
+	}
+
+	part = alloc(sizeof(d->part));
+	if (part == NULL) {
+		rv = ENOMEM;
+		goto out;
+	}
+
+	memcpy(part, d->part, sizeof(d->part));
+	*partpp = part;
+	*rnum = (int)__arraycount(d->part);
+	rv = 0;
+out:
+	dealloc(d, sizeof(*d));
+	return rv;
 #endif /* NO_DISKLABEL && NO_GPT */
 }
 

cvs diff -r1.8 -r1.8.52.1 src/sys/arch/i386/stand/lib/biosdisk.h (expand / switch to context diff)
--- src/sys/arch/i386/stand/lib/biosdisk.h 2010/12/24 20:36:51 1.8
+++ src/sys/arch/i386/stand/lib/biosdisk.h 2018/03/13 14:54:52 1.8.52.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: biosdisk.h,v 1.8 2010/12/24 20:36:51 jakllsch Exp $	*/
+/*	$NetBSD: biosdisk.h,v 1.8.52.1 2018/03/13 14:54:52 martin Exp $	*/
 
 /*
  * Copyright (c) 1996
@@ -25,8 +25,22 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+struct biosdisk_partition {
+	daddr_t offset;
+	daddr_t size;
+	int     fstype;
+#ifdef EFIBOOT
+	const struct gpt_part {
+		const struct uuid *guid;
+		const char *name;
+	} *guid;
+	uint64_t attr;
+#endif
+};
+
 int biosdisk_strategy(void *, int, daddr_t, size_t, void *, size_t *);
 int biosdisk_open(struct open_file *, ...);
 int biosdisk_close(struct open_file *);
 int biosdisk_ioctl(struct open_file *, u_long, void *);
 int biosdisk_findpartition(int, daddr_t);
+int biosdisk_readpartition(int, struct biosdisk_partition **, int *);

cvs diff -r1.15 -r1.15.90.1 src/sys/arch/i386/stand/lib/biosdisk_ll.h (expand / switch to context diff)
--- src/sys/arch/i386/stand/lib/biosdisk_ll.h 2007/12/25 18:33:34 1.15
+++ src/sys/arch/i386/stand/lib/biosdisk_ll.h 2018/03/13 14:54:52 1.15.90.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: biosdisk_ll.h,v 1.15 2007/12/25 18:33:34 perry Exp $	 */
+/*	$NetBSD: biosdisk_ll.h,v 1.15.90.1 2018/03/13 14:54:52 martin Exp $	 */
 
 /*
  * Copyright (c) 1996
@@ -120,7 +120,9 @@
 #define EXTINFO_LOCKABLE	0x0020	/* device is lockable */
 #define EXTINFO_MAXGEOM		0x0040	/* geometry set to max; no media */
 
+#ifndef BIOSDISK_DEFAULT_SECSIZE
 #define BIOSDISK_DEFAULT_SECSIZE	512
+#endif
 
 int set_geometry(struct biosdisk_ll *, struct biosdisk_extinfo *);
 int readsects(struct biosdisk_ll *, daddr_t, int, char *, int);

cvs diff -r1.30 -r1.30.22.1 src/sys/lib/libsa/cd9660.c (expand / switch to context diff)
--- src/sys/lib/libsa/cd9660.c 2014/03/20 03:13:18 1.30
+++ src/sys/lib/libsa/cd9660.c 2018/03/13 14:54:52 1.30.22.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: cd9660.c,v 1.30 2014/03/20 03:13:18 christos Exp $	*/
+/*	$NetBSD: cd9660.c,v 1.30.22.1 2018/03/13 14:54:52 martin Exp $	*/
 
 /*
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -71,7 +71,9 @@
 #define	PTFIXSZ		8
 #define	PTSIZE(pp)	roundup(PTFIXSZ + isonum_711((pp)->namlen), 2)
 
+#ifndef	cdb2devb
 #define	cdb2devb(bno)	((bno) * ISO_DEFAULT_BLOCK_SIZE / DEV_BSIZE)
+#endif
 
 static int	pnmatch(const char *, struct ptable_ent *);
 static int	dirmatch(const char *, struct iso_directory_record *);