Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Jan 2016 16:52:02 +0000 (UTC)
From:      Steven Hartland <smh@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r294997 - in stable/10/sys/boot: common efi/boot1 efi/include efi/loader
Message-ID:  <201601281652.u0SGq2L9039493@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: smh
Date: Thu Jan 28 16:52:02 2016
New Revision: 294997
URL: https://svnweb.freebsd.org/changeset/base/294997

Log:
  MFC r281060, r294060, r294291, r294493, r294284:
  
  MFC r281060:
  Remove an unnecessary space in a printf call
  
  MFC r294060:
  Modularise EFI boot loader
  
  MFC r294291 (by andrew):
  Reset the filesystem cache
  
  MFC r294493:
  Fix EFI UFS caching
  
  MFC r294284 (by emaste):
  boot1: correct typo in error message
  
  Sponsored by:	Multiplay

Added:
  stable/10/sys/boot/efi/boot1/boot_module.h
     - copied unchanged from r294060, head/sys/boot/efi/boot1/boot_module.h
  stable/10/sys/boot/efi/boot1/ufs_module.c
     - copied, changed from r294060, head/sys/boot/efi/boot1/ufs_module.c
Modified:
  stable/10/sys/boot/common/ufsread.c
  stable/10/sys/boot/efi/boot1/Makefile
  stable/10/sys/boot/efi/boot1/boot1.c
  stable/10/sys/boot/efi/include/efilib.h
  stable/10/sys/boot/efi/loader/devicename.c
  stable/10/sys/boot/efi/loader/main.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/boot/common/ufsread.c
==============================================================================
--- stable/10/sys/boot/common/ufsread.c	Thu Jan 28 16:51:56 2016	(r294996)
+++ stable/10/sys/boot/common/ufsread.c	Thu Jan 28 16:52:02 2016	(r294997)
@@ -165,7 +165,7 @@ static int sblock_try[] = SBLOCKSEARCH;
 #endif
 
 static ssize_t
-fsread(ufs_ino_t inode, void *buf, size_t nbyte)
+fsread_size(ufs_ino_t inode, void *buf, size_t nbyte, size_t *fsizep)
 {
 #ifndef UFS2_ONLY
 	static struct ufs1_dinode dp1;
@@ -185,6 +185,10 @@ fsread(ufs_ino_t inode, void *buf, size_
 	static ufs2_daddr_t blkmap, indmap;
 	u_int u;
 
+	/* Basic parameter validation. */
+	if ((buf == NULL && nbyte != 0) || dmadat == NULL)
+		return (-1);
+
 	blkbuf = dmadat->blkbuf;
 	indbuf = dmadat->indbuf;
 
@@ -231,18 +235,18 @@ fsread(ufs_ino_t inode, void *buf, size_
 			return -1;
 		n = INO_TO_VBO(n, inode);
 #if defined(UFS1_ONLY)
-		memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
-		    sizeof(struct ufs1_dinode));
+		memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
+		    sizeof(dp1));
 #elif defined(UFS2_ONLY)
-		memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
-		    sizeof(struct ufs2_dinode));
+		memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
+		    sizeof(dp2));
 #else
 		if (fs.fs_magic == FS_UFS1_MAGIC)
 			memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
-			    sizeof(struct ufs1_dinode));
+			    sizeof(dp1));
 		else
 			memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
-			    sizeof(struct ufs2_dinode));
+			    sizeof(dp2));
 #endif
 		inomap = inode;
 		fs_off = 0;
@@ -306,5 +310,17 @@ fsread(ufs_ino_t inode, void *buf, size_
 		fs_off += n;
 		nb -= n;
 	}
+
+	if (fsizep != NULL)
+		*fsizep = size;
+
 	return nbyte;
 }
+
+static ssize_t
+fsread(ufs_ino_t inode, void *buf, size_t nbyte)
+{
+
+	return fsread_size(inode, buf, nbyte, NULL);
+}
+

Modified: stable/10/sys/boot/efi/boot1/Makefile
==============================================================================
--- stable/10/sys/boot/efi/boot1/Makefile	Thu Jan 28 16:51:56 2016	(r294996)
+++ stable/10/sys/boot/efi/boot1/Makefile	Thu Jan 28 16:52:02 2016	(r294997)
@@ -11,7 +11,7 @@ INTERNALPROG=
 WARNS?=		6
 
 # architecture-specific loader code
-SRCS=	boot1.c reloc.c start.S
+SRCS=	boot1.c reloc.c start.S ufs_module.c
 
 CFLAGS+=	-fPIC
 CFLAGS+=	-I.
