Author: smh
Date: Thu Jan 28 17:24:40 2016
New Revision: 294999
URL: https://svnweb.freebsd.org/changeset/base/294999

Log:
  MFC r294068, r294265
  
  MFC r294068:
  Add EFI ZFS boot support
  
  MFC r294265:
  Fix broken DPRINTF and wire up EFI_DEBUG so -DEFI_DEBUG to make works.
  
  Relnotes:     Yes
  Sponsored by: Multiplay

Added:
  stable/10/sys/boot/efi/boot1/zfs_module.c
     - copied, changed from r294068, head/sys/boot/efi/boot1/zfs_module.c
Modified:
  stable/10/sys/boot/efi/boot1/Makefile
  stable/10/sys/boot/efi/boot1/boot1.c
  stable/10/sys/boot/efi/boot1/boot_module.h
  stable/10/sys/boot/efi/include/efilib.h
  stable/10/sys/boot/efi/libefi/handles.c
  stable/10/sys/boot/efi/loader/Makefile
  stable/10/sys/boot/efi/loader/conf.c
  stable/10/sys/boot/efi/loader/devicename.c
  stable/10/sys/boot/efi/loader/main.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/boot/efi/boot1/Makefile
==============================================================================
--- stable/10/sys/boot/efi/boot1/Makefile       Thu Jan 28 16:58:49 2016        
(r294998)
+++ stable/10/sys/boot/efi/boot1/Makefile       Thu Jan 28 17:24:40 2016        
(r294999)
@@ -10,8 +10,22 @@ PROG=                boot1.sym
 INTERNALPROG=
 WARNS?=                6
 
+.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
+.endif
+
 # architecture-specific loader code
 SRCS=  boot1.c reloc.c start.S ufs_module.c
+.if ${MK_ZFS} != "no"
+SRCS+=         zfs_module.c
+.endif
 
 CFLAGS+=       -fPIC
 CFLAGS+=       -I.
