Module Name: src
Committed By: skrll
Date: Sat Apr 2 11:16:08 UTC 2022
Modified Files:
src/sys/arch/aarch64/aarch64: efi_machdep.c pmap.c
src/sys/arch/aarch64/include: pmap.h vmparam.h
src/sys/arch/arm/arm: efi_runtime.c
src/sys/arch/arm/arm32: arm32_kvminit.c locore.S pmap.c
src/sys/arch/arm/conf: files.arm
src/sys/arch/arm/include: asan.h frame.h
src/sys/arch/arm/include/arm32: machdep.h pmap.h
src/sys/arch/evbarm/conf: GENERIC
src/sys/arch/evbarm/fdt: fdt_machdep.c
src/sys/stand/efiboot: version
src/sys/stand/efiboot/bootaa64: Makefile
src/sys/stand/efiboot/bootarm: Makefile
Added Files:
src/sys/arch/arm/arm: efi_machdep.c trap.c
Log Message:
Update to support EFI runtime outside the kernel virtual address space
by creating an EFI RT pmap that can be activated / deactivated when
required.
Adds support for EFI RT to ARM_MMU_EXTENDED (ASID) 32-bit Arm machines.
On Arm64 the usage of pmapboot_enter is reduced and the mappings are
created much later in the boot process -- now in cpu_startup_hook.
Backward compatiblity for KVA mapped RT from old bootaa64.efi is
maintained.
Adding support to other platforms should be easier as a result.
To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/aarch64/aarch64/efi_machdep.c
cvs rdiff -u -r1.131 -r1.132 src/sys/arch/aarch64/aarch64/pmap.c
cvs rdiff -u -r1.51 -r1.52 src/sys/arch/aarch64/include/pmap.h
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/aarch64/include/vmparam.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/arm/efi_machdep.c \
src/sys/arch/arm/arm/trap.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/arm/efi_runtime.c
cvs rdiff -u -r1.68 -r1.69 src/sys/arch/arm/arm32/arm32_kvminit.c
cvs rdiff -u -r1.43 -r1.44 src/sys/arch/arm/arm32/locore.S
cvs rdiff -u -r1.434 -r1.435 src/sys/arch/arm/arm32/pmap.c
cvs rdiff -u -r1.165 -r1.166 src/sys/arch/arm/conf/files.arm
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/include/asan.h
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/arm/include/frame.h
cvs rdiff -u -r1.35 -r1.36 src/sys/arch/arm/include/arm32/machdep.h
cvs rdiff -u -r1.172 -r1.173 src/sys/arch/arm/include/arm32/pmap.h
cvs rdiff -u -r1.106 -r1.107 src/sys/arch/evbarm/conf/GENERIC
cvs rdiff -u -r1.90 -r1.91 src/sys/arch/evbarm/fdt/fdt_machdep.c
cvs rdiff -u -r1.30 -r1.31 src/sys/stand/efiboot/version
cvs rdiff -u -r1.11 -r1.12 src/sys/stand/efiboot/bootaa64/Makefile
cvs rdiff -u -r1.8 -r1.9 src/sys/stand/efiboot/bootarm/Makefile
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.10 src/sys/arch/aarch64/aarch64/efi_machdep.c:1.11
--- src/sys/arch/aarch64/aarch64/efi_machdep.c:1.10 Sun Mar 21 07:09:54 2021
+++ src/sys/arch/aarch64/aarch64/efi_machdep.c Sat Apr 2 11:16:06 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: efi_machdep.c,v 1.10 2021/03/21 07:09:54 skrll Exp $ */
+/* $NetBSD: efi_machdep.c,v 1.11 2022/04/02 11:16:06 skrll 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.10 2021/03/21 07:09:54 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efi_machdep.c,v 1.11 2022/04/02 11:16:06 skrll Exp $");
#include <sys/param.h>
#include <uvm/uvm_extern.h>
@@ -46,35 +46,68 @@ static struct {
bool fpu_used;
} arm_efirt_state;
+static bool efi_userva = true;
+
void
-arm_efirt_md_map_range(vaddr_t va, paddr_t pa, size_t sz, enum arm_efirt_mem_type type)
+arm_efirt_md_map_range(vaddr_t va, paddr_t pa, size_t sz,
+ enum arm_efirt_mem_type type)
{
- pt_entry_t attr;
+ int flags = 0;
+ int prot = 0;
switch (type) {
case ARM_EFIRT_MEM_CODE:
- attr = LX_BLKPAG_AF | LX_BLKPAG_AP_RW | LX_BLKPAG_UXN |
- LX_BLKPAG_ATTR_NORMAL_WB;
+ /* need write permission because fw devs */
+ prot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
break;
case ARM_EFIRT_MEM_DATA:
- attr = LX_BLKPAG_AF | LX_BLKPAG_AP_RW | LX_BLKPAG_UXN | LX_BLKPAG_PXN |
- LX_BLKPAG_ATTR_NORMAL_WB;
+ prot = VM_PROT_READ | VM_PROT_WRITE;
break;
case ARM_EFIRT_MEM_MMIO:
- attr = LX_BLKPAG_AF | LX_BLKPAG_AP_RW | LX_BLKPAG_UXN | LX_BLKPAG_PXN |
- LX_BLKPAG_ATTR_DEVICE_MEM;
+ prot = VM_PROT_READ | VM_PROT_WRITE;
+ flags = PMAP_DEV;
break;
default:
- panic("arm_efirt_md_map_range: unsupported type %d", type);
+ panic("%s: unsupported type %d", __func__, type);
+ }
+
+ /* even if TBI is disabled, AARCH64_ADDRTOP_TAG means KVA */
+ bool kva = (va & AARCH64_ADDRTOP_TAG) != 0;
+ if (kva) {
+ if (va < EFI_RUNTIME_VA ||
+ va >= EFI_RUNTIME_VA + EFI_RUNTIME_SIZE) {
+ printf("Incorrect EFI mapping address %" PRIxVADDR "\n", va);
+ return;
+ }
+ efi_userva = false;
+ } else {
+ if (!efi_userva) {
+ printf("Can't mix EFI RT address spaces\n");
+ return;
+ }
}
- pmapboot_enter(va, pa, sz, L3_SIZE, attr, NULL);
+ while (sz != 0) {
+ if (kva) {
+ pmap_kenter_pa(va, pa, prot, flags);
+ } else {
+ pmap_enter(pmap_efirt(), va, pa, prot, flags | PMAP_WIRED);
+ }
+ va += PAGE_SIZE;
+ pa += PAGE_SIZE;
+ sz -= PAGE_SIZE;
+ }
+ if (kva)
+ pmap_update(pmap_kernel());
+ else
+ pmap_update(pmap_efirt());
}
int
arm_efirt_md_enter(void)
{
struct lwp *l = curlwp;
+ int err;
/* Save FPU state */
arm_efirt_state.fpu_used = fpu_used_p(l) != 0;
@@ -89,7 +122,14 @@ arm_efirt_md_enter(void)
* Install custom fault handler. EFI lock is held across calls so
* shared faultbuf is safe here.
*/
- return cpu_set_onfault(&arm_efirt_state.faultbuf);
+ err = cpu_set_onfault(&arm_efirt_state.faultbuf);
+ if (err)
+ return err;
+
+ if (efi_userva)
+ pmap_activate_efirt();
+
+ return 0;
}
void
@@ -97,6 +137,9 @@ arm_efirt_md_exit(void)
{
struct lwp *l = curlwp;
+ if (efi_userva)
+ pmap_deactivate_efirt();
+
/* Disable FP access */
reg_cpacr_el1_write(CPACR_FPEN_NONE);
isb();
Index: src/sys/arch/aarch64/aarch64/pmap.c
diff -u src/sys/arch/aarch64/aarch64/pmap.c:1.131 src/sys/arch/aarch64/aarch64/pmap.c:1.132
--- src/sys/arch/aarch64/aarch64/pmap.c:1.131 Sat Mar 19 09:53:18 2022
+++ src/sys/arch/aarch64/aarch64/pmap.c Sat Apr 2 11:16:06 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.131 2022/03/19 09:53:18 skrll Exp $ */
+/* $NetBSD: pmap.c,v 1.132 2022/04/02 11:16:06 skrll Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -27,11 +27,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.131 2022/03/19 09:53:18 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.132 2022/04/02 11:16:06 skrll Exp $");
#include "opt_arm_debug.h"
#include "opt_cpuoptions.h"
#include "opt_ddb.h"
+#include "opt_efi.h"
#include "opt_modular.h"
#include "opt_multiprocessor.h"
#include "opt_pmap.h"
@@ -198,8 +199,16 @@ static int _pmap_get_pdp(struct pmap *,
struct vm_page **);
static struct pmap kernel_pmap __cacheline_aligned;
+static struct pmap efirt_pmap __cacheline_aligned;
struct pmap * const kernel_pmap_ptr = &kernel_pmap;
+
+pmap_t
+pmap_efirt(void)
+{
+ return &efirt_pmap;
+}
+
static vaddr_t pmap_maxkvaddr;
vaddr_t virtual_avail, virtual_end;
@@ -281,6 +290,9 @@ phys_to_pp(paddr_t pa)
#define IN_DIRECTMAP_ADDR(va) \
IN_RANGE((va), AARCH64_DIRECTMAP_START, AARCH64_DIRECTMAP_END)
+#define PMAP_EFIVA_P(va) \
+ IN_RANGE((va), EFI_RUNTIME_VA, EFI_RUNTIME_VA + EFI_RUNTIME_SIZE)
+
#ifdef MODULAR
#define IN_MODULE_VA(va) IN_RANGE((va), module_start, module_end)
#else
@@ -290,7 +302,8 @@ phys_to_pp(paddr_t pa)
#ifdef DIAGNOSTIC
#define KERNEL_ADDR_P(va) \
- IN_RANGE((va), VM_MIN_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS)
+ (IN_RANGE((va), VM_MIN_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS) || \
+ PMAP_EFIVA_P(va))
#define KASSERT_PM_ADDR(pm, va) \
do { \
@@ -492,6 +505,28 @@ pmap_bootstrap(vaddr_t vstart, vaddr_t v
CTASSERT(sizeof(kpm->pm_stats.wired_count) == sizeof(long));
CTASSERT(sizeof(kpm->pm_stats.resident_count) == sizeof(long));
+
+#if defined(EFI_RUNTIME)
+ memset(&efirt_pmap, 0, sizeof(efirt_pmap));
+ struct pmap * const efipm = &efirt_pmap;
+ struct pmap_asid_info * const efipai = PMAP_PAI(efipm, cpu_tlb_info(ci));
+
+ efipai->pai_asid = KERNEL_PID;
+ efipm->pm_refcnt = 1;
+
+ vaddr_t efi_l0va = uvm_pageboot_alloc(Ln_TABLE_SIZE);
+ KASSERT((efi_l0va & PAGE_MASK) == 0);
+
+ efipm->pm_l0table = (pd_entry_t *)efi_l0va;
+ memset(efipm->pm_l0table, 0, Ln_TABLE_SIZE);
+
+ efipm->pm_l0table_pa = AARCH64_KVA_TO_PA(efi_l0va);
+
+ efipm->pm_activated = false;
+ LIST_INIT(&efipm->pm_vmlist);
+ LIST_INIT(&efipm->pm_pvlist); /* not used for efi pmap */
+ mutex_init(&efipm->pm_lock, MUTEX_DEFAULT, IPL_NONE);
+#endif
}
#ifdef MULTIPROCESSOR
@@ -1456,6 +1491,33 @@ pmap_protect(struct pmap *pm, vaddr_t sv
pm_unlock(pm);
}
+#if defined(EFI_RUNTIME)
+void
+pmap_activate_efirt(void)
+{
+ kpreempt_disable();
+
+ struct cpu_info *ci = curcpu();
+ struct pmap *pm = &efirt_pmap;
+ struct pmap_asid_info * const pai = PMAP_PAI(pm, cpu_tlb_info(ci));
+
+ UVMHIST_FUNC(__func__);
+ UVMHIST_CALLARGS(pmaphist, " (pm=%#jx)", (uintptr_t)pm, 0, 0, 0);
+
+ ci->ci_pmap_asid_cur = pai->pai_asid;
+ UVMHIST_LOG(pmaphist, "setting asid to %#jx", pai->pai_asid,
+ 0, 0, 0);
+ tlb_set_asid(pai->pai_asid, pm);
+
+ /* Re-enable translation table walks using TTBR0 */
+ uint64_t tcr = reg_tcr_el1_read();
+ reg_tcr_el1_write(tcr & ~TCR_EPD0);
+ isb();
+ pm->pm_activated = true;
+
+ PMAP_COUNT(activate);
+}
+#endif
void
pmap_activate(struct lwp *l)
@@ -1492,6 +1554,32 @@ pmap_activate(struct lwp *l)
PMAP_COUNT(activate);
}
+#if defined(EFI_RUNTIME)
+void
+pmap_deactivate_efirt(void)
+{
+ struct cpu_info * const ci = curcpu();
+ struct pmap * const pm = &efirt_pmap;
+
+ UVMHIST_FUNC(__func__); UVMHIST_CALLED(pmaphist);
+
+ /* Disable translation table walks using TTBR0 */
+ uint64_t tcr = reg_tcr_el1_read();
+ reg_tcr_el1_write(tcr | TCR_EPD0);
+ isb();
+
+ UVMHIST_LOG(pmaphist, "setting asid to %#jx", KERNEL_PID,
+ 0, 0, 0);
+
+ ci->ci_pmap_asid_cur = KERNEL_PID;
+ tlb_set_asid(KERNEL_PID, pmap_kernel());
+
+ pm->pm_activated = false;
+
+ PMAP_COUNT(deactivate);
+}
+#endif
+
void
pmap_deactivate(struct lwp *l)
{
@@ -1607,6 +1695,12 @@ _pmap_pdp_addref(struct pmap *pm, paddr_
if (pm == pmap_kernel())
return;
+#if defined(EFI_RUNTIME)
+ /* EFI runtme L0-L3 pages will never be freed */
+ if (pm == pmap_efirt())
+ return;
+#endif
+
KASSERT(mutex_owned(&pm->pm_lock));
/* no need for L0 page */
@@ -1641,6 +1735,12 @@ _pmap_pdp_delref(struct pmap *pm, paddr_
if (pm == pmap_kernel())
return false;
+#if defined(EFI_RUNTIME)
+ /* EFI runtme L0-L3 pages will never be freed */
+ if (pm == pmap_efirt())
+ return false;
+#endif
+
KASSERT(mutex_owned(&pm->pm_lock));
/* no need for L0 page */
@@ -1722,7 +1822,8 @@ _pmap_get_pdp(struct pmap *pm, vaddr_t v
idx = l0pde_index(va);
pde = l0[idx];
if (!l0pde_valid(pde)) {
- KASSERT(!kenter || IN_MODULE_VA(va));
+ KASSERTMSG(!kenter || IN_MODULE_VA(va) || PMAP_EFIVA_P(va),
+ "%s va %" PRIxVADDR, kenter ? "kernel" : "user", va);
/* no need to increment L0 occupancy. L0 page never freed */
pdppa = pmap_alloc_pdp(pm, &pdppg, flags, false); /* L1 pdp */
if (pdppa == POOL_PADDR_INVALID) {
@@ -1739,7 +1840,8 @@ _pmap_get_pdp(struct pmap *pm, vaddr_t v
idx = l1pde_index(va);
pde = l1[idx];
if (!l1pde_valid(pde)) {
- KASSERT(!kenter || IN_MODULE_VA(va));
+ KASSERTMSG(!kenter || IN_MODULE_VA(va) || PMAP_EFIVA_P(va),
+ "%s va %" PRIxVADDR, kenter ? "kernel" : "user", va);
pdppa0 = pdppa;
pdppg0 = pdppg;
pdppa = pmap_alloc_pdp(pm, &pdppg, flags, false); /* L2 pdp */
@@ -1758,7 +1860,8 @@ _pmap_get_pdp(struct pmap *pm, vaddr_t v
idx = l2pde_index(va);
pde = l2[idx];
if (!l2pde_valid(pde)) {
- KASSERT(!kenter || IN_MODULE_VA(va));
+ KASSERTMSG(!kenter || IN_MODULE_VA(va) || PMAP_EFIVA_P(va),
+ "%s va %" PRIxVADDR, kenter ? "kernel" : "user", va);
pdppa0 = pdppa;
pdppg0 = pdppg;
pdppa = pmap_alloc_pdp(pm, &pdppg, flags, false); /* L3 pdp */
@@ -1790,7 +1893,13 @@ _pmap_enter(struct pmap *pm, vaddr_t va,
uint32_t mdattr;
unsigned int idx;
int error = 0;
- const bool user = (pm != pmap_kernel());
+#if defined(EFI_RUNTIME)
+ const bool efirt_p = pm == pmap_efirt();
+#else
+ const bool efirt_p = false;
+#endif
+ const bool kernel_p = pm == pmap_kernel();
+ const bool user = !kernel_p && !efirt_p;
bool need_sync_icache, need_enter_pv;
UVMHIST_FUNC(__func__);
@@ -2005,7 +2114,7 @@ _pmap_enter(struct pmap *pm, vaddr_t va,
attr = L3_PAGE | (kenter ? 0 : LX_BLKPAG_NG);
attr = _pmap_pte_adjust_prot(attr, prot, mdattr, user);
attr = _pmap_pte_adjust_cacheflags(attr, flags);
- if (VM_MAXUSER_ADDRESS > va)
+ if (VM_MAXUSER_ADDRESS > va && !efirt_p)
attr |= LX_BLKPAG_APUSER;
if (flags & PMAP_WIRED)
attr |= LX_BLKPAG_OS_WIRED;
Index: src/sys/arch/aarch64/include/pmap.h
diff -u src/sys/arch/aarch64/include/pmap.h:1.51 src/sys/arch/aarch64/include/pmap.h:1.52
--- src/sys/arch/aarch64/include/pmap.h:1.51 Sat Jan 15 08:14:37 2022
+++ src/sys/arch/aarch64/include/pmap.h Sat Apr 2 11:16:06 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.51 2022/01/15 08:14:37 skrll Exp $ */
+/* $NetBSD: pmap.h,v 1.52 2022/04/02 11:16:06 skrll Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -388,6 +388,11 @@ aarch64_mmap_flags(paddr_t mdpgno)
#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
+struct pmap *
+ pmap_efirt(void);
+void pmap_activate_efirt(void);
+void pmap_deactivate_efirt(void);
+
void pmap_procwr(struct proc *, vaddr_t, int);
bool pmap_extract_coherency(pmap_t, vaddr_t, paddr_t *, bool *);
void pmap_icache_sync_range(pmap_t, vaddr_t, vaddr_t);
Index: src/sys/arch/aarch64/include/vmparam.h
diff -u src/sys/arch/aarch64/include/vmparam.h:1.18 src/sys/arch/aarch64/include/vmparam.h:1.19
--- src/sys/arch/aarch64/include/vmparam.h:1.18 Sun Mar 21 07:32:44 2021
+++ src/sys/arch/aarch64/include/vmparam.h Sat Apr 2 11:16:06 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: vmparam.h,v 1.18 2021/03/21 07:32:44 skrll Exp $ */
+/* $NetBSD: vmparam.h,v 1.19 2022/04/02 11:16:06 skrll Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
* 0xffff_0000_0000_0000 - 64T direct mapping
* 0xffff_4000_0000_0000 - 32T (KASAN SHADOW MAP)
* 0xffff_6000_0000_0000 - 32T (not used)
- * 0xffff_8000_0000_0000 - 1G EFI_RUNTIME
+ * 0xffff_8000_0000_0000 - 1G (EFI_RUNTIME - legacy)
* 0xffff_8000_4000_0000 - 64T (not used)
* 0xffff_c000_0000_0000 - 64T KERNEL VM Space (including text/data/bss)
* (0xffff_c000_4000_0000 -1GB) KERNEL VM start of KVM
@@ -141,6 +141,13 @@
#define VM_MAX_KERNEL_ADDRESS ((vaddr_t) 0xffffffffffe00000L)
/*
+ * Reserved space for EFI runtime services (legacy)
+ */
+#define EFI_RUNTIME_VA 0xffff800000000000L
+#define EFI_RUNTIME_SIZE 0x0000000040000000L
+
+
+/*
* last 254MB of kernel vm area (0xfffffffff0000000-0xffffffffffe00000)
* may be used for devmap. see aarch64/pmap.c:pmap_devmap_*
*/
@@ -149,11 +156,6 @@
#define VM_KERNEL_VM_BASE (0xffffc00040000000L)
#define VM_KERNEL_VM_SIZE (VM_KERNEL_IO_ADDRESS - VM_KERNEL_VM_BASE)
-/*
- * Reserved space for EFI runtime services
- */
-#define EFI_RUNTIME_VA 0xffff800000000000L
-#define EFI_RUNTIME_SIZE 0x0000000040000000L
/* virtual sizes (bytes) for various kernel submaps */
#define USRIOSIZE (PAGE_SIZE / 8)
Index: src/sys/arch/arm/arm/efi_runtime.c
diff -u src/sys/arch/arm/arm/efi_runtime.c:1.6 src/sys/arch/arm/arm/efi_runtime.c:1.7
--- src/sys/arch/arm/arm/efi_runtime.c:1.6 Sun Oct 10 13:03:09 2021
+++ src/sys/arch/arm/arm/efi_runtime.c Sat Apr 2 11:16:06 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: efi_runtime.c,v 1.6 2021/10/10 13:03:09 jmcneill Exp $ */
+/* $NetBSD: efi_runtime.c,v 1.7 2022/04/02 11:16:06 skrll Exp $ */
/*-
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
#include "efi.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efi_runtime.c,v 1.6 2021/10/10 13:03:09 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efi_runtime.c,v 1.7 2022/04/02 11:16:06 skrll Exp $");
#include <sys/param.h>
#include <sys/mutex.h>
@@ -54,11 +54,11 @@ __KERNEL_RCSID(0, "$NetBSD: efi_runtime.
#define EFI_DEVICE_ERROR EFIERR(7)
static kmutex_t efi_lock;
-
-static struct efi_rt *RT = NULL;
+static struct efi_rt *RT;
+static struct efi_rt efi_rtcopy;
#if NEFI > 0 && BYTE_ORDER == LITTLE_ENDIAN
-static const struct efi_ops arm_efi_ops = {
+static struct efi_ops arm_efi_ops = {
.efi_gettime = arm_efirt_gettime,
.efi_settime = arm_efirt_settime,
.efi_getvar = arm_efirt_getvar,
@@ -95,10 +95,19 @@ arm_efirt_init(paddr_t efi_system_table)
return EINVAL;
}
- RT = ST->st_rt;
+ struct efi_rt *rt = ST->st_rt;
mutex_init(&efi_lock, MUTEX_DEFAULT, IPL_HIGH);
+ pmap_activate_efirt();
+
+ memcpy(&efi_rtcopy, rt, sizeof(efi_rtcopy));
+ RT = &efi_rtcopy;
+
+ pmap_deactivate_efirt();
+
+#if NEFI > 0
efi_register_ops(&arm_efi_ops);
+#endif
return 0;
#else
Index: src/sys/arch/arm/arm32/arm32_kvminit.c
diff -u src/sys/arch/arm/arm32/arm32_kvminit.c:1.68 src/sys/arch/arm/arm32/arm32_kvminit.c:1.69
--- src/sys/arch/arm/arm32/arm32_kvminit.c:1.68 Sun Mar 21 09:00:55 2021
+++ src/sys/arch/arm/arm32/arm32_kvminit.c Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: arm32_kvminit.c,v 1.68 2021/03/21 09:00:55 skrll Exp $ */
+/* $NetBSD: arm32_kvminit.c,v 1.69 2022/04/02 11:16:07 skrll Exp $ */
/*
* Copyright (c) 2002, 2003, 2005 Genetec Corporation. All rights reserved.
@@ -123,11 +123,12 @@
#include "opt_arm_debug.h"
#include "opt_arm_start.h"
+#include "opt_efi.h"
#include "opt_fdt.h"
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm32_kvminit.c,v 1.68 2021/03/21 09:00:55 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm32_kvminit.c,v 1.69 2022/04/02 11:16:07 skrll Exp $");
#include <sys/param.h>
@@ -171,6 +172,12 @@ __KERNEL_RCSID(0, "$NetBSD: arm32_kvmini
#endif
#endif
+#if defined(EFI_RUNTIME)
+#if !defined(ARM_MMU_EXTENDED)
+#error EFI_RUNTIME is only supported with ARM_MMU_EXTENDED
+#endif
+#endif
+
struct bootmem_info bootmem_info;
extern void *msgbufaddr;
@@ -389,6 +396,11 @@ valloc_pages(struct bootmem_info *bmi, p
valloc_pages(bmi, &kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE,
VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE, true);
add_pages(bmi, &kernel_l1pt);
+#if defined(EFI_RUNTIME)
+ valloc_pages(bmi, &efirt_l1pt, L1_TABLE_SIZE / PAGE_SIZE,
+ VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE, true);
+ add_pages(bmi, &efirt_l1pt);
+#endif
}
while (nbytes > free_pv->pv_size) {
@@ -544,6 +556,10 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b
kernel_l1pt.pv_pa = 0;
kernel_l1pt.pv_va = 0;
+#if defined(EFI_RUNTIME)
+ efirt_l1pt.pv_pa = 0;
+ efirt_l1pt.pv_va = 0;
+#endif
/*
* Allocate the L2 pages, but if we get to a page that is aligned for
* an L1 page table, we will allocate the pages for it first and then
@@ -972,6 +988,12 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b
kernel_l1pt.pv_pa, kernel_l1pt.pv_pa + L1_TABLE_SIZE - 1,
kernel_l1pt.pv_va, kernel_l1pt.pv_va + L1_TABLE_SIZE - 1,
L1_TABLE_SIZE / PAGE_SIZE);
+#if defined(EFI_RUNTIME)
+ VPRINTF(mem_fmt, "EFI L1 page directory",
+ efirt_l1pt.pv_pa, efirt_l1pt.pv_pa + L1_TABLE_SIZE - 1,
+ efirt_l1pt.pv_va, efirt_l1pt.pv_va + L1_TABLE_SIZE - 1,
+ L1_TABLE_SIZE / PAGE_SIZE);
+#endif
VPRINTF(mem_fmt, "ABT stack (CPU 0)",
abtstack.pv_pa, abtstack.pv_pa + (ABT_STACK_SIZE * PAGE_SIZE) - 1,
abtstack.pv_va, abtstack.pv_va + (ABT_STACK_SIZE * PAGE_SIZE) - 1,
Index: src/sys/arch/arm/arm32/locore.S
diff -u src/sys/arch/arm/arm32/locore.S:1.43 src/sys/arch/arm/arm32/locore.S:1.44
--- src/sys/arch/arm/arm32/locore.S:1.43 Fri Aug 28 13:36:52 2020
+++ src/sys/arch/arm/arm32/locore.S Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.43 2020/08/28 13:36:52 skrll Exp $ */
+/* $NetBSD: locore.S,v 1.44 2022/04/02 11:16:07 skrll Exp $ */
/*
* Copyright (C) 1994-1997 Mark Brinicombe
@@ -40,7 +40,7 @@
#include <arm/asm.h>
#include <arm/locore.h>
- RCSID("$NetBSD: locore.S,v 1.43 2020/08/28 13:36:52 skrll Exp $")
+ RCSID("$NetBSD: locore.S,v 1.44 2022/04/02 11:16:07 skrll Exp $")
/*
* This is for kvm_mkdb, and should be the address of the beginning
@@ -201,6 +201,18 @@ ENTRY_NP(cpu_reset)
END(cpu_reset)
#endif /* OFW */
+
+/*
+ * int cpu_set_onfault(struct faultbuf *fb)
+ */
+ENTRY_NP(cpu_set_onfault)
+ GET_CURPCB(r1)
+ str r0, [r1, #PCB_ONFAULT]
+ stmia r0, {r4-r14}
+ mov r0, #0
+ RET
+END(cpu_set_onfault)
+
/*
* setjump + longjmp
*/
Index: src/sys/arch/arm/arm32/pmap.c
diff -u src/sys/arch/arm/arm32/pmap.c:1.434 src/sys/arch/arm/arm32/pmap.c:1.435
--- src/sys/arch/arm/arm32/pmap.c:1.434 Sat Mar 19 09:54:25 2022
+++ src/sys/arch/arm/arm32/pmap.c Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.434 2022/03/19 09:54:25 skrll Exp $ */
+/* $NetBSD: pmap.c,v 1.435 2022/04/02 11:16:07 skrll Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@@ -184,6 +184,7 @@
#include "opt_arm_debug.h"
#include "opt_cpuoptions.h"
#include "opt_ddb.h"
+#include "opt_efi.h"
#include "opt_lockdebug.h"
#include "opt_multiprocessor.h"
@@ -192,7 +193,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.434 2022/03/19 09:54:25 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.435 2022/04/02 11:16:07 skrll Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -225,6 +226,12 @@ __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.4
#define VPRINTF(...) __nothing
#endif
+#if defined(EFI_RUNTIME)
+#if !defined(ARM_MMU_EXTENDED)
+#error EFI_RUNTIME is only supported with ARM_MMU_EXTENDED
+#endif
+#endif
+
/*
* pmap_kernel() points here
*/
@@ -238,6 +245,17 @@ static struct pmap kernel_pmap_store = {
struct pmap * const kernel_pmap_ptr = &kernel_pmap_store;
#undef pmap_kernel
#define pmap_kernel() (&kernel_pmap_store)
+
+#if defined(EFI_RUNTIME)
+static struct pmap efirt_pmap;
+
+struct pmap *
+pmap_efirt(void)
+{
+ return &efirt_pmap;
+}
+#endif
+
#ifdef PMAP_NEED_ALLOC_POOLPAGE
int arm_poolpage_vmfreelist = VM_FREELIST_DEFAULT;
#endif
@@ -760,6 +778,9 @@ pv_addrqh_t pmap_boot_freeq = SLIST_HEAD
pv_addr_t kernelpages;
pv_addr_t kernel_l1pt;
pv_addr_t systempage;
+#if defined(EFI_RUNTIME)
+pv_addr_t efirt_l1pt;
+#endif
#ifdef PMAP_CACHE_VIPT
#define PMAP_VALIDATE_MD_PAGE(md) \
@@ -3075,7 +3096,12 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
struct vm_page *pg, *opg;
u_int nflags;
u_int oflags;
- const bool kpm_p = (pm == pmap_kernel());
+ const bool kpm_p = pm == pmap_kernel();
+#if defined(EFI_RUNTIME)
+ const bool efirt_p = pm == pmap_efirt();
+#else
+ const bool efirt_p = false;
+#endif
#ifdef ARM_HAS_VBAR
const bool vector_page_p = false;
#else
@@ -3298,6 +3324,12 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
if (prot & VM_PROT_WRITE)
npte = l2pte_set_writable(npte);
+ if (efirt_p) {
+ if (prot & VM_PROT_EXECUTE) {
+ npte &= ~L2_XS_XN; /* and executable */
+ }
+ }
+
/*
* Make sure the vector table is mapped cacheable
*/
@@ -3357,6 +3389,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
* If exec protection was requested but the page hasn't been synced,
* sync it now and allow execution from it.
*/
+
if ((nflags & PVF_EXEC) && (npte & L2_XS_XN)) {
struct vm_page_md *md = VM_PAGE_TO_MD(pg);
npte &= ~L2_XS_XN;
@@ -4948,6 +4981,53 @@ pmap_md_pdetab_deactivate(pmap_t pm)
}
#endif
+
+#if defined(EFI_RUNTIME)
+void
+pmap_activate_efirt(void)
+{
+ kpreempt_disable();
+
+ struct cpu_info * const ci = curcpu();
+ struct pmap * const pm = &efirt_pmap;
+ struct pmap_asid_info * const pai = PMAP_PAI(pm, cpu_tlb_info(ci));
+
+ UVMHIST_FUNC(__func__);
+ UVMHIST_CALLARGS(maphist, " (pm=%#jx)", (uintptr_t)pm, 0, 0, 0);
+
+ PMAPCOUNT(activations);
+
+ /*
+ * Assume that TTBR1 has only global mappings and TTBR0 only
+ * has non-global mappings. To prevent speculation from doing
+ * evil things we disable translation table walks using TTBR0
+ * before setting the CONTEXTIDR (ASID) or new TTBR0 value.
+ * Once both are set, table walks are reenabled.
+ */
+ const uint32_t old_ttbcr = armreg_ttbcr_read();
+ armreg_ttbcr_write(old_ttbcr | TTBCR_S_PD0);
+ isb();
+
+ armreg_contextidr_write(pai->pai_asid);
+ armreg_ttbr_write(pm->pm_l1_pa |
+ (ci->ci_mpidr ? TTBR_MPATTR : TTBR_UPATTR));
+ /*
+ * Now we can reenable tablewalks since the CONTEXTIDR and TTRB0
+ * have been updated.
+ */
+ isb();
+
+ armreg_ttbcr_write(old_ttbcr & ~TTBCR_S_PD0);
+
+ ci->ci_pmap_asid_cur = pai->pai_asid;
+ ci->ci_pmap_cur = pm;
+
+ UVMHIST_LOG(maphist, " <-- done", 0, 0, 0, 0);
+}
+
+#endif
+
+
void
pmap_activate(struct lwp *l)
{
@@ -5106,6 +5186,7 @@ pmap_activate(struct lwp *l)
UVMHIST_LOG(maphist, " <-- done", 0, 0, 0, 0);
}
+
void
pmap_deactivate(struct lwp *l)
{
@@ -5131,6 +5212,35 @@ pmap_deactivate(struct lwp *l)
UVMHIST_LOG(maphist, " <-- done", 0, 0, 0, 0);
}
+
+#if defined(EFI_RUNTIME)
+void
+pmap_deactivate_efirt(void)
+{
+ UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
+
+ struct cpu_info * const ci = curcpu();
+
+ /*
+ * Disable translation table walks from TTBR0 while no pmap has been
+ * activated.
+ */
+ const uint32_t old_ttbcr = armreg_ttbcr_read();
+ armreg_ttbcr_write(old_ttbcr | TTBCR_S_PD0);
+ isb();
+
+ armreg_contextidr_write(KERNEL_PID);
+ isb();
+
+ KASSERTMSG(ci->ci_pmap_asid_cur == KERNEL_PID, "ci_pmap_asid_cur %u",
+ ci->ci_pmap_asid_cur);
+ kpreempt_enable();
+
+ UVMHIST_LOG(maphist, " <-- done", 0, 0, 0, 0);
+}
+#endif
+
+
void
pmap_update(pmap_t pm)
{
@@ -6245,6 +6355,27 @@ pmap_bootstrap(vaddr_t vstart, vaddr_t v
#endif
mutex_init(&pm->pm_lock, MUTEX_DEFAULT, IPL_VM);
+
+#if defined(EFI_RUNTIME)
+ VPRINTF("efirt ");
+ memset(&efirt_pmap, 0, sizeof(efirt_pmap));
+ struct pmap * const efipm = &efirt_pmap;
+ struct pmap_asid_info * const efipai = PMAP_PAI(efipm, cpu_tlb_info(curcpu()));
+
+ efipai->pai_asid = KERNEL_PID;
+ efipm->pm_refs = 1;
+ efipm->pm_stats.wired_count = 0;
+ efipm->pm_stats.resident_count = 1;
+ efipm->pm_l1 = (pd_entry_t *)efirt_l1pt.pv_va;
+ efipm->pm_l1_pa = efirt_l1pt.pv_pa;
+ // Needed?
+#ifdef MULTIPROCESSOR
+ kcpuset_create(&efipm->pm_active, true);
+ kcpuset_create(&efipm->pm_onproc, true);
+#endif
+ mutex_init(&efipm->pm_lock, MUTEX_DEFAULT, IPL_VM);
+#endif
+
VPRINTF("locks ");
/*
* pmap_kenter_pa() and pmap_kremove() may be called from interrupt
@@ -6338,6 +6469,13 @@ pmap_bootstrap(vaddr_t vstart, vaddr_t v
printf("pmap_bootstrap: WARNING! wrong cache mode for "
"primary L1 @ 0x%lx\n", kernel_l1pt.pv_va);
}
+#if defined(EFI_RUNTIME)
+ if (pmap_set_pt_cache_mode(l1pt, efirt_l1pt.pv_va,
+ L1_TABLE_SIZE / L2_S_SIZE)) {
+ printf("pmap_bootstrap: WARNING! wrong cache mode for "
+ "EFI RT L1 @ 0x%lx\n", efirt_l1pt.pv_va);
+ }
+#endif
#ifdef PMAP_CACHE_VIVT
cpu_dcache_wbinv_all();
Index: src/sys/arch/arm/conf/files.arm
diff -u src/sys/arch/arm/conf/files.arm:1.165 src/sys/arch/arm/conf/files.arm:1.166
--- src/sys/arch/arm/conf/files.arm:1.165 Fri Aug 6 19:38:53 2021
+++ src/sys/arch/arm/conf/files.arm Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-# $NetBSD: files.arm,v 1.165 2021/08/06 19:38:53 jmcneill Exp $
+# $NetBSD: files.arm,v 1.166 2022/04/02 11:16:07 skrll Exp $
# temporary define to allow easy moving to ../arch/arm/arm32
defflag ARM32
@@ -208,9 +208,14 @@ file arch/arm/arm/procfs_machdep.c proc
file arch/arm/arm/sig_machdep.c
file arch/arm/arm/sigcode.S
file arch/arm/arm/syscall.c
+file arch/arm/arm/trap.c
file arch/arm/arm/undefined.c
file arch/arm/arm/vectors.S arm32
+# EFI runtime (machdep)
+file arch/arm/arm/efi_machdep.c efi_runtime
+
+
# files common to arm32 implementations
file arch/arm/arm32/arm32_machdep.c arm32
file arch/arm/arm32/bus_dma.c arm32
Index: src/sys/arch/arm/include/asan.h
diff -u src/sys/arch/arm/include/asan.h:1.7 src/sys/arch/arm/include/asan.h:1.8
--- src/sys/arch/arm/include/asan.h:1.7 Wed Jan 27 08:40:32 2021
+++ src/sys/arch/arm/include/asan.h Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: asan.h,v 1.7 2021/01/27 08:40:32 skrll Exp $ */
+/* $NetBSD: asan.h,v 1.8 2022/04/02 11:16:07 skrll Exp $ */
/*
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -29,6 +29,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_efi.h"
+
#include <sys/atomic.h>
#include <sys/ksyms.h>
Index: src/sys/arch/arm/include/frame.h
diff -u src/sys/arch/arm/include/frame.h:1.22 src/sys/arch/arm/include/frame.h:1.23
--- src/sys/arch/arm/include/frame.h:1.22 Wed Oct 6 05:29:32 2021
+++ src/sys/arch/arm/include/frame.h Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: frame.h,v 1.22 2021/10/06 05:29:32 skrll Exp $ */
+/* $NetBSD: frame.h,v 1.23 2022/04/02 11:16:07 skrll Exp $ */
/*
* Copyright (c) 1994-1997 Mark Brinicombe.
@@ -81,6 +81,22 @@ typedef struct trapframe {
#define TRAP_USERMODE(tf) (((tf)->tf_spsr & PSR_MODE) == PSR_USR32_MODE)
+#define FB_R4 0
+#define FB_R5 1
+#define FB_R6 2
+#define FB_R7 3
+#define FB_R8 4
+#define FB_R9 5
+#define FB_R10 6
+#define FB_R11 7
+#define FB_R12 8
+#define FB_R13 9
+#define FB_R14 10
+#define FB_MAX 11
+struct faultbuf {
+ register_t fb_reg[FB_MAX];
+};
+
/*
* Signal frame. Pushed onto user stack before calling sigcode.
*/
Index: src/sys/arch/arm/include/arm32/machdep.h
diff -u src/sys/arch/arm/include/arm32/machdep.h:1.35 src/sys/arch/arm/include/arm32/machdep.h:1.36
--- src/sys/arch/arm/include/arm32/machdep.h:1.35 Fri Aug 28 13:36:52 2020
+++ src/sys/arch/arm/include/arm32/machdep.h Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.h,v 1.35 2020/08/28 13:36:52 skrll Exp $ */
+/* $NetBSD: machdep.h,v 1.36 2022/04/02 11:16:07 skrll Exp $ */
#ifndef _ARM32_MACHDEP_H_
#define _ARM32_MACHDEP_H_
@@ -110,6 +110,31 @@ void set_spl_masks(void);
void dump_spl_masks(void);
#endif
+/* cpu_onfault */
+int cpu_set_onfault(struct faultbuf *) __returns_twice;
+void cpu_jump_onfault(struct trapframe *, const struct faultbuf *, int);
+
+static inline void
+cpu_unset_onfault(void)
+{
+ curpcb->pcb_onfault = NULL;
+}
+
+static inline void
+cpu_enable_onfault(struct faultbuf *fb)
+{
+ curpcb->pcb_onfault = fb;
+}
+
+static inline struct faultbuf *
+cpu_disable_onfault(void)
+{
+ struct faultbuf * const fb = curpcb->pcb_onfault;
+ if (fb != NULL)
+ curpcb->pcb_onfault = NULL;
+ return fb;
+}
+
#endif /* _KERNEL */
#endif /* _ARM32_MACHDEP_H_ */
Index: src/sys/arch/arm/include/arm32/pmap.h
diff -u src/sys/arch/arm/include/arm32/pmap.h:1.172 src/sys/arch/arm/include/arm32/pmap.h:1.173
--- src/sys/arch/arm/include/arm32/pmap.h:1.172 Sat Jan 15 08:14:37 2022
+++ src/sys/arch/arm/include/arm32/pmap.h Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.172 2022/01/15 08:14:37 skrll Exp $ */
+/* $NetBSD: pmap.h,v 1.173 2022/04/02 11:16:07 skrll Exp $ */
/*
* Copyright (c) 2002, 2003 Wasabi Systems, Inc.
@@ -286,6 +286,9 @@ extern pv_addr_t undstack;
extern pv_addr_t idlestack;
extern pv_addr_t systempage;
extern pv_addr_t kernel_l1pt;
+#if defined(EFI_RUNTIME)
+extern pv_addr_t efirt_l1pt;
+#endif
#ifdef ARM_MMU_EXTENDED
extern bool arm_has_tlbiasid_p; /* also in <arm/locore.h> */
@@ -386,6 +389,8 @@ void pmap_prefer(vaddr_t, vaddr_t *, int
#ifdef ARM_MMU_EXTENDED
int pmap_maxproc_set(int);
+struct pmap *
+ pmap_efirt(void);
#endif
void pmap_icache_sync_range(pmap_t, vaddr_t, vaddr_t);
@@ -398,6 +403,11 @@ vaddr_t pmap_steal_memory(vsize_t, vaddr
#endif
void pmap_bootstrap(vaddr_t, vaddr_t);
+struct pmap *
+ pmap_efirt(void);
+void pmap_activate_efirt(void);
+void pmap_deactivate_efirt(void);
+
void pmap_do_remove(pmap_t, vaddr_t, vaddr_t, int);
int pmap_fault_fixup(pmap_t, vaddr_t, vm_prot_t, int);
int pmap_prefetchabt_fixup(void *);
Index: src/sys/arch/evbarm/conf/GENERIC
diff -u src/sys/arch/evbarm/conf/GENERIC:1.106 src/sys/arch/evbarm/conf/GENERIC:1.107
--- src/sys/arch/evbarm/conf/GENERIC:1.106 Mon Mar 21 09:20:04 2022
+++ src/sys/arch/evbarm/conf/GENERIC Sat Apr 2 11:16:07 2022
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC,v 1.106 2022/03/21 09:20:04 jmcneill Exp $
+# $NetBSD: GENERIC,v 1.107 2022/04/02 11:16:07 skrll Exp $
#
# GENERIC ARM (aarch32) kernel
#
@@ -109,6 +109,10 @@ makeoptions COPY_SYMTAB=1
config netbsd root on ? type ?
+# EFI runtime support
+options EFI_RUNTIME
+#pseudo-device efi # /dev/efi
+
# Device tree support
armfdt0 at root
simplebus* at fdt? pass 0
Index: src/sys/arch/evbarm/fdt/fdt_machdep.c
diff -u src/sys/arch/evbarm/fdt/fdt_machdep.c:1.90 src/sys/arch/evbarm/fdt/fdt_machdep.c:1.91
--- src/sys/arch/evbarm/fdt/fdt_machdep.c:1.90 Sat Mar 19 13:51:35 2022
+++ src/sys/arch/evbarm/fdt/fdt_machdep.c Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_machdep.c,v 1.90 2022/03/19 13:51:35 hannken Exp $ */
+/* $NetBSD: fdt_machdep.c,v 1.91 2022/04/02 11:16:07 skrll Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.90 2022/03/19 13:51:35 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.91 2022/04/02 11:16:07 skrll Exp $");
#include "opt_arm_debug.h"
#include "opt_bootconfig.h"
@@ -613,12 +613,6 @@ initarm(void *arg)
VPRINTF("%s: fdt_build_bootconfig\n", __func__);
fdt_build_bootconfig(memory_start, memory_end);
-#ifdef EFI_RUNTIME
- fdt_map_efi_runtime("netbsd,uefi-runtime-code", ARM_EFIRT_MEM_CODE);
- fdt_map_efi_runtime("netbsd,uefi-runtime-data", ARM_EFIRT_MEM_DATA);
- fdt_map_efi_runtime("netbsd,uefi-runtime-mmio", ARM_EFIRT_MEM_MMIO);
-#endif
-
/* Perform PT build and VM init */
cpu_kernel_vm_init(memory_start, memory_size);
@@ -722,6 +716,11 @@ consinit(void)
void
cpu_startup_hook(void)
{
+#ifdef EFI_RUNTIME
+ fdt_map_efi_runtime("netbsd,uefi-runtime-code", ARM_EFIRT_MEM_CODE);
+ fdt_map_efi_runtime("netbsd,uefi-runtime-data", ARM_EFIRT_MEM_DATA);
+ fdt_map_efi_runtime("netbsd,uefi-runtime-mmio", ARM_EFIRT_MEM_MMIO);
+#endif
fdtbus_intr_init();
Index: src/sys/stand/efiboot/version
diff -u src/sys/stand/efiboot/version:1.30 src/sys/stand/efiboot/version:1.31
--- src/sys/stand/efiboot/version:1.30 Fri Mar 25 21:23:00 2022
+++ src/sys/stand/efiboot/version Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.30 2022/03/25 21:23:00 jmcneill Exp $
+$NetBSD: version,v 1.31 2022/04/02 11:16:07 skrll Exp $
NOTE ANY CHANGES YOU MAKE TO THE EFI BOOTLOADER HERE. The format of this
file is important - make sure the entries are appended on end, last item
@@ -33,3 +33,4 @@ is taken as the current.
2.10: Use disk I/O protocol for block devices.
2.11: Add support for changing the video mode.
2.12: Add userconf support.
+2.13: Add Arm RT support and change Arm64 (aarch64) RT VAs.
Index: src/sys/stand/efiboot/bootaa64/Makefile
diff -u src/sys/stand/efiboot/bootaa64/Makefile:1.11 src/sys/stand/efiboot/bootaa64/Makefile:1.12
--- src/sys/stand/efiboot/bootaa64/Makefile:1.11 Wed Oct 6 10:13:19 2021
+++ src/sys/stand/efiboot/bootaa64/Makefile Sat Apr 2 11:16:07 2022
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.11 2021/10/06 10:13:19 jmcneill Exp $
+# $NetBSD: Makefile,v 1.12 2022/04/02 11:16:07 skrll Exp $
PROG= bootaa64.efi
OBJFMT= binary
@@ -16,8 +16,8 @@ EXTRA_SOURCES+= cache.S
COPTS+= -mgeneral-regs-only -mlittle-endian -fno-jump-tables
AFLAGS+= -mlittle-endian
CFLAGS+= -DEFIBOOT_ALIGN=0x200000
-CFLAGS+= -DEFIBOOT_RUNTIME_ADDRESS=0xffff800000000000L
-CFLAGS+= -DEFIBOOT_RUNTIME_SIZE=0x40000000UL
+CFLAGS+= -DEFIBOOT_RUNTIME_ADDRESS=0x0000000200200000UL
+CFLAGS+= -DEFIBOOT_RUNTIME_SIZE=0xfe00000UL
CFLAGS+= -DEFIBOOT_MODULE_MACHINE=\"evbarm\"
LDFLAGS+= -EL
Index: src/sys/stand/efiboot/bootarm/Makefile
diff -u src/sys/stand/efiboot/bootarm/Makefile:1.8 src/sys/stand/efiboot/bootarm/Makefile:1.9
--- src/sys/stand/efiboot/bootarm/Makefile:1.8 Wed Oct 6 10:15:20 2021
+++ src/sys/stand/efiboot/bootarm/Makefile Sat Apr 2 11:16:08 2022
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.8 2021/10/06 10:15:20 jmcneill Exp $
+# $NetBSD: Makefile,v 1.9 2022/04/02 11:16:08 skrll Exp $
PROG= bootarm.efi
OBJFMT= binary
@@ -16,7 +16,10 @@ COPTS+= -mfloat-abi=soft -mno-unaligned
COPTS+= -ffreestanding -fno-unwind-tables
AFLAGS+= -mlittle-endian
CFLAGS+= -DEFIBOOT_ALIGN=0x1000000
+CFLAGS+= -DEFIBOOT_RUNTIME_ADDRESS=0x00010000U
+CFLAGS+= -DEFIBOOT_RUNTIME_SIZE=0x7ff0000U
CFLAGS+= -DEFIBOOT_MODULE_MACHINE=\"evbarm\"
+#CPPFLAGS.efifdt.c+= -Wconversion
LDFLAGS+= -N -EL
.include "${.CURDIR}/../Makefile.efiboot"
Added files:
Index: src/sys/arch/arm/arm/efi_machdep.c
diff -u /dev/null src/sys/arch/arm/arm/efi_machdep.c:1.1
--- /dev/null Sat Apr 2 11:16:08 2022
+++ src/sys/arch/arm/arm/efi_machdep.c Sat Apr 2 11:16:06 2022
@@ -0,0 +1,123 @@
+/* $NetBSD: efi_machdep.c,v 1.1 2022/04/02 11:16:06 skrll Exp $ */
+
+/*-
+ * Copyright (c) 2018 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jared McNeill <[email protected]> and Nick Hudson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: efi_machdep.c,v 1.1 2022/04/02 11:16:06 skrll Exp $");
+
+#include <sys/param.h>
+#include <uvm/uvm_extern.h>
+
+#include <arm/vfpreg.h>
+
+#include <arm/arm/efi_runtime.h>
+
+#include <arm/arm32/machdep.h>
+
+static struct {
+ struct faultbuf aert_faultbuf;
+ uint32_t aert_tpidrprw;
+ uint32_t aert_fpexc;
+} arm_efirt_state;
+
+int
+arm_efirt_md_enter(void)
+{
+ arm_efirt_state.aert_tpidrprw = armreg_tpidrprw_read();
+
+ /* Disable the VFP. */
+ arm_efirt_state.aert_fpexc = armreg_fpexc_read();
+ armreg_fpexc_write(arm_efirt_state.aert_fpexc & ~VFP_FPEXC_EN);
+ isb();
+
+ /*
+ * Install custom fault handler. EFI lock is held across calls so
+ * shared faultbuf is safe here.
+ */
+ int err = cpu_set_onfault(&arm_efirt_state.aert_faultbuf);
+ if (err)
+ return err;
+
+ pmap_activate_efirt();
+
+ return 0;
+}
+
+void
+arm_efirt_md_exit(void)
+{
+ pmap_deactivate_efirt();
+
+ armreg_tpidrprw_write(arm_efirt_state.aert_tpidrprw);
+
+ /* Restore FP access (if it existed) */
+ armreg_fpexc_write(arm_efirt_state.aert_fpexc);
+ isb();
+
+ /* Remove custom fault handler */
+ cpu_unset_onfault();
+}
+
+
+void
+arm_efirt_md_map_range(vaddr_t va, paddr_t pa, size_t sz,
+ enum arm_efirt_mem_type type)
+{
+ int flags = 0;
+ int prot = 0;
+
+ switch (type) {
+ case ARM_EFIRT_MEM_CODE:
+ /* need write permission because fw devs */
+ prot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
+ break;
+ case ARM_EFIRT_MEM_DATA:
+ prot = VM_PROT_READ | VM_PROT_WRITE;
+ break;
+ case ARM_EFIRT_MEM_MMIO:
+ prot = VM_PROT_READ | VM_PROT_WRITE;
+ flags = PMAP_DEV;
+ break;
+ default:
+ panic("%s: unsupported type %d", __func__, type);
+ }
+ if (va >= VM_MAXUSER_ADDRESS || va >= VM_MAXUSER_ADDRESS - sz) {
+ printf("Incorrect EFI mapping range %" PRIxVADDR
+ "- %" PRIxVADDR "\n", va, va + sz);
+ }
+
+ while (sz != 0) {
+ pmap_enter(pmap_efirt(), va, pa, prot, flags | PMAP_WIRED);
+ va += PAGE_SIZE;
+ pa += PAGE_SIZE;
+ sz -= PAGE_SIZE;
+ }
+ pmap_update(pmap_efirt());
+}
Index: src/sys/arch/arm/arm/trap.c
diff -u /dev/null src/sys/arch/arm/arm/trap.c:1.1
--- /dev/null Sat Apr 2 11:16:08 2022
+++ src/sys/arch/arm/arm/trap.c Sat Apr 2 11:16:06 2022
@@ -0,0 +1,61 @@
+/* $NetBSD: trap.c,v 1.1 2022/04/02 11:16:06 skrll Exp $ */
+
+/*-
+ * Copyright (c) 2022 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nick Hudson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.1 2022/04/02 11:16:06 skrll Exp $");
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <arm/frame.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <arm/arm32/pmap.h>
+#include <arm/arm32/machdep.h>
+
+void
+cpu_jump_onfault(struct trapframe *tf, const struct faultbuf *fb, int val)
+{
+ tf->tf_r4 = fb->fb_reg[FB_R4];
+ tf->tf_r5 = fb->fb_reg[FB_R5];
+ tf->tf_r6 = fb->fb_reg[FB_R6];
+ tf->tf_r7 = fb->fb_reg[FB_R7];
+ tf->tf_r8 = fb->fb_reg[FB_R8];
+ tf->tf_r9 = fb->fb_reg[FB_R9];
+ tf->tf_r10 = fb->fb_reg[FB_R10];
+ tf->tf_r11 = fb->fb_reg[FB_R11];
+ tf->tf_r12 = fb->fb_reg[FB_R12];
+ tf->tf_svc_sp = fb->fb_reg[FB_R13];
+ tf->tf_pc = fb->fb_reg[FB_R14];
+ tf->tf_r0 = val;
+}
+