Module Name:    src
Committed By:   martin
Date:           Tue Mar 13 14:54:52 UTC 2018

Modified Files:
        src/sys/arch/i386/stand/efiboot [netbsd-8]: Makefile.efiboot
            TODO.efiboot boot.c devopen.c efiboot.c efiboot.h efidisk.c
            efidisk.h efidisk_ll.c
        src/sys/arch/i386/stand/lib [netbsd-8]: biosdisk.c biosdisk.h
            biosdisk_ll.h
        src/sys/lib/libsa [netbsd-8]: cd9660.c
Added Files:
        src/sys/arch/i386/stand/efiboot [netbsd-8]: efidev.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.9.2.1 src/sys/arch/i386/stand/efiboot/Makefile.efiboot
cvs rdiff -u -r1.3 -r1.3.10.1 src/sys/arch/i386/stand/efiboot/TODO.efiboot
cvs rdiff -u -r1.5 -r1.5.2.1 src/sys/arch/i386/stand/efiboot/boot.c \
    src/sys/arch/i386/stand/efiboot/efiboot.h
cvs rdiff -u -r1.1 -r1.1.12.1 src/sys/arch/i386/stand/efiboot/devopen.c \
    src/sys/arch/i386/stand/efiboot/efidisk.c \
    src/sys/arch/i386/stand/efiboot/efidisk.h \
    src/sys/arch/i386/stand/efiboot/efidisk_ll.c
cvs rdiff -u -r1.4 -r1.4.10.1 src/sys/arch/i386/stand/efiboot/efiboot.c
cvs rdiff -u -r0 -r1.1.2.2 src/sys/arch/i386/stand/efiboot/efidev.c
cvs rdiff -u -r1.46 -r1.46.6.1 src/sys/arch/i386/stand/lib/biosdisk.c
cvs rdiff -u -r1.8 -r1.8.52.1 src/sys/arch/i386/stand/lib/biosdisk.h
cvs rdiff -u -r1.15 -r1.15.90.1 src/sys/arch/i386/stand/lib/biosdisk_ll.h
cvs rdiff -u -r1.30 -r1.30.22.1 src/sys/lib/libsa/cd9660.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/i386/stand/efiboot/Makefile.efiboot
diff -u src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.9 src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.9.2.1
--- src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.9	Sat Apr 29 00:05:35 2017
+++ src/sys/arch/i386/stand/efiboot/Makefile.efiboot	Tue Mar 13 14:54:52 2018
@@ -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 @@ SOURCES?= start.S conf.c devopen.c efibo
 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+= -Wno-pointer-sign
 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 @@ CPPFLAGS+= -I${EFIDIR}/inc/protocol
 
 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
 

Index: src/sys/arch/i386/stand/efiboot/TODO.efiboot
diff -u src/sys/arch/i386/stand/efiboot/TODO.efiboot:1.3 src/sys/arch/i386/stand/efiboot/TODO.efiboot:1.3.10.1
--- src/sys/arch/i386/stand/efiboot/TODO.efiboot:1.3	Sun Mar 12 06:37:41 2017
+++ src/sys/arch/i386/stand/efiboot/TODO.efiboot	Tue Mar 13 14:54:52 2018
@@ -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

