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 */

Reply via email to