Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/sys efi: Add /dev/efi character device



details:   https://anonhg.NetBSD.org/src/rev/7ae25a12c1ab
branches:  trunk
changeset: 1024114:7ae25a12c1ab
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Oct 10 13:03:08 2021 +0000

description:
efi: Add /dev/efi character device

Introduce a /dev/efi character device that provides a means for accessing
UEFI RT variable services from userland. Compatible with the FreeBSD ioctl
interface for ease of porting their libefivar and associated tools.

The ioctl interface is defined in sys/efiio.h.

To enable support for this on an arch, the kernel needs `pseudo-device efi`
and the MD EFI implementation needs to register its backend by calling
efi_ops_register(). This commit includes an implementation for Arm.

diffstat:

 distrib/sets/lists/comp/mi     |    3 +-
 etc/MAKEDEV.tmpl               |    6 +-
 etc/etc.evbarm/MAKEDEV.conf    |    3 +-
 sys/arch/arm/arm/efi_runtime.c |  127 ++++++++++++++--
 sys/arch/arm/arm/efi_runtime.h |   11 +-
 sys/arch/arm/fdt/arm_fdt.c     |   21 +-
 sys/arch/evbarm/conf/GENERIC64 |    3 +-
 sys/conf/majors                |    3 +-
 sys/dev/efi.c                  |  306 +++++++++++++++++++++++++++++++++++++++++
 sys/dev/efivar.h               |   46 ++++++
 sys/dev/files.dev              |    5 +-
 sys/sys/Makefile               |    7 +-
 sys/sys/efiio.h                |   64 ++++++++
 13 files changed, 564 insertions(+), 41 deletions(-)

diffs (truncated from 835 to 300 lines):

diff -r abb1abe3b749 -r 7ae25a12c1ab distrib/sets/lists/comp/mi
--- a/distrib/sets/lists/comp/mi        Sun Oct 10 11:21:05 2021 +0000
+++ b/distrib/sets/lists/comp/mi        Sun Oct 10 13:03:08 2021 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: mi,v 1.2395 2021/09/30 02:00:19 yamaguchi Exp $
+#      $NetBSD: mi,v 1.2396 2021/10/10 13:03:09 jmcneill Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 ./etc/mtree/set.comp                           comp-sys-root
@@ -3273,6 +3273,7 @@
 ./usr/include/sys/domain.h                     comp-c-include
 ./usr/include/sys/drvctlio.h                   comp-c-include
 ./usr/include/sys/dvdio.h                      comp-c-include
+./usr/include/sys/efiio.h                      comp-c-include
 ./usr/include/sys/elfdefinitions.h             comp-c-include
 ./usr/include/sys/endian.h                     comp-c-include
 ./usr/include/sys/envsys.h                     comp-c-include
diff -r abb1abe3b749 -r 7ae25a12c1ab etc/MAKEDEV.tmpl
--- a/etc/MAKEDEV.tmpl  Sun Oct 10 11:21:05 2021 +0000
+++ b/etc/MAKEDEV.tmpl  Sun Oct 10 13:03:08 2021 +0000
@@ -1,5 +1,5 @@
 #!/bin/sh -
-#      $NetBSD: MAKEDEV.tmpl,v 1.224 2021/07/24 11:39:18 jmcneill Exp $
+#      $NetBSD: MAKEDEV.tmpl,v 1.225 2021/10/10 13:03:08 jmcneill Exp $
 #
 # Copyright (c) 2003,2007,2008 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -2244,6 +2244,10 @@
        mkdev smbios c %smbios_chr% 0
        ;;
 
+efi)
+       mkdev efi c %efi_chr% 0 660
+       ;;
+
 midevend)
 %MI_DEVICES_END%
 local)
diff -r abb1abe3b749 -r 7ae25a12c1ab etc/etc.evbarm/MAKEDEV.conf
--- a/etc/etc.evbarm/MAKEDEV.conf       Sun Oct 10 11:21:05 2021 +0000
+++ b/etc/etc.evbarm/MAKEDEV.conf       Sun Oct 10 13:03:08 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: MAKEDEV.conf,v 1.21 2020/11/10 08:52:36 rin Exp $
+# $NetBSD: MAKEDEV.conf,v 1.22 2021/10/10 13:03:09 jmcneill Exp $
 
 all_md)
        makedev wscons fd0 fd1 wd0 wd1 wd2 wd3 sd0 sd1 sd2 sd3
@@ -27,6 +27,7 @@
        makedev spiflash0
        makedev bpf
        makedev openfirm
