Module Name: src
Committed By: jmcneill
Date: Mon Dec 16 00:03:51 UTC 2019
Modified Files:
src/sys/arch/aarch64/aarch64: efi_machdep.c
src/sys/arch/arm/arm: efi_runtime.c efi_runtime.h
Log Message:
Enable FP access for EFI RT and improve error handling.
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/aarch64/aarch64/efi_machdep.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/arm/efi_runtime.c \
src/sys/arch/arm/arm/efi_runtime.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/aarch64/aarch64/efi_machdep.c
diff -u src/sys/arch/aarch64/aarch64/efi_machdep.c:1.4 src/sys/arch/aarch64/aarch64/efi_machdep.c:1.5
--- src/sys/arch/aarch64/aarch64/efi_machdep.c:1.4 Mon Aug 12 15:47:02 2019
+++ src/sys/arch/aarch64/aarch64/efi_machdep.c Mon Dec 16 00:03:50 2019
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: efi_machdep.
#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 @@ arm_efirt_md_map_range(vaddr_t va, paddr
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();
+}
Index: src/sys/arch/arm/arm/efi_runtime.c
diff -u src/sys/arch/arm/arm/efi_runtime.c:1.2 src/sys/arch/arm/arm/efi_runtime.c:1.3
--- src/sys/arch/arm/arm/efi_runtime.c:1.2 Thu Jul 25 02:00:40 2019
+++ src/sys/arch/arm/arm/efi_runtime.c Mon Dec 16 00:03:50 2019
@@ -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 @@ arm_efirt_init(paddr_t efi_system_table)
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 @@ arm_efirt_reset(enum efi_reset type)
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;
}
Index: src/sys/arch/arm/arm/efi_runtime.h
diff -u src/sys/arch/arm/arm/efi_runtime.h:1.2 src/sys/arch/arm/arm/efi_runtime.h:1.3
--- src/sys/arch/arm/arm/efi_runtime.h:1.2 Wed Oct 31 13:01:48 2018
+++ src/sys/arch/arm/arm/efi_runtime.h Mon Dec 16 00:03:50 2019
@@ -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 @@ enum arm_efirt_mem_type {
};
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 */