svn commit: r360083 - in head/sys: conf riscv/include riscv/riscv

Mitchell Horne mhorne at FreeBSD.org
Sun Apr 19 00:18:17 UTC 2020


Author: mhorne
Date: Sun Apr 19 00:18:16 2020
New Revision: 360083
URL: https://svnweb.freebsd.org/changeset/base/360083

Log:
  RISC-V: use physmem to manage physical memory
  
  Replace our hand-rolled functions with the generic ones provided by
  kern/subr_physmem.c. This greatly simplifies the initialization of
  physical memory regions and kernel globals.
  
  Tested by:	nick
  Differential Revision:	https://reviews.freebsd.org/D24154

Modified:
  head/sys/conf/files.riscv
  head/sys/riscv/include/machdep.h
  head/sys/riscv/riscv/machdep.c
  head/sys/riscv/riscv/pmap.c

Modified: head/sys/conf/files.riscv
==============================================================================
--- head/sys/conf/files.riscv	Sun Apr 19 00:12:30 2020	(r360082)
+++ head/sys/conf/files.riscv	Sun Apr 19 00:18:16 2020	(r360083)
@@ -20,6 +20,7 @@ kern/pic_if.m			standard
 kern/subr_devmap.c		standard
 kern/subr_dummy_vdso_tc.c	standard
 kern/subr_intr.c		standard
+kern/subr_physmem.c		standard
 libkern/bcmp.c			standard
 libkern/bcopy.c			standard
 libkern/ffs.c			standard

Modified: head/sys/riscv/include/machdep.h
==============================================================================
--- head/sys/riscv/include/machdep.h	Sun Apr 19 00:12:30 2020	(r360082)
+++ head/sys/riscv/include/machdep.h	Sun Apr 19 00:18:16 2020	(r360083)
@@ -44,7 +44,7 @@ struct riscv_bootparams {
 	vm_offset_t	dtbp_virt;	/* Device tree blob virtual addr */
 };
 
-extern vm_paddr_t physmap[];
+extern vm_paddr_t physmap[PHYS_AVAIL_ENTRIES];
 extern u_int physmap_idx;
 
 vm_offset_t fake_preload_metadata(struct riscv_bootparams *rbp);

Modified: head/sys/riscv/riscv/machdep.c
==============================================================================
--- head/sys/riscv/riscv/machdep.c	Sun Apr 19 00:12:30 2020	(r360082)
+++ head/sys/riscv/riscv/machdep.c	Sun Apr 19 00:18:16 2020	(r360083)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/linker.h>
 #include <sys/msgbuf.h>
 #include <sys/pcpu.h>
+#include <sys/physmem.h>
 #include <sys/proc.h>
 #include <sys/ptrace.h>
 #include <sys/reboot.h>
@@ -108,8 +109,6 @@ static struct trapframe proc0_tf;
 
 int early_boot = 1;
 int cold = 1;
-long realmem = 0;
-long Maxmem = 0;
 
 #define	DTB_SIZE_MAX	(1024 * 1024)
 
@@ -673,74 +672,6 @@ init_proc0(vm_offset_t kstack)
 	pcpup->pc_curpcb = thread0.td_pcb;
 }
 
-static int
-add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
-    u_int *physmap_idxp)
-{
-	u_int i, insert_idx, _physmap_idx;
-
-	_physmap_idx = *physmap_idxp;
-
-	if (length == 0)
-		return (1);
-
-	/*
-	 * Find insertion point while checking for overlap.  Start off by
-	 * assuming the new entry will be added to the end.
-	 */
-	insert_idx = _physmap_idx;
-	for (i = 0; i <= _physmap_idx; i += 2) {
-		if (base < physmap[i + 1]) {
-			if (base + length <= physmap[i]) {
-				insert_idx = i;
-				break;
-			}
-			if (boothowto & RB_VERBOSE)
-				printf(
-		    "Overlapping memory regions, ignoring second region\n");
-			return (1);
-		}
-	}
-
-	/* See if we can prepend to the next entry. */
-	if (insert_idx <= _physmap_idx &&
-	    base + length == physmap[insert_idx]) {
-		physmap[insert_idx] = base;
-		return (1);
-	}
-
-	/* See if we can append to the previous entry. */
-	if (insert_idx > 0 && base == physmap[insert_idx - 1]) {
-		physmap[insert_idx - 1] += length;
-		return (1);
-	}
-
-	_physmap_idx += 2;
-	*physmap_idxp = _physmap_idx;
-	if (_physmap_idx == PHYS_AVAIL_ENTRIES) {
-		printf(
-		"Too many segments in the physical address map, giving up\n");
-		return (0);
-	}
-
-	/*
-	 * Move the last 'N' entries down to make room for the new
-	 * entry if needed.
-	 */
-	for (i = _physmap_idx; i > insert_idx; i -= 2) {
-		physmap[i] = physmap[i - 2];
-		physmap[i + 1] = physmap[i - 1];
-	}
-
-	/* Insert the new entry. */
-	physmap[insert_idx] = base;
-	physmap[insert_idx + 1] = base + length;
-
-	printf("physmap[%d] = 0x%016lx\n", insert_idx, base);
-	printf("physmap[%d] = 0x%016lx\n", insert_idx + 1, base + length);
-	return (1);
-}
-
 #ifdef FDT
 static void
 try_load_dtb(caddr_t kmdp)