@@ -19,6 +19,7 @@ CFLAGS+=	-I${.CURDIR}/../include
 CFLAGS+=	-I${.CURDIR}/../include/${MACHINE}
 CFLAGS+=	-I${.CURDIR}/../../../contrib/dev/acpica/include
 CFLAGS+=	-I${.CURDIR}/../../..
+CFLAGS+=	-DEFI_UFS_BOOT
 
 # Always add MI sources and REGULAR efi loader bits
 .PATH:		${.CURDIR}/../loader/arch/${MACHINE}

Modified: stable/10/sys/boot/efi/boot1/boot1.c
==============================================================================
--- stable/10/sys/boot/efi/boot1/boot1.c	Thu Jan 28 16:51:56 2016	(r294996)
+++ stable/10/sys/boot/efi/boot1/boot1.c	Thu Jan 28 16:52:02 2016	(r294997)
@@ -5,6 +5,8 @@
  * All rights reserved.
  * Copyright (c) 2014 Nathan Whitehorn
  * All rights reserved.
+ * Copyright (c) 2015 Eric McCorkle
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms are freely
  * permitted provided that the above copyright notice and this
@@ -21,7 +23,6 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
-#include <sys/dirent.h>
 #include <machine/elf.h>
 #include <machine/stdarg.h>
 #include <stand.h>
@@ -29,19 +30,29 @@ __FBSDID("$FreeBSD$");
 #include <efi.h>
 #include <eficonsctl.h>
 
+#include "boot_module.h"
+
 #define _PATH_LOADER	"/boot/loader.efi"
-#define _PATH_KERNEL	"/boot/kernel/kernel"
 
-#define BSIZEMAX	16384
+static const boot_module_t *boot_modules[] =
+{
+#ifdef EFI_UFS_BOOT
+	&ufs_module
+#endif
+};
+
+#define NUM_BOOT_MODULES (sizeof(boot_modules) / sizeof(boot_module_t*))
+/* The initial number of handles used to query EFI for partitions. */
+#define NUM_HANDLES_INIT	24
 
-void panic(const char *fmt, ...) __dead2;
 void putchar(int c);
 EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
 
-static int domount(EFI_DEVICE_PATH *device, EFI_BLOCK_IO *blkio, int quiet);
-static void load(const char *fname);
+static void try_load(const boot_module_t* mod);
+static EFI_STATUS probe_handle(EFI_HANDLE h);
 
-static EFI_SYSTEM_TABLE *systab;
+EFI_SYSTEM_TABLE *systab;
+EFI_BOOT_SERVICES *bs;
 static EFI_HANDLE *image;
 
 static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
@@ -49,27 +60,92 @@ static EFI_GUID DevicePathGUID = DEVICE_
 static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
 static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
 
-static EFI_BLOCK_IO *bootdev;
-static EFI_DEVICE_PATH *bootdevpath;
-static EFI_HANDLE *bootdevhandle;
+/*
+ * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
+ * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
+ * EFI methods.
+ */
+void *
+Malloc(size_t len, const char *file __unused, int line __unused)
+{
+	void *out;
+
+	if (bs->AllocatePool(EfiLoaderData, len, &out) == EFI_SUCCESS)
+		return (out);
+
+	return (NULL);
+}
+
+void
+Free(void *buf, const char *file __unused, int line __unused)
+{
+	(void)bs->FreePool(buf);
+}
 
-EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab)
+/*
+ * This function only returns if it fails to load the kernel. If it
+ * succeeds, it simply boots the kernel.
+ */
+void
+try_load(const boot_module_t *mod)
 {
-	EFI_HANDLE handles[128];
-	EFI_BLOCK_IO *blkio;
-	UINTN i, nparts = sizeof(handles), cols, rows, max_dim, best_mode;
+	size_t bufsize;
+	void *buf;
+	dev_info_t *dev;
+	EFI_HANDLE loaderhandle;
+	EFI_LOADED_IMAGE *loaded_image;
+	EFI_STATUS status;
+
+	status = mod->load(_PATH_LOADER, &dev, &buf, &bufsize);
+	if (status == EFI_NOT_FOUND)
+		return;
+
+	if (status != EFI_SUCCESS) {
+		printf("%s failed to load %s (%lu)\n", mod->name, _PATH_LOADER,
+		    EFI_ERROR_CODE(status));
+		return;
+	}
+
+	if ((status = bs->LoadImage(TRUE, image, dev->devpath, buf, bufsize,
+	    &loaderhandle)) != EFI_SUCCESS) {
+		printf("Failed to load image provided by %s, size: %zu, (%lu)\n",
+		     mod->name, bufsize, EFI_ERROR_CODE(status));
+		return;
+	}
+
+	if ((status = bs->HandleProtocol(loaderhandle, &LoadedImageGUID,
+	    (VOID**)&loaded_image)) != EFI_SUCCESS) {
+		printf("Failed to query LoadedImage provided by %s (%lu)\n",
+		    mod->name, EFI_ERROR_CODE(status));
+		return;
+	}
+
+	loaded_image->DeviceHandle = dev->devhandle;
+
+	if ((status = bs->StartImage(loaderhandle, NULL, NULL)) !=
+	    EFI_SUCCESS) {
+		printf("Failed to start image provided by %s (%lu)\n",
+		    mod->name, EFI_ERROR_CODE(status));
+		return;
+	}
+}
+
+EFI_STATUS
+efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
+{
+	EFI_HANDLE *handles;
 	EFI_STATUS status;
-	EFI_DEVICE_PATH *devpath;
-	EFI_BOOT_SERVICES *BS;
 	EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
 	SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
-	const char *path = _PATH_LOADER;
+	UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles;
 
+	/* Basic initialization*/
 	systab = Xsystab;
 	image = Ximage;
+	bs = Xsystab->BootServices;
 
-	BS = systab->BootServices;
-	status = BS->LocateProtocol(&ConsoleControlGUID, NULL,
+	/* Set up the console, so printf works. */
+	status = bs->LocateProtocol(&ConsoleControlGUID, NULL,
 	    (VOID **)&ConsoleControl);
 	if (status == EFI_SUCCESS)
 		(void)ConsoleControl->SetMode(ConsoleControl,
@@ -94,199 +170,162 @@ EFI_STATUS efi_main(EFI_HANDLE Ximage, E
 	conout->EnableCursor(conout, TRUE);
 	conout->ClearScreen(conout);
 
-	printf(" \n>> FreeBSD EFI boot block\n");
-	printf("   Loader path: %s\n", path);
-
-	status = systab->BootServices->LocateHandle(ByProtocol,
-	    &BlockIoProtocolGUID, NULL, &nparts, handles);
-	nparts /= sizeof(handles[0]);
-
-	for (i = 0; i < nparts; i++) {
-		status = systab->BootServices->HandleProtocol(handles[i],
-		    &DevicePathGUID, (void **)&devpath);
-		if (EFI_ERROR(status))
+	printf("\n>> FreeBSD EFI boot block\n");
+	printf("   Loader path: %s\n\n", _PATH_LOADER);
+	printf("   Initializing modules:");
+	for (i = 0; i < NUM_BOOT_MODULES; i++) {
+		if (boot_modules[i] == NULL)
 			continue;
 
-		while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
-			devpath = NextDevicePathNode(devpath);
+		printf(" %s", boot_modules[i]->name);
+		if (boot_modules[i]->init != NULL)
+			boot_modules[i]->init();
+	}
+	putchar('\n');
 
-		status = systab->BootServices->HandleProtocol(handles[i],
-		    &BlockIoProtocolGUID, (void **)&blkio);
-		if (EFI_ERROR(status))
-			continue;
+	/* Get all the device handles */
+	hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE);
+	if ((status = bs->AllocatePool(EfiLoaderData, hsize, (void **)&handles))
+	    != EFI_SUCCESS)
+		panic("Failed to allocate %d handles (%lu)", NUM_HANDLES_INIT,
+		    EFI_ERROR_CODE(status));
 
-		if (!blkio->Media->LogicalPartition)
-			continue;
+	status = bs->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL,
+	    &hsize, handles);
+	switch (status) {
+	case EFI_SUCCESS:
+		break;
+	case EFI_BUFFER_TOO_SMALL:
+		(void)bs->FreePool(handles);
+		if ((status = bs->AllocatePool(EfiLoaderData, hsize,
+		    (void **)&handles) != EFI_SUCCESS)) {
+			panic("Failed to allocate %zu handles (%lu)", hsize /
+			    sizeof(*handles), EFI_ERROR_CODE(status));
+		}
+		status = bs->LocateHandle(ByProtocol, &BlockIoProtocolGUID,
+		    NULL, &hsize, handles);
+		if (status != EFI_SUCCESS)
+			panic("Failed to get device handles (%lu)\n",
+			    EFI_ERROR_CODE(status));
+		break;
+	default:
+		panic("Failed to get device handles (%lu)",
+		    EFI_ERROR_CODE(status));
+	}
 
-		if (domount(devpath, blkio, 1) >= 0)
+	/* Scan all partitions, probing with all modules. */
+	nhandles = hsize / sizeof(*handles);
+	printf("   Probing %zu block devices...", nhandles);
+	for (i = 0; i < nhandles; i++) {
+		status = probe_handle(handles[i]);
+		switch (status) {
+		case EFI_UNSUPPORTED:
+			printf(".");
+			break;
+		case EFI_SUCCESS:
+			printf("+");
+			break;
+		default:
+			printf("x");
 			break;
+		}
 	}
+	printf(" done\n");
 
-	if (i == nparts)
-		panic("No bootable partition found");
-
-	bootdevhandle = handles[i];
-	load(path);
+	/* Status summary. */
+	for (i = 0; i < NUM_BOOT_MODULES; i++) {
+		if (boot_modules[i] != NULL) {
+			printf("    ");
+			boot_modules[i]->status();
+		}
+	}
 
-	panic("Load failed");
+	/* Select a partition to boot by trying each module in order. */
+	for (i = 0; i < NUM_BOOT_MODULES; i++)
+		if (boot_modules[i] != NULL)
+			try_load(boot_modules[i]);
 
-	return EFI_SUCCESS;
+	/* If we get here, we're out of luck... */
+	panic("No bootable partitions found!");
 }
 
-static int
-dskread(void *buf, u_int64_t lba, int nblk)
+static EFI_STATUS
+probe_handle(EFI_HANDLE h)
 {
+	dev_info_t *devinfo;
+	EFI_BLOCK_IO *blkio;
+	EFI_DEVICE_PATH *devpath;
 	EFI_STATUS status;
-	int size;
+	UINTN i;
 
-	lba = lba / (bootdev->Media->BlockSize / DEV_BSIZE);
-	size = nblk * DEV_BSIZE;
-	status = bootdev->ReadBlocks(bootdev, bootdev->Media->MediaId, lba,
-	    size, buf);
+	/* Figure out if we're dealing with an actual partition. */
+	status = bs->HandleProtocol(h, &DevicePathGUID, (void **)&devpath);
+	if (status == EFI_UNSUPPORTED)
+		return (status);
 
-	if (EFI_ERROR(status))
-		return (-1);
+	if (status != EFI_SUCCESS) {
+		DPRINTF("\nFailed to query DevicePath (%lu)\n",
+		    EFI_ERROR_CODE(status));
+		return (status);
+	}
 
-	return (0);
-}
+	while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
+		devpath = NextDevicePathNode(devpath);
 
-#include "ufsread.c"
+	status = bs->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio);
+	if (status == EFI_UNSUPPORTED)
+		return (status);
 
-static ssize_t
-fsstat(ufs_ino_t inode)
-{
-#ifndef UFS2_ONLY
-	static struct ufs1_dinode dp1;
-#endif
-#ifndef UFS1_ONLY
-	static struct ufs2_dinode dp2;
-#endif
-	static struct fs fs;
-	static ufs_ino_t inomap;
-	char *blkbuf;
-	void *indbuf;
-	size_t n, size;
-	static ufs2_daddr_t blkmap, indmap;
-
-	blkbuf = dmadat->blkbuf;
-	indbuf = dmadat->indbuf;
-	if (!dsk_meta) {
-		inomap = 0;
-		for (n = 0; sblock_try[n] != -1; n++) {
-			if (dskread(dmadat->sbbuf, sblock_try[n] / DEV_BSIZE,
-			    SBLOCKSIZE / DEV_BSIZE))
-				return -1;
-			memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
-			if ((
-#if defined(UFS1_ONLY)
-			    fs.fs_magic == FS_UFS1_MAGIC
-#elif defined(UFS2_ONLY)
-			    (fs.fs_magic == FS_UFS2_MAGIC &&
-			    fs.fs_sblockloc == sblock_try[n])
-#else
-			    fs.fs_magic == FS_UFS1_MAGIC ||
-			    (fs.fs_magic == FS_UFS2_MAGIC &&
-			    fs.fs_sblockloc == sblock_try[n])
-#endif
-			    ) &&
-			    fs.fs_bsize <= MAXBSIZE &&
-			    fs.fs_bsize >= (int32_t)sizeof(struct fs))
-				break;
-		}
-		if (sblock_try[n] == -1) {
-			return -1;
-		}
-		dsk_meta++;
-	} else
-		memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
-	if (!inode)
-		return 0;
-	if (inomap != inode) {
-		n = IPERVBLK(&fs);
-		if (dskread(blkbuf, INO_TO_VBA(&fs, n, inode), DBPERVBLK))
-			return -1;
-		n = INO_TO_VBO(n, inode);
-#if defined(UFS1_ONLY)
-		memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
-		    sizeof(struct ufs1_dinode));
-#elif defined(UFS2_ONLY)
-		memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
-		    sizeof(struct ufs2_dinode));
-#else
-		if (fs.fs_magic == FS_UFS1_MAGIC)
-			memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
-			    sizeof(struct ufs1_dinode));
-		else
-			memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
-			    sizeof(struct ufs2_dinode));
-#endif
-		inomap = inode;
-		fs_off = 0;
-		blkmap = indmap = 0;
-	}
-	size = DIP(di_size);
-	n = size - fs_off;
-	return (n);
-}
+	if (status != EFI_SUCCESS) {
+		DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n",
+		    EFI_ERROR_CODE(status));
+		return (status);
+	}
 