+       makedev acpi smbios efi
        ;;
 
 ramdisk|floppy)
diff -r abb1abe3b749 -r 7ae25a12c1ab sys/arch/arm/arm/efi_runtime.c
--- a/sys/arch/arm/arm/efi_runtime.c    Sun Oct 10 11:21:05 2021 +0000
+++ b/sys/arch/arm/arm/efi_runtime.c    Sun Oct 10 13:03:08 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efi_runtime.c,v 1.5 2020/12/18 07:40:27 skrll Exp $ */
+/* $NetBSD: efi_runtime.c,v 1.6 2021/10/10 13:03:09 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -29,8 +29,10 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "efi.h"
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efi_runtime.c,v 1.5 2020/12/18 07:40:27 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efi_runtime.c,v 1.6 2021/10/10 13:03:09 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/mutex.h>
@@ -38,12 +40,33 @@
 
 #include <uvm/uvm_extern.h>
 
+#include <dev/efivar.h>
+
 #include <arm/arm/efi_runtime.h>
 
+#ifdef _LP64
+#define        EFIERR(x)       (0x8000000000000000 | x)
+#else
+#define        EFIERR(x)       (0x80000000 | x)
+#endif
+
+#define        EFI_UNSUPPORTED         EFIERR(3)
+#define        EFI_DEVICE_ERROR        EFIERR(7)
+
 static kmutex_t efi_lock;
 
 static struct efi_rt *RT = NULL;
 
+#if NEFI > 0 && BYTE_ORDER == LITTLE_ENDIAN
+static const struct efi_ops arm_efi_ops = {
+       .efi_gettime    = arm_efirt_gettime,
+       .efi_settime    = arm_efirt_settime,
+       .efi_getvar     = arm_efirt_getvar,
+       .efi_setvar     = arm_efirt_setvar,
+       .efi_nextvar    = arm_efirt_nextvar,
+};
+#endif
+
 int
 arm_efirt_init(paddr_t efi_system_table)
 {
@@ -75,6 +98,8 @@
        RT = ST->st_rt;
        mutex_init(&efi_lock, MUTEX_DEFAULT, IPL_HIGH);
 
+       efi_register_ops(&arm_efi_ops);
+
        return 0;
 #else
        /* EFI runtime not supported in big endian mode */
@@ -82,42 +107,101 @@
 #endif
 }
 