Index: src/sys/arch/i386/stand/efiboot/boot.c
diff -u src/sys/arch/i386/stand/efiboot/boot.c:1.5 src/sys/arch/i386/stand/efiboot/boot.c:1.5.2.1
--- src/sys/arch/i386/stand/efiboot/boot.c:1.5	Mon May  1 13:03:01 2017
+++ src/sys/arch/i386/stand/efiboot/boot.c	Tue Mar 13 14:54:52 2018
@@ -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 <non...@netbsd.org>
@@ -419,7 +419,7 @@ command_dev(char *arg)
 	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 @@ command_multiboot(char *arg)
 void
 command_version(char *arg)
 {
+	CHAR16 *path;
 
 	if (strcmp(arg, "full") == 0) {
 		printf("ImageBase: 0x%" PRIxPTR "\n",
@@ -563,6 +564,10 @@ command_version(char *arg)
 		    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"
Index: src/sys/arch/i386/stand/efiboot/efiboot.h
diff -u src/sys/arch/i386/stand/efiboot/efiboot.h:1.5 src/sys/arch/i386/stand/efiboot/efiboot.h:1.5.2.1
--- src/sys/arch/i386/stand/efiboot/efiboot.h:1.5	Mon May  1 13:03:01 2017
+++ src/sys/arch/i386/stand/efiboot/efiboot.h	Tue Mar 13 14:54:52 2018
@@ -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 <non...@netbsd.org>
@@ -46,6 +46,7 @@ void print_banner(void);
 /* 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 consinit(int, int, int);
 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);

Index: src/sys/arch/i386/stand/efiboot/devopen.c
diff -u src/sys/arch/i386/stand/efiboot/devopen.c:1.1 src/sys/arch/i386/stand/efiboot/devopen.c:1.1.12.1
--- src/sys/arch/i386/stand/efiboot/devopen.c:1.1	Tue Jan 24 11:09:14 2017
+++ src/sys/arch/i386/stand/efiboot/devopen.c	Tue Mar 13 14:54:52 2018
@@ -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 @@ dev2bios(char *devname, int unit, int *b
 
 	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 @@ bios2dev(int biosdev, daddr_t sector, ch
 {
 
 	*unit = biosdev & 0x7f;
-	*devname = "hd";
+
+	if (biosdev >= 0x80 + get_harddrives()) {
+		*devname = "cd";
+		*unit -= get_harddrives();
+	} else
+		*devname = "hd";
+
 	*partition = biosdisk_findpartition(biosdev, sector);
 }
 
Index: src/sys/arch/i386/stand/efiboot/efidisk.c
diff -u src/sys/arch/i386/stand/efiboot/efidisk.c:1.1 src/sys/arch/i386/stand/efiboot/efidisk.c:1.1.12.1
--- src/sys/arch/i386/stand/efiboot/efidisk.c:1.1	Tue Jan 24 11:09:14 2017
+++ src/sys/arch/i386/stand/efiboot/efidisk.c	Tue Mar 13 14:54:52 2018
@@ -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 <non...@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_disk_probe(void)
 	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 @@ efi_disk_probe(void)
 	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 @@ efi_disk_probe(void)
 
 		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);
 	}
 }
 
Index: src/sys/arch/i386/stand/efiboot/efidisk.h
diff -u src/sys/arch/i386/stand/efiboot/efidisk.h:1.1 src/sys/arch/i386/stand/efiboot/efidisk.h:1.1.12.1
--- src/sys/arch/i386/stand/efiboot/efidisk.h:1.1	Tue Jan 24 11:09:14 2017
+++ src/sys/arch/i386/stand/efiboot/efidisk.h	Tue Mar 13 14:54:52 2018
@@ -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 <non...@netbsd.org>
@@ -32,8 +32,10 @@ struct efidiskinfo {
 	TAILQ_ENTRY(efidiskinfo) list;
 
 	int		dev;
+	int		type;
 	EFI_BLOCK_IO	*bio;
 	UINT32		media_id;
+	bool		bootdev;
 };
 TAILQ_HEAD(efidiskinfo_lh, efidiskinfo);
 
Index: src/sys/arch/i386/stand/efiboot/efidisk_ll.c
diff -u src/sys/arch/i386/stand/efiboot/efidisk_ll.c:1.1 src/sys/arch/i386/stand/efiboot/efidisk_ll.c:1.1.12.1
--- src/sys/arch/i386/stand/efiboot/efidisk_ll.c:1.1	Tue Jan 24 11:09:14 2017
+++ src/sys/arch/i386/stand/efiboot/efidisk_ll.c	Tue Mar 13 14:54:52 2018
@@ -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 @@ set_geometry(struct biosdisk_ll *d, stru
 	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;
 }

Index: src/sys/arch/i386/stand/efiboot/efiboot.c
diff -u src/sys/arch/i386/stand/efiboot/efiboot.c:1.4 src/sys/arch/i386/stand/efiboot/efiboot.c:1.4.10.1
--- src/sys/arch/i386/stand/efiboot/efiboot.c:1.4	Sat Feb 11 10:23:39 2017
+++ src/sys/arch/i386/stand/efiboot/efiboot.c	Tue Mar 13 14:54:52 2018
@@ -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 <non...@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 @@ efi_main(EFI_HANDLE imageHandle, EFI_SYS
 	    &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();

Index: src/sys/arch/i386/stand/lib/biosdisk.c
diff -u src/sys/arch/i386/stand/lib/biosdisk.c:1.46 src/sys/arch/i386/stand/lib/biosdisk.c:1.46.6.1
--- src/sys/arch/i386/stand/lib/biosdisk.c:1.46	Tue Jan 24 11:09:14 2017
+++ src/sys/arch/i386/stand/lib/biosdisk.c	Tue Mar 13 14:54:52 2018
@@ -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,27 +89,18 @@
 #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;
-#endif
-	} part[BIOSDISKNPART];
+	struct biosdisk_partition part[BIOSDISKNPART];
 #endif
 };
 
@@ -178,6 +169,10 @@ static struct btinfo_bootwedge bi_wedge;
 
 #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 @@ biosdisk_strategy(void *devdata, int fla
 	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,6 +512,39 @@ read_minix_subp(struct biosdisk *d, stru
 	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)
 {
@@ -624,6 +652,13 @@ read_label(struct biosdisk *d)
 	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 @@ biosdisk_findpartition(int biosdev, dadd
 				case FS_RAID:
 				case FS_CCD:
 				case FS_CGD:
+				case FS_ISO9660:
 					break;
 
 				default:
@@ -798,6 +834,43 @@ biosdisk_findpartition(int biosdev, dadd
 #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 */
+}
+
 #ifdef _STANDALONE
 static void
 add_biosdisk_bootinfo(void)

Index: src/sys/arch/i386/stand/lib/biosdisk.h
diff -u src/sys/arch/i386/stand/lib/biosdisk.h:1.8 src/sys/arch/i386/stand/lib/biosdisk.h:1.8.52.1
--- src/sys/arch/i386/stand/lib/biosdisk.h:1.8	Fri Dec 24 20:36:51 2010
+++ src/sys/arch/i386/stand/lib/biosdisk.h	Tue Mar 13 14:54:52 2018
@@ -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 *);

Index: src/sys/arch/i386/stand/lib/biosdisk_ll.h
diff -u src/sys/arch/i386/stand/lib/biosdisk_ll.h:1.15 src/sys/arch/i386/stand/lib/biosdisk_ll.h:1.15.90.1
--- src/sys/arch/i386/stand/lib/biosdisk_ll.h:1.15	Tue Dec 25 18:33:34 2007
+++ src/sys/arch/i386/stand/lib/biosdisk_ll.h	Tue Mar 13 14:54:52 2018
@@ -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 @@ struct biosdisk_extinfo {
 #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);

Index: src/sys/lib/libsa/cd9660.c
diff -u src/sys/lib/libsa/cd9660.c:1.30 src/sys/lib/libsa/cd9660.c:1.30.22.1
--- src/sys/lib/libsa/cd9660.c:1.30	Thu Mar 20 03:13:18 2014
+++ src/sys/lib/libsa/cd9660.c	Tue Mar 13 14:54:52 2018
@@ -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 @@ struct ptable_ent {
 #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 *);

Added files:

Index: src/sys/arch/i386/stand/efiboot/efidev.c
diff -u /dev/null src/sys/arch/i386/stand/efiboot/efidev.c:1.1.2.2
--- /dev/null	Tue Mar 13 14:54:52 2018
+++ src/sys/arch/i386/stand/efiboot/efidev.c	Tue Mar 13 14:54:52 2018
@@ -0,0 +1,59 @@
+/*	$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 <yasu...@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);
+}

Reply via email to