@@ -20,6 +34,15 @@ CFLAGS+=     -I${.CURDIR}/../include/${MACHI
 CFLAGS+=       -I${.CURDIR}/../../../contrib/dev/acpica/include
 CFLAGS+=       -I${.CURDIR}/../../..
 CFLAGS+=       -DEFI_UFS_BOOT
+.ifdef(EFI_DEBUG)
+CFLAGS+=       -DEFI_DEBUG
+.endif
+
+.if ${MK_ZFS} != "no"
+CFLAGS+=       -I${.CURDIR}/../../zfs/
+CFLAGS+=       -I${.CURDIR}/../../../cddl/boot/zfs/
+CFLAGS+=       -DEFI_ZFS_BOOT
+.endif
 
 # Always add MI sources and REGULAR efi loader bits
 .PATH:         ${.CURDIR}/../loader/arch/${MACHINE}

Modified: stable/10/sys/boot/efi/boot1/boot1.c
==============================================================================
--- stable/10/sys/boot/efi/boot1/boot1.c        Thu Jan 28 16:58:49 2016        
(r294998)
+++ stable/10/sys/boot/efi/boot1/boot1.c        Thu Jan 28 17:24:40 2016        
(r294999)
@@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$");
 
 static const boot_module_t *boot_modules[] =
 {
+#ifdef EFI_ZFS_BOOT
+       &zfs_module,
+#endif
 #ifdef EFI_UFS_BOOT
        &ufs_module
 #endif

Modified: stable/10/sys/boot/efi/boot1/boot_module.h
==============================================================================
--- stable/10/sys/boot/efi/boot1/boot_module.h  Thu Jan 28 16:58:49 2016        
(r294998)
+++ stable/10/sys/boot/efi/boot1/boot_module.h  Thu Jan 28 17:24:40 2016        
(r294999)
@@ -36,12 +36,9 @@
 #include <eficonsctl.h>
 
 #ifdef EFI_DEBUG
-#define DPRINTF(fmt, args...) \
-        do { \
-                printf(fmt, ##args) \
-        } while (0)
+#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
 #else
-#define DPRINTF(fmt, args...) {}
+#define DPRINTF(fmt, ...) {}
 #endif
 
 /* EFI device info */
@@ -97,6 +94,9 @@ typedef struct boot_module_t
 #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);

Copied and modified: stable/10/sys/boot/efi/boot1/zfs_module.c (from r294068, 
head/sys/boot/efi/boot1/zfs_module.c)
==============================================================================
--- head/sys/boot/efi/boot1/zfs_module.c        Fri Jan 15 02:33:47 2016        
(r294068, copy source)
+++ stable/10/sys/boot/efi/boot1/zfs_module.c   Thu Jan 28 17:24:40 2016        
(r294999)
@@ -53,9 +53,9 @@ vdev_read(vdev_t *vdev, void *priv, off_
        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: %lu, size: %d,"
+               DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %zu, size: 
%zu,"
                     " status: %lu\n", devinfo->dev,
-                    devinfo->dev->Media->MediaId, lba, size,
+                    devinfo->dev->Media->MediaId, lba, bytes,
                     EFI_ERROR_CODE(status));
                return (-1);
        }

Modified: stable/10/sys/boot/efi/include/efilib.h
==============================================================================
--- stable/10/sys/boot/efi/include/efilib.h     Thu Jan 28 16:58:49 2016        
(r294998)
+++ stable/10/sys/boot/efi/include/efilib.h     Thu Jan 28 17:24:40 2016        
(r294999)
@@ -42,7 +42,8 @@ void *efi_get_table(EFI_GUID *tbl);
 
 int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int);
 EFI_HANDLE efi_find_handle(struct devsw *, int);
-int efi_handle_lookup(EFI_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_status_to_errno(EFI_STATUS);
 time_t efi_time(EFI_TIME *);

Modified: stable/10/sys/boot/efi/libefi/handles.c
==============================================================================
--- stable/10/sys/boot/efi/libefi/handles.c     Thu Jan 28 16:58:49 2016        
(r294998)
+++ stable/10/sys/boot/efi/libefi/handles.c     Thu Jan 28 17:24:40 2016        
(r294999)
@@ -35,6 +35,7 @@ struct entry {
        EFI_HANDLE alias;
        struct devsw *dev;
        int unit;
+       uint64_t extra;
 };
 
 struct entry *entry;
@@ -79,7 +80,7 @@ efi_find_handle(struct devsw *dev, int u
 }
 
 int
-efi_handle_lookup(EFI_HANDLE h, struct devsw **dev, int *unit)
+efi_handle_lookup(EFI_HANDLE h, struct devsw **dev, int *unit, uint64_t *extra)
 {
        int idx;
 
@@ -90,7 +91,28 @@ efi_handle_lookup(EFI_HANDLE h, struct d
                        *dev = entry[idx].dev;
                if (unit != NULL)
                        *unit = entry[idx].unit;
+               if (extra != NULL)
+                       *extra = entry[idx].extra;
                return (0);
        }
        return (ENOENT);
 }
+
+int
+efi_handle_update_dev(EFI_HANDLE h, struct devsw *dev, int unit,
+    uint64_t guid)
+{
+       int idx;
+
+       for (idx = 0; idx < nentries; idx++) {
+               if (entry[idx].handle != h)
+                       continue;
+               entry[idx].dev = dev;
+               entry[idx].unit = unit;
+               entry[idx].alias = NULL;
+               entry[idx].extra = guid;
+               return (0);
+       }
+
+       return (ENOENT);
+}

Modified: stable/10/sys/boot/efi/loader/Makefile
==============================================================================
--- stable/10/sys/boot/efi/loader/Makefile      Thu Jan 28 16:58:49 2016        
(r294998)
+++ stable/10/sys/boot/efi/loader/Makefile      Thu Jan 28 17:24:40 2016        
(r294999)
@@ -20,6 +20,16 @@ SRCS=        autoload.c \
        smbios.c \
        vers.c
 
+.if ${MK_ZFS} != "no"
+SRCS+=         zfs.c
+.PATH:         ${.CURDIR}/../../zfs
+
+# Disable warnings that are currently incompatible with the zfs boot code
+CWARNFLAGS.zfs.c+=     -Wno-sign-compare
+CWARNFLAGS.zfs.c+=     -Wno-array-bounds
+CWARNFLAGS.zfs.c+=     -Wno-missing-prototypes
+.endif
+
 .PATH: ${.CURDIR}/arch/${MACHINE}
 # For smbios.c
 .PATH: ${.CURDIR}/../../i386/libi386
@@ -33,6 +43,11 @@ CFLAGS+=     -I${.CURDIR}/../include/${MACHI
 CFLAGS+=       -I${.CURDIR}/../../../contrib/dev/acpica/include
 CFLAGS+=       -I${.CURDIR}/../../..
 CFLAGS+=       -I${.CURDIR}/../../i386/libi386
+.if ${MK_ZFS} != "no"
+CFLAGS+=       -I${.CURDIR}/../../zfs
+CFLAGS+=       -I${.CURDIR}/../../../cddl/boot/zfs
+CFLAGS+=       -DEFI_ZFS_BOOT
+.endif
 CFLAGS+=       -DNO_PCI -DEFI
 
 .if ${MK_FORTH} != "no"

Modified: stable/10/sys/boot/efi/loader/conf.c
==============================================================================
--- stable/10/sys/boot/efi/loader/conf.c        Thu Jan 28 16:58:49 2016        
(r294998)
+++ stable/10/sys/boot/efi/loader/conf.c        Thu Jan 28 17:24:40 2016        
(r294999)
@@ -31,14 +31,23 @@ __FBSDID("$FreeBSD$");
 #include <bootstrap.h>
 #include <efi.h>
 #include <efilib.h>
+#ifdef EFI_ZFS_BOOT
+#include <libzfs.h>
+#endif
 
 struct devsw *devsw[] = {
        &efipart_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,

Modified: stable/10/sys/boot/efi/loader/devicename.c
==============================================================================
--- stable/10/sys/boot/efi/loader/devicename.c  Thu Jan 28 16:58:49 2016        
(r294998)
+++ stable/10/sys/boot/efi/loader/devicename.c  Thu Jan 28 17:24:40 2016        
(r294999)
@@ -33,6 +33,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/disklabel.h>
 #include <sys/param.h>
 #include <bootstrap.h>
+#ifdef EFI_ZFS_BOOT
+#include <libzfs.h>
+#endif
 
 #include <efi.h>
 #include <efilib.h>
@@ -104,6 +107,23 @@ efi_parsedev(struct devdesc **dev, const
 
        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)
@@ -143,6 +163,10 @@ efi_fmtdev(void *vdev)
        static char buf[SPECNAMELEN + 1];
 
        switch(dev->d_type) {
+#ifdef EFI_ZFS_BOOT
+       case DEVT_ZFS:
+               return (zfs_fmtdev(dev));
+#endif
        case DEVT_NONE:
                strcpy(buf, "(no device)");
                break;

Modified: stable/10/sys/boot/efi/loader/main.c
==============================================================================
--- stable/10/sys/boot/efi/loader/main.c        Thu Jan 28 16:58:49 2016        
(r294998)
+++ stable/10/sys/boot/efi/loader/main.c        Thu Jan 28 17:24:40 2016        
(r294999)
@@ -39,6 +39,10 @@ __FBSDID("$FreeBSD$");
 #include <bootstrap.h>
 #include <smbios.h>
 
+#ifdef EFI_ZFS_BOOT
+#include <libzfs.h>
+#endif
+
 #include "loader_efi.h"
 
 extern char bootprog_name[];
@@ -60,6 +64,10 @@ EFI_GUID hoblist = HOB_LIST_TABLE_GUID;
 EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID;
 EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID;
 
+#ifdef EFI_ZFS_BOOT
+static void efi_zfs_probe(void);
+#endif
+
 /*
  * Need this because EFI uses UTF-16 unicode string constants, but we
  * use UTF-8. We can't use printf due to the possiblity of \0 and we
@@ -82,6 +90,7 @@ main(int argc, CHAR16 *argv[])
        EFI_GUID *guid;
        int i, j, vargood, unit;
        struct devsw *dev;
+       uint64_t pool_guid;
        UINTN k;
 
        archsw.arch_autoload = efi_autoload;
@@ -89,6 +98,10 @@ main(int argc, CHAR16 *argv[])
        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
 
        /*
         * XXX Chicken-and-egg problem; we want to have console output
@@ -167,10 +180,27 @@ main(int argc, CHAR16 *argv[])
         */
        BS->SetWatchdogTimer(0, 0, 0, NULL);
 
-       if (efi_handle_lookup(img->DeviceHandle, &dev, &unit) != 0)
+       if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &pool_guid) != 0)
                return (EFI_NOT_FOUND);
 
        switch (dev->dv_type) {
+#ifdef EFI_ZFS_BOOT
+       case DEVT_ZFS: {
+               struct zfs_devdesc currdev;
+
+               currdev.d_dev = dev;
+               currdev.d_unit = unit;
+               currdev.d_type = currdev.d_dev->dv_type;
+               currdev.d_opendata = NULL;
+               currdev.pool_guid = pool_guid;
+               currdev.root_guid = 0;
+               env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev),
+                          efi_setcurrdev, env_nounset);
+               env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), 
env_noset,
+                          env_nounset);
+               break;
+       }
+#endif
        default: {
                struct devdesc currdev;
 
@@ -452,3 +482,46 @@ command_nvram(int argc, char *argv[])
 
        return (CMD_OK);
 }
+
+#ifdef EFI_ZFS_BOOT
+COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset",
+    command_lszfs);
+
+static int
+command_lszfs(int argc, char *argv[])
+{
+       int err;
+
+       if (argc != 2) {
+               command_errmsg = "wrong number of arguments";
+               return (CMD_ERROR);
+       }
+
+       err = zfs_list(argv[1]);
+       if (err != 0) {
+               command_errmsg = strerror(err);
+               return (CMD_ERROR);
+       }
+       return (CMD_OK);
+}
+#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
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to