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 <r...@nerv.org> @@ -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 <jmcne...@invisible.ca> @@ -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 <jmcne...@invisible.ca> 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; +} +