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/415f395068b9
branches: trunk
changeset: 466251:415f395068b9
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 8230cd68dc0f -r 415f395068b9 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 8230cd68dc0f -r 415f395068b9 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 8230cd68dc0f -r 415f395068b9 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