-static struct dmadat __dmadat;
+	if (!blkio->Media->LogicalPartition)
+		return (EFI_UNSUPPORTED);
 
-static int
-domount(EFI_DEVICE_PATH *device, EFI_BLOCK_IO *blkio, int quiet)
-{
+	/* Run through each module, see if it can load this partition */
+	for (i = 0; i < NUM_BOOT_MODULES; i++) {
+		if (boot_modules[i] == NULL)
+			continue;
+
+		if ((status = bs->AllocatePool(EfiLoaderData,
+		    sizeof(*devinfo), (void **)&devinfo)) !=
+		    EFI_SUCCESS) {
+			DPRINTF("\nFailed to allocate devinfo (%lu)\n",
+			    EFI_ERROR_CODE(status));
+			continue;
+		}
+		devinfo->dev = blkio;
+		devinfo->devpath = devpath;
+		devinfo->devhandle = h;
+		devinfo->devdata = NULL;
+		devinfo->next = NULL;
+
+		status = boot_modules[i]->probe(devinfo);
+		if (status == EFI_SUCCESS)
+			return (EFI_SUCCESS);
+		(void)bs->FreePool(devinfo);
+	}
 
-	dmadat = &__dmadat;
-	bootdev = blkio;
-	bootdevpath = device;
-	if (fsread(0, NULL, 0)) {
-		if (!quiet)
-			printf("domount: can't read superblock\n");
-		return (-1);
-	}
-	if (!quiet)
-		printf("Succesfully mounted UFS filesystem\n");
-	return (0);
+	return (EFI_UNSUPPORTED);
 }
 
