1 1.28 skrll /* $NetBSD: pmap.h,v 1.28 2024/11/25 22:03:44 skrll Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (c) 1992, 1993 5 1.1 christos * The Regents of the University of California. All rights reserved. 6 1.1 christos * 7 1.1 christos * This code is derived from software contributed to Berkeley by 8 1.1 christos * Ralph Campbell. 9 1.1 christos * 10 1.1 christos * Redistribution and use in source and binary forms, with or without 11 1.1 christos * modification, are permitted provided that the following conditions 12 1.1 christos * are met: 13 1.1 christos * 1. Redistributions of source code must retain the above copyright 14 1.1 christos * notice, this list of conditions and the following disclaimer. 15 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 christos * notice, this list of conditions and the following disclaimer in the 17 1.1 christos * documentation and/or other materials provided with the distribution. 18 1.1 christos * 3. Neither the name of the University nor the names of its contributors 19 1.1 christos * may be used to endorse or promote products derived from this software 20 1.1 christos * without specific prior written permission. 21 1.1 christos * 22 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 1.1 christos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.1 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.1 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.1 christos * SUCH DAMAGE. 33 1.1 christos * 34 1.1 christos * @(#)pmap.h 8.1 (Berkeley) 6/10/93 35 1.1 christos */ 36 1.1 christos 37 1.1 christos /* 38 1.1 christos * Copyright (c) 1987 Carnegie-Mellon University 39 1.1 christos * 40 1.1 christos * This code is derived from software contributed to Berkeley by 41 1.1 christos * Ralph Campbell. 42 1.1 christos * 43 1.1 christos * Redistribution and use in source and binary forms, with or without 44 1.1 christos * modification, are permitted provided that the following conditions 45 1.1 christos * are met: 46 1.1 christos * 1. Redistributions of source code must retain the above copyright 47 1.1 christos * notice, this list of conditions and the following disclaimer. 48 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 49 1.1 christos * notice, this list of conditions and the following disclaimer in the 50 1.1 christos * documentation and/or other materials provided with the distribution. 51 1.1 christos * 3. All advertising materials mentioning features or use of this software 52 1.1 christos * must display the following acknowledgement: 53 1.1 christos * This product includes software developed by the University of 54 1.1 christos * California, Berkeley and its contributors. 55 1.1 christos * 4. Neither the name of the University nor the names of its contributors 56 1.1 christos * may be used to endorse or promote products derived from this software 57 1.1 christos * without specific prior written permission. 58 1.1 christos * 59 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 1.1 christos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 1.1 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 1.1 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 1.1 christos * SUCH DAMAGE. 70 1.1 christos * 71 1.1 christos * @(#)pmap.h 8.1 (Berkeley) 6/10/93 72 1.1 christos */ 73 1.1 christos 74 1.26 skrll #ifdef _KERNEL_OPT 75 1.25 skrll #include "opt_efi.h" 76 1.26 skrll #endif 77 1.25 skrll 78 1.8 skrll #ifndef _UVM_PMAP_PMAP_H_ 79 1.8 skrll #define _UVM_PMAP_PMAP_H_ 80 1.1 christos 81 1.22 skrll #include <sys/rwlock.h> 82 1.22 skrll #include <uvm/uvm_object.h> 83 1.28 skrll #include <uvm/uvm_pmap.h> 84 1.1 christos #include <uvm/uvm_stat.h> 85 1.22 skrll 86 1.28 skrll #ifdef _KERNEL 87 1.28 skrll 88 1.1 christos #ifdef UVMHIST 89 1.1 christos UVMHIST_DECL(pmapexechist); 90 1.1 christos UVMHIST_DECL(pmaphist); 91 1.22 skrll UVMHIST_DECL(pmapxtabhist); 92 1.22 skrll #endif 93 1.22 skrll 94 1.22 skrll /* 95 1.22 skrll * Alternate mapping hooks for pool pages. Avoids thrashing the TLB. 96 1.22 skrll */ 97 1.22 skrll struct vm_page *pmap_md_alloc_poolpage(int); 98 1.22 skrll 99 1.22 skrll #if !defined(KASAN) 100 1.22 skrll vaddr_t pmap_map_poolpage(paddr_t); 101 1.22 skrll paddr_t pmap_unmap_poolpage(vaddr_t); 102 1.22 skrll #define PMAP_ALLOC_POOLPAGE(flags) pmap_md_alloc_poolpage(flags) 103 1.22 skrll #define PMAP_MAP_POOLPAGE(pa) pmap_map_poolpage(pa) 104 1.22 skrll #define PMAP_UNMAP_POOLPAGE(va) pmap_unmap_poolpage(va) 105 1.22 skrll 106 1.22 skrll #if defined(_LP64) 107 1.22 skrll #define PMAP_DIRECT 108 1.22 skrll static __inline int 109 1.22 skrll pmap_direct_process(paddr_t pa, voff_t pgoff, size_t len, 110 1.22 skrll int (*process)(void *, size_t, void *), void *arg) 111 1.22 skrll { 112 1.22 skrll vaddr_t va = pmap_md_direct_map_paddr(pa); 113 1.22 skrll 114 1.22 skrll return process((void *)(va + pgoff), len, arg); 115 1.22 skrll } 116 1.1 christos #endif 117 1.22 skrll #endif 118 1.22 skrll 119 1.22 skrll #define PMAP_MAP_PDETABPAGE(pa) pmap_md_map_poolpage(pa, PAGE_SIZE) 120 1.22 skrll #define PMAP_MAP_SEGTABPAGE(pa) pmap_md_map_poolpage(pa, PAGE_SIZE) 121 1.22 skrll #define PMAP_MAP_PTEPAGE(pa) pmap_md_map_poolpage(pa, PAGE_SIZE) 122 1.1 christos 123 1.1 christos /* 124 1.1 christos * The user address space is mapped using a two level structure where 125 1.1 christos * virtual address bits 31..22 are used to index into a segment table which 126 1.1 christos * points to a page worth of PTEs (4096 page can hold 1024 PTEs). 127 1.1 christos * Bits 21..12 are then used to index a PTE which describes a page within 128 1.1 christos * a segment. 129 1.1 christos */ 130 1.1 christos 131 1.1 christos #define pmap_trunc_seg(x) ((vaddr_t)(x) & ~SEGOFSET) 132 1.1 christos #define pmap_round_seg(x) (((vaddr_t)(x) + SEGOFSET) & ~SEGOFSET) 133 1.1 christos 134 1.1 christos /* 135 1.22 skrll * Each ptpage maps a "segment" worth of address space. That is 136 1.22 skrll * NPTEPG * PAGE_SIZE. 137 1.1 christos */ 138 1.22 skrll 139 1.28 skrll #endif /* _KERNEL */ 140 1.28 skrll 141 1.22 skrll typedef struct { 142 1.22 skrll pt_entry_t ppg_ptes[NPTEPG]; 143 1.22 skrll } pmap_ptpage_t; 144 1.22 skrll 145 1.22 skrll #if defined(PMAP_HWPAGEWALKER) 146 1.22 skrll typedef union pmap_pdetab { 147 1.22 skrll pd_entry_t pde_pde[PMAP_PDETABSIZE]; 148 1.22 skrll union pmap_pdetab * pde_next; 149 1.22 skrll } pmap_pdetab_t; 150 1.22 skrll #endif 151 1.22 skrll #if !defined(PMAP_HWPAGEWALKER) || !defined(PMAP_MAP_PDETABPAGE) 152 1.1 christos typedef union pmap_segtab { 153 1.22 skrll #ifdef _LP64 154 1.1 christos union pmap_segtab * seg_seg[PMAP_SEGTABSIZE]; 155 1.22 skrll #endif 156 1.22 skrll pmap_ptpage_t * seg_ppg[PMAP_SEGTABSIZE]; 157 1.22 skrll #ifdef PMAP_HWPAGEWALKER 158 1.22 skrll pd_entry_t seg_pde[PMAP_PDETABSIZE]; 159 1.22 skrll #endif 160 1.22 skrll union pmap_segtab * seg_next; 161 1.1 christos } pmap_segtab_t; 162 1.22 skrll #endif 163 1.22 skrll 164 1.1 christos 165 1.1 christos #ifdef _KERNEL 166 1.1 christos struct pmap; 167 1.1 christos typedef bool (*pte_callback_t)(struct pmap *, vaddr_t, vaddr_t, 168 1.1 christos pt_entry_t *, uintptr_t); 169 1.15 skrll 170 1.15 skrll /* 171 1.15 skrll * Common part of the bootstraping the system enough to run with 172 1.15 skrll * virtual memory. 173 1.15 skrll */ 174 1.13 thorpej void pmap_bootstrap_common(void); 175 1.22 skrll 176 1.1 christos pt_entry_t *pmap_pte_lookup(struct pmap *, vaddr_t); 177 1.1 christos pt_entry_t *pmap_pte_reserve(struct pmap *, vaddr_t, int); 178 1.1 christos void pmap_pte_process(struct pmap *, vaddr_t, vaddr_t, pte_callback_t, 179 1.1 christos uintptr_t); 180 1.1 christos void pmap_segtab_activate(struct pmap *, struct lwp *); 181 1.16 skrll void pmap_segtab_deactivate(struct pmap *); 182 1.1 christos void pmap_segtab_init(struct pmap *); 183 1.1 christos void pmap_segtab_destroy(struct pmap *, pte_callback_t, uintptr_t); 184 1.22 skrll #ifdef PMAP_HWPAGEWALKER 185 1.22 skrll pd_entry_t *pmap_pde_lookup(struct pmap *, vaddr_t, paddr_t *); 186 1.22 skrll bool pmap_pdetab_fixup(struct pmap *, vaddr_t); 187 1.22 skrll #endif 188 1.1 christos extern kmutex_t pmap_segtab_lock; 189 1.1 christos #endif /* _KERNEL */ 190 1.1 christos 191 1.3 matt #ifdef MULTIPROCESSOR 192 1.3 matt #include <sys/kcpuset.h> 193 1.3 matt #endif 194 1.2 matt #include <uvm/pmap/pmap_tlb.h> 195 1.1 christos 196 1.1 christos /* 197 1.1 christos * Machine dependent pmap structure. 198 1.1 christos */ 199 1.1 christos struct pmap { 200 1.22 skrll struct uvm_object pm_uobject; 201 1.24 skrll #define pm_refcnt pm_uobject.uo_refs /* pmap reference count */ 202 1.22 skrll #define pm_pvp_list pm_uobject.memq 203 1.22 skrll 204 1.22 skrll krwlock_t pm_obj_lock; /* lock for pm_uobject */ 205 1.22 skrll #define pm_lock pm_uobject.vmobjlock 206 1.22 skrll 207 1.22 skrll struct pglist pm_ppg_list; 208 1.22 skrll #if defined(PMAP_HWPAGEWALKER) 209 1.22 skrll struct pglist pm_pdetab_list; 210 1.22 skrll #endif 211 1.22 skrll #if !defined(PMAP_HWPAGEWALKER) || !defined(PMAP_MAP_PDETABPAGE) 212 1.22 skrll struct pglist pm_segtab_list; 213 1.22 skrll #endif 214 1.1 christos #ifdef MULTIPROCESSOR 215 1.3 matt kcpuset_t *pm_active; /* pmap was active on ... */ 216 1.3 matt kcpuset_t *pm_onproc; /* pmap is active on ... */ 217 1.1 christos volatile u_int pm_shootdown_pending; 218 1.1 christos #endif 219 1.22 skrll #if defined(PMAP_HWPAGEWALKER) 220 1.22 skrll pmap_pdetab_t * pm_pdetab; /* pointer to HW PDEs */ 221 1.22 skrll #endif 222 1.22 skrll #if !defined(PMAP_HWPAGEWALKER) || !defined(PMAP_MAP_PDETABPAGE) 223 1.22 skrll pmap_segtab_t * pm_segtab; /* pointers to pages of PTEs; or */ 224 1.22 skrll /* virtual shadow of HW PDEs */ 225 1.22 skrll #endif 226 1.1 christos u_int pm_flags; 227 1.11 skrll #define PMAP_DEFERRED_ACTIVATE __BIT(0) 228 1.1 christos struct pmap_statistics pm_stats; /* pmap statistics */ 229 1.1 christos vaddr_t pm_minaddr; 230 1.1 christos vaddr_t pm_maxaddr; 231 1.12 maxv #ifdef __HAVE_PMAP_MD 232 1.12 maxv struct pmap_md pm_md; 233 1.12 maxv #endif 234 1.1 christos struct pmap_asid_info pm_pai[1]; 235 1.1 christos }; 236 1.1 christos 237 1.23 skrll 238 1.23 skrll #ifdef _KERNEL 239 1.22 skrll static inline void 240 1.22 skrll pmap_lock(struct pmap *pm) 241 1.22 skrll { 242 1.22 skrll 243 1.22 skrll rw_enter(pm->pm_lock, RW_WRITER); 244 1.22 skrll } 245 1.22 skrll 246 1.22 skrll static inline void 247 1.22 skrll pmap_unlock(struct pmap *pm) 248 1.22 skrll { 249 1.22 skrll 250 1.22 skrll rw_exit(pm->pm_lock); 251 1.22 skrll } 252 1.22 skrll 253 1.1 christos struct pmap_kernel { 254 1.1 christos struct pmap kernel_pmap; 255 1.3 matt #if defined(MULTIPROCESSOR) && PMAP_TLB_MAX > 1 256 1.3 matt struct pmap_asid_info kernel_pai[PMAP_TLB_MAX-1]; 257 1.1 christos #endif 258 1.1 christos }; 259 1.1 christos 260 1.1 christos struct pmap_limits { 261 1.1 christos paddr_t avail_start; 262 1.1 christos paddr_t avail_end; 263 1.5 matt vaddr_t virtual_start; 264 1.1 christos vaddr_t virtual_end; 265 1.1 christos }; 266 1.1 christos 267 1.7 matt /* 268 1.7 matt * Initialize the kernel pmap. 269 1.9 skrll */ 270 1.7 matt #ifdef MULTIPROCESSOR 271 1.7 matt #define PMAP_SIZE offsetof(struct pmap, pm_pai[PMAP_TLB_MAX]) 272 1.10 skrll #else 273 1.7 matt #define PMAP_SIZE sizeof(struct pmap) 274 1.10 skrll #endif 275 1.7 matt 276 1.10 skrll /* 277 1.1 christos * The pools from which pmap structures and sub-structures are allocated. 278 1.1 christos */ 279 1.6 msaitoh extern struct pool pmap_pmap_pool; 280 1.1 christos extern struct pool pmap_pv_pool; 281 1.1 christos extern struct pool_allocator pmap_pv_page_allocator; 282 1.1 christos 283 1.1 christos extern struct pmap_kernel kernel_pmap_store; 284 1.1 christos extern struct pmap_limits pmap_limits; 285 1.1 christos 286 1.7 matt extern u_int pmap_page_colormask; 287 1.7 matt 288 1.20 skrll /* 289 1.20 skrll * The current top of kernel VM 290 1.20 skrll */ 291 1.20 skrll extern vaddr_t pmap_curmaxkvaddr; 292 1.20 skrll 293 1.22 skrll #if defined(PMAP_HWPAGEWALKER) 294 1.22 skrll extern pmap_pdetab_t pmap_kern_pdetab; 295 1.22 skrll #else 296 1.22 skrll extern pmap_segtab_t pmap_kern_segtab; 297 1.22 skrll #endif 298 1.22 skrll 299 1.1 christos #define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count) 300 1.1 christos #define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) 301 1.1 christos 302 1.14 rin bool pmap_remove_all(pmap_t); 303 1.1 christos void pmap_set_modified(paddr_t); 304 1.27 skrll bool pmap_page_clear_attributes(struct vm_page_md *, u_long); 305 1.27 skrll void pmap_page_set_attributes(struct vm_page_md *, u_long); 306 1.1 christos void pmap_pvlist_lock_init(size_t); 307 1.7 matt #ifdef PMAP_VIRTUAL_CACHE_ALIASES 308 1.19 skrll void pmap_page_cache(struct vm_page_md *, bool); 309 1.7 matt #endif 310 1.7 matt 311 1.21 rin #if defined(__HAVE_PMAP_PV_TRACK) && !defined(PMAP_PV_TRACK_ONLY_STUBS) 312 1.18 skrll void pmap_pv_protect(paddr_t, vm_prot_t); 313 1.18 skrll #endif 314 1.1 christos 315 1.1 christos #define PMAP_WB 0 316 1.1 christos #define PMAP_WBINV 1 317 1.1 christos #define PMAP_INV 2 318 1.1 christos 319 1.7 matt kmutex_t *pmap_pvlist_lock_addr(struct vm_page_md *); 320 1.1 christos 321 1.1 christos #define PMAP_STEAL_MEMORY /* enable pmap_steal_memory() */ 322 1.1 christos #define PMAP_GROWKERNEL /* enable pmap_growkernel() */ 323 1.1 christos 324 1.7 matt #define PMAP_COUNT(name) (pmap_evcnt_##name.ev_count++ + 0) 325 1.7 matt #define PMAP_COUNTER(name, desc) \ 326 1.7 matt struct evcnt pmap_evcnt_##name = \ 327 1.7 matt EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "pmap", desc); \ 328 1.7 matt EVCNT_ATTACH_STATIC(pmap_evcnt_##name) 329 1.7 matt 330 1.22 skrll 331 1.22 skrll static inline pt_entry_t * 332 1.22 skrll kvtopte(vaddr_t va) 333 1.22 skrll { 334 1.22 skrll 335 1.22 skrll return pmap_pte_lookup(pmap_kernel(), va); 336 1.22 skrll } 337 1.22 skrll 338 1.22 skrll /* for ddb */ 339 1.22 skrll void pmap_db_pmap_print(struct pmap *, void (*)(const char *, ...) __printflike(1, 2)); 340 1.22 skrll void pmap_db_mdpg_print(struct vm_page *, void (*)(const char *, ...) __printflike(1, 2)); 341 1.22 skrll 342 1.22 skrll #if defined(EFI_RUNTIME) 343 1.22 skrll struct pmap * 344 1.22 skrll pmap_efirt(void); 345 1.22 skrll 346 1.22 skrll #define pmap_activate_efirt() pmap_md_activate_efirt() 347 1.22 skrll #define pmap_deactivate_efirt() pmap_md_deactivate_efirt() 348 1.22 skrll 349 1.22 skrll #endif 350 1.22 skrll 351 1.1 christos #endif /* _KERNEL */ 352 1.8 skrll #endif /* _UVM_PMAP_PMAP_H_ */ 353