@@ -864,7 +795,6 @@ initriscv(struct riscv_bootparams *rvbp)
 	vm_offset_t lastaddr;
 	vm_size_t kernlen;
 	caddr_t kmdp;
-	int i;
 
 	TSRAW(&thread0, TS_ENTER, __func__, NULL);
 
@@ -896,20 +826,12 @@ initriscv(struct riscv_bootparams *rvbp)
 
 #ifdef FDT
 	try_load_dtb(kmdp);
-#endif
 
-	/* Load the physical memory ranges */
-	physmap_idx = 0;
-
-#ifdef FDT
 	/* Grab physical memory regions information from device tree. */
-	if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, NULL) != 0)
+	if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, NULL) != 0) {
 		panic("Cannot get physical memory regions");
-
-	for (i = 0; i < mem_regions_sz; i++) {
-		add_physmap_entry(mem_regions[i].mr_start,
-		    mem_regions[i].mr_size, physmap, &physmap_idx);
 	}
+	physmem_hardware_regions(mem_regions, mem_regions_sz);
 #endif
 
 	/* Do basic tuning, hz etc */
@@ -921,6 +843,8 @@ initriscv(struct riscv_bootparams *rvbp)
 	kernlen = (lastaddr - KERNBASE);
 	pmap_bootstrap(rvbp->kern_l1pt, mem_regions[0].mr_start, kernlen);
 
+	physmem_init_kernel_globals();
+
 	/* Establish static device mappings */
 	devmap_bootstrap(0, NULL);
 
@@ -932,6 +856,9 @@ initriscv(struct riscv_bootparams *rvbp)
 	mutex_init();
 	init_param2(physmem);
 	kdb_init();
+
+	if (boothowto & RB_VERBOSE)
+		physmem_print_tables();
 
 	early_boot = 0;
 

Modified: head/sys/riscv/riscv/pmap.c
==============================================================================
--- head/sys/riscv/riscv/pmap.c	Sun Apr 19 00:12:30 2020	(r360082)
+++ head/sys/riscv/riscv/pmap.c	Sun Apr 19 00:18:16 2020	(r360083)
@@ -129,6 +129,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mman.h>
 #include <sys/msgbuf.h>
 #include <sys/mutex.h>
+#include <sys/physmem.h>
 #include <sys/proc.h>
 #include <sys/rwlock.h>
 #include <sys/sbuf.h>
@@ -554,10 +555,10 @@ pmap_bootstrap_l3(vm_offset_t l1pt, vm_offset_t va, vm
 void
 pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen)
 {
-	u_int l1_slot, l2_slot, avail_slot, map_slot;
+	u_int l1_slot, l2_slot;
 	vm_offset_t freemempos;
 	vm_offset_t dpcpu, msgbufpv;
-	vm_paddr_t end, max_pa, min_pa, pa, start;
+	vm_paddr_t max_pa, min_pa, pa;
 	pt_entry_t *l2p;
 	int i;
 
@@ -576,6 +577,9 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart,
 	/* Assume the address we were loaded to is a valid physical address. */
 	min_pa = max_pa = kernstart;
 
+	physmap_idx = physmem_avail(physmap, nitems(physmap));
+	physmap_idx /= 2;
+
 	/*
 	 * Find the minimum physical address. physmap is sorted,
 	 * but may contain empty ranges.
@@ -641,46 +645,7 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart,
 	
 	pa = pmap_early_vtophys(l1pt, freemempos);
 
-	/* Initialize phys_avail and dump_avail. */
-	for (avail_slot = map_slot = physmem = 0; map_slot < physmap_idx * 2;
-	    map_slot += 2) {
-		start = physmap[map_slot];
-		end = physmap[map_slot + 1];
-
-		if (start == end)
-			continue;
-		dump_avail[map_slot] = start;
-		dump_avail[map_slot + 1] = end;
-		realmem += atop((vm_offset_t)(end - start));
-
-		if (start >= kernstart && end <= pa)
-			continue;
-
-		if (start < kernstart && end > kernstart)
-			end = kernstart;
-		else if (start < pa && end > pa)
-			start = pa;
-		phys_avail[avail_slot] = start;
-		phys_avail[avail_slot + 1] = end;
-		physmem += (end - start) >> PAGE_SHIFT;
-		avail_slot += 2;
-
-		if (end != physmap[map_slot + 1] && end > pa) {
-			phys_avail[avail_slot] = pa;
-			phys_avail[avail_slot + 1] = physmap[map_slot + 1];
-			physmem += (physmap[map_slot + 1] - pa) >> PAGE_SHIFT;
-			avail_slot += 2;
-		}
-	}
-	phys_avail[avail_slot] = 0;
-	phys_avail[avail_slot + 1] = 0;
-
-	/*
-	 * Maxmem isn't the "maximum memory", it's one larger than the
-	 * highest page of the physical address space.  It should be
-	 * called something like "Maxphyspage".
-	 */
-	Maxmem = atop(phys_avail[avail_slot - 1]);
+	physmem_exclude_region(kernstart, pa - kernstart, EXFLAG_NOALLOC);
 }
 
 /*


More information about the svn-src-all mailing list