svn commit: r307070 - in head/sys: amd64/amd64 conf dev/efidev i386/include modules/efirt sys
Warner Losh
imp at FreeBSD.org
Tue Oct 11 22:24:32 UTC 2016
Author: imp
Date: Tue Oct 11 22:24:30 2016
New Revision: 307070
URL: https://svnweb.freebsd.org/changeset/base/307070
Log:
Create /dev/efidev to provide an ioctl interface to
userland. It supports userland interfaces to UEFI Runtime Services. This is
indended to the the MI portion of EFI RuntimeServices support.
Differential Revision: https://reviews.freebsd.org/D8128
Reviewed by: kib@, wblock@, Ganael Laplanche
Added:
head/sys/dev/efidev/
head/sys/dev/efidev/efidev.c (contents, props changed)
head/sys/i386/include/efi.h (contents, props changed)
head/sys/sys/efiio.h (contents, props changed)
Modified:
head/sys/amd64/amd64/efirt.c
head/sys/conf/files
head/sys/modules/efirt/Makefile
head/sys/sys/efi.h
Modified: head/sys/amd64/amd64/efirt.c
==============================================================================
--- head/sys/amd64/amd64/efirt.c Tue Oct 11 21:59:22 2016 (r307069)
+++ head/sys/amd64/amd64/efirt.c Tue Oct 11 22:24:30 2016 (r307070)
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
static struct efi_systbl *efi_systbl;
static struct efi_cfgtbl *efi_cfgtbl;
static struct efi_rt *efi_runtime;
+static struct cdev *efi_cdev;
static int efi_status2err[25] = {
0, /* EFI_SUCCESS */
@@ -402,13 +403,15 @@ efi_init(void)
return (ENXIO);
}
- return (0);
+ return (efidev_init(&efi_cdev));
}
static void
efi_uninit(void)
{
+ efidev_uninit(efi_cdev);
+
efi_destroy_1t1_map();
efi_systbl = NULL;
Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files Tue Oct 11 21:59:22 2016 (r307069)
+++ head/sys/conf/files Tue Oct 11 22:24:30 2016 (r307070)
@@ -1431,6 +1431,7 @@ dev/ed/if_ed_novell.c optional ed
dev/ed/if_ed_rtl80x9.c optional ed
dev/ed/if_ed_pccard.c optional ed pccard
dev/ed/if_ed_pci.c optional ed pci
+dev/efidev/efidev.c optional efirt
dev/eisa/eisa_if.m standard
dev/eisa/eisaconf.c optional eisa
dev/e1000/if_em.c optional em \
Added: head/sys/dev/efidev/efidev.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/dev/efidev/efidev.c Tue Oct 11 22:24:30 2016 (r307070)
@@ -0,0 +1,199 @@
+/*-
+ * Copyright (c) 2016 Netflix, Inc.
+ * 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
+ * in this position and unchanged.
+ * 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 ``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 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+
+#include <machine/efi.h>
+#include <sys/efiio.h>
+
+static d_ioctl_t efidev_ioctl;
+
+static struct cdevsw efi_cdevsw = {
+ .d_name = "efi",
+ .d_version = D_VERSION,
+ .d_ioctl = efidev_ioctl,
+};
+
+/* ARGSUSED */
+static int
+efidev_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr,
+ int flags __unused, struct thread *td __unused)
+{
+ int error;
+
+ switch (cmd) {
+ case EFIIOC_GET_TABLE:
+ {
+ struct efi_get_table_ioc *egtioc =
+ (struct efi_get_table_ioc *)addr;
+
+ error = efi_get_table(&egtioc->uuid, &egtioc->ptr);
+ break;
+ }
+ case EFIIOC_GET_TIME:
+ {
+ struct efi_tm *tm = (struct efi_tm *)addr;
+
+ error = efi_get_time(tm);
+ break;
+ }
+ case EFIIOC_SET_TIME:
+ {
+ struct efi_tm *tm = (struct efi_tm *)addr;
+
+ error = efi_set_time(tm);
+ break;
+ }
+ case EFIIOC_VAR_GET:
+ {
+ struct efi_var_ioc *ev = (struct efi_var_ioc *)addr;
+ void *data;
+ efi_char *name;
+
+ data = malloc(ev->datasize, M_TEMP, M_WAITOK);
+ name = malloc(ev->namesize, M_TEMP, M_WAITOK);
+ error = copyin(ev->name, name, ev->namesize);
+ if (error)
+ goto vg_out;
+ if (name[ev->namesize / sizeof(efi_char) - 1] != 0) {
+ error = EINVAL;
+ goto vg_out;
+ }
+
+ error = efi_var_get(name, &ev->vendor, &ev->attrib,
+ &ev->datasize, data);
+
+ if (error == 0) {
+ error = copyout(data, ev->data, ev->datasize);
+ } else if (error == EOVERFLOW) {
+ /*
+ * Pass back the size we really need, but
+ * convert the error to 0 so the copyout
+ * happens. datasize was updated in the
+ * efi_var_get call.
+ */
+ ev->data = NULL;
+ error = 0;
+ }
+vg_out:
+ free(data, M_TEMP);
+ free(name, M_TEMP);
+ break;
+ }
+ case EFIIOC_VAR_NEXT:
+ {
+ struct efi_var_ioc *ev = (struct efi_var_ioc *)addr;
+ efi_char *name;
+
+ name = malloc(ev->namesize, M_TEMP, M_WAITOK);
+ if (name == NULL) {
+ error = ENOMEM;
+ goto vn_out;
+ }
+ error = copyin(ev->name, name, ev->namesize);
+ if (error)
+ goto vn_out;
+ /* Note: namesize is the buffer size, not the string lenght */
+
+ error = efi_var_nextname(&ev->namesize, name, &ev->vendor);
+ if (error == 0) {
+ error = copyout(name, ev->name, ev->namesize);
+ } else if (error == EOVERFLOW) {
+ ev->name = NULL;
+ error = 0;
+ }
+ vn_out:
+ if (name != NULL)
+ free(name, M_TEMP);
+ break;
+ }
+ case EFIIOC_VAR_SET:
+ {
+ struct efi_var_ioc *ev = (struct efi_var_ioc *)addr;
+ void *data = NULL;
+ efi_char *name;
+
+ /* datasize == 0 -> delete (more or less) */
+ if (ev->datasize > 0)
+ data = malloc(ev->datasize, M_TEMP, M_WAITOK);
+ name = malloc(ev->namesize, M_TEMP, M_WAITOK);
+ if (ev->datasize) {
+ error = copyin(ev->data, data, ev->datasize);
+ if (error)
+ goto vs_out;
+ }
+ error = copyin(ev->name, name, ev->namesize);
+ if (error)
+ goto vs_out;
+ if (name[ev->namesize / sizeof(efi_char) - 1] != 0) {
+ error = EINVAL;
+ goto vs_out;
+ }
+
+ error = efi_var_set(name, &ev->vendor, ev->attrib, ev->datasize,
+ data);
+vs_out:
+ if (data != NULL)
+ free(data, M_TEMP);
+ free(name, M_TEMP);
+ break;
+ }
+ default:
+ error = ENOTTY;
+ break;
+ }
+
+ return (error);
+}
+
+int
+efidev_init(struct cdev **cdev)
+{
+
+ *cdev = make_dev(&efi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0700,
+ "efidev");
+
+ return (0);
+}
+
+int
+efidev_uninit(struct cdev *cdev)
+{
+
+ destroy_dev(cdev);
+
+ return (0);
+}
Added: head/sys/i386/include/efi.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/i386/include/efi.h Tue Oct 11 22:24:30 2016 (r307070)
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 2016 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov <kib at FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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 __I386_INCLUDE_EFI_H_
+#define __I386_INCLUDE_EFI_H_
+
+#define EFIABI_ATTR /* __attribute__((ms_abi)) */ /* clang fails with this */
+
+/* Note: we don't actually support this on i386 yet */
+
+#endif /* __I386_INCLUDE_EFI_H_ */
Modified: head/sys/modules/efirt/Makefile
==============================================================================
--- head/sys/modules/efirt/Makefile Tue Oct 11 21:59:22 2016 (r307069)
+++ head/sys/modules/efirt/Makefile Tue Oct 11 22:24:30 2016 (r307070)
@@ -1,9 +1,10 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../${MACHINE}/${MACHINE}
+.PATH: ${.CURDIR}/../../dev/efidev
KMOD= efirt
-SRCS= efirt.c
+SRCS= efirt.c efidev.c
SRCS+= device_if.h bus_if.h
.include <bsd.kmod.mk>
Modified: head/sys/sys/efi.h
==============================================================================
--- head/sys/sys/efi.h Tue Oct 11 21:59:22 2016 (r307069)
+++ head/sys/sys/efi.h Tue Oct 11 22:24:30 2016 (r307070)
@@ -165,6 +165,9 @@ struct efi_systbl {
#ifdef _KERNEL
extern vm_paddr_t efi_systbl_phys;
+struct cdev;
+int efidev_init(struct cdev **);
+int efidev_uninit(struct cdev *);
#endif /* _KERNEL */
#endif /* _SYS_EFI_H_ */
Added: head/sys/sys/efiio.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/sys/efiio.h Tue Oct 11 22:24:30 2016 (r307070)
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 2016 Netflix, Inc.
+ * 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
+ * in this position and unchanged.
+ * 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 ``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 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 _SYS_EFIIO_H_
+#define _SYS_EFIIO_H_
+
+#include <sys/ioccom.h>
+#include <sys/uuid.h>
+#include <sys/efi.h>
+
+struct efi_get_table_ioc
+{
+ struct uuid uuid; /* UUID to look up */
+ void *ptr; /* Pointer to table in KVA space */
+};
+
+struct efi_var_ioc
+{
+ efi_char *name; /* User pointer to name, in wide chars */
+ size_t namesize; /* Number of wide characters in name */
+ struct uuid vendor; /* Vendor's UUID for variable */
+ uint32_t attrib; /* Attributes */
+ void *data; /* User pointer to the data */
+ size_t datasize; /* Number of *bytes* in the data */
+};
+
+#define EFIIOC_GET_TABLE _IOWR('E', 1, struct efi_get_table_ioc)
+#define EFIIOC_GET_TIME _IOR('E', 2, struct efi_tm)
+#define EFIIOC_SET_TIME _IOW('E', 3, struct efi_tm)
+#define EFIIOC_VAR_GET _IOWR('E', 4, struct efi_var_ioc)
+#define EFIIOC_VAR_NEXT _IOWR('E', 5, struct efi_var_ioc)
+#define EFIIOC_VAR_SET _IOWR('E', 6, struct efi_var_ioc)
+
+#endif /* _SYS_EFIIO_H_ */
More information about the svn-src-all
mailing list