Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Enable FP access for EFI RT and improve error handl...



details:   https://anonhg.NetBSD.org/src/rev/cb26342ee7ac
branches:  trunk
changeset: 967629:cb26342ee7ac
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Dec 16 00:03:50 2019 +0000

description:
Enable FP access for EFI RT and improve error handling.

diffstat:

 sys/arch/aarch64/aarch64/efi_machdep.c |  49 ++++++++++++++++++++++++++++++++-
 sys/arch/arm/arm/efi_runtime.c         |  42 ++++++++++++++++------------
 sys/arch/arm/arm/efi_runtime.h         |   4 ++-
 3 files changed, 74 insertions(+), 21 deletions(-)

diffs (188 lines):

diff -r b43f86de1132 -r cb26342ee7ac sys/arch/aarch64/aarch64/efi_machdep.c
--- a/sys/arch/aarch64/aarch64/efi_machdep.c    Sun Dec 15 23:13:33 2019 +0000
+++ b/sys/arch/aarch64/aarch64/efi_machdep.c    Mon Dec 16 00:03:50 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efi_machdep.c,v 1.4 2019/08/12 15:47:02 skrll Exp $ */
+/* $NetBSD: efi_machdep.c,v 1.5 2019/12/16 00:03:50 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efi_machdep.c,v 1.4 2019/08/12 15:47:02 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efi_machdep.c,v 1.5 2019/12/16 00:03:50 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <uvm/uvm_extern.h>
@@ -38,6 +38,13 @@
 
 #include <arm/arm/efi_runtime.h>
 
+#include <aarch64/machdep.h>
+
+static struct {
+       struct faultbuf faultbuf;
+       bool            fpu_used;
+} arm_efirt_state;
+
 void
 arm_efirt_md_map_range(vaddr_t va, paddr_t pa, size_t sz, enum arm_efirt_mem_type type)
 {
@@ -70,3 +77,41 @@
                sz -= PAGE_SIZE;
        }
 }
+
+int
+arm_efirt_md_enter(void)
+{
+       struct lwp *l = curlwp;
+
+       /* Save FPU state */
+       arm_efirt_state.fpu_used = fpu_used_p(l) != 0;
+       if (arm_efirt_state.fpu_used)
+               fpu_save(l);
+
+       /* Enable FP access (AArch64 UEFI calling convention) */
+       reg_cpacr_el1_write(CPACR_FPEN_ALL);
+       __asm __volatile ("isb");
+
+       /*
+        * Install custom fault handler. EFI lock is held across calls so
+        * shared faultbuf is safe here.
+        */
+       return cpu_set_onfault(&arm_efirt_state.faultbuf);
+}
+
+void
+arm_efirt_md_exit(void)
+{
+       struct lwp *l = curlwp;
+
+       /* Disable FP access */
+       reg_cpacr_el1_write(CPACR_FPEN_NONE);
+       __asm __volatile ("isb");
+
+       /* Restore FPU state */
+       if (arm_efirt_state.fpu_used)
+               fpu_load(l);
+
+       /* Remove custom fault handler */
+       cpu_unset_onfault();
+}
diff -r b43f86de1132 -r cb26342ee7ac sys/arch/arm/arm/efi_runtime.c
--- a/sys/arch/arm/arm/efi_runtime.c    Sun Dec 15 23:13:33 2019 +0000
+++ b/sys/arch/arm/arm/efi_runtime.c    Mon Dec 16 00:03:50 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efi_runtime.c,v 1.2 2019/07/25 02:00:40 jmcneill Exp $ */
+/* $NetBSD: efi_runtime.c,v 1.3 2019/12/16 00:03:50 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efi_runtime.c,v 1.2 2019/07/25 02:00:40 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efi_runtime.c,v 1.3 2019/12/16 00:03:50 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/mutex.h>
@@ -79,42 +79,46 @@
 int
 arm_efirt_gettime(struct efi_tm *tm)
 {
-       efi_status status;
+       int error;
 
        if (RT == NULL || RT->rt_gettime == NULL)
                return ENXIO;
 
        mutex_enter(&efi_lock);
-       status = RT->rt_gettime(tm, NULL);
+       if ((error = arm_efirt_md_enter()) == 0) {
+               if (RT->rt_gettime(tm, NULL) != 0)
+                       error = EIO;
+       }
+       arm_efirt_md_exit();
        mutex_exit(&efi_lock);
-       if (status)
-               return EIO;
 
-       return 0;
+       return error;
 }
 
 int
 arm_efirt_settime(struct efi_tm *tm)
 {
-       efi_status status;
+       int error;
 
        if (RT == NULL || RT->rt_settime == NULL)
                return ENXIO;
 
        mutex_enter(&efi_lock);
-       status = RT->rt_settime(tm);
+       if ((error = arm_efirt_md_enter()) == 0) {
+               if (RT->rt_settime(tm) != 0)
+                       error = EIO;
+       }
+       arm_efirt_md_exit();
        mutex_exit(&efi_lock);
-       if (status)
-               return EIO;
 
-       return 0;
+       return error;
 }
 
 int
 arm_efirt_reset(enum efi_reset type)
 {
        static int reset_called = false;
-       efi_status status;
+       int error;
 
        if (RT == NULL || RT->rt_reset == NULL)
                return ENXIO;
@@ -122,13 +126,15 @@
        mutex_enter(&efi_lock);
        if (reset_called == false) {
                reset_called = true;
-               status = RT->rt_reset(type, 0, 0, NULL);
+               if ((error = arm_efirt_md_enter()) == 0) {
+                       if (RT->rt_reset(type, 0, 0, NULL) != 0)
+                               error = EIO;
+               }
+               arm_efirt_md_exit();
        } else {
-               status = 1;
+               error = EPERM;
        }
        mutex_exit(&efi_lock);
-       if (status)
-               return EIO;
 
-       return 0;
+       return error;
 }
diff -r b43f86de1132 -r cb26342ee7ac sys/arch/arm/arm/efi_runtime.h
--- a/sys/arch/arm/arm/efi_runtime.h    Sun Dec 15 23:13:33 2019 +0000
+++ b/sys/arch/arm/arm/efi_runtime.h    Mon Dec 16 00:03:50 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efi_runtime.h,v 1.2 2018/10/31 13:01:48 jmcneill Exp $ */
+/* $NetBSD: efi_runtime.h,v 1.3 2019/12/16 00:03:50 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -46,5 +46,7 @@
 };
 
 void           arm_efirt_md_map_range(vaddr_t, paddr_t, size_t, enum arm_efirt_mem_type);
+int            arm_efirt_md_enter(void);
+void           arm_efirt_md_exit(void);
 
 #endif /* !_ARM_EFI_RUNTIME_H */



Home | Main Index | Thread Index | Old Index