svn commit: r359673 - in head/sys/riscv: include riscv

Mitchell Horne mhorne at FreeBSD.org
Mon Apr 6 22:48:45 UTC 2020


Author: mhorne
Date: Mon Apr  6 22:48:43 2020
New Revision: 359673
URL: https://svnweb.freebsd.org/changeset/base/359673

Log:
  RISC-V: copy the DTB to early KVA
  
  The location of the device-tree blob is passed to the kernel by the
  previous booting stage (i.e. BBL or OpenSBI). Currently, we leave it
  untouched and mark the 1MB of memory holding it as unavailable.
  
  Instead, do what is done by other fake_preload_metadata() routines and
  copy to the DTB to KVA space. This is more in line with what loader(8)
  will provide us in the future, and it allows us to reclaim the hole in
  physical memory.
  
  Reviewed by:	markj, kp (earlier version)
  Differential Revision:	https://reviews.freebsd.org/D24152

Added:
  head/sys/riscv/include/metadata.h   (contents, props changed)
Modified:
  head/sys/riscv/include/machdep.h
  head/sys/riscv/include/vmparam.h
  head/sys/riscv/riscv/genassym.c
  head/sys/riscv/riscv/locore.S
  head/sys/riscv/riscv/machdep.c
  head/sys/riscv/riscv/pmap.c

Modified: head/sys/riscv/include/machdep.h
==============================================================================
--- head/sys/riscv/include/machdep.h	Mon Apr  6 22:31:30 2020	(r359672)
+++ head/sys/riscv/include/machdep.h	Mon Apr  6 22:48:43 2020	(r359673)
@@ -42,7 +42,6 @@ struct riscv_bootparams {
 	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[];

Added: head/sys/riscv/include/metadata.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/riscv/include/metadata.h	Mon Apr  6 22:48:43 2020	(r359673)
@@ -0,0 +1,35 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Mitchell Horne <mhorne at FreeBSD.org>
+ *
+ * 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_ */

Modified: head/sys/riscv/include/vmparam.h
==============================================================================
--- head/sys/riscv/include/vmparam.h	Mon Apr  6 22:31:30 2020	(r359672)
+++ head/sys/riscv/include/vmparam.h	Mon Apr  6 22:48:43 2020	(r359673)
@@ -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.
  */

Modified: head/sys/riscv/riscv/genassym.c
==============================================================================
--- head/sys/riscv/riscv/genassym.c	Mon Apr  6 22:31:30 2020	(r359672)
+++ head/sys/riscv/riscv/genassym.c	Mon Apr  6 22:48:43 2020	(r359673)
@@ -56,10 +56,12 @@ __FBSDID("$FreeBSD$");
 #include <machine/pte.h>
 #include <machine/intr.h>
 #include <machine/machdep.h>
+#include <machine/vmparam.h>
 
 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_PHYS, offsetof(struct risc
 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));

Modified: head/sys/riscv/riscv/locore.S
==============================================================================
--- head/sys/riscv/riscv/locore.S	Mon Apr  6 22:31:30 2020	(r359672)
+++ head/sys/riscv/riscv/locore.S	Mon Apr  6 22:48:43 2020	(r359673)
@@ -217,9 +217,8 @@ va:
 	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 */

Modified: head/sys/riscv/riscv/machdep.c
==============================================================================
--- head/sys/riscv/riscv/machdep.c	Mon Apr  6 22:31:30 2020	(r359672)
+++ head/sys/riscv/riscv/machdep.c	Mon Apr  6 22:48:43 2020	(r359673)
@@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr.h>
 #include <machine/kdb.h>
 #include <machine/machdep.h>
+#include <machine/metadata.h>
 #include <machine/pcb.h>
 #include <machine/reg.h>
 #include <machine/riscvreg.h>
@@ -93,6 +94,7 @@ __FBSDID("$FreeBSD$");
 #endif
 
 #ifdef FDT
+#include <contrib/libfdt/libfdt.h>
 #include <dev/fdt/fdt_common.h>
 #include <dev/ofw/openfirm.h>
 #endif
@@ -741,11 +743,19 @@ add_physmap_entry(uint64_t base, uint64_t length, vm_p
 
 #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 @@ cache_setup(void)
  * 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 @@ fake_preload_metadata(struct riscv_bootparams *rvbp __
 #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 @@ initriscv(struct riscv_bootparams *rvbp)
 {
 	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 @@ initriscv(struct riscv_bootparams *rvbp)
 	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 @@ initriscv(struct riscv_bootparams *rvbp)
 	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
 

Modified: head/sys/riscv/riscv/pmap.c
==============================================================================
--- head/sys/riscv/riscv/pmap.c	Mon Apr  6 22:31:30 2020	(r359672)
+++ head/sys/riscv/riscv/pmap.c	Mon Apr  6 22:48:43 2020	(r359673)
@@ -558,6 +558,7 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart,
 	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 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart,
 	/* 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();
 


More information about the svn-src-head mailing list