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);
 }
 
 /*
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to