Page MenuHomeFreeBSD

D24153.1785436488.diff
No OneTemporary

Size
39 KB
Referenced Files
None
Subscribers
None

D24153.1785436488.diff

Index: head/sys/arm/arm/machdep.c
===================================================================
--- head/sys/arm/arm/machdep.c
+++ head/sys/arm/arm/machdep.c
@@ -66,6 +66,7 @@
#include <sys/ktr.h>
#include <sys/linker.h>
#include <sys/msgbuf.h>
+#include <sys/physmem.h>
#include <sys/reboot.h>
#include <sys/rwlock.h>
#include <sys/sched.h>
@@ -83,7 +84,6 @@
#include <machine/machdep.h>
#include <machine/metadata.h>
#include <machine/pcb.h>
-#include <machine/physmem.h>
#include <machine/platform.h>
#include <machine/sysarch.h>
#include <machine/undefined.h>
@@ -123,6 +123,9 @@
int cold = 1;
vm_offset_t vector_page;
+/* The address at which the kernel was loaded. Set early in initarm(). */
+vm_paddr_t arm_physmem_kernaddr;
+
int (*_arm_memcpy)(void *, void *, int, int) = NULL;
int (*_arm_bzero)(void *, int, int) = NULL;
int _min_memcpy_size = 0;
@@ -160,7 +163,6 @@
#endif
struct kva_md_info kmi;
-
/*
* arm32_vector_init:
*
@@ -237,7 +239,7 @@
(uintmax_t)arm32_ptob(vm_free_count()),
(uintmax_t)arm32_ptob(vm_free_count()) / mbyte);
if (bootverbose) {
- arm_physmem_print_tables();
+ physmem_print_tables();
devmap_print_table();
}
@@ -870,11 +872,11 @@
/* Grab physical memory regions information from device tree. */
if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, &memsize) != 0)
panic("Cannot get physical memory regions");
- arm_physmem_hardware_regions(mem_regions, mem_regions_sz);
+ physmem_hardware_regions(mem_regions, mem_regions_sz);
/* Grab reserved memory regions information from device tree. */
if (fdt_get_reserved_regions(mem_regions, &mem_regions_sz) == 0)
- arm_physmem_exclude_regions(mem_regions, mem_regions_sz,
+ physmem_exclude_regions(mem_regions, mem_regions_sz,
EXFLAG_NODUMP | EXFLAG_NOALLOC);
/* Platform-specific initialisation */
@@ -1081,9 +1083,9 @@
*
* Prepare the list of physical memory available to the vm subsystem.
*/
- arm_physmem_exclude_region(abp->abp_physaddr,
+ physmem_exclude_region(abp->abp_physaddr,
(virtual_avail - KERNVIRTADDR), EXFLAG_NOALLOC);
- arm_physmem_init_kernel_globals();
+ physmem_init_kernel_globals();
init_param2(physmem);
dbg_monitor_init();
@@ -1149,11 +1151,11 @@
if (fdt_get_mem_regions(mem_regions, &mem_regions_sz,NULL) != 0)
panic("Cannot get physical memory regions");
}
- arm_physmem_hardware_regions(mem_regions, mem_regions_sz);
+ physmem_hardware_regions(mem_regions, mem_regions_sz);
/* Grab reserved memory regions information from device tree. */
if (fdt_get_reserved_regions(mem_regions, &mem_regions_sz) == 0)
- arm_physmem_exclude_regions(mem_regions, mem_regions_sz,
+ physmem_exclude_regions(mem_regions, mem_regions_sz,
EXFLAG_NODUMP | EXFLAG_NOALLOC);
/*
@@ -1288,9 +1290,9 @@
*
* Prepare the list of physical memory available to the vm subsystem.
*/
- arm_physmem_exclude_region(abp->abp_physaddr,
+ physmem_exclude_region(abp->abp_physaddr,
pmap_preboot_get_pages(0) - abp->abp_physaddr, EXFLAG_NOALLOC);
- arm_physmem_init_kernel_globals();
+ physmem_init_kernel_globals();
init_param2(physmem);
/* Init message buffer. */
Index: head/sys/arm/arm/machdep_boot.c
===================================================================
--- head/sys/arm/arm/machdep_boot.c
+++ head/sys/arm/arm/machdep_boot.c
@@ -36,6 +36,7 @@
#include <sys/systm.h>
#include <sys/ctype.h>
#include <sys/linker.h>
+#include <sys/physmem.h>
#include <sys/reboot.h>
#include <sys/sysctl.h>
#if defined(LINUX_BOOT_ABI)
@@ -46,7 +47,6 @@
#include <machine/cpu.h>
#include <machine/machdep.h>
#include <machine/metadata.h>
-#include <machine/physmem.h>
#include <machine/vmparam.h> /* For KERNVIRTADDR */
#ifdef FDT
@@ -228,7 +228,7 @@
case ATAG_CORE:
break;
case ATAG_MEM:
- arm_physmem_hardware_region(walker->u.tag_mem.start,
+ physmem_hardware_region(walker->u.tag_mem.start,
walker->u.tag_mem.size);
break;
case ATAG_INITRD2:
Index: head/sys/arm/arm/mp_machdep.c
===================================================================
--- head/sys/arm/arm/mp_machdep.c
+++ head/sys/arm/arm/mp_machdep.c
@@ -53,7 +53,6 @@
#include <machine/debug_monitor.h>
#include <machine/smp.h>
#include <machine/pcb.h>
-#include <machine/physmem.h>
#include <machine/intr.h>
#include <machine/vmparam.h>
#ifdef VFP
Index: head/sys/arm/arm/physmem.c
===================================================================
--- head/sys/arm/arm/physmem.c
+++ head/sys/arm/arm/physmem.c
@@ -1,406 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2014 Ian Lepore <ian@freebsd.org>
- * All rights reserved.
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_acpi.h"
-#include "opt_ddb.h"
-
-/*
- * Routines for describing and initializing anything related to physical memory.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_page.h>
-#include <vm/vm_phys.h>
-#include <machine/md_var.h>
-#include <arm/include/physmem.h>
-
-/*
- * These structures are used internally to keep track of regions of physical
- * ram, and regions within the physical ram that need to be excluded. An
- * exclusion region can be excluded from crash dumps, from the vm pool of pages
- * that can be allocated, or both, depending on the exclusion flags associated
- * with the region.
- */
-#ifdef DEV_ACPI
-#define MAX_HWCNT 32 /* ACPI needs more regions */
-#define MAX_EXCNT 32
-#else
-#define MAX_HWCNT 16
-#define MAX_EXCNT 16
-#endif
-
-#if defined(__arm__)
-#define MAX_PHYS_ADDR 0xFFFFFFFFull
-#define pm_btop(x) arm32_btop(x)
-#elif defined(__aarch64__)
-#define MAX_PHYS_ADDR 0xFFFFFFFFFFFFFFFFull
-#define pm_btop(x) arm64_btop(x)
-#endif
-
-struct region {
- vm_paddr_t addr;
- vm_size_t size;
- uint32_t flags;
-};
-
-static struct region hwregions[MAX_HWCNT];
-static struct region exregions[MAX_EXCNT];
-
-static size_t hwcnt;
-static size_t excnt;
-
-/*
- * realmem is the total number of hardware pages, excluded or not.
- * Maxmem is one greater than the last physical page number.
- */
-long realmem;
-long Maxmem;
-
-/* The address at which the kernel was loaded. Set early in initarm(). */
-vm_paddr_t arm_physmem_kernaddr;
-
-/*
- * Print the contents of the physical and excluded region tables using the
- * provided printf-like output function (which will be either printf or
- * db_printf).
- */
-static void
-physmem_dump_tables(int (*prfunc)(const char *, ...))
-{
- int flags, i;
- uintmax_t addr, size;
- const unsigned int mbyte = 1024 * 1024;
-
- prfunc("Physical memory chunk(s):\n");
- for (i = 0; i < hwcnt; ++i) {
- addr = hwregions[i].addr;
- size = hwregions[i].size;
- prfunc(" 0x%08jx - 0x%08jx, %5ju MB (%7ju pages)\n", addr,
- addr + size - 1, size / mbyte, size / PAGE_SIZE);
- }
-
- prfunc("Excluded memory regions:\n");
- for (i = 0; i < excnt; ++i) {
- addr = exregions[i].addr;
- size = exregions[i].size;
- flags = exregions[i].flags;
- prfunc(" 0x%08jx - 0x%08jx, %5ju MB (%7ju pages) %s %s\n",
- addr, addr + size - 1, size / mbyte, size / PAGE_SIZE,
- (flags & EXFLAG_NOALLOC) ? "NoAlloc" : "",
- (flags & EXFLAG_NODUMP) ? "NoDump" : "");
- }
-
-#ifdef DEBUG
- prfunc("Avail lists:\n");
- for (i = 0; phys_avail[i] != 0; ++i) {
- prfunc(" phys_avail[%d] 0x%08x\n", i, phys_avail[i]);
- }
- for (i = 0; dump_avail[i] != 0; ++i) {
- prfunc(" dump_avail[%d] 0x%08x\n", i, dump_avail[i]);
- }
-#endif
-}
-
-/*
- * Print the contents of the static mapping table. Used for bootverbose.
- */
-void
-arm_physmem_print_tables(void)
-{
-
- physmem_dump_tables(printf);
-}
-
-/*
- * Walk the list of hardware regions, processing it against the list of
- * exclusions that contain the given exflags, and generating an "avail list".
- *
- * Updates the value at *pavail with the sum of all pages in all hw regions.
- *
- * Returns the number of pages of non-excluded memory added to the avail list.
- */
-static size_t
-regions_to_avail(vm_paddr_t *avail, uint32_t exflags, size_t maxavail,
- long *pavail, long *prealmem)
-{
- size_t acnt, exi, hwi;
- uint64_t end, start, xend, xstart;
- long availmem, totalmem;
- const struct region *exp, *hwp;
-
- totalmem = 0;
- availmem = 0;
- acnt = 0;
- for (hwi = 0, hwp = hwregions; hwi < hwcnt; ++hwi, ++hwp) {
- start = hwp->addr;
- end = hwp->size + start;
- totalmem += pm_btop((vm_offset_t)(end - start));
- for (exi = 0, exp = exregions; exi < excnt; ++exi, ++exp) {
- /*
- * If the excluded region does not match given flags,
- * continue checking with the next excluded region.
- */
- if ((exp->flags & exflags) == 0)
- continue;
- xstart = exp->addr;
- xend = exp->size + xstart;
- /*
- * If the excluded region ends before this hw region,
- * continue checking with the next excluded region.
- */
- if (xend <= start)
- continue;
- /*
- * If the excluded region begins after this hw region
- * we're done because both lists are sorted.
- */
- if (xstart >= end)
- break;
- /*
- * If the excluded region completely covers this hw
- * region, shrink this hw region to zero size.
- */
- if ((start >= xstart) && (end <= xend)) {
- start = xend;
- end = xend;
- break;
- }
- /*
- * If the excluded region falls wholly within this hw
- * region without abutting or overlapping the beginning
- * or end, create an available entry from the leading
- * fragment, then adjust the start of this hw region to
- * the end of the excluded region, and continue checking
- * the next excluded region because another exclusion
- * could affect the remainder of this hw region.
- */
- if ((xstart > start) && (xend < end)) {
- if (acnt > 0 &&
- avail[acnt - 1] == (vm_paddr_t)start) {
- avail[acnt - 1] = (vm_paddr_t)xstart;
- } else {
- avail[acnt++] = (vm_paddr_t)start;
- avail[acnt++] = (vm_paddr_t)xstart;
- }
- availmem +=
- pm_btop((vm_offset_t)(xstart - start));
- start = xend;
- continue;
- }
- /*
- * We know the excluded region overlaps either the start
- * or end of this hardware region (but not both), trim
- * the excluded portion off the appropriate end.
- */
- if (xstart <= start)
- start = xend;
- else
- end = xstart;
- }
- /*
- * If the trimming actions above left a non-zero size, create an
- * available entry for it.
- */
- if (end > start) {
- if (acnt > 0 && avail[acnt - 1] == (vm_paddr_t)start) {
- avail[acnt - 1] = (vm_paddr_t)end;
- } else {
- avail[acnt++] = (vm_paddr_t)start;
- avail[acnt++] = (vm_paddr_t)end;
- }
- availmem += pm_btop((vm_offset_t)(end - start));
- }
- if (acnt >= maxavail)
- panic("Not enough space in the dump/phys_avail arrays");
- }
-
- if (pavail != NULL)
- *pavail = availmem;
- if (prealmem != NULL)
- *prealmem = totalmem;
- return (acnt);
-}
-
-/*
- * Insertion-sort a new entry into a regions list; sorted by start address.
- */
-static size_t
-insert_region(struct region *regions, size_t rcnt, vm_paddr_t addr,
- vm_size_t size, uint32_t flags)
-{
- size_t i;
- struct region *ep, *rp;
-
- ep = regions + rcnt;
- for (i = 0, rp = regions; i < rcnt; ++i, ++rp) {
- if (rp->addr == addr && rp->size == size) /* Pure dup. */
- return (rcnt);
- if (flags == rp->flags) {
- if (addr + size == rp->addr) {
- rp->addr = addr;
- rp->size += size;
- return (rcnt);
- } else if (rp->addr + rp->size == addr) {
- rp->size += size;
- return (rcnt);
- }
- }
- if (addr < rp->addr) {
- bcopy(rp, rp + 1, (ep - rp) * sizeof(*rp));
- break;
- }
- }
- rp->addr = addr;
- rp->size = size;
- rp->flags = flags;
- rcnt++;
-
- return (rcnt);
-}
-
-/*
- * Add a hardware memory region.
- */
-void
-arm_physmem_hardware_region(uint64_t pa, uint64_t sz)
-{
- vm_offset_t adj;
-
- /*
- * Filter out the page at PA 0x00000000. The VM can't handle it, as
- * pmap_extract() == 0 means failure.
- */
- if (pa == 0) {
- if (sz <= PAGE_SIZE)
- return;
- pa = PAGE_SIZE;
- sz -= PAGE_SIZE;
- } else if (pa > MAX_PHYS_ADDR) {
- /* This range is past usable memory, ignore it */
- return;
- }
-
- /*
- * Also filter out the page at the end of the physical address space --
- * if addr is non-zero and addr+size is zero we wrapped to the next byte
- * beyond what vm_paddr_t can express. That leads to a NULL pointer
- * deref early in startup; work around it by leaving the last page out.
- *
- * XXX This just in: subtract out a whole megabyte, not just 1 page.
- * Reducing the size by anything less than 1MB results in the NULL
- * pointer deref in _vm_map_lock_read(). Better to give up a megabyte
- * than leave some folks with an unusable system while we investigate.
- */
- if ((pa + sz) > (MAX_PHYS_ADDR - 1024 * 1024)) {
- sz = MAX_PHYS_ADDR - pa + 1;
- if (sz <= 1024 * 1024)
- return;
- sz -= 1024 * 1024;
- }
-
- /*
- * Round the starting address up to a page boundary, and truncate the
- * ending page down to a page boundary.
- */
- adj = round_page(pa) - pa;
- pa = round_page(pa);
- sz = trunc_page(sz - adj);
-
- if (sz > 0 && hwcnt < nitems(hwregions))
- hwcnt = insert_region(hwregions, hwcnt, pa, sz, 0);
-}
-
-/*
- * Add an exclusion region.
- */
-void
-arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags)
-{
- vm_offset_t adj;
-
- /*
- * Truncate the starting address down to a page boundary, and round the
- * ending page up to a page boundary.
- */
- adj = pa - trunc_page(pa);
- pa = trunc_page(pa);
- sz = round_page(sz + adj);
-
- if (excnt >= nitems(exregions))
- panic("failed to exclude region %#jx-%#jx", (uintmax_t)pa,
- (uintmax_t)(pa + sz));
- excnt = insert_region(exregions, excnt, pa, sz, exflags);
-}
-
-size_t
-arm_physmem_avail(vm_paddr_t *avail, size_t maxavail)
-{
-
- return (regions_to_avail(avail, EXFLAG_NOALLOC, maxavail, NULL, NULL));
-}
-
-/*
- * Process all the regions added earlier into the global avail lists.
- *
- * Updates the kernel global 'physmem' with the number of physical pages
- * available for use (all pages not in any exclusion region).
- *
- * Updates the kernel global 'Maxmem' with the page number one greater then the
- * last page of physical memory in the system.
- */
-void
-arm_physmem_init_kernel_globals(void)
-{
- size_t nextidx;
-
- regions_to_avail(dump_avail, EXFLAG_NODUMP, PHYS_AVAIL_ENTRIES, NULL,
- NULL);
- nextidx = regions_to_avail(phys_avail, EXFLAG_NOALLOC,
- PHYS_AVAIL_ENTRIES, &physmem, &realmem);
- if (nextidx == 0)
- panic("No memory entries in phys_avail");
- Maxmem = atop(phys_avail[nextidx - 1]);
-}
-
-#ifdef DDB
-#include <ddb/ddb.h>
-
-DB_SHOW_COMMAND(physmem, db_show_physmem)
-{
-
- physmem_dump_tables(db_printf);
-}
-
-#endif /* DDB */
-
Index: head/sys/arm/arm/pmap-v6.c
===================================================================
--- head/sys/arm/arm/pmap-v6.c
+++ head/sys/arm/arm/pmap-v6.c
@@ -117,8 +117,6 @@
#include <ddb/ddb.h>
#endif
-#include <machine/physmem.h>
-
#include <vm/vm.h>
#include <vm/uma.h>
#include <vm/pmap.h>
Index: head/sys/arm/include/md_var.h
===================================================================
--- head/sys/arm/include/md_var.h
+++ head/sys/arm/include/md_var.h
@@ -42,6 +42,7 @@
extern int vm_page_dump_size;
extern u_long elf_hwcap;
extern u_long elf_hwcap2;
+extern vm_paddr_t arm_physmem_kernaddr;
extern int (*_arm_memcpy)(void *, void *, int, int);
extern int (*_arm_bzero)(void *, int, int);
Index: head/sys/arm/include/physmem.h
===================================================================
--- head/sys/arm/include/physmem.h
+++ head/sys/arm/include/physmem.h
@@ -1,94 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2014 Ian Lepore <ian@freebsd.org>
- * All rights reserved.
- *
- * 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_PHYSMEM_H_
-#define _MACHINE_PHYSMEM_H_
-
-/*
- * The physical address at which the kernel was loaded.
- */
-extern vm_paddr_t arm_physmem_kernaddr;
-
-/*
- * Routines to help configure physical ram.
- *
- * Multiple regions of contiguous physical ram can be added (in any order).
- *
- * Multiple regions of physical ram that should be excluded from crash dumps, or
- * memory allocation, or both, can be added (in any order).
- *
- * After all early kernel init is done and it's time to configure all
- * remainining non-excluded physical ram for use by other parts of the kernel,
- * arm_physmem_init_kernel_globals() processes the hardware regions and
- * exclusion regions to generate the global dump_avail and phys_avail arrays
- * that communicate physical ram configuration to other parts of the kernel.
- */
-
-#define EXFLAG_NODUMP 0x01
-#define EXFLAG_NOALLOC 0x02
-
-void arm_physmem_hardware_region(uint64_t pa, uint64_t sz);
-void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t flags);
-size_t arm_physmem_avail(vm_paddr_t *avail, size_t maxavail);
-void arm_physmem_init_kernel_globals(void);
-void arm_physmem_print_tables(void);
-
-/*
- * Convenience routines for FDT.
- */
-
-#ifdef FDT
-
-#include <machine/ofw_machdep.h>
-
-static inline void
-arm_physmem_hardware_regions(struct mem_region * mrptr, int mrcount)
-{
- while (mrcount--) {
- arm_physmem_hardware_region(mrptr->mr_start, mrptr->mr_size);
- ++mrptr;
- }
-}
-
-static inline void
-arm_physmem_exclude_regions(struct mem_region * mrptr, int mrcount,
- uint32_t exflags)
-{
- while (mrcount--) {
- arm_physmem_exclude_region(mrptr->mr_start, mrptr->mr_size,
- exflags);
- ++mrptr;
- }
-}
-
-#endif /* FDT */
-
-#endif
-
Index: head/sys/arm64/arm64/machdep.c
===================================================================
--- head/sys/arm64/arm64/machdep.c
+++ head/sys/arm64/arm64/machdep.c
@@ -50,6 +50,7 @@
#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>
@@ -82,8 +83,6 @@
#include <machine/undefined.h>
#include <machine/vmparam.h>
-#include <arm/include/physmem.h>
-
#ifdef VFP
#include <machine/vfp.h>
#endif
@@ -855,7 +854,7 @@
*/
break;
default:
- arm_physmem_exclude_region(p->md_phys, p->md_pages * PAGE_SIZE,
+ physmem_exclude_region(p->md_phys, p->md_pages * PAGE_SIZE,
EXFLAG_NOALLOC);
}
}
@@ -886,7 +885,7 @@
/*
* We're allowed to use any entry with these types.
*/
- arm_physmem_hardware_region(p->md_phys,
+ physmem_hardware_region(p->md_phys,
p->md_pages * PAGE_SIZE);
break;
}
@@ -1113,10 +1112,10 @@
if (fdt_get_mem_regions(mem_regions, &mem_regions_sz,
NULL) != 0)
panic("Cannot get physical memory regions");
- arm_physmem_hardware_regions(mem_regions, mem_regions_sz);
+ physmem_hardware_regions(mem_regions, mem_regions_sz);
}
if (fdt_get_reserved_mem(mem_regions, &mem_regions_sz) == 0)
- arm_physmem_exclude_regions(mem_regions, mem_regions_sz,
+ physmem_exclude_regions(mem_regions, mem_regions_sz,
EXFLAG_NODUMP | EXFLAG_NOALLOC);
#endif
@@ -1124,7 +1123,7 @@
efifb = (struct efi_fb *)preload_search_info(kmdp,
MODINFO_METADATA | MODINFOMD_EFI_FB);
if (efifb != NULL)
- arm_physmem_exclude_region(efifb->fb_addr, efifb->fb_size,
+ physmem_exclude_region(efifb->fb_addr, efifb->fb_size,
EXFLAG_NOALLOC);
/* Set the pcpu data, this is needed by pmap_bootstrap */
@@ -1153,7 +1152,7 @@
/* Exclude entries neexed in teh DMAP region, but not phys_avail */
if (efihdr != NULL)
exclude_efi_map_entries(efihdr);
- arm_physmem_init_kernel_globals();
+ physmem_init_kernel_globals();
devmap_bootstrap(0, NULL);
@@ -1182,7 +1181,7 @@
if (boothowto & RB_VERBOSE) {
print_efi_map_entries(efihdr);
- arm_physmem_print_tables();
+ physmem_print_tables();
}
early_boot = 0;
Index: head/sys/arm64/arm64/pmap.c
===================================================================
--- head/sys/arm64/arm64/pmap.c
+++ head/sys/arm64/arm64/pmap.c
@@ -119,6 +119,7 @@
#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>
@@ -148,8 +149,6 @@
#include <machine/md_var.h>
#include <machine/pcb.h>
-#include <arm/include/physmem.h>
-
#define PMAP_ASSERT_STAGE1(pmap) MPASS((pmap)->pm_stage == PM_STAGE1)
#define NL0PG (PAGE_SIZE/(sizeof (pd_entry_t)))
@@ -861,7 +860,7 @@
/* Assume the address we were loaded to is a valid physical address */
min_pa = KERNBASE - kern_delta;
- physmap_idx = arm_physmem_avail(physmap, nitems(physmap));
+ physmap_idx = physmem_avail(physmap, nitems(physmap));
physmap_idx /= 2;
/*
@@ -942,7 +941,7 @@
pa = pmap_early_vtophys(l1pt, freemempos);
- arm_physmem_exclude_region(start_pa, pa - start_pa, EXFLAG_NOALLOC);
+ physmem_exclude_region(start_pa, pa - start_pa, EXFLAG_NOALLOC);
cpu_tlb_flushID();
}
Index: head/sys/conf/files.arm
===================================================================
--- head/sys/conf/files.arm
+++ head/sys/conf/files.arm
@@ -58,7 +58,6 @@
arm/arm/mpcore_timer.c optional mpcore_timer
arm/arm/nexus.c standard
arm/arm/ofw_machdep.c optional fdt
-arm/arm/physmem.c standard
arm/arm/pl190.c optional pl190
arm/arm/pl310.c optional pl310
arm/arm/platform.c optional platform
@@ -116,6 +115,7 @@
kern/pic_if.m optional intrng
kern/subr_busdma_bufalloc.c standard
kern/subr_devmap.c standard
+kern/subr_physmem.c standard
kern/subr_sfbuf.c standard
libkern/arm/aeabi_unwind.c standard
libkern/arm/divsi3.S standard
Index: head/sys/conf/files.arm64
===================================================================
--- head/sys/conf/files.arm64
+++ head/sys/conf/files.arm64
@@ -85,7 +85,6 @@
arm/arm/gic_acpi.c optional acpi
arm/arm/gic_fdt.c optional fdt
arm/arm/pmu.c standard
-arm/arm/physmem.c standard
arm/broadcom/bcm2835/bcm2835_audio.c optional sound vchiq fdt \
compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq"
arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc fdt
@@ -291,6 +290,7 @@
kern/pic_if.m optional intrng
kern/subr_devmap.c standard
kern/subr_intr.c optional intrng
+kern/subr_physmem.c standard
libkern/bcmp.c standard
libkern/memcmp.c standard \
compile-with "${NORMAL_C:N-fsanitize*}"
Index: head/sys/kern/subr_physmem.c
===================================================================
--- head/sys/kern/subr_physmem.c
+++ head/sys/kern/subr_physmem.c
@@ -0,0 +1,399 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2014 Ian Lepore <ian@freebsd.org>
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_acpi.h"
+#include "opt_ddb.h"
+
+/*
+ * Routines for describing and initializing anything related to physical memory.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/physmem.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_page.h>
+#include <vm/vm_phys.h>
+#include <machine/md_var.h>
+
+/*
+ * These structures are used internally to keep track of regions of physical
+ * ram, and regions within the physical ram that need to be excluded. An
+ * exclusion region can be excluded from crash dumps, from the vm pool of pages
+ * that can be allocated, or both, depending on the exclusion flags associated
+ * with the region.
+ */
+#ifdef DEV_ACPI
+#define MAX_HWCNT 32 /* ACPI needs more regions */
+#define MAX_EXCNT 32
+#else
+#define MAX_HWCNT 16
+#define MAX_EXCNT 16
+#endif
+
+#if defined(__arm__)
+#define MAX_PHYS_ADDR 0xFFFFFFFFull
+#elif defined(__aarch64__) || defined(__riscv)
+#define MAX_PHYS_ADDR 0xFFFFFFFFFFFFFFFFull
+#endif
+
+struct region {
+ vm_paddr_t addr;
+ vm_size_t size;
+ uint32_t flags;
+};
+
+static struct region hwregions[MAX_HWCNT];
+static struct region exregions[MAX_EXCNT];
+
+static size_t hwcnt;
+static size_t excnt;
+
+/*
+ * realmem is the total number of hardware pages, excluded or not.
+ * Maxmem is one greater than the last physical page number.
+ */
+long realmem;
+long Maxmem;
+
+/*
+ * Print the contents of the physical and excluded region tables using the
+ * provided printf-like output function (which will be either printf or
+ * db_printf).
+ */
+static void
+physmem_dump_tables(int (*prfunc)(const char *, ...))
+{
+ int flags, i;
+ uintmax_t addr, size;
+ const unsigned int mbyte = 1024 * 1024;
+
+ prfunc("Physical memory chunk(s):\n");
+ for (i = 0; i < hwcnt; ++i) {
+ addr = hwregions[i].addr;
+ size = hwregions[i].size;
+ prfunc(" 0x%08jx - 0x%08jx, %5ju MB (%7ju pages)\n", addr,
+ addr + size - 1, size / mbyte, size / PAGE_SIZE);
+ }
+
+ prfunc("Excluded memory regions:\n");
+ for (i = 0; i < excnt; ++i) {
+ addr = exregions[i].addr;
+ size = exregions[i].size;
+ flags = exregions[i].flags;
+ prfunc(" 0x%08jx - 0x%08jx, %5ju MB (%7ju pages) %s %s\n",
+ addr, addr + size - 1, size / mbyte, size / PAGE_SIZE,
+ (flags & EXFLAG_NOALLOC) ? "NoAlloc" : "",
+ (flags & EXFLAG_NODUMP) ? "NoDump" : "");
+ }
+
+#ifdef DEBUG
+ prfunc("Avail lists:\n");
+ for (i = 0; phys_avail[i] != 0; ++i) {
+ prfunc(" phys_avail[%d] 0x%08x\n", i, phys_avail[i]);
+ }
+ for (i = 0; dump_avail[i] != 0; ++i) {
+ prfunc(" dump_avail[%d] 0x%08x\n", i, dump_avail[i]);
+ }
+#endif
+}
+
+/*
+ * Print the contents of the static mapping table. Used for bootverbose.
+ */
+void
+physmem_print_tables(void)
+{
+
+ physmem_dump_tables(printf);
+}
+
+/*
+ * Walk the list of hardware regions, processing it against the list of
+ * exclusions that contain the given exflags, and generating an "avail list".
+ *
+ * Updates the value at *pavail with the sum of all pages in all hw regions.
+ *
+ * Returns the number of pages of non-excluded memory added to the avail list.
+ */
+static size_t
+regions_to_avail(vm_paddr_t *avail, uint32_t exflags, size_t maxavail,
+ long *pavail, long *prealmem)
+{
+ size_t acnt, exi, hwi;
+ uint64_t end, start, xend, xstart;
+ long availmem, totalmem;
+ const struct region *exp, *hwp;
+
+ totalmem = 0;
+ availmem = 0;
+ acnt = 0;
+ for (hwi = 0, hwp = hwregions; hwi < hwcnt; ++hwi, ++hwp) {
+ start = hwp->addr;
+ end = hwp->size + start;
+ totalmem += atop((vm_offset_t)(end - start));
+ for (exi = 0, exp = exregions; exi < excnt; ++exi, ++exp) {
+ /*
+ * If the excluded region does not match given flags,
+ * continue checking with the next excluded region.
+ */
+ if ((exp->flags & exflags) == 0)
+ continue;
+ xstart = exp->addr;
+ xend = exp->size + xstart;
+ /*
+ * If the excluded region ends before this hw region,
+ * continue checking with the next excluded region.
+ */
+ if (xend <= start)
+ continue;
+ /*
+ * If the excluded region begins after this hw region
+ * we're done because both lists are sorted.
+ */
+ if (xstart >= end)
+ break;
+ /*
+ * If the excluded region completely covers this hw
+ * region, shrink this hw region to zero size.
+ */
+ if ((start >= xstart) && (end <= xend)) {
+ start = xend;
+ end = xend;
+ break;
+ }
+ /*
+ * If the excluded region falls wholly within this hw
+ * region without abutting or overlapping the beginning
+ * or end, create an available entry from the leading
+ * fragment, then adjust the start of this hw region to
+ * the end of the excluded region, and continue checking
+ * the next excluded region because another exclusion
+ * could affect the remainder of this hw region.
+ */
+ if ((xstart > start) && (xend < end)) {
+ if (acnt > 0 &&
+ avail[acnt - 1] == (vm_paddr_t)start) {
+ avail[acnt - 1] = (vm_paddr_t)xstart;
+ } else {
+ avail[acnt++] = (vm_paddr_t)start;
+ avail[acnt++] = (vm_paddr_t)xstart;
+ }
+ availmem += atop((vm_offset_t)(xstart - start));
+ start = xend;
+ continue;
+ }
+ /*
+ * We know the excluded region overlaps either the start
+ * or end of this hardware region (but not both), trim
+ * the excluded portion off the appropriate end.
+ */
+ if (xstart <= start)
+ start = xend;
+ else
+ end = xstart;
+ }
+ /*
+ * If the trimming actions above left a non-zero size, create an
+ * available entry for it.
+ */
+ if (end > start) {
+ if (acnt > 0 && avail[acnt - 1] == (vm_paddr_t)start) {
+ avail[acnt - 1] = (vm_paddr_t)end;
+ } else {
+ avail[acnt++] = (vm_paddr_t)start;
+ avail[acnt++] = (vm_paddr_t)end;
+ }
+ availmem += atop((vm_offset_t)(end - start));
+ }
+ if (acnt >= maxavail)
+ panic("Not enough space in the dump/phys_avail arrays");
+ }
+
+ if (pavail != NULL)
+ *pavail = availmem;
+ if (prealmem != NULL)
+ *prealmem = totalmem;
+ return (acnt);
+}
+
+/*
+ * Insertion-sort a new entry into a regions list; sorted by start address.
+ */
+static size_t
+insert_region(struct region *regions, size_t rcnt, vm_paddr_t addr,
+ vm_size_t size, uint32_t flags)
+{
+ size_t i;
+ struct region *ep, *rp;
+
+ ep = regions + rcnt;
+ for (i = 0, rp = regions; i < rcnt; ++i, ++rp) {
+ if (rp->addr == addr && rp->size == size) /* Pure dup. */
+ return (rcnt);
+ if (flags == rp->flags) {
+ if (addr + size == rp->addr) {
+ rp->addr = addr;
+ rp->size += size;
+ return (rcnt);
+ } else if (rp->addr + rp->size == addr) {
+ rp->size += size;
+ return (rcnt);
+ }
+ }
+ if (addr < rp->addr) {
+ bcopy(rp, rp + 1, (ep - rp) * sizeof(*rp));
+ break;
+ }
+ }
+ rp->addr = addr;
+ rp->size = size;
+ rp->flags = flags;
+ rcnt++;
+
+ return (rcnt);
+}
+
+/*
+ * Add a hardware memory region.
+ */
+void
+physmem_hardware_region(uint64_t pa, uint64_t sz)
+{
+ vm_offset_t adj;
+
+ /*
+ * Filter out the page at PA 0x00000000. The VM can't handle it, as
+ * pmap_extract() == 0 means failure.
+ */
+ if (pa == 0) {
+ if (sz <= PAGE_SIZE)
+ return;
+ pa = PAGE_SIZE;
+ sz -= PAGE_SIZE;
+ } else if (pa > MAX_PHYS_ADDR) {
+ /* This range is past usable memory, ignore it */
+ return;
+ }
+
+ /*
+ * Also filter out the page at the end of the physical address space --
+ * if addr is non-zero and addr+size is zero we wrapped to the next byte
+ * beyond what vm_paddr_t can express. That leads to a NULL pointer
+ * deref early in startup; work around it by leaving the last page out.
+ *
+ * XXX This just in: subtract out a whole megabyte, not just 1 page.
+ * Reducing the size by anything less than 1MB results in the NULL
+ * pointer deref in _vm_map_lock_read(). Better to give up a megabyte
+ * than leave some folks with an unusable system while we investigate.
+ */
+ if ((pa + sz) > (MAX_PHYS_ADDR - 1024 * 1024)) {
+ sz = MAX_PHYS_ADDR - pa + 1;
+ if (sz <= 1024 * 1024)
+ return;
+ sz -= 1024 * 1024;
+ }
+
+ /*
+ * Round the starting address up to a page boundary, and truncate the
+ * ending page down to a page boundary.
+ */
+ adj = round_page(pa) - pa;
+ pa = round_page(pa);
+ sz = trunc_page(sz - adj);
+
+ if (sz > 0 && hwcnt < nitems(hwregions))
+ hwcnt = insert_region(hwregions, hwcnt, pa, sz, 0);
+}
+
+/*
+ * Add an exclusion region.
+ */
+void
+physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags)
+{
+ vm_offset_t adj;
+
+ /*
+ * Truncate the starting address down to a page boundary, and round the
+ * ending page up to a page boundary.
+ */
+ adj = pa - trunc_page(pa);
+ pa = trunc_page(pa);
+ sz = round_page(sz + adj);
+
+ if (excnt >= nitems(exregions))
+ panic("failed to exclude region %#jx-%#jx", (uintmax_t)pa,
+ (uintmax_t)(pa + sz));
+ excnt = insert_region(exregions, excnt, pa, sz, exflags);
+}
+
+size_t
+physmem_avail(vm_paddr_t *avail, size_t maxavail)
+{
+
+ return (regions_to_avail(avail, EXFLAG_NOALLOC, maxavail, NULL, NULL));
+}
+
+/*
+ * Process all the regions added earlier into the global avail lists.
+ *
+ * Updates the kernel global 'physmem' with the number of physical pages
+ * available for use (all pages not in any exclusion region).
+ *
+ * Updates the kernel global 'Maxmem' with the page number one greater then the
+ * last page of physical memory in the system.
+ */
+void
+physmem_init_kernel_globals(void)
+{
+ size_t nextidx;
+
+ regions_to_avail(dump_avail, EXFLAG_NODUMP, PHYS_AVAIL_ENTRIES, NULL,
+ NULL);
+ nextidx = regions_to_avail(phys_avail, EXFLAG_NOALLOC,
+ PHYS_AVAIL_ENTRIES, &physmem, &realmem);
+ if (nextidx == 0)
+ panic("No memory entries in phys_avail");
+ Maxmem = atop(phys_avail[nextidx - 1]);
+}
+
+#ifdef DDB
+#include <ddb/ddb.h>
+
+DB_SHOW_COMMAND(physmem, db_show_physmem)
+{
+
+ physmem_dump_tables(db_printf);
+}
+
+#endif /* DDB */
Index: head/sys/sys/physmem.h
===================================================================
--- head/sys/sys/physmem.h
+++ head/sys/sys/physmem.h
@@ -0,0 +1,88 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2014 Ian Lepore <ian@freebsd.org>
+ * All rights reserved.
+ *
+ * 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 _SYS_PHYSMEM_H_
+#define _SYS_PHYSMEM_H_
+
+/*
+ * Routines to help configure physical ram.
+ *
+ * Multiple regions of contiguous physical ram can be added (in any order).
+ *
+ * Multiple regions of physical ram that should be excluded from crash dumps, or
+ * memory allocation, or both, can be added (in any order).
+ *
+ * After all early kernel init is done and it's time to configure all
+ * remainining non-excluded physical ram for use by other parts of the kernel,
+ * physmem_init_kernel_globals() processes the hardware regions and
+ * exclusion regions to generate the global dump_avail and phys_avail arrays
+ * that communicate physical ram configuration to other parts of the kernel.
+ */
+
+#define EXFLAG_NODUMP 0x01
+#define EXFLAG_NOALLOC 0x02
+
+void physmem_hardware_region(uint64_t pa, uint64_t sz);
+void physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t flags);
+size_t physmem_avail(vm_paddr_t *avail, size_t maxavail);
+void physmem_init_kernel_globals(void);
+void physmem_print_tables(void);
+
+/*
+ * Convenience routines for FDT.
+ */
+
+#ifdef FDT
+
+#include <machine/ofw_machdep.h>
+
+static inline void
+physmem_hardware_regions(struct mem_region * mrptr, int mrcount)
+{
+ while (mrcount--) {
+ physmem_hardware_region(mrptr->mr_start, mrptr->mr_size);
+ ++mrptr;
+ }
+}
+
+static inline void
+physmem_exclude_regions(struct mem_region * mrptr, int mrcount,
+ uint32_t exflags)
+{
+ while (mrcount--) {
+ physmem_exclude_region(mrptr->mr_start, mrptr->mr_size,
+ exflags);
+ ++mrptr;
+ }
+}
+
+#endif /* FDT */
+
+#endif /* !_SYS_PHYSMEM_H_ */

File Metadata

Mime Type
text/plain
Expires
Thu, Jul 30, 6:34 PM (5 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29316050
Default Alt Text
D24153.1785436488.diff (39 KB)

Event Timeline