Index: sys/riscv/include/machdep.h =================================================================== --- sys/riscv/include/machdep.h +++ 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: sys/riscv/include/metadata.h =================================================================== --- sys/riscv/include/metadata.h +++ sys/riscv/include/metadata.h @@ -1,14 +1,7 @@ /*- - * Copyright (c) 2015-2017 Ruslan Bukin - * All rights reserved. + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * - * Portions of this software were developed by SRI International and the - * University of Cambridge Computer Laboratory under DARPA/AFRL contract - * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. - * - * Portions of this software were developed by the University of Cambridge - * Computer Laboratory as part of the CTSRD Project, with support from the - * UK Higher Education Innovation Fund (HEIF). + * Copyright (c) 2020 Mitchell Horne * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,21 +27,9 @@ * $FreeBSD$ */ -#ifndef _MACHINE_MACHDEP_H_ -#define _MACHINE_MACHDEP_H_ - -struct riscv_bootparams { - vm_offset_t kern_l1pt; /* Kernel L1 base */ - 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[]; -extern u_int physmap_idx; +#ifndef _MACHINE_METADATA_H_ +#define _MACHINE_METADATA_H_ -vm_offset_t fake_preload_metadata(struct riscv_bootparams *rbp); -void initriscv(struct riscv_bootparams *); +#define MODINFOMD_DTBP 0x1001 -#endif /* _MACHINE_MACHDEP_H_ */ +#endif /* !_MACHINE_METADATA_H_ */ Index: sys/riscv/include/vmparam.h =================================================================== --- sys/riscv/include/vmparam.h +++ 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: sys/riscv/riscv/genassym.c =================================================================== --- sys/riscv/riscv/genassym.c +++ 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: sys/riscv/riscv/locore.S =================================================================== --- sys/riscv/riscv/locore.S +++ 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: sys/riscv/riscv/machdep.c =================================================================== --- sys/riscv/riscv/machdep.c +++ 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: sys/riscv/riscv/pmap.c =================================================================== --- sys/riscv/riscv/pmap.c +++ 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); @@ -610,6 +611,15 @@ 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(); #define alloc_pages(var, np) \