41#include <sys/kernel.h>
42#include <sys/physmem.h>
44#include <vm/vm_param.h>
45#include <vm/vm_page.h>
46#include <vm/vm_phys.h>
47#include <vm/vm_dumpset.h>
48#include <machine/md_var.h>
66#define MAX_PHYS_ADDR 0xFFFFFFFFull
67#elif defined(__aarch64__) || defined(__riscv)
68#define MAX_PHYS_ADDR 0xFFFFFFFFFFFFFFFFull
100 const unsigned int mbyte = 1024 * 1024;
102 prfunc(
"Physical memory chunk(s):\n");
103 for (i = 0; i <
hwcnt; ++i) {
106 prfunc(
" 0x%08jx - 0x%08jx, %5ju MB (%7ju pages)\n",
addr,
110 prfunc(
"Excluded memory regions:\n");
111 for (i = 0; i <
excnt; ++i) {
115 prfunc(
" 0x%08jx - 0x%08jx, %5ju MB (%7ju pages) %s %s\n",
117 (
flags & EXFLAG_NOALLOC) ?
"NoAlloc" :
"",
118 (
flags & EXFLAG_NODUMP) ?
"NoDump" :
"");
122 prfunc(
"Avail lists:\n");
123 for (i = 0; phys_avail[i] != 0; ++i) {
124 prfunc(
" phys_avail[%d] 0x%08x\n", i, phys_avail[i]);
126 for (i = 0; dump_avail[i] != 0; ++i) {
127 prfunc(
" dump_avail[%d] 0x%08x\n", i, dump_avail[i]);
156 uint64_t maxphyssz,
long *pavail,
long *prealmem)
158 size_t acnt, exi, hwi;
159 uint64_t end,
start, xend, xstart;
160 long availmem, totalmem;
161 const struct region *exp, *hwp;
171 totalmem += atop((vm_offset_t)(end -
start));
177 if ((exp->
flags & exflags) == 0)
180 xend = exp->
size + xstart;
197 if ((
start >= xstart) && (end <= xend)) {
211 if ((xstart >
start) && (xend < end)) {
213 if ((maxphyssz != 0) &&
214 (availsz + xstart -
start > maxphyssz)) {
215 xstart = maxphyssz +
start - availsz;
220 avail[acnt - 1] == (vm_paddr_t)
start) {
221 avail[acnt - 1] = (vm_paddr_t)xstart;
223 avail[acnt++] = (vm_paddr_t)
start;
224 avail[acnt++] = (vm_paddr_t)xstart;
226 availsz += (xstart -
start);
227 availmem += atop((vm_offset_t)(xstart -
start));
246 if ((maxphyssz != 0) &&
247 (availsz + end -
start > maxphyssz)) {
248 end = maxphyssz +
start - availsz;
253 if (acnt > 0 && avail[acnt - 1] == (vm_paddr_t)
start) {
254 avail[acnt - 1] = (vm_paddr_t)end;
256 avail[acnt++] = (vm_paddr_t)
start;
257 avail[acnt++] = (vm_paddr_t)end;
259 availsz += end -
start;
260 availmem += atop((vm_offset_t)(end -
start));
262 if (acnt >= maxavail)
263 panic(
"Not enough space in the dump/phys_avail arrays");
268 if (prealmem != NULL)
269 *prealmem = totalmem;
279 struct region *lower, *upper;
280 vm_paddr_t lend, uend;
281 size_t i, mergecnt, movecnt;
283 lower = ®ions[idx];
291 for (i = idx + 1; i < rcnt; i++) {
298 lower->
size += uend - lend;
319 mergecnt = i - (idx + 1);
326 memmove(®ions[idx + 1], ®ions[idx + mergecnt + 1],
327 movecnt *
sizeof(*regions));
342 vm_paddr_t nend, rend;
347 for (i = 0, rp = regions; i < rcnt; ++i, ++rp) {
350 if (addr <= rp->
addr && nend >= rp->
addr) {
359 rp->
size += nend - rend;
364 }
else if (addr <= rend && nend > rp->
addr) {
370 rp->
size += nend - rend;
377 if (addr < rp->
addr) {
378 bcopy(rp, rp + 1, (ep - rp) *
sizeof(*rp));
407 }
else if (pa > MAX_PHYS_ADDR) {
423 if ((pa + sz) > (MAX_PHYS_ADDR - 1024 * 1024)) {
424 sz = MAX_PHYS_ADDR - pa + 1;
425 if (sz <= 1024 * 1024)
434 adj = round_page(pa) - pa;
436 sz = trunc_page(sz - adj);
454 adj = pa - trunc_page(pa);
456 sz = round_page(sz + adj);
459 panic(
"failed to exclude region %#jx-%#jx", (uintmax_t)pa,
460 (uintmax_t)(pa + sz));
487 TUNABLE_ULONG_FETCH(
"hw.physmem", &hwphyssz);
490 hwphyssz, NULL, NULL);
492 PHYS_AVAIL_ENTRIES, hwphyssz, &physmem, &
realmem);
494 panic(
"No memory entries in phys_avail");
495 Maxmem = atop(phys_avail[nextidx - 1]);
501DB_SHOW_COMMAND(physmem, db_show_physmem)
void panic(const char *fmt,...)
void physmem_hardware_region(uint64_t pa, uint64_t sz)
void physmem_init_kernel_globals(void)
size_t physmem_avail(vm_paddr_t *avail, size_t maxavail)
static struct region exregions[MAX_EXCNT]
void physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t exflags)
static size_t merge_upper_regions(struct region *regions, size_t rcnt, size_t idx)
static struct region hwregions[MAX_HWCNT]
static void physmem_dump_tables(int(*prfunc)(const char *,...))
void physmem_print_tables(void)
static size_t insert_region(struct region *regions, size_t rcnt, vm_paddr_t addr, vm_size_t size, uint32_t flags)
static size_t regions_to_avail(vm_paddr_t *avail, uint32_t exflags, size_t maxavail, uint64_t maxphyssz, long *pavail, long *prealmem)
int printf(const char *fmt,...)