Index: head/sys/riscv/include/machdep.h =================================================================== --- head/sys/riscv/include/machdep.h +++ head/sys/riscv/include/machdep.h @@ -42,7 +42,6 @@ vm_offset_t kern_phys; /* Kernel base (physical) addr */ vm_offset_t kern_stack; vm_offset_t dtbp_virt; /* Device tree blob virtual addr */ - vm_offset_t dtbp_phys; /* Device tree blob physical addr */ }; extern vm_paddr_t physmap[]; Index: head/sys/riscv/include/metadata.h =================================================================== --- head/sys/riscv/include/metadata.h +++ head/sys/riscv/include/metadata.h @@ -0,0 +1,35 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 Mitchell Horne + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_METADATA_H_ +#define _MACHINE_METADATA_H_ + +#define MODINFOMD_DTBP 0x1001 + +#endif /* !_MACHINE_METADATA_H_ */ Index: head/sys/riscv/include/vmparam.h =================================================================== --- head/sys/riscv/include/vmparam.h +++ head/sys/riscv/include/vmparam.h @@ -192,6 +192,8 @@ #define KERNENTRY (0) +#define VM_EARLY_DTB_ADDRESS (VM_MAX_KERNEL_ADDRESS - (2 * L2_SIZE)) + /* * How many physical pages per kmem arena virtual page. */ Index: head/sys/riscv/riscv/genassym.c =================================================================== --- head/sys/riscv/riscv/genassym.c +++ head/sys/riscv/riscv/genassym.c @@ -56,10 +56,12 @@ #include #include #include +#include ASSYM(KERNBASE, KERNBASE); ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); ASSYM(VM_MAX_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS); +ASSYM(VM_EARLY_DTB_ADDRESS, VM_EARLY_DTB_ADDRESS); ASSYM(TDF_ASTPENDING, TDF_ASTPENDING); ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); @@ -104,4 +106,3 @@ ASSYM(RISCV_BOOTPARAMS_KERN_STACK, offsetof(struct riscv_bootparams, kern_stack)); ASSYM(RISCV_BOOTPARAMS_DTBP_VIRT, offsetof(struct riscv_bootparams, dtbp_virt)); -ASSYM(RISCV_BOOTPARAMS_DTBP_PHYS, offsetof(struct riscv_bootparams, dtbp_phys)); Index: head/sys/riscv/riscv/locore.S =================================================================== --- head/sys/riscv/riscv/locore.S +++ head/sys/riscv/riscv/locore.S @@ -217,9 +217,8 @@ la t0, initstack sd t0, RISCV_BOOTPARAMS_KERN_STACK(sp) - li t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE) + li t0, (VM_EARLY_DTB_ADDRESS) sd t0, RISCV_BOOTPARAMS_DTBP_VIRT(sp) - sd a1, RISCV_BOOTPARAMS_DTBP_PHYS(sp) mv a0, sp call _C_LABEL(initriscv) /* Off we go */ Index: head/sys/riscv/riscv/machdep.c =================================================================== --- head/sys/riscv/riscv/machdep.c +++ head/sys/riscv/riscv/machdep.c @@ -81,6 +81,7 @@ #include #include #include +#include #include #include #include @@ -93,6 +94,7 @@ #endif #ifdef FDT +#include #include #include #endif @@ -741,11 +743,19 @@ #ifdef FDT static void -try_load_dtb(caddr_t kmdp, vm_offset_t dtbp) +try_load_dtb(caddr_t kmdp) { + vm_offset_t dtbp; + dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); + #if defined(FDT_DTB_STATIC) - dtbp = (vm_offset_t)&fdt_static_dtb; + /* + * In case the device tree blob was not retrieved (from metadata) try + * to use the statically embedded one. + */ + if (dtbp == (vm_offset_t)NULL) + dtbp = (vm_offset_t)&fdt_static_dtb; #endif if (dtbp == (vm_offset_t)NULL) { @@ -777,13 +787,14 @@ * RISCVTODO: This needs to be done via loader (when it's available). */ vm_offset_t -fake_preload_metadata(struct riscv_bootparams *rvbp __unused) +fake_preload_metadata(struct riscv_bootparams *rvbp) { static uint32_t fake_preload[35]; #ifdef DDB vm_offset_t zstart = 0, zend = 0; #endif vm_offset_t lastaddr; + size_t dtb_size; int i; i = 0; @@ -824,10 +835,23 @@ #endif #endif lastaddr = (vm_offset_t)&end; + + /* Copy the DTB to KVA space. */ + lastaddr = roundup(lastaddr, sizeof(int)); + fake_preload[i++] = MODINFO_METADATA | MODINFOMD_DTBP; + fake_preload[i++] = sizeof(vm_offset_t); + *(vm_offset_t *)&fake_preload[i] = (vm_offset_t)lastaddr; + i += sizeof(vm_offset_t) / sizeof(uint32_t); + dtb_size = fdt_totalsize(rvbp->dtbp_virt); + memmove((void *)lastaddr, (const void *)rvbp->dtbp_virt, dtb_size); + lastaddr = roundup(lastaddr + dtb_size, sizeof(int)); + fake_preload[i++] = 0; fake_preload[i] = 0; preload_metadata = (void *)fake_preload; + KASSERT(i < nitems(fake_preload), ("Too many fake_preload items")); + return (lastaddr); } @@ -836,8 +860,6 @@ { struct mem_region mem_regions[FDT_MEM_REGIONS]; struct pcpu *pcpup; - vm_offset_t rstart, rend; - vm_offset_t s, e; int mem_regions_sz; vm_offset_t lastaddr; vm_size_t kernlen; @@ -873,7 +895,7 @@ kern_envp = NULL; #ifdef FDT - try_load_dtb(kmdp, rvbp->dtbp_virt); + try_load_dtb(kmdp); #endif /* Load the physical memory ranges */ @@ -884,21 +906,9 @@ if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, NULL) != 0) panic("Cannot get physical memory regions"); - s = rvbp->dtbp_phys; - e = s + DTB_SIZE_MAX; - for (i = 0; i < mem_regions_sz; i++) { - rstart = mem_regions[i].mr_start; - rend = (mem_regions[i].mr_start + mem_regions[i].mr_size); - - if ((rstart < s) && (rend > e)) { - /* Exclude DTB region. */ - add_physmap_entry(rstart, (s - rstart), physmap, &physmap_idx); - add_physmap_entry(e, (rend - e), physmap, &physmap_idx); - } else { - add_physmap_entry(mem_regions[i].mr_start, - mem_regions[i].mr_size, physmap, &physmap_idx); - } + add_physmap_entry(mem_regions[i].mr_start, + mem_regions[i].mr_size, physmap, &physmap_idx); } #endif Index: head/sys/riscv/riscv/pmap.c =================================================================== --- head/sys/riscv/riscv/pmap.c +++ head/sys/riscv/riscv/pmap.c @@ -558,6 +558,7 @@ vm_offset_t freemempos; vm_offset_t dpcpu, msgbufpv; vm_paddr_t end, max_pa, min_pa, pa, start; + pt_entry_t *l2p; int i; printf("pmap_bootstrap %lx %lx %lx\n", l1pt, kernstart, kernlen); @@ -609,6 +610,15 @@ /* Create the l3 tables for the early devmap */ freemempos = pmap_bootstrap_l3(l1pt, VM_MAX_KERNEL_ADDRESS - L2_SIZE, freemempos); + + /* + * Invalidate the mapping we created for the DTB. At this point a copy + * has been created, and we no longer need it. We want to avoid the + * possibility of an aliased mapping in the future. + */ + l2p = pmap_l2(kernel_pmap, VM_EARLY_DTB_ADDRESS); + KASSERT((pmap_load(l2p) & PTE_V) != 0, ("dtpb not mapped")); + pmap_clear(l2p); sfence_vma();