111752d88SAlan Cox /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3fe267a55SPedro F. Giffuni *
411752d88SAlan Cox * Copyright (c) 2002-2006 Rice University
57bfda801SAlan Cox * Copyright (c) 2007 Alan L. Cox <alc@cs.rice.edu>
611752d88SAlan Cox * All rights reserved.
711752d88SAlan Cox *
811752d88SAlan Cox * This software was developed for the FreeBSD Project by Alan L. Cox,
911752d88SAlan Cox * Olivier Crameri, Peter Druschel, Sitaram Iyer, and Juan Navarro.
1011752d88SAlan Cox *
1111752d88SAlan Cox * Redistribution and use in source and binary forms, with or without
1211752d88SAlan Cox * modification, are permitted provided that the following conditions
1311752d88SAlan Cox * are met:
1411752d88SAlan Cox * 1. Redistributions of source code must retain the above copyright
1511752d88SAlan Cox * notice, this list of conditions and the following disclaimer.
1611752d88SAlan Cox * 2. Redistributions in binary form must reproduce the above copyright
1711752d88SAlan Cox * notice, this list of conditions and the following disclaimer in the
1811752d88SAlan Cox * documentation and/or other materials provided with the distribution.
1911752d88SAlan Cox *
2011752d88SAlan Cox * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2111752d88SAlan Cox * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2211752d88SAlan Cox * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2311752d88SAlan Cox * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2411752d88SAlan Cox * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2511752d88SAlan Cox * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2611752d88SAlan Cox * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
2711752d88SAlan Cox * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2811752d88SAlan Cox * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2911752d88SAlan Cox * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
3011752d88SAlan Cox * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3111752d88SAlan Cox * POSSIBILITY OF SUCH DAMAGE.
3211752d88SAlan Cox */
3311752d88SAlan Cox
3411752d88SAlan Cox /*
3511752d88SAlan Cox * Physical memory system definitions
3611752d88SAlan Cox */
3711752d88SAlan Cox
3811752d88SAlan Cox #ifndef _VM_PHYS_H_
3911752d88SAlan Cox #define _VM_PHYS_H_
4011752d88SAlan Cox
41e35395ceSAlan Cox #ifdef _KERNEL
42e35395ceSAlan Cox
439e817428SDoug Moore #include <vm/_vm_phys.h>
449e817428SDoug Moore
45431fb8abSMark Johnston extern vm_paddr_t phys_avail[];
4621943937SJeff Roberson
47a3870a18SJohn Baldwin /* Domains must be dense (non-sparse) and zero-based. */
48a3870a18SJohn Baldwin struct mem_affinity {
49a3870a18SJohn Baldwin vm_paddr_t start;
50a3870a18SJohn Baldwin vm_paddr_t end;
51a3870a18SJohn Baldwin int domain;
52a3870a18SJohn Baldwin };
53b6715dabSJeff Roberson #ifdef NUMA
54b6715dabSJeff Roberson extern struct mem_affinity *mem_affinity;
55b6715dabSJeff Roberson extern int *mem_locality;
56b6715dabSJeff Roberson #endif
57a3870a18SJohn Baldwin
58fbd80bd0SAlan Cox /*
59fbd80bd0SAlan Cox * The following functions are only to be used by the virtual memory system.
60fbd80bd0SAlan Cox */
61271f0f12SAlan Cox void vm_phys_add_seg(vm_paddr_t start, vm_paddr_t end);
62ef435ae7SJeff Roberson vm_page_t vm_phys_alloc_contig(int domain, u_long npages, vm_paddr_t low,
63ef435ae7SJeff Roberson vm_paddr_t high, u_long alignment, vm_paddr_t boundary);
64ef435ae7SJeff Roberson vm_page_t vm_phys_alloc_freelist_pages(int domain, int freelist, int pool,
65ef435ae7SJeff Roberson int order);
6689ea39a7SAlan Cox int vm_phys_alloc_npages(int domain, int pool, int npages, vm_page_t ma[]);
67ef435ae7SJeff Roberson vm_page_t vm_phys_alloc_pages(int domain, int pool, int order);
686f4acaf4SJeff Roberson int vm_phys_domain_match(int prefer, vm_paddr_t low, vm_paddr_t high);
69b8590daeSDoug Moore void vm_phys_enqueue_contig(vm_page_t m, u_long npages);
70b6de32bdSKonstantin Belousov int vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end,
71b6de32bdSKonstantin Belousov vm_memattr_t memattr);
72b6de32bdSKonstantin Belousov void vm_phys_fictitious_unreg_range(vm_paddr_t start, vm_paddr_t end);
73b6de32bdSKonstantin Belousov vm_page_t vm_phys_fictitious_to_vm_page(vm_paddr_t pa);
749e817428SDoug Moore int vm_phys_find_range(vm_page_t bounds[], int segind, int domain,
759e817428SDoug Moore u_long npages, vm_paddr_t low, vm_paddr_t high);
765c1f2cc4SAlan Cox void vm_phys_free_contig(vm_page_t m, u_long npages);
7711752d88SAlan Cox void vm_phys_free_pages(vm_page_t m, int order);
7811752d88SAlan Cox void vm_phys_init(void);
7943f48b65SKonstantin Belousov vm_page_t vm_phys_paddr_to_vm_page(vm_paddr_t pa);
80662e7fa8SMark Johnston void vm_phys_register_domains(int ndomains, struct mem_affinity *affinity,
81662e7fa8SMark Johnston int *locality);
826062d9faSMark Johnston bool vm_phys_unfree_page(vm_page_t m);
836520495aSAdrian Chadd int vm_phys_mem_affinity(int f, int t);
8481302f1dSMark Johnston void vm_phys_early_add_seg(vm_paddr_t start, vm_paddr_t end);
85b7565d44SJeff Roberson vm_paddr_t vm_phys_early_alloc(int domain, size_t alloc_size);
86b7565d44SJeff Roberson void vm_phys_early_startup(void);
87b7565d44SJeff Roberson int vm_phys_avail_largest(void);
88b7565d44SJeff Roberson vm_paddr_t vm_phys_avail_size(int i);
8931991a5aSMitchell Horne bool vm_phys_is_dumpable(vm_paddr_t pa);
90b7565d44SJeff Roberson
91ef435ae7SJeff Roberson static inline int
vm_phys_domain(vm_paddr_t pa __numa_used)92cb20a74cSStephen J. Kiernan vm_phys_domain(vm_paddr_t pa __numa_used)
93449c2e92SKonstantin Belousov {
94b6715dabSJeff Roberson #ifdef NUMA
95431fb8abSMark Johnston int i;
96449c2e92SKonstantin Belousov
97431fb8abSMark Johnston if (vm_ndomains == 1)
98431fb8abSMark Johnston return (0);
99431fb8abSMark Johnston for (i = 0; mem_affinity[i].end != 0; i++)
100431fb8abSMark Johnston if (mem_affinity[i].start <= pa &&
101431fb8abSMark Johnston mem_affinity[i].end >= pa)
102431fb8abSMark Johnston return (mem_affinity[i].domain);
103431fb8abSMark Johnston return (-1);
104b6715dabSJeff Roberson #else
105b6715dabSJeff Roberson return (0);
106b6715dabSJeff Roberson #endif
107449c2e92SKonstantin Belousov }
108449c2e92SKonstantin Belousov
1099e817428SDoug Moore /*
1109e817428SDoug Moore * Find the segind for the first segment at or after the given physical address.
1119e817428SDoug Moore */
1129e817428SDoug Moore static inline int
vm_phys_lookup_segind(vm_paddr_t pa)1139e817428SDoug Moore vm_phys_lookup_segind(vm_paddr_t pa)
1149e817428SDoug Moore {
1159e817428SDoug Moore u_int hi, lo, mid;
1169e817428SDoug Moore
1179e817428SDoug Moore lo = 0;
1189e817428SDoug Moore hi = vm_phys_nsegs;
1199e817428SDoug Moore while (lo != hi) {
1209e817428SDoug Moore /*
1219e817428SDoug Moore * for i in [0, lo), segs[i].end <= pa
1229e817428SDoug Moore * for i in [hi, nsegs), segs[i].end > pa
1239e817428SDoug Moore */
1249e817428SDoug Moore mid = lo + (hi - lo) / 2;
1259e817428SDoug Moore if (vm_phys_segs[mid].end <= pa)
1269e817428SDoug Moore lo = mid + 1;
1279e817428SDoug Moore else
1289e817428SDoug Moore hi = mid;
1299e817428SDoug Moore }
1309e817428SDoug Moore return (lo);
1319e817428SDoug Moore }
1329e817428SDoug Moore
1339e817428SDoug Moore /*
1349e817428SDoug Moore * Find the segment corresponding to the given physical address.
1359e817428SDoug Moore */
1369e817428SDoug Moore static inline struct vm_phys_seg *
vm_phys_paddr_to_seg(vm_paddr_t pa)1379e817428SDoug Moore vm_phys_paddr_to_seg(vm_paddr_t pa)
1389e817428SDoug Moore {
1399e817428SDoug Moore struct vm_phys_seg *seg;
1409e817428SDoug Moore int segind;
1419e817428SDoug Moore
1429e817428SDoug Moore segind = vm_phys_lookup_segind(pa);
1439e817428SDoug Moore if (segind < vm_phys_nsegs) {
1449e817428SDoug Moore seg = &vm_phys_segs[segind];
1459e817428SDoug Moore if (pa >= seg->start)
1469e817428SDoug Moore return (seg);
1479e817428SDoug Moore }
1489e817428SDoug Moore return (NULL);
1499e817428SDoug Moore }
1509e817428SDoug Moore
151e35395ceSAlan Cox #endif /* _KERNEL */
15211752d88SAlan Cox #endif /* !_VM_PHYS_H_ */
153