-int
-arm_efirt_gettime(struct efi_tm *tm)
+efi_status
+arm_efirt_gettime(struct efi_tm *tm, struct efi_tmcap *tmcap)
 {
-       int error;
+       efi_status status = EFI_DEVICE_ERROR;
 
-       if (RT == NULL || RT->rt_gettime == NULL)
-               return ENXIO;
+       if (RT == NULL || RT->rt_gettime == NULL) {
+               return EFI_UNSUPPORTED;
+       }
 
        mutex_enter(&efi_lock);
-       if ((error = arm_efirt_md_enter()) == 0) {
-               if (RT->rt_gettime(tm, NULL) != 0)
-                       error = EIO;
+       if (arm_efirt_md_enter() == 0) {
+               status = RT->rt_gettime(tm, tmcap);
+       }
+       arm_efirt_md_exit();
+       mutex_exit(&efi_lock);
+
+       return status;
+}
+
+efi_status
+arm_efirt_settime(struct efi_tm *tm)
+{
+       efi_status status = EFI_DEVICE_ERROR;
+
+       if (RT == NULL || RT->rt_settime == NULL) {
+               return EFI_UNSUPPORTED;
+       }
+
+       mutex_enter(&efi_lock);
+       if (arm_efirt_md_enter() == 0) {
+               status = RT->rt_settime(tm);
        }
        arm_efirt_md_exit();
        mutex_exit(&efi_lock);
 
-       return error;
+       return status;
 }
 
-int
-arm_efirt_settime(struct efi_tm *tm)
+efi_status
+arm_efirt_getvar(uint16_t *name, struct uuid *vendor, uint32_t *attrib,
+    u_long *datasize, void *data)
 {
-       int error;
+       efi_status status = EFI_DEVICE_ERROR;
 
-       if (RT == NULL || RT->rt_settime == NULL)
-               return ENXIO;
+       if (RT == NULL || RT->rt_getvar == NULL) {
+               return EFI_UNSUPPORTED;
+       }
 
        mutex_enter(&efi_lock);
-       if ((error = arm_efirt_md_enter()) == 0) {
-               if (RT->rt_settime(tm) != 0)
-                       error = EIO;
+       if (arm_efirt_md_enter() == 0) {
+               status = RT->rt_getvar(name, vendor, attrib, datasize, data);
        }
        arm_efirt_md_exit();
        mutex_exit(&efi_lock);
 
-       return error;
+       return status;
+}
+
+efi_status
+arm_efirt_nextvar(u_long *namesize, efi_char *name, struct uuid *vendor)
+{
+       efi_status status = EFI_DEVICE_ERROR;
+
+       if (RT == NULL || RT->rt_scanvar == NULL) {
+               return EFI_UNSUPPORTED;
+       }
+
+       mutex_enter(&efi_lock);
+       if (arm_efirt_md_enter() == 0) {
+               status = RT->rt_scanvar(namesize, name, vendor);
+       }
+       arm_efirt_md_exit();
+       mutex_exit(&efi_lock);
+
+       return status;
+}
+
+efi_status
+arm_efirt_setvar(uint16_t *name, struct uuid *vendor, uint32_t attrib,
+    u_long datasize, void *data)
+{
+       efi_status status = EFI_DEVICE_ERROR;
+
+       if (RT == NULL || RT->rt_setvar == NULL) {
+               return EFI_UNSUPPORTED;
+       }
+
+       mutex_enter(&efi_lock);
+       if (arm_efirt_md_enter() == 0) {
+               status = RT->rt_setvar(name, vendor, attrib, datasize, data);
+       }
+       arm_efirt_md_exit();
+       mutex_exit(&efi_lock);
+
+       return status;
 }
 
 int
@@ -133,8 +217,9 @@
        if (reset_called == false) {
                reset_called = true;
                if ((error = arm_efirt_md_enter()) == 0) {
-                       if (RT->rt_reset(type, 0, 0, NULL) != 0)
+                       if (RT->rt_reset(type, 0, 0, NULL) != 0) {
                                error = EIO;
+                       }
                }
                arm_efirt_md_exit();
        } else {
diff -r abb1abe3b749 -r 7ae25a12c1ab sys/arch/arm/arm/efi_runtime.h
--- a/sys/arch/arm/arm/efi_runtime.h    Sun Oct 10 11:21:05 2021 +0000
+++ b/sys/arch/arm/arm/efi_runtime.h    Sun Oct 10 13:03:08 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efi_runtime.h,v 1.3 2019/12/16 00:03:50 jmcneill Exp $ */
+/* $NetBSD: efi_runtime.h,v 1.4 2021/10/10 13:03:09 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -35,8 +35,13 @@
 #include <arm/efi.h>
 
 int            arm_efirt_init(paddr_t);
-int            arm_efirt_gettime(struct efi_tm *);
-int            arm_efirt_settime(struct efi_tm *);
+efi_status     arm_efirt_gettime(struct efi_tm *, struct efi_tmcap *);
+efi_status     arm_efirt_settime(struct efi_tm *);
+efi_status     arm_efirt_getvar(uint16_t *, struct uuid *, uint32_t *,
+                                u_long *, void *);
+efi_status     arm_efirt_nextvar(u_long *, uint16_t *, struct uuid *);
+efi_status     arm_efirt_setvar(uint16_t *, struct uuid *, uint32_t,
+                                u_long, void *);
 int            arm_efirt_reset(enum efi_reset);
 
 enum arm_efirt_mem_type {
diff -r abb1abe3b749 -r 7ae25a12c1ab sys/arch/arm/fdt/arm_fdt.c
--- a/sys/arch/arm/fdt/arm_fdt.c        Sun Oct 10 11:21:05 2021 +0000
+++ b/sys/arch/arm/fdt/arm_fdt.c        Sun Oct 10 13:03:08 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arm_fdt.c,v 1.19 2021/09/05 13:20:34 jmcneill Exp $ */
+/* $NetBSD: arm_fdt.c,v 1.20 2021/10/10 13:03:09 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -31,7 +31,7 @@
 #include "opt_modular.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm_fdt.c,v 1.19 2021/09/05 13:20:34 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm_fdt.c,v 1.20 2021/10/10 13:03:09 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -308,7 +308,7 @@
 
        aprint_debug_dev(dev, "EFI system table at %#" PRIx64 "\n", efi_system_table);
 
-       if (arm_efirt_gettime(&tm) == 0) {
+       if (arm_efirt_gettime(&tm, NULL) == 0) {
                aprint_normal_dev(dev, "using EFI runtime services for RTC\n");



Home | Main Index | Thread Index | Old Index