Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111873598
D7589.id21305.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
127 KB
Referenced Files
None
Subscribers
None
D7589.id21305.diff
View Options
Index: lib/libstand/Makefile
===================================================================
--- lib/libstand/Makefile
+++ lib/libstand/Makefile
@@ -41,7 +41,7 @@
.PATH: ${LIBC_SRC}/string
SRCS+= bcmp.c bcopy.c bzero.c ffs.c fls.c \
memccpy.c memchr.c memcmp.c memcpy.c memmove.c memset.c \
- qdivrem.c strcat.c strchr.c strcmp.c strcpy.c \
+ qdivrem.c strcat.c strchr.c strcmp.c strcpy.c stpcpy.c stpncpy.c \
strcspn.c strlcat.c strlcpy.c strlen.c strncat.c strncmp.c strncpy.c \
strpbrk.c strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c
.if ${MACHINE_CPUARCH} == "arm"
Index: lib/libstand/stand.h
===================================================================
--- lib/libstand/stand.h
+++ lib/libstand/stand.h
@@ -24,7 +24,7 @@
* SUCH DAMAGE.
*
* $FreeBSD$
- * From $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $
+ * From $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $
*/
/*-
@@ -131,7 +131,7 @@
#define SEEK_CUR 1 /* set file offset to current plus offset */
#define SEEK_END 2 /* set file offset to EOF plus offset */
-/*
+/*
* Device switch
*/
struct devsw {
@@ -166,8 +166,9 @@
#define DEVT_NONE 0
#define DEVT_DISK 1
#define DEVT_NET 2
-#define DEVT_CD 3
+#define DEVT_CD 3
#define DEVT_ZFS 4
+#define DEVT_EFI 5
int d_unit;
void *d_opendata;
};
@@ -279,7 +280,7 @@
extern void srandom(u_long seed);
extern u_long random(void);
-
+
/* imports from stdlib, locally modified */
extern long strtol(const char *, char **, int);
extern unsigned long strtoul(const char *, char **, int);
@@ -368,9 +369,9 @@
extern int null_readdir(struct open_file *f, struct dirent *d);
-/*
- * Machine dependent functions and data, must be provided or stubbed by
- * the consumer
+/*
+ * Machine dependent functions and data, must be provided or stubbed by
+ * the consumer
*/
extern int getchar(void);
extern int ischar(void);
Index: sys/boot/efi/Makefile
===================================================================
--- sys/boot/efi/Makefile
+++ sys/boot/efi/Makefile
@@ -15,7 +15,7 @@
.if ${MACHINE_CPUARCH} == "aarch64" || \
${MACHINE_CPUARCH} == "amd64" || \
${MACHINE_CPUARCH} == "arm"
-SUBDIR+= libefi loader boot1
+SUBDIR+= libefi drivers loader boot1
.endif
.endif # ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 404500
Index: sys/boot/efi/boot1/Makefile
===================================================================
--- sys/boot/efi/boot1/Makefile
+++ sys/boot/efi/boot1/Makefile
@@ -10,32 +10,48 @@
INTERNALPROG=
WARNS?= 6
+# Include bcache code.
+HAVE_BCACHE= yes
+
.if ${MK_ZFS} != "no"
# Disable warnings that are currently incompatible with the zfs boot code
-CWARNFLAGS.zfs_module.c += -Wno-array-bounds
-CWARNFLAGS.zfs_module.c += -Wno-cast-align
-CWARNFLAGS.zfs_module.c += -Wno-cast-qual
-CWARNFLAGS.zfs_module.c += -Wno-missing-prototypes
-CWARNFLAGS.zfs_module.c += -Wno-sign-compare
-CWARNFLAGS.zfs_module.c += -Wno-unused-parameter
-CWARNFLAGS.zfs_module.c += -Wno-unused-function
+CWARNFLAGS.boot1.c += -Wno-missing-variable-declarations
+CWARNFLAGS.zfs.c += -Wno-incompatible-pointer-types-discards-qualifiers
+CWARNFLAGS.zfs.c += -Wno-missing-variable-declarations
+CWARNFLAGS.zfs.c += -Wno-array-bounds
+CWARNFLAGS.zfs.c += -Wno-cast-align
+CWARNFLAGS.zfs.c += -Wno-cast-qual
+CWARNFLAGS.zfs.c += -Wno-missing-prototypes
+CWARNFLAGS.zfs.c += -Wno-sign-compare
+CWARNFLAGS.zfs.c += -Wno-unused-parameter
+CWARNFLAGS.zfs.c += -Wno-unused-function
CWARNFLAGS.skein.c += -Wno-cast-align
CWARNFLAGS.skein.c += -Wno-missing-variable-declarations
.endif
+
# architecture-specific loader code
-SRCS= boot1.c self_reloc.c start.S ufs_module.c
+SRCS= boot1.c self_reloc.c start.S
.if ${MK_ZFS} != "no"
-SRCS+= zfs_module.c
+.PATH: ${.CURDIR}/../../../crypto/skein
SRCS+= skein.c skein_block.c
# Do not unroll skein loops, reduce code size
CFLAGS+= -DSKEIN_LOOP=111
-.PATH: ${.CURDIR}/../../../crypto/skein
+.PATH: ${.CURDIR}/../../zfs
+SRCS+= zfs.c
.endif
+# Always add MI sources
+.PATH: ${.CURDIR}/../../common
+.include "${.CURDIR}/../../common/Makefile.inc"
+CFLAGS+= -I${.CURDIR}/../../common
+
+.PATH: ${.CURDIR}/arch/${MACHINE}
+
CFLAGS+= -I.
CFLAGS+= -I${.CURDIR}/../include
CFLAGS+= -I${.CURDIR}/../include/${MACHINE}
+CFLAGS+= -I${.CURDIR}/../drivers/
CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include
CFLAGS+= -I${.CURDIR}/../../..
CFLAGS+= -DEFI_UFS_BOOT
@@ -56,6 +72,20 @@
.PATH: ${.CURDIR}/../../common
CFLAGS+= -I${.CURDIR}/../../common
+# make buildenv doesn't set DESTDIR, this means LIBSTAND
+# will be wrong when crossbuilding.
+.if exists(${.OBJDIR}/../../../../lib/libstand/libstand.a)
+LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a
+.endif
+
+# Add libefi
+.PATH: ${.CURDIR}/../libefi
+LIBEFI= ${.OBJDIR}/../libefi/libefi.a
+
+.PATH: ${.CURDIR}/../drivers
+LIBEFI_DRIVERS= ${.OBJDIR}/../drivers/libefi_drivers.a
+
+
FILES= boot1.efi boot1.efifat
FILESMODE_boot1.efi= ${BINMODE}
@@ -75,8 +105,8 @@
# __aeabi_* (arm) or __divdi3 (i386).
# as well as required string and memory functions for all platforms.
#
-DPADD+= ${LIBSTAND}
-LDADD+= -lstand
+DPADD+= ${LIBEFI_DRIVERS} ${LIBEFI} ${LIBSTAND}
+LDADD+= ${LIBEFI_DRIVERS} ${LIBEFI} -lstand
DPADD+= ${LDSCRIPT}
@@ -102,7 +132,7 @@
SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH} \
${OBJCOPY} -j .peheader -j .text -j .sdata -j .data \
-j .dynamic -j .dynsym -j .rel.dyn \
- -j .rela.dyn -j .reloc -j .eh_frame \
+ -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \
--output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}
boot1.o: ${.CURDIR}/../../common/ufsread.c
@@ -111,7 +141,7 @@
# created by generate-fat.sh
.include "${.CURDIR}/Makefile.fat"
-BOOT1_MAXSIZE?= 131072
+BOOT1_MAXSIZE?= 524288
boot1.efifat: boot1.efi
@set -- `ls -l boot1.efi`; \
Index: sys/boot/efi/boot1/Makefile.fat
===================================================================
--- sys/boot/efi/boot1/Makefile.fat
+++ sys/boot/efi/boot1/Makefile.fat
@@ -1,4 +1,4 @@
# This file autogenerated by generate-fat.sh - DO NOT EDIT
# $FreeBSD$
BOOT1_OFFSET=0x2d
-BOOT1_MAXSIZE=131072
+BOOT1_MAXSIZE=524288
Index: sys/boot/efi/boot1/boot1.c
===================================================================
--- sys/boot/efi/boot1/boot1.c
+++ sys/boot/efi/boot1/boot1.c
@@ -26,108 +26,117 @@
#include <machine/elf.h>
#include <machine/stdarg.h>
#include <stand.h>
+#include <string16.h>
#include <efi.h>
+#include <efilib.h>
+#include <efiprot.h>
#include <eficonsctl.h>
+#ifdef EFI_ZFS_BOOT
+#include <libzfs.h>
+#endif
+
+#include <bootstrap.h>
-#include "boot_module.h"
+#include "efi_drivers.h"
#include "paths.h"
-static const boot_module_t *boot_modules[] =
-{
-#ifdef EFI_ZFS_BOOT
- &zfs_module,
-#endif
-#ifdef EFI_UFS_BOOT
- &ufs_module
+#ifdef EFI_DEBUG
+#define DPRINTF(fmt, args...) printf(fmt, ##args)
+#define DSTALL(d) bs->Stall(d)
+#else
+#define DPRINTF(fmt, ...) {}
+#define DSTALL(d) {}
#endif
+
+struct arch_switch archsw; /* MI/MD interface boundary */
+
+static const efi_driver_t *efi_drivers[] = {
+ &fs_driver,
+ NULL
};
-#define NUM_BOOT_MODULES nitems(boot_modules)
-/* The initial number of handles used to query EFI for partitions. */
-#define NUM_HANDLES_INIT 24
+extern struct console efi_console;
+#if defined(__amd64__) || defined(__i386__)
+extern struct console comconsole;
+extern struct console nullconsole;
+#endif
-void putchar(int c);
-EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
+struct fs_ops *file_system[] = {
+ &dosfs_fsops,
+ &ufs_fsops,
+ &cd9660_fsops,
+ &nfs_fsops,
+ &gzipfs_fsops,
+ &bzipfs_fsops,
+ NULL
+};
-EFI_SYSTEM_TABLE *systab;
-EFI_BOOT_SERVICES *bs;
-static EFI_HANDLE *image;
+struct devsw *devsw[] = {
+ &efipart_dev,
+#ifdef EFI_ZFS_BOOT
+ &zfs_dev,
+#endif
+ NULL
+};
-static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
-static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
-static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
-static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+struct console *consoles[] = {
+ &efi_console,
+ NULL
+};
-/*
- * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
- * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
- * EFI methods.
+/* Definitions we don't actually need for boot, but we need to define
+ * to make the linker happy.
*/
-void *
-Malloc(size_t len, const char *file __unused, int line __unused)
-{
- void *out;
+struct file_format *file_formats[] = { NULL };
- if (bs->AllocatePool(EfiLoaderData, len, &out) == EFI_SUCCESS)
- return (out);
+struct netif_driver *netif_drivers[] = { NULL };
- return (NULL);
+static int
+efi_autoload(void)
+{
+ printf("******** Boot block should not call autoload\n");
+ return (-1);
}
-void
-Free(void *buf, const char *file __unused, int line __unused)
+static int efi_getdev(void **vdev __unused, const char *devspec __unused,
+ const char **path __unused)
{
- if (buf != NULL)
- (void)bs->FreePool(buf);
+ printf("******** Boot block should not call getdev\n");
+ return (-1);
}
-/*
- * nodes_match returns TRUE if the imgpath isn't NULL and the nodes match,
- * FALSE otherwise.
- */
-static BOOLEAN
-nodes_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
+static ssize_t
+efi_copyin(const void *src __unused, vm_offset_t dest __unused,
+ const size_t len __unused)
{
- int len;
-
- if (imgpath == NULL || imgpath->Type != devpath->Type ||
- imgpath->SubType != devpath->SubType)
- return (FALSE);
-
- len = DevicePathNodeLength(imgpath);
- if (len != DevicePathNodeLength(devpath))
- return (FALSE);
-
- return (memcmp(imgpath, devpath, (size_t)len) == 0);
+ printf("******** Boot block should not call copyin\n");
+ return (-1);
}
-/*
- * device_paths_match returns TRUE if the imgpath isn't NULL and all nodes
- * in imgpath and devpath match up to their respective occurrences of a
- * media node, FALSE otherwise.
- */
-static BOOLEAN
-device_paths_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
+static ssize_t
+efi_copyout(vm_offset_t src __unused, void *dest __unused,
+ const size_t len __unused)
{
+ printf("******** Boot block should not call copyout\n");
+ return (-1);
+}
- if (imgpath == NULL)
- return (FALSE);
-
- while (!IsDevicePathEnd(imgpath) && !IsDevicePathEnd(devpath)) {
- if (IsDevicePathType(imgpath, MEDIA_DEVICE_PATH) &&
- IsDevicePathType(devpath, MEDIA_DEVICE_PATH))
- return (TRUE);
-
- if (!nodes_match(imgpath, devpath))
- return (FALSE);
+static ssize_t
+efi_readin(int fd __unused, vm_offset_t dest __unused,
+ const size_t len __unused)
+{
+ printf("******** Boot block should not call readin\n");
+ return (-1);
+}
- imgpath = NextDevicePathNode(imgpath);
- devpath = NextDevicePathNode(devpath);
- }
+/* The initial number of handles used to query EFI for partitions. */
+#define NUM_HANDLES_INIT 24
- return (FALSE);
-}
+static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
+static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
+static EFI_GUID SimpleFileSystemProtocolGUID = SIMPLE_FILE_SYSTEM_PROTOCOL;
+static EFI_GUID FileInfoGUID = EFI_FILE_INFO_ID;;
/*
* devpath_last returns the last non-path end node in devpath.
@@ -142,6 +151,7 @@
return (devpath);
}
+#ifdef EFI_DEBUG
/*
* devpath_node_str is a basic output method for a devpath node which
* only understands a subset of the available sub types.
@@ -273,7 +283,7 @@
* devpath_strlcat appends a text description of devpath to buf but not more
* than size - 1 characters followed by NUL-terminator.
*/
-int
+static int
devpath_strlcat(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
{
size_t len, used;
@@ -304,7 +314,7 @@
* devpath_str is convenience method which returns the text description of
* devpath using a static buffer, so it isn't thread safe!
*/
-char *
+static char *
devpath_str(EFI_DEVICE_PATH *devpath)
{
static char buf[256];
@@ -313,39 +323,171 @@
return buf;
}
+#endif
+
+static EFI_STATUS
+efi_load(EFI_HANDLE dev, const char *filepath, void **bufp, size_t *bufsize)
+{
+ UINTN infosize = sizeof(EFI_FILE_INFO) +
+ ((strlen(filepath) + 1) * sizeof(CHAR16));
+ EFI_FILE_INFO *finfo;
+ EFI_STATUS status;
+ EFI_FILE_IO_INTERFACE *iface;
+ EFI_FILE_HANDLE root;
+ EFI_FILE_HANDLE target;
+ CHAR16 path16[strlen(filepath) + 1];
+ void *buf;
+
+ finfo = malloc(infosize);
+
+ if (finfo == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ status = BS->OpenProtocol(dev, &SimpleFileSystemProtocolGUID,
+ (void **)&iface, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (status != EFI_SUCCESS) {
+ free(finfo);
+ printf("Open protocol failed! %ld\n", EFI_ERROR_CODE(status));
+ return (status);
+ }
+
+ status = iface->OpenVolume(iface, &root);
+
+ if (status != EFI_SUCCESS) {
+ BS->CloseProtocol(dev, &SimpleFileSystemProtocolGUID, IH, NULL);
+ free(finfo);
+ printf("Open volume failed! %ld\n", EFI_ERROR_CODE(status));
+ return (status);
+ }
+
+ strcpy_to_16(path16, filepath);
+ status = root->Open(root, &target, path16, EFI_FILE_MODE_READ, 0);
+
+ if (status != EFI_SUCCESS) {
+ BS->CloseProtocol(dev, &SimpleFileSystemProtocolGUID, IH, NULL);
+ free(finfo);
+
+ return (status);
+ }
+
+ *bufsize = infosize;
+ status = target->GetInfo(target, &FileInfoGUID, bufsize, finfo);
+
+ if (status != EFI_SUCCESS) {
+ BS->CloseProtocol(dev, &SimpleFileSystemProtocolGUID, IH, NULL);
+ free(finfo);
+ printf("Get info failed! %ld\n", EFI_ERROR_CODE(status));
+ return (status);
+ }
+
+ *bufsize = finfo->FileSize;
+
+ if ((status = BS->AllocatePool(EfiLoaderData, finfo->FileSize, &buf))
+ != EFI_SUCCESS) {
+ BS->CloseProtocol(dev, &SimpleFileSystemProtocolGUID, IH, NULL);
+ free(finfo);
+ printf("Failed to allocate load buffer %zd for '%s' "
+ "(%lu)\n", finfo->FileSize, filepath, EFI_ERROR_CODE(status));
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ *bufp = buf;
+ status = target->Read(target, bufsize, buf);
+ BS->CloseProtocol(dev, &SimpleFileSystemProtocolGUID, IH, NULL);
+ free(finfo);
+
+ if (status != EFI_SUCCESS) {
+ printf("Read failed! %ld\n", EFI_ERROR_CODE(status));
+ return (status);
+ }
+
+ return (EFI_SUCCESS);
+}
/*
* load_loader attempts to load the loader image data.
*
- * It tries each module and its respective devices, identified by mod->probe,
- * in order until a successful load occurs at which point it returns EFI_SUCCESS
- * and EFI_NOT_FOUND otherwise.
+ * This tries all handles which support the EFI_SIMPLE_FILE_SYSTEM interface.
+ * It is expected that the drivers will have installed this interface on every
+ * handle representing a device containing a supported file system.
+ *
+ * Note: In the future, this may be altered to use the EFI_LOAD_FILE interface,
+ * which should work transparently with network booting.
*
* Only devices which have preferred matching the preferred parameter are tried.
*/
static EFI_STATUS
-load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp,
- size_t *bufsize, BOOLEAN preferred)
+load_loader(EFI_HANDLE *handlep, void **bufp, size_t *bufsize)
{
- UINTN i;
- dev_info_t *dev;
- const boot_module_t *mod;
-
- for (i = 0; i < NUM_BOOT_MODULES; i++) {
- mod = boot_modules[i];
- for (dev = mod->devices(); dev != NULL; dev = dev->next) {
- if (dev->preferred != preferred)
- continue;
-
- if (mod->load(PATH_LOADER_EFI, dev, bufp, bufsize) ==
- EFI_SUCCESS) {
- *devinfop = dev;
- *modp = mod;
- return (EFI_SUCCESS);
- }
+ EFI_LOADED_IMAGE *boot_image;
+ EFI_HANDLE *boot_handle;
+ EFI_HANDLE *handles;
+ EFI_STATUS status;
+ UINTN i, hsize, nhandles;
+
+ if ((status = BS->OpenProtocol(IH, &LoadedImageGUID,
+ (VOID**)&boot_image, IH, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL)) != EFI_SUCCESS) {
+ panic("Failed to query LoadedImage (%lu)\n",
+ EFI_ERROR_CODE(status));
+ }
+
+ boot_handle = boot_image->DeviceHandle;
+
+ /* Try the device handle for our image first
+ */
+ if (BS->OpenProtocol(boot_handle, &SimpleFileSystemProtocolGUID,
+ NULL, IH, boot_handle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL) == EFI_SUCCESS &&
+ efi_load(boot_handle, PATH_LOADER_EFI, bufp, bufsize) ==
+ EFI_SUCCESS) {
+ *handlep = boot_handle;
+ return (EFI_SUCCESS);
+ }
+
+ 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));
+
+ status = BS->LocateHandle(ByProtocol, &SimpleFileSystemProtocolGUID, 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,
+ &SimpleFileSystemProtocolGUID, 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));
}
+ nhandles = hsize / sizeof(*handles);
+
+ for (i = 0; i < nhandles; i++) {
+ if (efi_load(handles[i], PATH_LOADER_EFI, bufp, bufsize) ==
+ EFI_SUCCESS) {
+ *handlep = handles[i];
+ return (EFI_SUCCESS);
+ }
+ }
+
+ printf("Failed to load %s from any device!\n", PATH_LOADER_EFI);
+
return (EFI_NOT_FOUND);
}
@@ -359,20 +501,27 @@
size_t bufsize, loadersize, cmdsize;
void *buf, *loaderbuf;
char *cmd;
- dev_info_t *dev;
- const boot_module_t *mod;
+ EFI_HANDLE fshandle;
EFI_HANDLE loaderhandle;
EFI_LOADED_IMAGE *loaded_image;
EFI_STATUS status;
+ EFI_DEVICE_PATH *fspath;
+
+ status = load_loader(&fshandle, &loaderbuf, &loadersize);
+
+ if (status != EFI_SUCCESS) {
+ return (status);
+ }
- status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE);
- if (status != EFI_SUCCESS) {
- status = load_loader(&mod, &dev, &loaderbuf, &loadersize,
- FALSE);
+ fspath = NULL;
+ if (status == EFI_SUCCESS) {
+ status = BS->OpenProtocol(fshandle, &DevicePathGUID,
+ (void **)&fspath, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (status != EFI_SUCCESS) {
- printf("Failed to load '%s'\n", PATH_LOADER_EFI);
- return (status);
- }
+ DPRINTF("Failed to get image DevicePath (%lu)\n",
+ EFI_ERROR_CODE(status));
+ }
+ DPRINTF("filesystem device path: %s\n", devpath_str(imgpath));
}
/*
@@ -387,9 +536,9 @@
*/
cmd = NULL;
cmdsize = 0;
- status = mod->load(PATH_DOTCONFIG, dev, &buf, &bufsize);
+ status = efi_load(fshandle, PATH_DOTCONFIG, &buf, &bufsize);
if (status == EFI_NOT_FOUND)
- status = mod->load(PATH_CONFIG, dev, &buf, &bufsize);
+ status = efi_load(fshandle, PATH_CONFIG, &buf, &bufsize);
if (status == EFI_SUCCESS) {
cmdsize = bufsize + 1;
cmd = malloc(cmdsize);
@@ -401,24 +550,25 @@
buf = NULL;
}
- if ((status = bs->LoadImage(TRUE, image, devpath_last(dev->devpath),
+ if ((status = BS->LoadImage(TRUE, IH, devpath_last(fspath),
loaderbuf, loadersize, &loaderhandle)) != EFI_SUCCESS) {
- printf("Failed to load image provided by %s, size: %zu, (%lu)\n",
- mod->name, loadersize, EFI_ERROR_CODE(status));
+ printf("Failed to load image, size: %zu, (%lu)\n",
+ loadersize, EFI_ERROR_CODE(status));
goto errout;
}
- 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));
+ if ((status = BS->OpenProtocol(loaderhandle, &LoadedImageGUID,
+ (VOID**)&loaded_image, IH, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL)) != EFI_SUCCESS) {
+ printf("Failed to query LoadedImage (%lu)\n",
+ EFI_ERROR_CODE(status));
goto errout;
}
if (cmd != NULL)
printf(" command args: %s\n", cmd);
- loaded_image->DeviceHandle = dev->devhandle;
+ loaded_image->DeviceHandle = fshandle;
loaded_image->LoadOptionsSize = cmdsize;
loaded_image->LoadOptions = cmd;
@@ -434,10 +584,10 @@
DSTALL(1000000);
DPRINTF(".\n");
- if ((status = bs->StartImage(loaderhandle, NULL, NULL)) !=
+ 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));
+ printf("Failed to start image (%lu)\n",
+ EFI_ERROR_CODE(status));
loaded_image->LoadOptionsSize = 0;
loaded_image->LoadOptions = NULL;
}
@@ -453,134 +603,19 @@
return (status);
}
-/*
- * probe_handle determines if the passed handle represents a logical partition
- * if it does it uses each module in order to probe it and if successful it
- * returns EFI_SUCCESS.
- */
-static EFI_STATUS
-probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN *preferred)
-{
- dev_info_t *devinfo;
- EFI_BLOCK_IO *blkio;
- EFI_DEVICE_PATH *devpath;
- EFI_STATUS status;
- UINTN i;
-
- /* Figure out if we're dealing with an actual partition. */
- status = bs->HandleProtocol(h, &DevicePathGUID, (void **)&devpath);
- if (status == EFI_UNSUPPORTED)
- return (status);
-
- if (status != EFI_SUCCESS) {
- DPRINTF("\nFailed to query DevicePath (%lu)\n",
- EFI_ERROR_CODE(status));
- return (status);
- }
-
- DPRINTF("probing: %s\n", devpath_str(devpath));
-
- status = bs->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio);
- if (status == EFI_UNSUPPORTED)
- return (status);
-
- if (status != EFI_SUCCESS) {
- DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n",
- EFI_ERROR_CODE(status));
- return (status);
- }
-
- if (!blkio->Media->LogicalPartition)
- return (EFI_UNSUPPORTED);
-
- *preferred = device_paths_match(imgpath, devpath);
-
- /* Run through each module, see if it can load this partition */
- for (i = 0; i < NUM_BOOT_MODULES; i++) {
- 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->preferred = *preferred;
- devinfo->next = NULL;
-
- status = boot_modules[i]->probe(devinfo);
- if (status == EFI_SUCCESS)
- return (EFI_SUCCESS);
- (void)bs->FreePool(devinfo);
- }
-
- return (EFI_UNSUPPORTED);
-}
-
-/*
- * probe_handle_status calls probe_handle and outputs the returned status
- * of the call.
- */
-static void
-probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath)
-{
- EFI_STATUS status;
- BOOLEAN preferred;
-
- status = probe_handle(h, imgpath, &preferred);
-
- DPRINTF("probe: ");
- switch (status) {
- case EFI_UNSUPPORTED:
- printf(".");
- DPRINTF(" not supported\n");
- break;
- case EFI_SUCCESS:
- if (preferred) {
- printf("%c", '*');
- DPRINTF(" supported (preferred)\n");
- } else {
- printf("%c", '+');
- DPRINTF(" supported\n");
- }
- break;
- default:
- printf("x");
- DPRINTF(" error (%lu)\n", EFI_ERROR_CODE(status));
- break;
- }
- DSTALL(500000);
-}
-
EFI_STATUS
-efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
+main(int argc __unused, CHAR16 *argv[] __unused)
{
- EFI_HANDLE *handles;
- EFI_LOADED_IMAGE *img;
- EFI_DEVICE_PATH *imgpath;
EFI_STATUS status;
- EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
- UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles;
-
- /* Basic initialization*/
- systab = Xsystab;
- image = Ximage;
- bs = Xsystab->BootServices;
-
- /* Set up the console, so printf works. */
- status = bs->LocateProtocol(&ConsoleControlGUID, NULL,
- (VOID **)&ConsoleControl);
- if (status == EFI_SUCCESS)
- (void)ConsoleControl->SetMode(ConsoleControl,
- EfiConsoleControlScreenText);
+ UINTN i, max_dim, best_mode, cols, rows;
+
+ cons_probe();
+
/*
* Reset the console and find the best text mode.
*/
- conout = systab->ConOut;
+ conout = ST->ConOut;
conout->Reset(conout, TRUE);
max_dim = best_mode = 0;
for (i = 0; ; i++) {
@@ -597,123 +632,31 @@
conout->EnableCursor(conout, TRUE);
conout->ClearScreen(conout);
- printf("\n>> FreeBSD EFI boot block\n");
- printf(" Loader path: %s\n\n", PATH_LOADER_EFI);
- printf(" Initializing modules:");
- for (i = 0; i < NUM_BOOT_MODULES; i++) {
- printf(" %s", boot_modules[i]->name);
- if (boot_modules[i]->init != NULL)
- boot_modules[i]->init();
- }
- putchar('\n');
-
- /* 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));
-
- 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));
- }
+ /*
+ * Initialise the block cache. Set the upper limit.
+ */
+ bcache_init(32768, 512);
- /* Scan all partitions, probing with all modules. */
- nhandles = hsize / sizeof(*handles);
- printf(" Probing %zu block devices...", nhandles);
- DPRINTF("\n");
+ printf("\n>> FreeBSD EFI boot block\n");
- /* Determine the devpath of our image so we can prefer it. */
- status = bs->HandleProtocol(image, &LoadedImageGUID, (VOID**)&img);
- imgpath = NULL;
- if (status == EFI_SUCCESS) {
- status = bs->HandleProtocol(img->DeviceHandle, &DevicePathGUID,
- (void **)&imgpath);
- if (status != EFI_SUCCESS)
- DPRINTF("Failed to get image DevicePath (%lu)\n",
- EFI_ERROR_CODE(status));
- DPRINTF("boot1 imagepath: %s\n", devpath_str(imgpath));
- }
+ 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;
- for (i = 0; i < nhandles; i++)
- probe_handle_status(handles[i], imgpath);
- printf(" done\n");
+ printf(" Loader path: %s\n\n", PATH_LOADER_EFI);
+ printf(" Initializing modules:");
- /* Status summary. */
- for (i = 0; i < NUM_BOOT_MODULES; i++) {
- printf(" ");
- boot_modules[i]->status();
+ for (i = 0; efi_drivers[i] != NULL; i++) {
+ printf(" %s", efi_drivers[i]->name);
+ if (efi_drivers[i]->init != NULL)
+ efi_drivers[i]->init();
}
+ putchar('\n');
try_boot();
/* If we get here, we're out of luck... */
panic("No bootable partitions found!");
}
-
-/*
- * add_device adds a device to the passed devinfo list.
- */
-void
-add_device(dev_info_t **devinfop, dev_info_t *devinfo)
-{
- dev_info_t *dev;
-
- if (*devinfop == NULL) {
- *devinfop = devinfo;
- return;
- }
-
- for (dev = *devinfop; dev->next != NULL; dev = dev->next)
- ;
-
- dev->next = devinfo;
-}
-
-void
-panic(const char *fmt, ...)
-{
- va_list ap;
-
- printf("panic: ");
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
- printf("\n");
-
- while (1) {}
-}
-
-void
-putchar(int c)
-{
- CHAR16 buf[2];
-
- if (c == '\n') {
- buf[0] = '\r';
- buf[1] = 0;
- systab->ConOut->OutputString(systab->ConOut, buf);
- }
- buf[0] = c;
- buf[1] = 0;
- systab->ConOut->OutputString(systab->ConOut, buf);
-}
Index: sys/boot/efi/boot1/boot_module.h
===================================================================
--- sys/boot/efi/boot1/boot_module.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*-
- * 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...) printf(fmt, ##args)
-#define DSTALL(d) bs->Stall(d)
-#else
-#define DPRINTF(fmt, ...) {}
-#define DSTALL(d) {}
-#endif
-
-/* EFI device info */
-typedef struct dev_info
-{
- EFI_BLOCK_IO *dev;
- EFI_DEVICE_PATH *devpath;
- EFI_HANDLE *devhandle;
- void *devdata;
- BOOLEAN preferred;
- 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 the specified file.
- *
- * 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 *filepath, dev_info_t *devinfo,
- void **buf, size_t *bufsize);
-
- /* status outputs information about the probed devices. */
- void (*status)();
-
- /* valid devices as found by probe. */
- dev_info_t *(*devices)();
-} boot_module_t;
-
-/* Standard boot modules. */
-#ifdef EFI_UFS_BOOT
-extern const boot_module_t ufs_module;
-#endif
-#ifdef EFI_ZFS_BOOT
-extern const boot_module_t zfs_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;
-
-extern int devpath_strlcat(char *buf, size_t size, EFI_DEVICE_PATH *devpath);
-extern char *devpath_str(EFI_DEVICE_PATH *devpath);
-#endif
Index: sys/boot/efi/boot1/fat-amd64.tmpl.bz2.uu
===================================================================
--- sys/boot/efi/boot1/fat-amd64.tmpl.bz2.uu
+++ sys/boot/efi/boot1/fat-amd64.tmpl.bz2.uu
@@ -2,25 +2,50 @@
DO NOT EDIT
$FreeBSD$
begin 644 fat-amd64.tmpl.bz2
-M0EIH.3%!62936?$)3$,`&U9_____Z^KJZ_^N_^O^Z_^[ON_NK^JJ^KZNKNNJ
-MZNKNZOJ^P`+\#$!0$#1D-,@#)DT#1B&AIDQ,AD:#1HTR`-#)D80Q!D:,)D``
-M#1@F30```&@`$JJ9!_HU4:",3!,F0&C(83`F30T`T!B&!,F`(P3`"#0,@`/2
-M::`#0!D`,C1`T9#3(`R9-`T8AH:9,3(9&@T:-,@#0R9&$,09&C"9```T8)DT
-M```!H``JBD@_2B:FF9)IHQ/1#:@-`:`R#(T`&@:-`!H8FAH:::'J::-`9&1Z
-MFF!'HAB8U/1/*8---3EV+*<ZL\S9BXEC[6I",BE$0BDA$1$%G66TH6PF$0(0
-MXDA!"&<HJ,=-W=K>PZ5:L^\19>>T2K3OA>TUS8M>VJ_;9P7"8;&7&8R51N>F
-M1E%A#6+F9*H@$(9J<K2V7=DH[YSK)LDN618]0S$3"M6JK5JU:M9J*5)44444
-M45JU%:5::U:M6K<:T42HHHHHHYI:J)44444,+B;R5>%%%%%%%$>!!!!!!!!!
-M!!!!!!!#76C@<C1HT:-&C1!!!!!!!!!TX&#!@P8,&#J8Y*BBBBBBBB'@<#!@
-MP8,&#"$4*******.?ZO)U59NW9Y_5RB9=SGK%AO91D/,RW:JUEWJ7CICT$M,
-M]]>OM;-N%^W[!<=H[<-1<QY)W<`%BRT<D`+3375[\FOS\YBD0`RSL8,UV51>
-MRR"SVLL>LG*Z1G+K%N;);>IIYL-7L*D<B5U+2/2:5J6K7K+ON7S<-ZW[`8;$
-M9ESS6Y>[Q-SH;5D;RU_+ZK.+TEMX%K(QQ813V:GS1ZT;"R\!H$K/Z:=%386M
-MPJL.<K?C*J6@DI)\#6KU=,@V3:-JW3>.`X;BN0SS2,I;U*I;;.]O5ZMI9CMV
-MY(;8*\CXX-SPW(^Z5WIWPW0V@?7DLGZ@QJQHC6!J-\U[>@T$2F)3"7UM2V+:
-M+YMFW;MO6^<-@L)R7+<WLVJEO,&HNI+>XU0JB(L,KI:F[OD%ZUC=-0WB\7C?
-M."P'%83CL1BM$RLHD):&7,DOSLY1=2Y,H_EOG`<%YS0,!Q&$XS]')8CXEXP_
-MFX2-7*,#%P;!Q]V)E#BO"83#?\V3C..Y#E,1?L5S&,NC%DQI>;+`DS>NQL5?
-?+6IF915V$0"$)@`M+"Q)@(_9+!?^+N2*<*$AXA*8A@``
+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
++WQ=R13A0D#$"%&\`
`
end
Index: sys/boot/efi/boot1/fat-arm.tmpl.bz2.uu
===================================================================
--- sys/boot/efi/boot1/fat-arm.tmpl.bz2.uu
+++ sys/boot/efi/boot1/fat-arm.tmpl.bz2.uu
@@ -2,25 +2,50 @@
DO NOT EDIT
$FreeBSD$
begin 644 fat-arm.tmpl.bz2
-M0EIH.3%!62936>#67)H`&U9_____Z^KJZ_ZN_^O^J_^[OJ[NK^JJ^KZNKNNJ
-MZNKNZOJ^P`+\```"``:`T::-`:8@P@&1D-!H:808)B:#0`T``,$T#!,@PC09
-M#33"9,0`T(`!H#1IHT!IB#"`9&0T&AIA!@F)H-`#0``P30,$R#"-!D--,)DQ
-M`#0@`&@-&FC0&F(,(!D9#0:&F$&"8F@T`-``#!-`P3(,(T&0TTPF3$`-`522
-M$_(H2-DT0T:8C(T!H!ZC30R-&@-`,@&C1H:`:#1M3(T,@:::/1#331FII@)@
-M)Z:)RK5N6<7,O<%[)S4ZD(ODD1"*2"(B(+E99)"P2A$"$.#(((0Z^BHO)97*
-MKNTS2;//!6_,:)5IVI>LPGUM8_)MV&_QO'$<Q>Y;`J/TETR.=50:\2B`0AF9
-M<_.ME;:;0N<9%D%\Q['*&6B4*U:JM6K5JUQ12I)1111116K45I*TJU:M6K<:
-MZ424444448Y-1)111111[F<_6R+%BQ8L6+$X3333333333333333=7Z\E2M6
-MK5JU:M--------->R44444447N#[%BQ8L6+%BQ-M)*******,!0HHHHHHHY[
-M-RR5757;.MS?HE)GL[:M-Q)&/TG09Q6MZ%)XJ4><D]5[S5M>^]M6W8C@..T=
-MV&HOX\@T$`%JWHY$`-/ZV!A?)K>YEEZ1`#*,&#,]G484F/7/RDR%Y<?]FG8X
-M&-?VUWJ*AR)+Z32//:9[#4M6R;8-FVK<,1OG$8K*LE&JR>4Q?U[J:^S$]EPK
-MD81)^D"<A>%H^>2OU:FLC31KK??,_$ES74S%+)U7JU5D:VQD)R-2U3"7[FWW
-M-DPVV;ANV^9-R&"T;G,A>6EJ3:=EVE6ENKC#PZG.]=9:75*G=>-4N\OA]'=-
-M`L[RN\MM/>Z'8:6Q.RAWU+=HOHDCZ6H?8_!^+:-JVS^6Z;UP'#<ERG-[$W'`
-MJ+^19>>T*HB+3GM+4VVS(NQ)&K?`_9IW\,PS#$;QOG"<-QV*QFB8^2)!)H).
-M7(_@P9(R$G)DC<L1NV\;UGV_<)Q'&?FY+%?$Z1Q?DWR/?DC@8W"M'(_<RTBJ
-M2'#=^XK8.,U[CN0Q'_,5MV,Y;F,`QI',DW7EU-_(S>MYF,_-.IT<D58,0"$)
-60`75I:D;]&V2<%_XNY(IPH2'!K+DT```
+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
+1(/F-#S7_XNY(IPH2!C]4XX``
`
end
Index: sys/boot/efi/boot1/fat-arm64.tmpl.bz2.uu
===================================================================
--- sys/boot/efi/boot1/fat-arm64.tmpl.bz2.uu
+++ sys/boot/efi/boot1/fat-arm64.tmpl.bz2.uu
@@ -2,25 +2,49 @@
DO NOT EDIT
$FreeBSD$
begin 644 fat-arm64.tmpl.bz2
-M0EIH.3%!629364C65#T`&U;_____Z^KJZ_^N_^O^J_^[OJ[NK^JJ^KZNKNNJ
-MZNKNZOJ^P`+\#0``0`#0#)D&@TR8AD`,0!D--&`@:!H&@`!B#)IHR:--#(9,
-MAA`8F@Q,0,#52`_U4?J@`&AH```:`:``````T-`T&@R&@T``````````$``T
-M`R9!H-,F(9`#$`9#31@(&@:!H``8@R::,FC30R&3(80&)H,3$#`521(]I1I)
-MF*:8C1Z`F0:`TR,@:&C30:`R!HTT,$!DTT-J:&@R&C)IA,:F33(S4]-3`--$
-MZ--B6=6F1M!<28FJA"+E)$0B<@B(B"TK+:2%L)0B!"'(D$$(9F:@LRO+Q;TL
-MNJ9YY2QZK1*-0US5+UM6R;E?-T_QQG*=-<9#J:#>R[!&-40;(2B`0AE9=956
-MO+"IH&,8M=KEBF(3,A$H5JU%:M6K5K1-.A)------6K35I*TJU:M6K<RU323
-M333338A4FDFFFFFFMX;;,<,#`P,#`P,".`@0($"!`@0($"!`@0J5,OJY*%:M
-M6K5JU:I4J5*E2I4J*E2I4J5*EQ<9OW>[LK*RLK*RLK*INY)IIIIIIL6F3333
-M333=7VLL91VEN[UP[M$I,5X--+@R1:XKTL?G%LL>,D\Y*-*DU+6MB^YMF\7S
-MB,!S6CMPUEU'H'B0`4V-'(@!JKN]^?Z<]*UB`&/9J#*9N@O9.H6FYDN5AT,L
-MS-UAW-A;:O3J61R=".=)EY-(TK3M8US8NM;1N&\<%Q%^Y3"9%=8Z-AUMYA;W
-MPYKK)5;?@6D;$DWL"J0LE*.Q]RA>Q[,;.QH%VDM/KGE)[.JBX4T=56_.0JD:
-MUL&Q73$OR;=NF^?PXKCL%SF=:1FKO&W%A1)O,YWU&FM;1N]W0QW=6U*UDS]Q
-M0M\CN\G:L^KT%O2U%G0;335JJYFAG8I,5$D?:UC\'Z/U;QO7`<)_3CL!R7/=
-M%B=L<+`H+J1;6??%$1%*H8[34M_N$+V0O6O;YJ7!95E7%<9?L%R7-83#:)BY
-M(D$F?DZ4B^,W)%W)SY(X;B/[<9?L\P'_-*YC<N>PGRLLY=[?HU\D?[A\BDOL
-MP)20P6A<ERG+;5S'-<YT&$OF&Z3IKLPY'3DPI,"1F-ET\-^SUZ&2DBC-1`(0
-6E`!:TJ9&`C?I,%_XNY(IPH2"1K*AZ```
+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
+G8X8&&&`U888`'G9,F3)E1111#QU%%$'GM3_Y_^+N2*<*$@UI8FV`
`
end
Index: sys/boot/efi/boot1/fat-i386.tmpl.bz2.uu
===================================================================
--- sys/boot/efi/boot1/fat-i386.tmpl.bz2.uu
+++ sys/boot/efi/boot1/fat-i386.tmpl.bz2.uu
@@ -2,25 +2,49 @@
DO NOT EDIT
$FreeBSD$
begin 644 fat-i386.tmpl.bz2
-M0EIH.3%!629361/"1&$`&U;_____Z^KJZ_ZN_^O^J_^[OJ[NK^JJ^KZNKNNJ
-MZNKNZOJ^P`+\#0``0`#0&C31H#3$&$`R,AH-#3"#!,30:`&@`!@F@8)D&$:#
-M(::83)B`&@:J0:?ZJ/U30`,@```-`,F@``````R-```R``````````$``T!H
-MTT:`TQ!A`,C(:#0TP@P3$T&@!H``8)H&"9!A&@R&FF$R8@!H"JB(GM*:(3VI
-MJ:;29-DF)ZC1H#)IA&0,C1H`R`VH#3$#(#R(R#(T8FFR$P(R8&AHQ3TTU.M/
-M4CH56XJBSBR%$R"%HBA""$HA"$(0*M)8Q06(C!"`@@OXA`@@[^28LHY?+JTZ
-MY4-*\Q4]=JDWP-DUR\;EM6^<1OW+<Q@,99V]K,<"*#>(;UG$,HJ0@""#-QRL
-MK%;U%@U#)LDM5=:+-(N(1@I4IJ5*E2I54DID4DDDDDE*E)2BI1I4J5*EU;!)
-M%))))))CE"2*222222VAMLQPP,#`P,#`P(X"!`@0($"!`@0($"!"A0[?7Q3*
-M5*E2I4J5"A0H4*%"A04*%"A0H4+.ST&QK*RLK*RLK*RA>Q22222226J1))))
-M)))E.[CDIL[6:1_==<1)HM-I)YW&BA1::S+:)65-0B]%&'M(M<V2\;ANU\XC
-MDN@P6KK!L*\/4/(@`3U-7$@`^+([2[^_Q8V$(`,J\&!FM!,;2+'JN_BM,?5?
-M]<L]7Q:]TM\Q0QVOF&%%<Q:Q[:EL&S7C+-RWS@N,Y+G,!B+A<VSZ\M;XG"\:
-M2OF*-[X56%V1<"`HB+(LZB&<]^9>0NH;>IIW;(JNVEFI;>C')YXV5+]XBB)\
-M[ZEVKL@W3>-^_IQW*<UT6$T3U7N9.RG317VA\.:ZL*J]MKV=;9^M.HBT^EF6
-M68O<S8-.I\NM.KV7E;C6TJ*9&IE4G.PA%#\6O?HW;^%\X#AN0Y3FN@Z;#=9D
-M/V./M9BO$L;+8B:$(3K:ZF<+>(%VV;@O/<5F69<ES'/=%TV"Q&*U3*10B$7C
-MQ3(=>*8X9GXH9&+#BAR'^.4Y;FM,Y[HL!@OY8;$?8S;J7G.0^F*'/Q;^<WV%
-MPQ&*#I-2P'4=5NF"PF&_UB.*Q778RU,6)C18D5_$SNVQL5?-;,[6*$V>A`$$
-7$8`%A.GB7Z'$1=)_XNY(IPH2`GA(C"``
+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
+A<#S[+FVTI2&VRRRR'P%EED'QVI_Z__%W)%.%"0W.\..`
`
end
Index: sys/boot/efi/boot1/generate-fat.sh
===================================================================
--- sys/boot/efi/boot1/generate-fat.sh
+++ sys/boot/efi/boot1/generate-fat.sh
@@ -13,7 +13,7 @@
FAT_SIZE=1600 #Size in 512-byte blocks of the produced image
-BOOT1_SIZE=128k
+BOOT1_SIZE=512k
#
# Known filenames
Index: sys/boot/efi/boot1/ufs_module.c
===================================================================
--- sys/boot/efi/boot1/ufs_module.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*-
- * Copyright (c) 1998 Robert Nordier
- * All rights reserved.
- * Copyright (c) 2001 Robert Drehmel
- * All rights reserved.
- * Copyright (c) 2014 Nathan Whitehorn
- * All rights reserved.
- * Copyright (c) 2015 Eric McCorkle
- * All rights reverved.
- *
- * 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$
- */
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#include <efi.h>
-
-#include "boot_module.h"
-
-static dev_info_t *devinfo;
-static dev_info_t *devices;
-
-static int
-dskread(void *buf, u_int64_t lba, int nblk)
-{
- int size;
- EFI_STATUS status;
-
- lba = lba / (devinfo->dev->Media->BlockSize / DEV_BSIZE);
- size = nblk * DEV_BSIZE;
-
- status = devinfo->dev->ReadBlocks(devinfo->dev,
- devinfo->dev->Media->MediaId, lba, size, buf);
-
- if (status != EFI_SUCCESS) {
- DPRINTF("dskread: failed dev: %p, id: %u, lba: %ju, size: %d, "
- "status: %lu\n", devinfo->dev,
- devinfo->dev->Media->MediaId, (uintmax_t)lba, size,
- EFI_ERROR_CODE(status));
- return (-1);
- }
-
- return (0);
-}
-
-#include "ufsread.c"
-
-static struct dmadat __dmadat;
-
-static int
-init_dev(dev_info_t* dev)
-{
-
- devinfo = dev;
- dmadat = &__dmadat;
-
- return fsread(0, NULL, 0);
-}
-
-static EFI_STATUS
-probe(dev_info_t* dev)
-{
-
- if (init_dev(dev) < 0)
- return (EFI_UNSUPPORTED);
-
- add_device(&devices, dev);
-
- return (EFI_SUCCESS);
-}
-
-static EFI_STATUS
-load(const char *filepath, dev_info_t *dev, void **bufp, size_t *bufsize)
-{
- ufs_ino_t ino;
- EFI_STATUS status;
- size_t size;
- ssize_t read;
- void *buf;
-
- DPRINTF("Loading '%s' from %s\n", filepath, devpath_str(dev->devpath));
-
- if (init_dev(dev) < 0) {
- DPRINTF("Failed to init device\n");
- return (EFI_UNSUPPORTED);
- }
-
- if ((ino = lookup(filepath)) == 0) {
- DPRINTF("Failed to lookup '%s' (file not found?)\n", filepath);
- return (EFI_NOT_FOUND);
- }
-
- if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) {
- printf("Failed to read size of '%s' ino: %d\n", filepath, ino);
- return (EFI_INVALID_PARAMETER);
- }
-
- if ((status = bs->AllocatePool(EfiLoaderData, size, &buf)) !=
- EFI_SUCCESS) {
- printf("Failed to allocate read buffer %zu for '%s' (%lu)\n",
- size, filepath, EFI_ERROR_CODE(status));
- return (status);
- }
-
- read = fsread(ino, buf, size);
- if ((size_t)read != size) {
- printf("Failed to read '%s' (%zd != %zu)\n", filepath, read,
- size);
- (void)bs->FreePool(buf);
- return (EFI_INVALID_PARAMETER);
- }
-
- DPRINTF("Load complete\n");
-
- *bufp = buf;
- *bufsize = size;
-
- return (EFI_SUCCESS);
-}
-
-static void
-status(void)
-{
- int i;
- dev_info_t *dev;
-
- for (dev = devices, i = 0; dev != NULL; dev = dev->next, i++)
- ;
-
- printf("%s found ", ufs_module.name);
- switch (i) {
- case 0:
- printf("no partitions\n");
- break;
- case 1:
- printf("%d partition\n", i);
- break;
- default:
- printf("%d partitions\n", i);
- }
-}
-
-static dev_info_t *
-_devices(void)
-{
-
- return (devices);
-}
-
-const boot_module_t ufs_module =
-{
- .name = "UFS",
- .probe = probe,
- .load = load,
- .status = status,
- .devices = _devices
-};
Index: sys/boot/efi/boot1/zfs_module.c
===================================================================
--- sys/boot/efi/boot1/zfs_module.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*-
- * 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$
- */
-#include <stddef.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <efi.h>
-
-#include "boot_module.h"
-
-#include "libzfs.h"
-#include "zfsimpl.c"
-
-static dev_info_t *devices;
-
-static int
-vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
-{
- dev_info_t *devinfo;
- off_t lba;
- EFI_STATUS status;
-
- devinfo = (dev_info_t *)priv;
- lba = off / devinfo->dev->Media->BlockSize;
-
- status = devinfo->dev->ReadBlocks(devinfo->dev,
- devinfo->dev->Media->MediaId, lba, bytes, buf);
- if (status != EFI_SUCCESS) {
- DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %jd, size: %zu,"
- " status: %lu\n", devinfo->dev,
- devinfo->dev->Media->MediaId, (intmax_t)lba, bytes,
- EFI_ERROR_CODE(status));
- return (-1);
- }
-
- return (0);
-}
-
-static EFI_STATUS
-probe(dev_info_t *dev)
-{
- spa_t *spa;
- dev_info_t *tdev;
- EFI_STATUS status;
-
- /* ZFS consumes the dev on success so we need a copy. */
- if ((status = bs->AllocatePool(EfiLoaderData, sizeof(*dev),
- (void**)&tdev)) != EFI_SUCCESS) {
- DPRINTF("Failed to allocate tdev (%lu)\n",
- EFI_ERROR_CODE(status));
- return (status);
- }
- memcpy(tdev, dev, sizeof(*dev));
-
- if (vdev_probe(vdev_read, tdev, &spa) != 0) {
- (void)bs->FreePool(tdev);
- return (EFI_UNSUPPORTED);
- }
-
- dev->devdata = spa;
- add_device(&devices, dev);
-
- return (EFI_SUCCESS);
-}
-
-static EFI_STATUS
-load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize)
-{
- spa_t *spa;
- struct zfsmount zfsmount;
- dnode_phys_t dn;
- struct stat st;
- int err;
- void *buf;
- EFI_STATUS status;
-
- spa = devinfo->devdata;
-
- DPRINTF("load: '%s' spa: '%s', devpath: %s\n", filepath, spa->spa_name,
- devpath_str(devinfo->devpath));
-
- if ((err = zfs_spa_init(spa)) != 0) {
- DPRINTF("Failed to load pool '%s' (%d)\n", spa->spa_name, err);
- return (EFI_NOT_FOUND);
- }
-
- if ((err = zfs_mount(spa, 0, &zfsmount)) != 0) {
- DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err);
- return (EFI_NOT_FOUND);
- }
-
- if ((err = zfs_lookup(&zfsmount, filepath, &dn)) != 0) {
- if (err == ENOENT) {
- DPRINTF("Failed to find '%s' on pool '%s' (%d)\n",
- filepath, spa->spa_name, err);
- return (EFI_NOT_FOUND);
- }
- printf("Failed to lookup '%s' on pool '%s' (%d)\n", filepath,
- spa->spa_name, err);
- return (EFI_INVALID_PARAMETER);
- }
-
- if ((err = zfs_dnode_stat(spa, &dn, &st)) != 0) {
- printf("Failed to stat '%s' on pool '%s' (%d)\n", filepath,
- spa->spa_name, err);
- return (EFI_INVALID_PARAMETER);
- }
-
- if ((status = bs->AllocatePool(EfiLoaderData, (UINTN)st.st_size, &buf))
- != EFI_SUCCESS) {
- printf("Failed to allocate load buffer %zd for pool '%s' for '%s' "
- "(%lu)\n", st.st_size, spa->spa_name, filepath, EFI_ERROR_CODE(status));
- return (EFI_INVALID_PARAMETER);
- }
-
- if ((err = dnode_read(spa, &dn, 0, buf, st.st_size)) != 0) {
- printf("Failed to read node from %s (%d)\n", spa->spa_name,
- err);
- (void)bs->FreePool(buf);
- return (EFI_INVALID_PARAMETER);
- }
-
- *bufsize = st.st_size;
- *bufp = buf;
-
- return (EFI_SUCCESS);
-}
-
-static void
-status(void)
-{
- spa_t *spa;
-
- spa = STAILQ_FIRST(&zfs_pools);
- if (spa == NULL) {
- printf("%s found no pools\n", zfs_module.name);
- return;
- }
-
- printf("%s found the following pools:", zfs_module.name);
- STAILQ_FOREACH(spa, &zfs_pools, spa_link)
- printf(" %s", spa->spa_name);
-
- printf("\n");
-}
-
-static void
-init(void)
-{
-
- zfs_init();
-}
-
-static dev_info_t *
-_devices(void)
-{
-
- return (devices);
-}
-
-const boot_module_t zfs_module =
-{
- .name = "ZFS",
- .init = init,
- .probe = probe,
- .load = load,
- .status = status,
- .devices = _devices
-};
Index: sys/boot/efi/drivers/Makefile
===================================================================
--- /dev/null
+++ sys/boot/efi/drivers/Makefile
@@ -0,0 +1,34 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+LIB= efi_drivers
+INTERNALLIB=
+WARNS?= 2
+
+SRCS= efipart.c fs_driver.c
+
+.if ${MACHINE_CPUARCH} == "aarch64"
+CFLAGS+= -msoft-float -mgeneral-regs-only
+.endif
+.if ${MACHINE_ARCH} == "amd64"
+CFLAGS+= -fPIC -mno-red-zone
+.endif
+.if ${MK_ZFS} != "no"
+CFLAGS+= -I${.CURDIR}/../../zfs
+CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs
+CFLAGS+= -DEFI_ZFS_BOOT
+.endif
+
+CFLAGS+= -I${.CURDIR}/../include
+CFLAGS+= -I${.CURDIR}/../include/${MACHINE}
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+
+# Pick up the bootstrap header for some interface items
+CFLAGS+= -I${.CURDIR}/../../common
+
+# Handle FreeBSD specific %b and %D printf format specifiers
+CFLAGS+= ${FORMAT_EXTENSIONS}
+CFLAGS+= -DTERM_EMU
+
+.include <bsd.lib.mk>
Index: sys/boot/efi/drivers/efi_drivers.h
===================================================================
--- /dev/null
+++ sys/boot/efi/drivers/efi_drivers.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2016 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 _EFI_DRIVERS_H_
+#define _EFI_DRIVERS_H_
+
+typedef struct efi_driver_t {
+ const char *name;
+ void (*init)(void);
+} efi_driver_t;
+
+extern struct devsw efipart_dev;
+
+/* EFI drivers. */
+extern const efi_driver_t fs_driver;
+
+#endif
Index: sys/boot/efi/drivers/efipart.c
===================================================================
--- sys/boot/efi/drivers/efipart.c
+++ sys/boot/efi/drivers/efipart.c
@@ -74,90 +74,109 @@
#define PD(dev) (pdinfo[(dev)->d_unit])
+static EFI_STATUS
+efipart_supported(EFI_DRIVER_BINDING *This, EFI_HANDLE handle,
+ EFI_DEVICE_PATH *RemainingDevicePath __unused)
+{
+ return BS->OpenProtocol(handle, &blkio_guid,
+ NULL, IH, handle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+}
+
+static EFI_STATUS
+efipart_start(EFI_DRIVER_BINDING *This, EFI_HANDLE handle,
+ EFI_DEVICE_PATH *RemainingDevicePath __unused,
+ u_int* ndisk, uint* nrdisk)
+{
+ EFI_BLOCK_IO *blkio;
+ EFI_DEVICE_PATH *devpath, *devpathcpy, *tmpdevpath, *node;
+ EFI_STATUS status;
+ EFI_HANDLE alias;
+
+ devpath = efi_lookup_devpath(handle);
+
+ if (devpath == NULL) {
+ return (EFI_DEVICE_ERROR);
+ }
+
+ status = BS->HandleProtocol(handle, &blkio_guid,
+ (void**)&blkio);
+ if (EFI_ERROR(status))
+ return (status);
+
+ if (!blkio->Media->LogicalPartition) {
+ *nrdisk++;
+ return (EFI_UNSUPPORTED);
+ }
+
+ /*
+ * If we come across a logical partition of subtype CDROM
+ * it doesn't refer to the CD filesystem itself, but rather
+ * to any usable El Torito boot image on it. In this case
+ * we try to find the parent device and add that instead as
+ * that will be the CD filesystem.
+ */
+ node = efi_devpath_last_node(devpath);
+ if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType(node) == MEDIA_CDROM_DP) {
+ devpathcpy = efi_devpath_trim(devpath);
+ tmpdevpath = devpathcpy;
+ status = BS->LocateDevicePath(&blkio_guid, &tmpdevpath,
+ &alias);
+ free(devpathcpy);
+
+ if (EFI_ERROR(status))
+ return (status);
+
+ efi_register_handle(&efipart_dev, handle, alias);
+ } else
+ efi_register_handle(&efipart_dev, handle, NULL);
+
+ pdinfo[npdinfo].pd_open = 0;
+ pdinfo[npdinfo].pd_bcache = NULL;
+ pdinfo[npdinfo].pd_unit = npdinfo;
+ npdinfo++;
+ *ndisk++;
+
+ return (EFI_SUCCESS);
+}
+
static int
-efipart_init(void)
+efipart_init(void)
{
- EFI_BLOCK_IO *blkio;
- EFI_DEVICE_PATH *devpath, *devpathcpy, *tmpdevpath, *node;
- EFI_HANDLE *hin, *hout, *aliases, handle;
+ EFI_HANDLE *handles;
EFI_STATUS status;
UINTN sz;
- u_int n, nin, nout, nrdisk;
+ u_int n, nin, ndisk, nrdisk;
int err;
sz = 0;
- hin = NULL;
+ handles = NULL;
status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, 0);
if (status == EFI_BUFFER_TOO_SMALL) {
- hin = (EFI_HANDLE *)malloc(sz * 3);
+ handles = (EFI_HANDLE *)malloc(sz);
status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz,
- hin);
+ handles);
if (EFI_ERROR(status))
- free(hin);
+ free(handles);
}
if (EFI_ERROR(status))
return (efi_status_to_errno(status));
/* Filter handles to only include FreeBSD partitions. */
nin = sz / sizeof(EFI_HANDLE);
- hout = hin + nin;
- aliases = hout + nin;
- nout = 0;
- nrdisk = 0;
-
- bzero(aliases, nin * sizeof(EFI_HANDLE));
pdinfo = malloc(nin * sizeof(*pdinfo));
- if (pdinfo == NULL)
- return (ENOMEM);
+ ndisk = 0;
+ nrdisk = 0;
for (n = 0; n < nin; n++) {
- devpath = efi_lookup_devpath(hin[n]);
- if (devpath == NULL) {
- continue;
- }
-
- status = BS->HandleProtocol(hin[n], &blkio_guid,
- (void**)&blkio);
- if (EFI_ERROR(status))
- continue;
- if (!blkio->Media->LogicalPartition) {
- nrdisk++;
- continue;
- }
-
- /*
- * If we come across a logical partition of subtype CDROM
- * it doesn't refer to the CD filesystem itself, but rather
- * to any usable El Torito boot image on it. In this case
- * we try to find the parent device and add that instead as
- * that will be the CD filesystem.
- */
- node = efi_devpath_last_node(devpath);
- if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
- DevicePathSubType(node) == MEDIA_CDROM_DP) {
- devpathcpy = efi_devpath_trim(devpath);
- tmpdevpath = devpathcpy;
- status = BS->LocateDevicePath(&blkio_guid, &tmpdevpath,
- &handle);
- free(devpathcpy);
- if (EFI_ERROR(status))
- continue;
- hout[nout] = handle;
- aliases[nout] = hin[n];
- } else
- hout[nout] = hin[n];
- nout++;
- pdinfo[npdinfo].pd_open = 0;
- pdinfo[npdinfo].pd_bcache = NULL;
- pdinfo[npdinfo].pd_unit = npdinfo;
- npdinfo++;
+ efipart_start(NULL, handles[n], NULL, &ndisk, &nrdisk);
}
bcache_add_dev(npdinfo);
- err = efi_register_handles(&efipart_dev, hout, aliases, nout);
- free(hin);
+ free(handles);
- if (nout == 0 && nrdisk > 0)
+ if (ndisk == 0 && nrdisk > 0)
printf("Found %d disk(s) but no logical partition\n", nrdisk);
return (err);
}
Index: sys/boot/efi/drivers/fs_driver.c
===================================================================
--- /dev/null
+++ sys/boot/efi/drivers/fs_driver.c
@@ -0,0 +1,853 @@
+/*-
+ * Copyright (c) 2016 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$
+ */
+
+#include <stddef.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <efi.h>
+#include <efilib.h>
+#include <efiprot.h>
+#include <string16.h>
+#ifdef EFI_ZFS_BOOT
+#include <libzfs.h>
+#endif
+#include <bootstrap.h>
+
+#include "efi_drivers.h"
+
+static EFI_GUID SimpleFileSystemProtocolGUID = SIMPLE_FILE_SYSTEM_PROTOCOL;
+
+static struct fs_ops *backend_file_system[] = {
+ &dosfs_fsops,
+ &ufs_fsops,
+ &cd9660_fsops,
+ &tftp_fsops,
+ &nfs_fsops,
+ &gzipfs_fsops,
+ &bzipfs_fsops,
+ NULL
+};
+
+static struct devsw *backend_devsw[] = {
+ &efipart_dev,
+#ifdef EFI_ZFS_BOOT
+ &zfs_dev,
+#endif
+ NULL
+};
+
+typedef struct volinfo_t {
+ struct fs_ops *fsops;
+ struct devdesc *dev;
+} volinfo_t;
+
+typedef struct fileinfo_t {
+ const volinfo_t* vinfo;
+ struct open_file fdata;
+ char path[];
+} fileinfo_t;
+
+static EFI_GUID FileInfoGUID = EFI_FILE_INFO_ID;;
+
+static EFIAPI EFI_STATUS
+file_open_impl(EFI_FILE_HANDLE File, EFI_FILE_HANDLE *NewHandle,
+ CHAR16 *FileName, UINT64 OpenMode, UINT64 Attributes);
+
+static EFIAPI EFI_STATUS
+file_close_impl(EFI_FILE_HANDLE File);
+
+static EFIAPI EFI_STATUS
+file_delete_impl(EFI_FILE_HANDLE File);
+
+static EFIAPI EFI_STATUS
+dir_read_impl(EFI_FILE_HANDLE File, UINTN *BufferSize, VOID *Buffer);
+
+static EFIAPI EFI_STATUS
+dir_write_impl(EFI_FILE_HANDLE File, UINTN *BufferSize,
+ VOID *Buffer);
+
+static EFIAPI EFI_STATUS
+file_read_impl(EFI_FILE_HANDLE File, UINTN *BufferSize, VOID *Buffer);
+
+static EFIAPI EFI_STATUS
+file_write_impl(EFI_FILE_HANDLE File, UINTN *BufferSize,
+ VOID *Buffer);
+
+static EFIAPI EFI_STATUS
+file_set_position_impl(EFI_FILE_HANDLE File, UINT64 Position);
+
+static EFIAPI EFI_STATUS
+file_get_position_impl(EFI_FILE_HANDLE File, UINT64 *Position);
+
+static EFIAPI EFI_STATUS
+file_get_info_impl(EFI_FILE_HANDLE File, EFI_GUID *InformationType,
+ UINTN *BufferSize, VOID *Buffer);
+
+static EFIAPI EFI_STATUS
+file_set_info_impl(EFI_FILE_HANDLE File, EFI_GUID *InformationType,
+ UINTN BufferSize, VOID *Buffer);
+
+static EFIAPI EFI_STATUS
+file_flush_impl(EFI_FILE_HANDLE File);
+
+static struct devdesc*
+clone_devdesc(struct devdesc *dev)
+{
+ struct devdesc *out;
+
+ switch(dev->d_dev->dv_type) {
+ case DEVT_ZFS:
+ out = malloc(sizeof(struct zfs_devdesc));
+
+ if (out == NULL) {
+ return NULL;
+ }
+
+ memcpy(out, dev, sizeof(struct zfs_devdesc));
+
+ return out;
+
+ default:
+ out = malloc(sizeof(struct devdesc));
+
+ if (out == NULL) {
+ return NULL;
+ }
+
+ memcpy(out, dev, sizeof(struct devdesc));
+
+ return out;
+ }
+}
+
+static EFI_STATUS
+do_file_open(const volinfo_t *vinfo, const char filepath[],
+ int mode, EFI_FILE_HANDLE *out)
+{
+ EFI_FILE_HANDLE fhandle;
+ fileinfo_t *finfo;
+ struct stat st;
+ struct devdesc *tmpdev;
+ int err;
+
+ memset(&st, 0, sizeof(struct stat));
+ fhandle = malloc(sizeof(EFI_FILE) + sizeof(fileinfo_t) +
+ strlen(filepath) + 1);
+
+ if (fhandle == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ tmpdev = clone_devdesc(vinfo->dev);
+
+ if (tmpdev == NULL) {
+ free(fhandle);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ finfo = (fileinfo_t*)(fhandle + 1);
+ finfo->fdata.f_flags = mode + 1;
+ finfo->fdata.f_dev = NULL;
+ finfo->fdata.f_ops = NULL;
+ finfo->fdata.f_offset = 0;
+ finfo->fdata.f_devdata = NULL;
+
+ if ((err = vinfo->dev->d_dev->dv_open(&(finfo->fdata), tmpdev)) != 0) {
+ free(fhandle);
+ return (errno_to_efi_status(err));
+ }
+
+ finfo->fdata.f_dev = vinfo->dev->d_dev;
+
+ if ((err = vinfo->fsops->fo_open(filepath, &(finfo->fdata))) != 0) {
+ free(fhandle);
+ return (errno_to_efi_status(err));
+ }
+
+ finfo->fdata.f_ops = vinfo->fsops;
+
+ if ((err = vinfo->fsops->fo_stat(&(finfo->fdata), &st)) != 0) {
+ free(fhandle);
+ return (errno_to_efi_status(err));
+ }
+
+ strcpy(finfo->path, filepath);
+ finfo->vinfo = vinfo;
+ fhandle->Revision = EFI_FILE_HANDLE_REVISION;
+ fhandle->Open = file_open_impl;
+ fhandle->Close = file_close_impl;
+ fhandle->Delete = file_delete_impl;
+ fhandle->SetPosition = file_set_position_impl;
+ fhandle->GetPosition = file_get_position_impl;
+ fhandle->GetInfo = file_get_info_impl;
+ fhandle->SetInfo = file_set_info_impl;
+ fhandle->Flush = file_flush_impl;
+
+ if (S_ISDIR(st.st_mode)) {
+ fhandle->Read = dir_read_impl;
+ fhandle->Write = dir_write_impl;
+ } else {
+ fhandle->Read = file_read_impl;
+ fhandle->Write = file_write_impl;
+ }
+
+ *out = fhandle;
+
+ return (EFI_SUCCESS);
+}
+
+static int
+mode_from_efi(UINT64 efi_mode)
+{
+ int mode = 0;
+
+ if (efi_mode & EFI_FILE_MODE_WRITE) {
+ mode |= O_WRONLY;
+ } else if (efi_mode & EFI_FILE_MODE_READ) {
+ mode |= O_RDONLY;
+ } else if (efi_mode & EFI_FILE_MODE_READ &&
+ efi_mode & EFI_FILE_MODE_WRITE) {
+ mode |= O_RDWR;
+ }
+
+ return mode;
+}
+
+static UINT64
+mode_to_efi(int mode)
+{
+ UINT64 efi_mode = 0;
+
+ if (mode & O_WRONLY) {
+ efi_mode |= EFI_FILE_MODE_WRITE;
+ } else if (mode & O_RDONLY) {
+ efi_mode |= EFI_FILE_MODE_READ;
+ } else if (mode & O_RDWR) {
+ efi_mode |= EFI_FILE_MODE_READ;
+ efi_mode |= EFI_FILE_MODE_WRITE;
+ }
+
+ return (efi_mode);
+}
+
+static EFIAPI EFI_STATUS
+file_open_impl(EFI_FILE_HANDLE File, EFI_FILE_HANDLE *NewHandle,
+ CHAR16 *FileName, UINT64 OpenMode, UINT64 Attributes)
+{
+ fileinfo_t *finfo = (fileinfo_t*)(File + 1);
+ char buf[strlen(finfo->path) + strlen16(FileName) + 1];
+
+ strcpy_from_16(stpcpy(buf, finfo->path), FileName);
+
+ return do_file_open(finfo->vinfo, buf,
+ mode_from_efi(OpenMode), NewHandle);
+}
+
+static EFIAPI EFI_STATUS
+file_close_impl(EFI_FILE_HANDLE File)
+{
+ fileinfo_t *finfo = (fileinfo_t*)(File + 1);
+ int res;
+
+ if ((res = finfo->fdata.f_ops->fo_close(&(finfo->fdata))) != 0) {
+ return (errno_to_efi_status(res));
+ }
+
+ if ((res = finfo->vinfo->dev->d_dev->dv_close(&(finfo->fdata))) != 0) {
+ return (errno_to_efi_status(res));
+ }
+
+ free(File);
+ return (EFI_SUCCESS);
+}
+
+static EFIAPI EFI_STATUS
+file_delete_impl(EFI_FILE_HANDLE File)
+{
+ file_close_impl(File);
+
+ return (EFI_WARN_DELETE_FAILURE);
+}
+
+static EFIAPI EFI_STATUS
+dir_read_impl(EFI_FILE_HANDLE File, UINTN *BufferSize, VOID *Buffer)
+{
+ fileinfo_t *finfo = (fileinfo_t*)(File + 1);
+ fileinfo_t *entinfo;
+ struct dirent d;
+ struct stat st;
+ int err;
+ UINTN currsize = *BufferSize;
+ UINTN reqsize;
+ EFI_FILE_INFO *out = (EFI_FILE_INFO*)Buffer;
+ EFI_FILE_HANDLE enthandle;
+ EFI_STATUS status;
+ off_t currpos;
+
+ /* Record teh current position so we can rewind if we have to */
+ if ((currpos = finfo->fdata.f_ops->fo_seek(&(finfo->fdata),
+ 0, SEEK_CUR)) < 0) {
+ return (errno_to_efi_status(errno));
+ }
+
+ if ((err = finfo->fdata.f_ops->fo_readdir(&(finfo->fdata), &d)) != 0) {
+ return (errno_to_efi_status(errno));
+ }
+
+ reqsize = sizeof(EFI_FILE_INFO) +
+ ((strlen(d.d_name) + 1) * sizeof(CHAR16));
+
+ if (Buffer == NULL || currsize < reqsize) {
+ finfo->fdata.f_ops->fo_seek(&(finfo->fdata), currpos, SEEK_SET);
+ *BufferSize = reqsize;
+
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+
+ // We have to actually open the file, since EFI directory
+ // reads are supposed to return stat information.
+ CHAR16 buf[d.d_namlen];
+ strcpy_to_16(buf, d.d_name);
+ status = file_open_impl(File, &enthandle, buf, EFI_FILE_READ_ONLY, 0);
+
+ if (EFI_ERROR(status)) {
+ finfo->fdata.f_ops->fo_seek(&(finfo->fdata), currpos, SEEK_SET);
+ return (status);
+ }
+
+ entinfo = (fileinfo_t*)(enthandle + 1);
+
+ if ((err = finfo->fdata.f_ops->fo_stat(&(entinfo->fdata), &st)) != 0) {
+ finfo->fdata.f_ops->fo_seek(&(finfo->fdata), currpos, SEEK_SET);
+ return (errno_to_efi_status(errno));
+ }
+
+ status = file_close_impl(enthandle);
+
+ if (EFI_ERROR(status)) {
+ finfo->fdata.f_ops->fo_seek(&(finfo->fdata), currpos, SEEK_SET);
+ return (status);
+ }
+
+ // We're good at this point, copy everything into place.
+ out->Size = reqsize;
+ out->FileSize = st.st_size;
+ out->PhysicalSize = st.st_blocks * st.st_blksize;
+ out->Attribute = mode_to_efi(st.st_mode);
+ to_efi_time(&(out->LastAccessTime), st.st_atime);
+ to_efi_time(&(out->ModificationTime), st.st_mtime);
+ to_efi_time(&(out->CreateTime), st.st_ctime);
+
+ if (S_ISDIR(st.st_mode)) {
+ out->Attribute |= EFI_FILE_DIRECTORY;
+ }
+
+ strcpy_to_16(out->FileName, d.d_name);
+ *BufferSize = reqsize;
+
+ return (EFI_SUCCESS);
+}
+
+static EFIAPI EFI_STATUS
+dir_write_impl(EFI_FILE_HANDLE File __unused, UINTN *BufferSize __unused,
+ VOID *Buffer __unused)
+{
+ // EFI API doesn't allow writing to directories
+ return (EFI_UNSUPPORTED);
+}
+
+static EFIAPI EFI_STATUS
+file_read_impl(EFI_FILE_HANDLE File, UINTN *BufferSize, VOID *Buffer)
+{
+ fileinfo_t *finfo = (fileinfo_t*)(File + 1);
+ size_t readsize = *BufferSize;
+ size_t resid;
+ int err;
+
+ if ((err = finfo->fdata.f_ops->fo_read(&(finfo->fdata), Buffer,
+ readsize, &resid)) != 0) {
+ return (errno_to_efi_status(errno));
+ }
+
+ *BufferSize = readsize - resid;
+
+ return (EFI_SUCCESS);
+}
+
+static EFIAPI EFI_STATUS
+file_write_impl(EFI_FILE_HANDLE File, UINTN *BufferSize, VOID *Buffer)
+{
+ fileinfo_t *finfo = (fileinfo_t*)(File + 1);
+ size_t writesize = *BufferSize;
+ size_t resid;
+ int err;
+
+ if ((err = finfo->fdata.f_ops->fo_write(&(finfo->fdata), Buffer,
+ writesize, &resid)) != 0) {
+ return (errno_to_efi_status(errno));
+ }
+
+ *BufferSize = writesize - resid;
+
+ return (EFI_SUCCESS);
+}
+
+static EFIAPI EFI_STATUS
+file_set_position_impl(EFI_FILE_HANDLE File, UINT64 Position)
+{
+ fileinfo_t *finfo = (fileinfo_t*)(File + 1);
+ int res;
+
+ if (Position != 0xffffffffffffffffLL) {
+ res = finfo->fdata.f_ops->fo_seek(&(finfo->fdata),
+ Position, SEEK_SET);
+ } else {
+ res = finfo->fdata.f_ops->fo_seek(&(finfo->fdata),
+ 0, SEEK_END);
+ }
+
+ if (res > 0) {
+ return (EFI_SUCCESS);
+ } else {
+ return (errno_to_efi_status(res));
+ }
+}
+
+
+static EFIAPI EFI_STATUS
+file_get_position_impl(EFI_FILE_HANDLE File, UINT64 *Position)
+{
+ fileinfo_t *finfo = (fileinfo_t*)(File + 1);
+ off_t res;
+
+ res = finfo->fdata.f_ops->fo_seek(&(finfo->fdata), 0, SEEK_CUR);
+
+ if (res > 0) {
+ *Position = res;
+
+ return (EFI_SUCCESS);
+ } else {
+ return (errno_to_efi_status(errno));
+ }
+}
+
+static EFIAPI EFI_STATUS
+file_get_info_impl(EFI_FILE_HANDLE File, EFI_GUID *InformationType,
+ UINTN *BufferSize, VOID *Buffer)
+{
+ fileinfo_t *finfo = (fileinfo_t*)(File + 1);
+
+ if (!memcmp(InformationType, &FileInfoGUID, sizeof(EFI_GUID))) {
+ EFI_FILE_INFO *out = (EFI_FILE_INFO*)Buffer;
+ UINTN str16len =(strlen(finfo->path) + 1) * sizeof(CHAR16);
+ UINTN currsize = *BufferSize;
+ UINTN reqsize = sizeof(EFI_FILE_INFO) + str16len;
+ struct stat st;
+ int err;
+
+ memset(&st, 0, sizeof(struct stat));
+ *BufferSize = reqsize;
+
+ if (Buffer == NULL ||
+ currsize < sizeof(EFI_FILE_INFO) + str16len) {
+ *BufferSize = sizeof(EFI_FILE_INFO) + str16len;
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+
+ if ((err = finfo->fdata.f_ops->fo_stat(&(finfo->fdata),
+ &st)) != 0) {
+ return (errno_to_efi_status(errno));
+ }
+
+ out->Size = sizeof(EFI_FILE_INFO) + str16len;
+ out->FileSize = st.st_size;
+ out->PhysicalSize = st.st_blocks * st.st_blksize;
+ to_efi_time(&(out->LastAccessTime), st.st_atime);
+ to_efi_time(&(out->ModificationTime), st.st_mtime);
+ to_efi_time(&(out->CreateTime), st.st_ctime);
+ out->Attribute = mode_to_efi(st.st_mode);
+
+ if (S_ISDIR(st.st_mode)) {
+ out->Attribute |= EFI_FILE_DIRECTORY;
+ }
+
+ strcpy_to_16(out->FileName, finfo->path);
+ } else {
+ return (EFI_UNSUPPORTED);
+ }
+
+ return (EFI_SUCCESS);
+}
+
+static EFIAPI EFI_STATUS
+file_set_info_impl(EFI_FILE_HANDLE File __unused,
+ EFI_GUID *InformationType __unused,
+ UINTN BufferSize __unused, VOID *Buffer __unused)
+{
+ return (EFI_WRITE_PROTECTED);
+}
+
+static EFIAPI EFI_STATUS
+file_flush_impl(EFI_FILE_HANDLE File __unused)
+{
+ return (EFI_SUCCESS);
+}
+
+static EFIAPI EFI_STATUS
+open_volume_impl(EFI_FILE_IO_INTERFACE *This, EFI_FILE_HANDLE *Root)
+{
+ volinfo_t *vinfo = (volinfo_t*)(This + 1);
+
+ return do_file_open(vinfo, "", O_RDONLY, Root);
+}
+
+static struct fs_ops*
+fs_probe(struct devdesc *dev)
+{
+ struct open_file f;
+ int err, i;
+
+ f.f_flags = O_RDONLY + 1;
+ f.f_dev = (struct devsw *)0;
+ f.f_ops = (struct fs_ops *)0;
+ f.f_offset = 0;
+ f.f_devdata = dev;
+
+ if ((err = dev->d_dev->dv_open(&f, dev)) != 0) {
+ return NULL;
+ }
+
+ for (i = 0; backend_file_system[i] != NULL; i++) {
+ f.f_ops = backend_file_system[i];
+
+ if ((err = f.f_ops->fo_open("/", &f)) == 0) {
+ return backend_file_system[i];
+ }
+ }
+
+ return NULL;
+}
+
+static EFI_STATUS
+make_fs_file_io_iface(struct devdesc *dev, EFI_FILE_IO_INTERFACE **out)
+{
+ static struct fs_ops* fsops;
+ EFI_FILE_IO_INTERFACE* fiface;
+ volinfo_t *vinfo;
+
+ switch (dev->d_type) {
+#ifdef EFI_ZFS_BOOT
+ case DEVT_ZFS:
+ fsops = &zfs_fsops;
+ break;
+#endif
+ default:
+ fsops = fs_probe(dev);
+ break;
+ }
+
+ if (fsops == NULL) {
+ return (EFI_UNSUPPORTED);
+ }
+
+ fiface = malloc(sizeof(EFI_FILE_IO_INTERFACE) + sizeof(volinfo_t));
+
+ if (fiface == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ vinfo = (volinfo_t*)(fiface + 1);
+
+ fiface->Revision = EFI_FILE_IO_INTERFACE_REVISION;
+ fiface->OpenVolume = open_volume_impl;
+ vinfo->dev = dev;
+ vinfo->fsops = fsops;
+
+ *out = fiface;
+
+ return (EFI_SUCCESS);
+}
+
+static EFIAPI EFI_STATUS
+bind_iface(EFI_HANDLE handle, struct devdesc *dev)
+{
+ EFI_STATUS status;
+ EFI_FILE_IO_INTERFACE *iface;
+
+ // Check if there is already a filesystem interface
+ status = BS->OpenProtocol(handle, &SimpleFileSystemProtocolGUID,
+ NULL, IH, handle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (!EFI_ERROR(status)) {
+ return (EFI_ACCESS_DENIED);
+ } else if (status != EFI_UNSUPPORTED) {
+ return (status);
+ }
+
+ status = make_fs_file_io_iface(dev, &iface);
+
+ if (EFI_ERROR(status)) {
+ return (status);
+ }
+
+ status = BS->InstallMultipleProtocolInterfaces(&handle,
+ &SimpleFileSystemProtocolGUID, iface, NULL);
+
+ if (EFI_ERROR(status)) {
+ free(iface);
+
+ return (status);
+ }
+
+ return (status);
+}
+
+static EFIAPI EFI_STATUS
+stop_impl(EFI_DRIVER_BINDING *This __unused, EFI_HANDLE ControllerHandle __unused,
+ UINTN NumberOfChildren __unused, EFI_HANDLE *ChildHandleBuffer __unused)
+{
+ // Get the protocol inteface, uninstall it, and free it
+ return (EFI_SUCCESS);
+}
+
+#ifdef EFI_ZFS_BOOT
+static void
+efi_zfs_probe(void)
+{
+ EFI_HANDLE h;
+ u_int unit;
+ int i;
+ char dname[SPECNAMELEN + 1];
+ uint64_t guid;
+
+ unit = 0;
+ h = efi_find_handle(&efipart_dev, 0);
+ for (i = 0; h != NULL; h = efi_find_handle(&efipart_dev, ++i)) {
+ snprintf(dname, sizeof(dname), "%s%d:", efipart_dev.dv_name, i);
+ if (zfs_probe_dev(dname, &guid) == 0) {
+ (void)efi_handle_update_dev(h, &zfs_dev, unit++, guid);
+ }
+ }
+}
+#endif
+
+static int
+backend_parsedev(struct devdesc **dev, const char *devspec, const char **path)
+{
+ struct devdesc *idev;
+ struct devsw *dv;
+ char *cp;
+ const char *np;
+ int i;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return (EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0; backend_devsw[i] != NULL; i++) {
+ dv = backend_devsw[i];
+ if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
+ break;
+ }
+ if (backend_devsw[i] == NULL) {
+ return (ENOENT);
+ }
+
+ np = devspec + strlen(dv->dv_name);
+
+#ifdef EFI_ZFS_BOOT
+ if (dv->dv_type == DEVT_ZFS) {
+ int err;
+
+ idev = malloc(sizeof(struct zfs_devdesc));
+ if (idev == NULL)
+ return (ENOMEM);
+
+ err = zfs_parsedev((struct zfs_devdesc*)idev, np, path);
+ if (err != 0) {
+ free(idev);
+ return (err);
+ }
+ *dev = idev;
+ cp = strchr(np + 1, ':');
+ } else
+#endif
+ {
+ 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);
+ }
+
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ if (dev != NULL)
+ *dev = idev;
+ else
+ free(idev);
+ return (0);
+}
+
+static int
+backend_getdev(void **vdev, const char *devspec, const char **path)
+{
+ struct devdesc **dev = (struct devdesc **)vdev;
+ int rv;
+
+ /*
+ * If it looks like this is just a path and no device, then
+ * use the current device instead.
+ */
+ if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) {
+ rv = backend_parsedev(dev, getenv("currdev"), NULL);
+ if (rv == 0 && path != NULL)
+ *path = devspec;
+ return (rv);
+ }
+
+ /* Parse the device name off the beginning of the devspec. */
+ return (backend_parsedev(dev, devspec, path));
+}
+
+static void
+init(void)
+{
+ EFI_HANDLE h;
+ EFI_STATUS status;
+ u_int unit;
+ int i;
+ struct devsw *dev;
+ uint64_t pool_guid;
+ int (*old_getdev)(void **, const char *, const char **) =
+ archsw.arch_getdev;
+
+ archsw.arch_getdev = backend_getdev;
+#ifdef EFI_ZFS_BOOT
+ /* Note this needs to be set before ZFS init. */
+ archsw.arch_zfs_probe = efi_zfs_probe;
+#endif
+
+ /* Initialize all the backend drivers */
+ for (i = 0; backend_devsw[i] != NULL; i++) {
+ if (backend_devsw[i]->dv_init != NULL)
+ (backend_devsw[i]->dv_init)();
+ }
+
+ /* Attach SIMPLE_FILE_SYSTEM interfaces to all efipart devices */
+ unit = 0;
+ h = efi_find_handle(&efipart_dev, 0);
+ for (i = 0; h != NULL; h = efi_find_handle(&efipart_dev, ++i)) {
+ struct devdesc *currdev;
+
+ currdev = malloc(sizeof(struct devdesc));
+
+ if (currdev == NULL) {
+ continue;
+ }
+
+ if (efi_handle_lookup(h, &dev, &unit, &pool_guid) != 0) {
+ free(currdev);
+ continue;
+ }
+
+ currdev->d_dev = dev;
+ currdev->d_unit = unit;
+ currdev->d_opendata = NULL;
+ currdev->d_type = currdev->d_dev->dv_type;
+
+ status = bind_iface(h, currdev);
+
+ if (EFI_ERROR(status) && status != EFI_UNSUPPORTED &&
+ status != EFI_ACCESS_DENIED) {
+ printf("Failed to attach filesystem interface to efipart%u (%ld)\n",
+ unit, EFI_ERROR_CODE(status));
+ free(currdev);
+ }
+ }
+
+ /* Attach SIMPLE_FILE_SYSTEM interface to all ZFS devices */
+#ifdef EFI_ZFS_BOOT
+ unit = 0;
+ h = efi_find_handle(&zfs_dev, 0);
+ for (i = 0; h != NULL; h = efi_find_handle(&zfs_dev, ++i)) {
+ struct zfs_devdesc *currdev;
+
+ currdev = malloc(sizeof(struct zfs_devdesc));
+
+ if (currdev == NULL) {
+ continue;
+ }
+
+ if (efi_handle_lookup(h, &dev, &unit, &pool_guid) != 0) {
+ free(currdev);
+ continue;
+ }
+
+ currdev->d_dev = dev;
+ currdev->d_unit = unit;
+ currdev->d_opendata = NULL;
+ currdev->d_type = currdev->d_dev->dv_type;
+ currdev->pool_guid = pool_guid;
+ currdev->root_guid = 0;
+
+ status = bind_iface(h, (struct devdesc*)currdev);
+
+ if (EFI_ERROR(status)) {
+ printf("Failed to attach filesystem interface to zfs%u (%ld)\n",
+ unit, EFI_ERROR_CODE(status));
+ }
+ }
+#endif
+ archsw.arch_getdev = old_getdev;
+}
+
+const efi_driver_t fs_driver =
+{
+ .name = "FS Backend",
+ .init = init,
+};
Index: sys/boot/efi/include/efilib.h
===================================================================
--- sys/boot/efi/include/efilib.h
+++ sys/boot/efi/include/efilib.h
@@ -31,22 +31,26 @@
#define _LOADER_EFILIB_H
#include <stand.h>
+#include <time.h>
extern EFI_HANDLE IH;
-extern EFI_SYSTEM_TABLE *ST;
+extern EFI_SYSTEM_TABLE *ST;
extern EFI_BOOT_SERVICES *BS;
extern EFI_RUNTIME_SERVICES *RS;
-extern struct devsw efipart_dev;
+extern struct devsw efifs_dev;
extern struct devsw efinet_dev;
+extern struct fs_ops efifs_fsops;
extern struct netif_driver efinetif;
void *efi_get_table(EFI_GUID *tbl);
int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int);
+int efi_register_handle(struct devsw *, EFI_HANDLE, EFI_HANDLE);
EFI_HANDLE efi_find_handle(struct devsw *, int);
int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *, uint64_t *);
int efi_handle_update_dev(EFI_HANDLE, struct devsw *, int, uint64_t);
+int efi_handle_remove_dev(EFI_HANDLE);
EFI_DEVICE_PATH *efi_lookup_image_devpath(EFI_HANDLE);
EFI_DEVICE_PATH *efi_lookup_devpath(EFI_HANDLE);
@@ -57,6 +61,7 @@
void efi_free_devpath_name(CHAR16 *);
int efi_status_to_errno(EFI_STATUS);
+EFI_STATUS errno_to_efi_status(int errno);
void efi_time_init(void);
void efi_time_fini(void);
@@ -65,4 +70,7 @@
void exit(EFI_STATUS status);
void delay(int usecs);
+time_t from_efi_time(EFI_TIME *efi_time);
+void to_efi_time(EFI_TIME *efi_time, time_t time);
+
#endif /* _LOADER_EFILIB_H */
Index: sys/boot/efi/include/efiprot.h
===================================================================
--- sys/boot/efi/include/efiprot.h
+++ sys/boot/efi/include/efiprot.h
@@ -27,6 +27,8 @@
--*/
+#include <efidef.h>
+
//
// Device Path protocol
//
@@ -307,9 +309,9 @@
//
// The FileName field of the EFI_FILE_INFO data structure is variable length.
// Whenever code needs to know the size of the EFI_FILE_INFO data structure, it needs to
-// be the size of the data structure without the FileName field. The following macro
+// be the size of the data structure without the FileName field. The following macro
// computes this size correctly no matter how big the FileName array is declared.
-// This is required to make the EFI_FILE_INFO data structure ANSI compilant.
+// This is required to make the EFI_FILE_INFO data structure ANSI compilant.
//
#define SIZE_OF_EFI_FILE_INFO EFI_FIELD_OFFSET(EFI_FILE_INFO,FileName)
@@ -329,9 +331,9 @@
//
// The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is variable length.
// Whenever code needs to know the size of the EFI_FILE_SYSTEM_INFO data structure, it needs
-// to be the size of the data structure without the VolumeLable field. The following macro
+// to be the size of the data structure without the VolumeLable field. The following macro
// computes this size correctly no matter how big the VolumeLable array is declared.
-// This is required to make the EFI_FILE_SYSTEM_INFO data structure ANSI compilant.
+// This is required to make the EFI_FILE_SYSTEM_INFO data structure ANSI compilant.
//
#define SIZE_OF_EFI_FILE_SYSTEM_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO,VolumeLabel)
@@ -411,7 +413,7 @@
EFI_DEVICE_IO Write;
} EFI_IO_ACCESS;
-typedef
+typedef
EFI_STATUS
(EFIAPI *EFI_PCI_DEVICE_PATH) (
IN struct _EFI_DEVICE_IO_INTERFACE *This,
@@ -555,4 +557,47 @@
CHAR8 *SupportedLanguages;
} EFI_UNICODE_COLLATION_INTERFACE;
+//
+// Driver Binding protocol
+//
+
+#define DRIVER_BINDING_PROTOCOL \
+ { 0x18a031ab, 0xb443, 0x4d1a, {0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71} }
+
+INTERFACE_DECL(_EFI_DRIVER_BINDING);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DRIVER_BINDING_SUPPORTED) (
+ IN struct _EFI_DRIVER_BINDING *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH *RemainingPath
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DRIVER_BINDING_START) (
+ IN struct _EFI_DRIVER_BINDING *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH *RemainingPath
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DRIVER_BINDING_STOP) (
+ IN struct _EFI_DRIVER_BINDING *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+typedef struct _EFI_DRIVER_BINDING {
+ EFI_DRIVER_BINDING_SUPPORTED Supported;
+ EFI_DRIVER_BINDING_START Start;
+ EFI_DRIVER_BINDING_STOP Stop;
+ UINT32 Version;
+ EFI_HANDLE ImageHandle;
+ EFI_HANDLE DriverBindingHandle;
+} EFI_DRIVER_BINDING;
+
#endif
Index: sys/boot/efi/include/string16.h
===================================================================
--- /dev/null
+++ sys/boot/efi/include/string16.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2016 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 _STRING16_H_
+#define _STRING16_H_
+
+#include <efi.h>
+#include <stddef.h>
+
+/*
+ * These are 16-bit variants of string,h functions for use with EFI code.
+ */
+
+extern size_t strlen16(const CHAR16 *str);
+extern CHAR16* strcpy16(CHAR16 *dst, const CHAR16 *src);
+extern CHAR16* stpcpy16(CHAR16 *dst, const CHAR16 *src);
+extern CHAR16* strcpy_to_16(CHAR16 *dst, const char *src);
+extern char* strcpy_from_16(char *dst, const CHAR16 *src);
+
+#endif
Index: sys/boot/efi/libefi/Makefile
===================================================================
--- sys/boot/efi/libefi/Makefile
+++ sys/boot/efi/libefi/Makefile
@@ -4,8 +4,8 @@
INTERNALLIB=
WARNS?= 2
-SRCS= delay.c devpath.c efi_console.c efinet.c efipart.c env.c errno.c \
- handles.c libefi.c
+SRCS= delay.c efi_console.c efinet.c env.c errno.c \
+ handles.c libefi.c efifs.c string16.c devpath.c
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
SRCS+= time.c
Index: sys/boot/efi/libefi/efifs.c
===================================================================
--- /dev/null
+++ sys/boot/efi/libefi/efifs.c
@@ -0,0 +1,463 @@
+/*-
+ * Copyright (c) 2016 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$
+ */
+
+#include <efi.h>
+#include <efilib.h>
+#include <efiprot.h>
+#include <stand.h>
+#include <stdarg.h>
+#include <bootstrap.h>
+#include <string16.h>
+
+static EFI_GUID FileInfoGUID = EFI_FILE_INFO_ID;;
+static EFI_GUID SimpleFileSystemProtocolGUID = SIMPLE_FILE_SYSTEM_PROTOCOL;
+static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
+static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
+
+static int efifs_open(const char *path, struct open_file *f);
+static int efifs_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+static int efifs_close(struct open_file *f);
+static int efifs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+static off_t efifs_seek(struct open_file *f, off_t offset, int where);
+static int efifs_stat(struct open_file *f, struct stat *sb);
+static int efifs_readdir(struct open_file *f, struct dirent *d);
+
+static int efifs_dev_init(void);
+static int efifs_dev_strategy(void *, int, daddr_t, size_t, size_t, char *, size_t *);
+static int efifs_dev_open(struct open_file *, ...);
+static int efifs_dev_close(struct open_file *);
+static void efifs_dev_print(int);
+
+struct devsw efifs_dev = {
+ .dv_name = "EFI",
+ .dv_type = DEVT_EFI,
+ .dv_init = efifs_dev_init,
+ .dv_strategy = efifs_dev_strategy,
+ .dv_open = efifs_dev_open,
+ .dv_close = efifs_dev_close,
+ .dv_ioctl = noioctl,
+ .dv_print = efifs_dev_print,
+ .dv_cleanup = NULL
+};
+
+struct fs_ops efifs_fsops = {
+ "EFI",
+ efifs_open,
+ efifs_close,
+ efifs_read,
+ efifs_write,
+ efifs_seek,
+ efifs_stat,
+ efifs_readdir
+};
+
+static int
+efifs_dev_init(void)
+{
+ EFI_HANDLE *hin;
+ EFI_STATUS status;
+ UINTN sz;
+ u_int n, nin, unit;
+ int err;
+
+ sz = 0;
+ hin = NULL;
+ status = BS->LocateHandle(ByProtocol, &SimpleFileSystemProtocolGUID,
+ 0, &sz, 0);
+ if (status == EFI_BUFFER_TOO_SMALL) {
+ hin = (EFI_HANDLE *)malloc(sz);
+ status = BS->LocateHandle(ByProtocol,
+ &SimpleFileSystemProtocolGUID, 0, &sz, hin);
+ if (EFI_ERROR(status))
+ free(hin);
+ }
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+
+ /* Filter handles to only include FreeBSD partitions. */
+ nin = sz / sizeof(EFI_HANDLE);
+ unit = 0;
+
+ for (n = 0; n < nin; n++) {
+ status = BS->OpenProtocol(hin[n], &SimpleFileSystemProtocolGUID,
+ NULL, IH, NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+ if (EFI_ERROR(status))
+ continue;
+
+ efi_handle_update_dev(hin[n], &efifs_dev, unit++, 0);
+ }
+
+ free(hin);
+ return (err);
+}
+
+
+static void
+efifs_dev_print(int verbose)
+{
+ char line[80];
+ EFI_DEVICE_PATH *devpath;
+ EFI_BLOCK_IO *blkio;
+ EFI_HANDLE h, *hin;
+ EFI_STATUS status;
+ u_int unit, n;
+
+ for (unit = 0, h = efi_find_handle(&efifs_dev, 0);
+ h != NULL; h = efi_find_handle(&efifs_dev, ++unit)) {
+ sprintf(line, " %s%d:", efifs_dev.dv_name, unit);
+ pager_output(line);
+ pager_output(" EFI(SIMPLE_FILE_SYSTEM");
+
+ status = BS->HandleProtocol(hin[n], &DevicePathGUID,
+ (void **)&devpath);
+ if (!EFI_ERROR(status)) {
+ pager_output(", DEVICE_PATH");
+ }
+
+ status = BS->HandleProtocol(hin[n], &BlockIoProtocolGUID,
+ (void **)&blkio);
+ if (!EFI_ERROR(status)) {
+ pager_output(", BLOCK_IO");
+ }
+ pager_output(")\n");
+ }
+}
+
+static int
+efifs_dev_open(struct open_file *f, ...)
+{
+ va_list args;
+ struct devdesc *dev;
+ EFI_FILE_IO_INTERFACE *fsiface;
+ EFI_HANDLE h;
+ EFI_STATUS status;
+
+ va_start(args, f);
+ dev = va_arg(args, struct devdesc*);
+ va_end(args);
+
+ h = efi_find_handle(&efifs_dev, dev->d_unit);
+
+ if (h == NULL)
+ return (EINVAL);
+
+ status = BS->OpenProtocol(h, &SimpleFileSystemProtocolGUID,
+ (void**)&fsiface, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(status)) {
+ return (efi_status_to_errno(status));
+ }
+
+ dev->d_opendata = fsiface;
+ return (0);
+}
+
+static int
+efifs_dev_close(struct open_file *f)
+{
+ struct devdesc *dev;
+ EFI_HANDLE h;
+ EFI_STATUS status;
+
+ dev = (struct devdesc *)(f->f_devdata);
+ h = efi_find_handle(&efifs_dev, dev->d_unit);
+
+ if (h == NULL)
+ return (EINVAL);
+
+ if (dev->d_opendata == NULL)
+ return (EINVAL);
+
+ status = BS->CloseProtocol(h, &SimpleFileSystemProtocolGUID, IH, NULL);
+
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+
+ dev->d_opendata = NULL;
+ return (0);
+}
+
+
+/* Raw I/O isn't supported on EFI FS devices, as they talk through
+ * SIMPLE_FILE_SYSTEM_INTERFACE.
+ */
+static int
+efifs_dev_strategy(void *devdata __unused, int rw __unused, daddr_t blk __unused,
+ size_t offset, size_t size __unused, char *buf __unused,
+ size_t *rsize __unused)
+{
+ printf("Raw I/O not supported on EFI FS interface\n");
+ return ENOTSUP;
+}
+
+/*
+ * Open a file.
+ */
+static int
+efifs_open(const char *upath, struct open_file *f)
+{
+ struct devdesc *dev;
+ EFI_FILE_IO_INTERFACE *fsiface;
+ EFI_FILE_HANDLE root;
+ EFI_STATUS status;
+ CHAR16 path[strlen(upath) + 1];
+
+ dev = (struct devdesc *)(f->f_devdata);
+ fsiface = dev->d_opendata;
+
+ if (!strcmp(upath, "") || !strcmp(upath, "/")) {
+ return (fsiface->OpenVolume(fsiface,
+ (EFI_FILE_HANDLE*)&(f->f_fsdata)));
+ } else {
+ status = fsiface->OpenVolume(fsiface, &root);
+
+ if (EFI_ERROR(status)) {
+ return (efi_status_to_errno(status));
+ }
+
+ strcpy_to_16(path, upath);
+ status = root->Open(root, (EFI_FILE_HANDLE*)&(f->f_fsdata), path,
+ EFI_FILE_MODE_READ, 0);
+
+ root->Close(root);
+
+ if (EFI_ERROR(status)) {
+ return (efi_status_to_errno(status));
+ }
+
+ return 0;
+ }
+}
+
+static int
+efifs_close(struct open_file *f)
+{
+ EFI_FILE_HANDLE file = (EFI_FILE_HANDLE)f->f_fsdata;
+ EFI_STATUS status;
+
+ status = file->Close(file);
+
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+
+ return (0);
+}
+
+static int
+efifs_read(struct open_file *f, void *start, size_t size, size_t *resid /* out */)
+{
+ EFI_FILE_HANDLE file = (EFI_FILE_HANDLE)f->f_fsdata;
+ UINTN readsize = size;
+ EFI_STATUS status;
+
+ status = file->Read(file, &readsize, start);
+
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+
+ if (resid)
+ *resid = size - readsize;
+
+ return (0);
+}
+
+static int
+efifs_write(struct open_file *f, void *start, size_t size,
+ size_t *resid /* out */)
+{
+ EFI_FILE_HANDLE file = (EFI_FILE_HANDLE)f->f_fsdata;
+ UINTN writesize = size;
+ EFI_STATUS status;
+
+ status = file->Write(file, &writesize, start);
+
+ if (EFI_ERROR(status))
+ return (efi_status_to_errno(status));
+
+ if (resid)
+ *resid = size - writesize;
+
+ return (0);
+}
+
+static off_t
+efifs_seek(struct open_file *f, off_t offset, int where)
+{
+ EFI_FILE_HANDLE file = (EFI_FILE_HANDLE)f->f_fsdata;
+ UINT64 pos;
+ EFI_STATUS status;
+
+ switch (where) {
+ case SEEK_SET:
+ status = file->SetPosition(file, offset);
+
+ if (status != EFI_SUCCESS) {
+ errno = (efi_status_to_errno(status));
+ return -1;
+ }
+
+ break;
+ case SEEK_CUR:
+ status = file->GetPosition(file, &pos);
+
+ if (status != EFI_SUCCESS) {
+ errno = (efi_status_to_errno(status));
+ return -1;
+ }
+
+ status = file->SetPosition(file, pos + offset);
+
+ if (status != EFI_SUCCESS) {
+ errno = (efi_status_to_errno(status));
+ return -1;
+ }
+
+ break;
+ case SEEK_END:
+ status = file->SetPosition(file, 0xffffffffffffffff);
+
+ if (status != EFI_SUCCESS) {
+ errno = (efi_status_to_errno(status));
+ return -1;
+ }
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+
+ status = file->GetPosition(file, &pos);
+
+ if (status != EFI_SUCCESS) {
+ errno = (efi_status_to_errno(status));
+ return -1;
+ }
+
+ return (pos);
+}
+
+/* SIMPLE_FILE_SYSTEM_PROTOCOL is geared towards FAT, so we can't
+ * reproduce stat with absolute fidelity.
+ */
+static int
+efifs_stat(struct open_file *f, struct stat *sb)
+{
+ EFI_FILE_HANDLE file;
+ UINTN size = 0;
+ EFI_FILE_INFO *finfo;;
+ EFI_STATUS status;
+
+ file = (EFI_FILE_HANDLE)f->f_fsdata;
+ status = file->GetInfo(file, &FileInfoGUID, &size, NULL);
+
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ errno = (efi_status_to_errno(status));
+ return -1;
+ }
+
+ finfo = malloc(size);
+ status = file->GetInfo(file, &FileInfoGUID, &size, finfo);
+
+ if (status != EFI_SUCCESS) {
+ errno = (efi_status_to_errno(status));
+ return -1;
+ }
+
+ /* We can't properly fill these in... */
+ sb->st_ino = 0;
+ sb->st_nlink = 0;
+ sb->st_uid = 0;
+ sb->st_gid = 0;
+ sb->st_blksize = 512;
+ /* Build the mode field */
+ if (finfo->Attribute & EFI_FILE_DIRECTORY) {
+ sb->st_mode = S_IFDIR;
+ } else {
+ sb->st_mode = S_IFREG;
+ }
+
+ if (finfo->Attribute & EFI_FILE_MODE_READ) {
+ sb->st_mode = S_IRUSR | S_IXUSR | S_IRGRP |
+ S_IXGRP | S_IROTH | S_IXOTH;
+ }
+
+ if (finfo->Attribute & EFI_FILE_MODE_READ) {
+ sb->st_mode = S_IWUSR | S_IWGRP | S_IWOTH;
+ }
+ /* This may or may not be supported, depending on the FS driver */
+ sb->st_blocks = finfo->PhysicalSize / 512;
+ /* These fields we can get right */
+ sb->st_size = finfo->FileSize;
+ sb->st_atime = from_efi_time(&(finfo->LastAccessTime));
+ sb->st_mtime = from_efi_time(&(finfo->ModificationTime));
+ sb->st_ctime = from_efi_time(&(finfo->CreateTime));
+
+ free(finfo);
+
+ return (0);
+}
+
+static int
+efifs_readdir(struct open_file *f, struct dirent *d)
+{
+ EFI_FILE_HANDLE file;
+ UINTN size = 0;
+ EFI_FILE_INFO *finfo;;
+ EFI_STATUS status;
+
+ file = (EFI_FILE_HANDLE)f->f_fsdata;
+ status = file->Read(file, &size, NULL);
+
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ errno = (efi_status_to_errno(status));
+ return -1;
+ }
+
+ if (size == 0) {
+ return (ENOENT);
+ }
+
+ finfo = malloc(size);
+ status = file->Read(file, &size, finfo);
+
+ if (status != EFI_SUCCESS) {
+ errno = (efi_status_to_errno(status));
+ return -1;
+ }
+
+ strcpy_from_16(d->d_name, finfo->FileName);
+ d->d_namlen = strlen(d->d_name);
+ d->d_reclen = sizeof(struct dirent);
+ /* We can't faithfully reproduce this due to the limitations
+ * of the SIMPLE_FILE_SYSTEM interface */
+ d->d_fileno = 0;
+
+ free(finfo);
+
+ return (0);
+}
Index: sys/boot/efi/libefi/errno.c
===================================================================
--- sys/boot/efi/libefi/errno.c
+++ sys/boot/efi/libefi/errno.c
@@ -30,6 +30,69 @@
#include <efi.h>
#include <efilib.h>
+EFI_STATUS
+errno_to_efi_status(int errno)
+{
+ EFI_STATUS status;
+
+ switch (errno) {
+ case EPERM:
+ status = EFI_ACCESS_DENIED;
+ break;
+
+ case EOVERFLOW:
+ status = EFI_BUFFER_TOO_SMALL;
+ break;
+
+ case EIO:
+ status = EFI_DEVICE_ERROR;
+ break;
+
+ case EINVAL:
+ status = EFI_INVALID_PARAMETER;
+ break;
+
+ case ESTALE:
+ status = EFI_MEDIA_CHANGED;
+ break;
+
+ case ENXIO:
+ status = EFI_NO_MEDIA;
+ break;
+
+ case ENOENT:
+ status = EFI_NOT_FOUND;
+ break;
+
+ case ENOMEM:
+ status = EFI_OUT_OF_RESOURCES;
+ break;
+
+ case ENOTSUP:
+ case ENODEV:
+ status = EFI_UNSUPPORTED;
+ break;
+
+ case ENOSPC:
+ status = EFI_VOLUME_FULL;
+ break;
+
+ case EACCES:
+ status = EFI_WRITE_PROTECTED;
+ break;
+
+ case 0:
+ status = EFI_SUCCESS;
+ break;
+
+ default:
+ status = EFI_DEVICE_ERROR;
+ break;
+ }
+
+ return (status);
+}
+
int
efi_status_to_errno(EFI_STATUS status)
{
Index: sys/boot/efi/libefi/handles.c
===================================================================
--- sys/boot/efi/libefi/handles.c
+++ sys/boot/efi/libefi/handles.c
@@ -41,21 +41,36 @@
struct entry *entry;
int nentries;
+static int
+get_next_unit(struct devsw *sw)
+{
+ int i, idx;
+
+ for (i = 0, idx = 0; i < nentries; i++) {
+ if (entry[i].dev == sw) {
+ idx++;
+ }
+ }
+
+ return (idx);
+}
+
int
efi_register_handles(struct devsw *sw, EFI_HANDLE *handles,
EFI_HANDLE *aliases, int count)
{
size_t sz;
- int idx, unit;
+ int idx, unit, i;
idx = nentries;
nentries += count;
sz = nentries * sizeof(struct entry);
+ unit = get_next_unit(sw);
entry = (entry == NULL) ? malloc(sz) : realloc(entry, sz);
- for (unit = 0; idx < nentries; idx++, unit++) {
- entry[idx].handle = handles[unit];
+ for (i = 0; idx < nentries; idx++, unit++, i++) {
+ entry[idx].handle = handles[i];
if (aliases != NULL)
- entry[idx].alias = aliases[unit];
+ entry[idx].alias = aliases[i];
else
entry[idx].alias = NULL;
entry[idx].dev = sw;
@@ -64,6 +79,16 @@
return (0);
}
+int
+efi_register_handle(struct devsw *sw, EFI_HANDLE handle, EFI_HANDLE alias)
+{
+ if (alias == NULL) {
+ return efi_register_handles(sw, &handle, NULL, 1);
+ } else {
+ return efi_register_handles(sw, &handle, &alias, 1);
+ }
+}
+
EFI_HANDLE
efi_find_handle(struct devsw *dev, int unit)
{
@@ -116,3 +141,29 @@
return (ENOENT);
}
+
+int
+efi_handle_remove_dev(EFI_HANDLE h)
+{
+ int idx;
+
+ /* Find the entry */
+ for (idx = 0; idx < nentries; idx++) {
+ if (entry[idx].handle != h)
+ continue;
+ }
+
+ if (idx >= nentries)
+ return (ENOENT);
+ else if (idx == nentries - 1) {
+ nentries--;
+ entry = realloc(entry, nentries * sizeof(struct entry));
+ } else {
+ memcpy(entry + idx, entry + idx + 1,
+ sizeof(struct entry) * (nentries - (idx + 1)));
+ nentries--;
+ entry = realloc(entry, nentries * sizeof(struct entry));
+ }
+
+ return (0);
+}
Index: sys/boot/efi/libefi/string16.c
===================================================================
--- /dev/null
+++ sys/boot/efi/libefi/string16.c
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 2016 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$
+ */
+
+#include "string16.h"
+#include <stddef.h>
+
+size_t
+strlen16(const CHAR16 *str)
+{
+ size_t i;
+
+ for (i = 0; str[i] != 0; i++);
+
+ return i;
+}
+
+CHAR16 *
+strcpy16(CHAR16 *dst, const CHAR16 *src)
+{
+ stpcpy16(dst, src);
+
+ return (dst);
+}
+
+CHAR16 *
+stpcpy16(CHAR16 *dst, const CHAR16 *src)
+{
+ for (; *src != 0; src++, dst++) {
+ *dst = *src;
+ }
+
+ *dst = *src;
+
+ return dst;
+}
+
+char *
+strcpy_from_16(char *dst, const CHAR16 *src)
+{
+ int i;
+
+ for (i = 0; src[i] != 0; i++) {
+ dst[i] = src[i];
+ }
+
+ dst[i] = 0;
+
+ return (dst);
+}
+
+CHAR16 *
+strcpy_to_16(CHAR16 *dst, const char *src)
+{
+ int i;
+
+ for (i = 0; src[i] != 0; i++) {
+ dst[i] = src[i];
+ }
+
+ dst[i] = 0;
+
+ return (dst);
+}
Index: sys/boot/efi/libefi/time.c
===================================================================
--- sys/boot/efi/libefi/time.c
+++ sys/boot/efi/libefi/time.c
@@ -2,28 +2,28 @@
* Copyright (c) 1999, 2000
* Intel Corporation.
* 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.
- *
+ *
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- *
+ *
* This product includes software developed by Intel Corporation and
* its contributors.
- *
+ *
* 4. Neither the name of Intel Corporation or its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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
@@ -35,7 +35,7 @@
* 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.
- *
+ *
*/
#include <sys/cdefs.h>
@@ -58,6 +58,41 @@
#define SECSPERHOUR ( 60*60 )
#define SECSPERDAY (24 * SECSPERHOUR)
+/*
+// These arrays give the cumulative number of days up to the first of the
+// month number used as the index (1 -> 12) for regular and leap years.
+// The value at index 13 is for the whole year.
+*/
+static const time_t CumulativeDays[2][14] = {
+ {0,
+ 0,
+ 31,
+ 31 + 28,
+ 31 + 28 + 31,
+ 31 + 28 + 31 + 30,
+ 31 + 28 + 31 + 30 + 31,
+ 31 + 28 + 31 + 30 + 31 + 30,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
+ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 },
+ {0,
+ 0,
+ 31,
+ 31 + 29,
+ 31 + 29 + 31,
+ 31 + 29 + 31 + 30,
+ 31 + 29 + 31 + 30 + 31,
+ 31 + 29 + 31 + 30 + 31 + 30,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
+ 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }};
+
void
efi_time_init(void)
{
@@ -68,45 +103,46 @@
{
}
-static time_t
-efi_time(EFI_TIME *ETime)
+void
+to_efi_time(EFI_TIME *efi_time, time_t time)
{
- /*
- // These arrays give the cumulative number of days up to the first of the
- // month number used as the index (1 -> 12) for regular and leap years.
- // The value at index 13 is for the whole year.
- */
- static time_t CumulativeDays[2][14] = {
- {0,
- 0,
- 31,
- 31 + 28,
- 31 + 28 + 31,
- 31 + 28 + 31 + 30,
- 31 + 28 + 31 + 30 + 31,
- 31 + 28 + 31 + 30 + 31 + 30,
- 31 + 28 + 31 + 30 + 31 + 30 + 31,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
- 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 },
- {0,
- 0,
- 31,
- 31 + 29,
- 31 + 29 + 31,
- 31 + 29 + 31 + 30,
- 31 + 29 + 31 + 30 + 31,
- 31 + 29 + 31 + 30 + 31 + 30,
- 31 + 29 + 31 + 30 + 31 + 30 + 31,
- 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
- 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
- 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
- 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
- 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 }};
-
- time_t UTime;
+ if (time >= 0) {
+ for (efi_time->Year = 1970;
+ time > CumulativeDays[isleap(efi_time->Year)][13] * SECSPERDAY;
+ time -= CumulativeDays[isleap(efi_time->Year)][13] * SECSPERDAY,
+ efi_time->Year++);
+
+ for (efi_time->Month = 0;
+ time > CumulativeDays[isleap(efi_time->Year)][efi_time->Month] *
+ SECSPERDAY;
+ efi_time->Month++);
+
+ time -= CumulativeDays[isleap(efi_time->Year)][efi_time->Month - 1] *
+ SECSPERDAY;
+
+ for (efi_time->Day = 0; time > SECSPERDAY;
+ time -= SECSPERDAY, efi_time->Day++);
+
+ for (efi_time->Hour = 0; time > SECSPERHOUR;
+ time -= SECSPERHOUR, efi_time->Hour++);
+
+ for (efi_time->Minute = 0; time > 60;
+ time -= 60, efi_time->Minute++);
+
+ efi_time->Second = time;
+ efi_time->Nanosecond = 0;
+ efi_time->TimeZone = 0;
+ efi_time->Daylight = 0;
+ } else {
+ memset(efi_time, 0, sizeof(EFI_TIME));
+ }
+}
+
+time_t
+from_efi_time(EFI_TIME *ETime)
+{
+
+ time_t UTime;
int Year;
/*
@@ -134,7 +170,7 @@
/*
// UTime should now be set to 00:00:00 on Jan 1 of the file's year.
//
- // Months
+ // Months
*/
UTime += (CumulativeDays[isleap(ETime->Year)][ETime->Month] * SECSPERDAY);
@@ -170,7 +206,7 @@
*/
UTime += (ETime->TimeZone * 60);
}
-
+
return UTime;
}
@@ -196,7 +232,7 @@
// Convert to UNIX time (ie seconds since the epoch
*/
- tp->tv_sec = efi_time( &EfiTime );
+ tp->tv_sec = from_efi_time( &EfiTime );
tp->tv_usec = 0; /* EfiTime.Nanosecond * 1000; */
/*
@@ -221,7 +257,7 @@
{
struct timeval tv;
EFI_GetTimeOfDay(&tv, 0);
-
+
if (tloc)
*tloc = tv.tv_sec;
return tv.tv_sec;
Index: sys/boot/efi/loader/Makefile
===================================================================
--- sys/boot/efi/loader/Makefile
+++ sys/boot/efi/loader/Makefile
@@ -50,6 +50,7 @@
CFLAGS+= -I${.CURDIR}
CFLAGS+= -I${.CURDIR}/arch/${MACHINE}
CFLAGS+= -I${.CURDIR}/../include
+CFLAGS+= -I${.CURDIR}/../drivers
CFLAGS+= -I${.CURDIR}/../include/${MACHINE}
CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include
CFLAGS+= -I${.CURDIR}/../../..
@@ -68,6 +69,8 @@
LIBSTAND= ${.OBJDIR}/../../../../lib/libstand/libstand.a
.endif
+LIBEFI_DRIVERS= ${.OBJDIR}/../drivers/libefi_drivers.a
+
.if !defined(BOOT_HIDE_SERIAL_NUMBERS)
# Export serial numbers, UUID, and asset tag from loader.
CFLAGS+= -DSMBIOS_SERIAL_NUMBERS
@@ -149,9 +152,10 @@
LIBEFI= ${.OBJDIR}/../libefi/libefi.a
-DPADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSTAND} \
- ${LDSCRIPT}
-LDADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSTAND}
+DPADD= ${LIBFICL} ${LIBEFI} ${LIBEFI_DRIVERS} ${LIBFDT} ${LIBEFI_FDT} \
+ ${LIBSTAND} ${LDSCRIPT}
+LDADD= ${LIBFICL} ${LIBEFI} ${LIBEFI_DRIVERS} ${LIBFDT} ${LIBEFI_FDT} \
+ ${LIBSTAND}
.include <bsd.prog.mk>
Index: sys/boot/efi/loader/conf.c
===================================================================
--- sys/boot/efi/loader/conf.c
+++ sys/boot/efi/loader/conf.c
@@ -31,30 +31,22 @@
#include <bootstrap.h>
#include <efi.h>
#include <efilib.h>
-#ifdef EFI_ZFS_BOOT
-#include <libzfs.h>
-#endif
+
+#include "efi_drivers.h"
+
+const efi_driver_t *efi_drivers[] = {
+ &fs_driver,
+ NULL
+};
struct devsw *devsw[] = {
- &efipart_dev,
+ &efifs_dev,
&efinet_dev,
-#ifdef EFI_ZFS_BOOT
- &zfs_dev,
-#endif
NULL
};
struct fs_ops *file_system[] = {
-#ifdef EFI_ZFS_BOOT
- &zfs_fsops,
-#endif
- &dosfs_fsops,
- &ufs_fsops,
- &cd9660_fsops,
- &tftp_fsops,
- &nfs_fsops,
- &gzipfs_fsops,
- &bzipfs_fsops,
+ &efifs_fsops,
NULL
};
Index: sys/boot/efi/loader/loader_efi.h
===================================================================
--- sys/boot/efi/loader/loader_efi.h
+++ sys/boot/efi/loader/loader_efi.h
@@ -33,6 +33,10 @@
#include <stand.h>
+#include "efi_drivers.h"
+
+extern const efi_driver_t *efi_drivers[];
+
int efi_autoload(void);
int efi_getdev(void **vdev, const char *devspec, const char **path);
Index: sys/boot/efi/loader/main.c
===================================================================
--- sys/boot/efi/loader/main.c
+++ sys/boot/efi/loader/main.c
@@ -71,10 +71,6 @@
EFI_GUID fdtdtb = FDT_TABLE_GUID;
EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL;
-#ifdef EFI_ZFS_BOOT
-static void efi_zfs_probe(void);
-#endif
-
/*
* cpy8to16 copies a traditional C string into a CHAR16 string and
* 0 terminates it. len is the size of *dst in bytes.
@@ -109,7 +105,7 @@
EFI_HANDLE *hin, *hin_end, *walker;
UINTN sz;
int retval = 0;
-
+
/*
* Find all the handles that support the SIMPLE_TEXT_INPUT_PROTOCOL and
* do the typical dance to get the right sized buffer.
@@ -166,7 +162,7 @@
} else if (DevicePathType(path) == MESSAGING_DEVICE_PATH &&
DevicePathSubType(path) == MSG_USB_CLASS_DP) {
USB_CLASS_DEVICE_PATH *usb;
-
+
usb = (USB_CLASS_DEVICE_PATH *)(void *)path;
if (usb->DeviceClass == 3 && /* HID */
usb->DeviceSubClass == 1 && /* Boot devices */
@@ -241,10 +237,6 @@
archsw.arch_copyin = efi_copyin;
archsw.arch_copyout = efi_copyout;
archsw.arch_readin = efi_readin;
-#ifdef EFI_ZFS_BOOT
- /* Note this needs to be set before ZFS init. */
- archsw.arch_zfs_probe = efi_zfs_probe;
-#endif
/* Init the time source */
efi_time_init();
@@ -369,6 +361,10 @@
/*
* March through the device switch probing for things.
*/
+ for (i = 0; efi_drivers[i] != NULL; i++)
+ if (efi_drivers[i]->init != NULL)
+ (efi_drivers[i]->init)();
+
for (i = 0; devsw[i] != NULL; i++)
if (devsw[i]->dv_init != NULL)
(devsw[i]->dv_init)();
@@ -405,6 +401,7 @@
if (find_currdev(img, &dev, &unit, &pool_guid) != 0)
return (EFI_NOT_FOUND);
+ printf("Found efi device under %s\n", dev->dv_name);
switch (dev->dv_type) {
#ifdef EFI_ZFS_BOOT
case DEVT_ZFS: {
@@ -1048,23 +1045,3 @@
COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt);
#endif
-
-#ifdef EFI_ZFS_BOOT
-static void
-efi_zfs_probe(void)
-{
- EFI_HANDLE h;
- u_int unit;
- int i;
- char dname[SPECNAMELEN + 1];
- uint64_t guid;
-
- unit = 0;
- h = efi_find_handle(&efipart_dev, 0);
- for (i = 0; h != NULL; h = efi_find_handle(&efipart_dev, ++i)) {
- snprintf(dname, sizeof(dname), "%s%d:", efipart_dev.dv_name, i);
- if (zfs_probe_dev(dname, &guid) == 0)
- (void)efi_handle_update_dev(h, &zfs_dev, unit++, guid);
- }
-}
-#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 10, 3:46 PM (10 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17086165
Default Alt Text
D7589.id21305.diff (127 KB)
Attached To
Mode
D7589: EFI boot1 and loader Refactoring
Attached
Detach File
Event Timeline
Log In to Comment