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) \