-static void
-load(const char *fname)
+void
+add_device(dev_info_t **devinfop, dev_info_t *devinfo)
 {
-	ufs_ino_t ino;
-	EFI_STATUS status;
-	EFI_HANDLE loaderhandle;
-	EFI_LOADED_IMAGE *loaded_image;
-	void *buffer;
-	size_t bufsize;
+	dev_info_t *dev;
 
-	if ((ino = lookup(fname)) == 0) {
-		printf("File %s not found\n", fname);
+	if (*devinfop == NULL) {
+		*devinfop = devinfo;
 		return;
 	}
 
-	bufsize = fsstat(ino);
-	status = systab->BootServices->AllocatePool(EfiLoaderData,
-	    bufsize, &buffer);
-	fsread(ino, buffer, bufsize);
-
-	/* XXX: For secure boot, we need our own loader here */
-	status = systab->BootServices->LoadImage(TRUE, image, bootdevpath,
-	    buffer, bufsize, &loaderhandle);
-	if (EFI_ERROR(status))
-		printf("LoadImage failed with error %lu\n",
-		    EFI_ERROR_CODE(status));
-
-	status = systab->BootServices->HandleProtocol(loaderhandle,
-	    &LoadedImageGUID, (VOID**)&loaded_image);
-	if (EFI_ERROR(status))
-		printf("HandleProtocol failed with error %lu\n",
-		    EFI_ERROR_CODE(status));
+	for (dev = *devinfop; dev->next != NULL; dev = dev->next)
+		;
 
-	loaded_image->DeviceHandle = bootdevhandle;
-
-	status = systab->BootServices->StartImage(loaderhandle, NULL, NULL);
-	if (EFI_ERROR(status))
-		printf("StartImage failed with error %lu\n",
-		    EFI_ERROR_CODE(status));
+	dev->next = devinfo;
 }
 
 void

Copied: stable/10/sys/boot/efi/boot1/boot_module.h (from r294060, head/sys/boot/efi/boot1/boot_module.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/sys/boot/efi/boot1/boot_module.h	Thu Jan 28 16:52:02 2016	(r294997, copy of r294060, head/sys/boot/efi/boot1/boot_module.h)
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2015 Eric McCorkle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BOOT_MODULE_H_
+#define _BOOT_MODULE_H_
+
+#include <stdbool.h>
+
+#include <efi.h>
+#include <efilib.h>
+#include <eficonsctl.h>
+
+#ifdef EFI_DEBUG
+#define DPRINTF(fmt, args...) \
+        do { \
+                printf(fmt, ##args) \
+        } while (0)
+#else
+#define DPRINTF(fmt, args...) {}
+#endif
+
+/* EFI device info */
+typedef struct dev_info
+{
+	EFI_BLOCK_IO *dev;
+	EFI_DEVICE_PATH *devpath;
+	EFI_HANDLE *devhandle;
+	void *devdata;
+	struct dev_info *next;
+} dev_info_t;
+
+/*
+ * A boot loader module.
+ *
+ * This is a standard interface for filesystem modules in the EFI system.
+ */
+typedef struct boot_module_t
+{
+	const char *name;
+
+	/* init is the optional initialiser for the module. */
+	void (*init)();
+
+	/*
+	 * probe checks to see if the module can handle dev.
+	 *
+	 * Return codes:
+	 * EFI_SUCCESS = The module can handle the device.
+	 * EFI_NOT_FOUND = The module can not handle the device.
+	 * Other = The module encountered an error.
+	 */
+	EFI_STATUS (*probe)(dev_info_t* dev);
+
+	/*
+	 * load should select the best out of a set of devices that probe
+	 * indicated were loadable and load it.
+	 *
+	 * Return codes:
+	 * EFI_SUCCESS = The module can handle the device.
+	 * EFI_NOT_FOUND = The module can not handle the device.
+	 * Other = The module encountered an error.
+	 */
+	EFI_STATUS (*load)(const char *loader_path, dev_info_t **devinfo,
+	    void **buf, size_t *bufsize);
+
+	/* status outputs information about the probed devices. */
+	void (*status)();
+
+} boot_module_t;
+
+/* Standard boot modules. */
+#ifdef EFI_UFS_BOOT
+extern const boot_module_t ufs_module;
+#endif
+
+/* Functions available to modules. */
+extern void add_device(dev_info_t **devinfop, dev_info_t *devinfo);
+extern void panic(const char *fmt, ...) __dead2;
+extern int printf(const char *fmt, ...);
+extern int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap);
+
+extern EFI_SYSTEM_TABLE *systab;
+extern EFI_BOOT_SERVICES *bs;
+
+#endif

Copied and modified: stable/10/sys/boot/efi/boot1/ufs_module.c (from r294060, head/sys/boot/efi/boot1/ufs_module.c)
==============================================================================
--- head/sys/boot/efi/boot1/ufs_module.c	Fri Jan 15 01:22:36 2016	(r294060, copy source)
+++ stable/10/sys/boot/efi/boot1/ufs_module.c	Thu Jan 28 16:52:02 2016	(r294997)
@@ -68,93 +68,23 @@ dskread(void *buf, u_int64_t lba, int nb
 
 #include "ufsread.c"
 
-static ssize_t
-fsstat(ufs_ino_t inode)
+static struct dmadat __dmadat;
+
+static int
+init_dev(dev_info_t* dev)
 {
-#ifndef UFS2_ONLY
-	static struct ufs1_dinode dp1;
-#endif
-#ifndef UFS1_ONLY
-	static struct ufs2_dinode dp2;
-#endif
-	static struct fs fs;
-	static ufs_ino_t inomap;
-	char *blkbuf;
-	void *indbuf;
-	size_t n, size;
-	static ufs2_daddr_t blkmap, indmap;
-
-	blkbuf = dmadat->blkbuf;
-	indbuf = dmadat->indbuf;
-	if (!dsk_meta) {
-		inomap = 0;
-		for (n = 0; sblock_try[n] != -1; n++) {
-			if (dskread(dmadat->sbbuf, sblock_try[n] / DEV_BSIZE,
-			    SBLOCKSIZE / DEV_BSIZE))
-				return (-1);
-			memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
-			if ((
-#if defined(UFS1_ONLY)
-			    fs.fs_magic == FS_UFS1_MAGIC
-#elif defined(UFS2_ONLY)
-			    (fs.fs_magic == FS_UFS2_MAGIC &&
-			    fs.fs_sblockloc == sblock_try[n])
-#else
-			    fs.fs_magic == FS_UFS1_MAGIC ||
-			    (fs.fs_magic == FS_UFS2_MAGIC &&
-			    fs.fs_sblockloc == sblock_try[n])
-#endif
-			    ) &&
-			    fs.fs_bsize <= MAXBSIZE &&
-			    fs.fs_bsize >= (int32_t)sizeof(struct fs))
-				break;
-		}
-		if (sblock_try[n] == -1) {
-			return (-1);
-		}
-		dsk_meta++;
-	} else
-		memcpy(&fs, dmadat->sbbuf, sizeof(struct fs));
-	if (!inode)
-		return (0);
-	if (inomap != inode) {
-		n = IPERVBLK(&fs);
-		if (dskread(blkbuf, INO_TO_VBA(&fs, n, inode), DBPERVBLK))
-			return (-1);
-		n = INO_TO_VBO(n, inode);
-#if defined(UFS1_ONLY)
-		memcpy(&dp1, (struct ufs1_dinode *)blkbuf + n,
-		    sizeof(struct ufs1_dinode));
-#elif defined(UFS2_ONLY)
-		memcpy(&dp2, (struct ufs2_dinode *)blkbuf + n,
-		    sizeof(struct ufs2_dinode));
-#else
-		if (fs.fs_magic == FS_UFS1_MAGIC)
-			memcpy(&dp1, (struct ufs1_dinode *)(void *)blkbuf + n,
-			    sizeof(struct ufs1_dinode));
-		else
-			memcpy(&dp2, (struct ufs2_dinode *)(void *)blkbuf + n,
-			    sizeof(struct ufs2_dinode));
-#endif
-		inomap = inode;
-		fs_off = 0;
-		blkmap = indmap = 0;
-	}
-	size = DIP(di_size);
-	n = size - fs_off;
 
-	return (n);
-}
+	devinfo = dev;
+	dmadat = &__dmadat;
 
-static struct dmadat __dmadat;
+	return fsread(0, NULL, 0);
+}
 
 static EFI_STATUS
 probe(dev_info_t* dev)
 {
 
-	devinfo = dev;
-	dmadat = &__dmadat;
-	if (fsread(0, NULL, 0) < 0)
+	if (init_dev(dev) < 0)
 		return (EFI_UNSUPPORTED);
 
 	add_device(&devices, dev);
@@ -171,13 +101,15 @@ try_load(dev_info_t *dev, const char *lo
 	ssize_t read;
 	void *buf;
 
-	devinfo = dev;
+	if (init_dev(dev) < 0)
+		return (EFI_UNSUPPORTED);
+
 	if ((ino = lookup(loader_path)) == 0)
 		return (EFI_NOT_FOUND);
 
-	size = fsstat(ino);
-	if (size <= 0) {
-		printf("Failed to fsstat %s ino: %d\n", loader_path, ino);
+	if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) {
+		printf("Failed to read size of '%s' ino: %d\n", loader_path,
+		    ino);
 		return (EFI_INVALID_PARAMETER);
 	}
 
@@ -190,7 +122,7 @@ try_load(dev_info_t *dev, const char *lo
 
 	read = fsread(ino, buf, size);
 	if ((size_t)read != size) {
-		printf("Failed to read %s (%zd != %zu)\n", loader_path, read,
+		printf("Failed to read '%s' (%zd != %zu)\n", loader_path, read,
 		    size);
 		(void)bs->FreePool(buf);
 		return (EFI_INVALID_PARAMETER);

Modified: stable/10/sys/boot/efi/include/efilib.h
==============================================================================
--- stable/10/sys/boot/efi/include/efilib.h	Thu Jan 28 16:51:56 2016	(r294996)
+++ stable/10/sys/boot/efi/include/efilib.h	Thu Jan 28 16:52:02 2016	(r294997)
@@ -39,7 +39,6 @@ extern struct devsw efinet_dev;
 extern struct netif_driver efinetif;
 
 void *efi_get_table(EFI_GUID *tbl);
-void efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
 
 int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int);
 EFI_HANDLE efi_find_handle(struct devsw *, int);

Modified: stable/10/sys/boot/efi/loader/devicename.c
==============================================================================
--- stable/10/sys/boot/efi/loader/devicename.c	Thu Jan 28 16:51:56 2016	(r294996)
+++ stable/10/sys/boot/efi/loader/devicename.c	Thu Jan 28 16:52:02 2016	(r294997)
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
 #include <stand.h>
 #include <string.h>
 #include <sys/disklabel.h>
+#include <sys/param.h>
 #include <bootstrap.h>
 
 #include <efi.h>
@@ -86,7 +87,7 @@ efi_parsedev(struct devdesc **dev, const
 	struct devsw *dv;
 	char *cp;
 	const char *np;
-	int i, err;
+	int i;
 
 	/* minimum length check */
 	if (strlen(devspec) < 2)
@@ -101,24 +102,26 @@ efi_parsedev(struct devdesc **dev, const
 	if (devsw[i] == NULL)
 		return (ENOENT);
 
-	idev = malloc(sizeof(struct devdesc));
-	if (idev == NULL)
-		return (ENOMEM);
-
-	idev->d_dev = dv;
-	idev->d_type = dv->dv_type;
-	idev->d_unit = -1;
-
-	err = 0;
 	np = devspec + strlen(dv->dv_name);
-	if (*np != '\0' && *np != ':') {
-		idev->d_unit = strtol(np, &cp, 0);
-		if (cp == np) {
-			idev->d_unit = -1;
-			free(idev);
-			return (EUNIT);
+
+	{
+		idev = malloc(sizeof(struct devdesc));
+		if (idev == NULL)
+			return (ENOMEM);
+
+		idev->d_dev = dv;
+		idev->d_type = dv->dv_type;
+		idev->d_unit = -1;
+		if (*np != '\0' && *np != ':') {
+			idev->d_unit = strtol(np, &cp, 0);
+			if (cp == np) {
+				idev->d_unit = -1;
+				free(idev);
+				return (EUNIT);
+			}
 		}
 	}
+
 	if (*cp != '\0' && *cp != ':') {
 		free(idev);
 		return (EINVAL);
@@ -137,7 +140,7 @@ char *
 efi_fmtdev(void *vdev)
 {
 	struct devdesc *dev = (struct devdesc *)vdev;
-	static char buf[32];	/* XXX device length constant? */
+	static char buf[SPECNAMELEN + 1];
 
 	switch(dev->d_type) {
 	case DEVT_NONE:

Modified: stable/10/sys/boot/efi/loader/main.c
==============================================================================
--- stable/10/sys/boot/efi/loader/main.c	Thu Jan 28 16:51:56 2016	(r294996)
+++ stable/10/sys/boot/efi/loader/main.c	Thu Jan 28 16:52:02 2016	(r294997)
@@ -28,6 +28,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/param.h>
 #include <stand.h>
 #include <string.h>
 #include <setjmp.h>
@@ -45,7 +46,6 @@ extern char bootprog_rev[];
 extern char bootprog_date[];
 extern char bootprog_maker[];
 
-struct devdesc currdev;		/* our current device */
 struct arch_switch archsw;	/* MI/MD interface boundary */
 
 EFI_GUID acpi = ACPI_TABLE_GUID;
@@ -60,15 +60,36 @@ EFI_GUID hoblist = HOB_LIST_TABLE_GUID;
 EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID;
 EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID;
 
+/*
+ * Need this because EFI uses UTF-16 unicode string constants, but we
+ * use UTF-8. We can't use printf due to the possiblity of \0 and we
+ * don't support support wide characters either.
+ */
+static void
+print_str16(const CHAR16 *str)
+{
+	int i;
+
+	for (i = 0; str[i]; i++)
+		printf("%c", (char)str[i]);
+}
+
 EFI_STATUS
 main(int argc, CHAR16 *argv[])
 {
 	char var[128];
 	EFI_LOADED_IMAGE *img;
 	EFI_GUID *guid;
-	int i, j, vargood;
+	int i, j, vargood, unit;
+	struct devsw *dev;
 	UINTN k;
 
+	archsw.arch_autoload = efi_autoload;
+	archsw.arch_getdev = efi_getdev;
+	archsw.arch_copyin = efi_copyin;
+	archsw.arch_copyout = efi_copyout;
+	archsw.arch_readin = efi_readin;
+
 	/*
 	 * XXX Chicken-and-egg problem; we want to have console output
 	 * early, but some console attributes may depend on reading from
@@ -115,6 +136,13 @@ main(int argc, CHAR16 *argv[])
 	/* Get our loaded image protocol interface structure. */
 	BS->HandleProtocol(IH, &imgid, (VOID**)&img);
 
+	printf("Command line arguments:");
+	for (i = 0; i < argc; i++) {
+		printf(" ");
+		print_str16(argv[i]);
+	}
+	printf("\n");
+
 	printf("Image base: 0x%lx\n", (u_long)img->ImageBase);
 	printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16,
 	    ST->Hdr.Revision & 0xffff);
@@ -128,9 +156,6 @@ main(int argc, CHAR16 *argv[])
 	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
 	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
 
-	efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
-	currdev.d_type = currdev.d_dev->dv_type;
-
 	/*
 	 * Disable the watchdog timer. By default the boot manager sets
 	 * the timer to 5 minutes before invoking a boot option. If we
@@ -142,18 +167,26 @@ main(int argc, CHAR16 *argv[])
 	 */
 	BS->SetWatchdogTimer(0, 0, 0, NULL);
 
-	env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev),
-	    efi_setcurrdev, env_nounset);
-	env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset,
-	    env_nounset);
+	if (efi_handle_lookup(img->DeviceHandle, &dev, &unit) != 0)
+		return (EFI_NOT_FOUND);
 
-	setenv("LINES", "24", 1);	/* optional */
+	switch (dev->dv_type) {
+	default: {
+		struct devdesc currdev;
+
+		currdev.d_dev = dev;
+		currdev.d_unit = unit;
+		currdev.d_opendata = NULL;
+		currdev.d_type = currdev.d_dev->dv_type;
+		env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev),
+			   efi_setcurrdev, env_nounset);
+		env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset,

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601281652.u0SGq2L9039493>