1 1.14 rin /* $NetBSD: pmap_kernel.c,v 1.14 2023/12/15 09:42:33 rin Exp $ */ 2 1.3 matt /*- 3 1.3 matt * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 1.3 matt * All rights reserved. 5 1.3 matt * 6 1.3 matt * This code is derived from software contributed to The NetBSD Foundation 7 1.3 matt * by Matt Thomas of 3am Software Foundry. 8 1.3 matt * 9 1.3 matt * Redistribution and use in source and binary forms, with or without 10 1.3 matt * modification, are permitted provided that the following conditions 11 1.3 matt * are met: 12 1.3 matt * 1. Redistributions of source code must retain the above copyright 13 1.3 matt * notice, this list of conditions and the following disclaimer. 14 1.3 matt * 2. Redistributions in binary form must reproduce the above copyright 15 1.3 matt * notice, this list of conditions and the following disclaimer in the 16 1.3 matt * documentation and/or other materials provided with the distribution. 17 1.3 matt * 18 1.3 matt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 1.3 matt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 1.3 matt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 1.3 matt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 1.3 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 1.3 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 1.3 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 1.3 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 1.3 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 1.3 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 1.3 matt * POSSIBILITY OF SUCH DAMAGE. 29 1.3 matt */ 30 1.3 matt 31 1.3 matt #include <sys/cdefs.h> 32 1.3 matt 33 1.14 rin __KERNEL_RCSID(1, "$NetBSD: pmap_kernel.c,v 1.14 2023/12/15 09:42:33 rin Exp $"); 34 1.3 matt 35 1.11 rin #ifdef _KERNEL_OPT 36 1.10 matt #include "opt_altivec.h" 37 1.3 matt #include "opt_ddb.h" 38 1.3 matt #include "opt_pmap.h" 39 1.11 rin #endif 40 1.2 pooka 41 1.1 pooka #include <sys/param.h> 42 1.14 rin #include <uvm/uvm.h> 43 1.1 pooka #include <uvm/uvm_extern.h> 44 1.14 rin #include <uvm/uvm_page.h> 45 1.3 matt 46 1.10 matt #ifdef ALTIVEC 47 1.10 matt int pmap_use_altivec; 48 1.10 matt #endif 49 1.10 matt volatile struct pteg *pmap_pteg_table; 50 1.10 matt unsigned int pmap_pteg_cnt; 51 1.10 matt unsigned int pmap_pteg_mask; 52 1.10 matt 53 1.10 matt struct pmap kernel_pmap_; 54 1.1 pooka struct pmap *const kernel_pmap_ptr = &kernel_pmap_; 55 1.3 matt 56 1.4 matt u_int 57 1.4 matt powerpc_mmap_flags(paddr_t pa) 58 1.4 matt { 59 1.9 matt u_int flags = PMAP_NOCACHE; 60 1.4 matt 61 1.4 matt if (pa & POWERPC_MMAP_FLAG_PREFETCHABLE) 62 1.4 matt flags |= PMAP_MD_PREFETCHABLE; 63 1.4 matt if (pa & POWERPC_MMAP_FLAG_CACHEABLE) 64 1.9 matt flags &= ~PMAP_NOCACHE; 65 1.4 matt return flags; 66 1.4 matt } 67 1.4 matt 68 1.14 rin struct vm_page * 69 1.14 rin pmap_alloc_poolpage(int flags) 70 1.14 rin { 71 1.14 rin 72 1.14 rin if (__predict_false(!uvm.page_init_done)) { 73 1.14 rin struct vm_page *pg; 74 1.14 rin paddr_t pa __diagused; 75 1.14 rin 76 1.14 rin pg = uvm_pagealloc(NULL, 0, NULL, flags); 77 1.14 rin KASSERT(pg != NULL); 78 1.14 rin pa = VM_PAGE_TO_PHYS(pg); 79 1.14 rin KASSERT(pa < PMAP_DIRECT_MAPPED_LEN); 80 1.14 rin return pg; 81 1.14 rin } 82 1.14 rin 83 1.14 rin return uvm_pagealloc_strat(NULL, 0, NULL, flags, UVM_PGA_STRAT_ONLY, 84 1.14 rin VM_FREELIST_DIRECT_MAPPED); 85 1.14 rin } 86 1.14 rin 87 1.3 matt #ifdef PMAP_NEEDS_FIXUP 88 1.3 matt #include <powerpc/instr.h> 89 1.3 matt 90 1.3 matt const struct pmap_ops *pmapops; 91 1.3 matt 92 1.8 matt #define __stub __section(".stub") __noprofile 93 1.3 matt 94 1.3 matt int pmap_pte_spill(struct pmap *, vaddr_t, bool) __stub; 95 1.3 matt void pmap_real_memory(paddr_t *, psize_t *) __stub; 96 1.3 matt void pmap_init(void) __stub; 97 1.3 matt void pmap_virtual_space(vaddr_t *, vaddr_t *) __stub; 98 1.3 matt pmap_t pmap_create(void) __stub; 99 1.3 matt void pmap_reference(pmap_t) __stub; 100 1.3 matt void pmap_destroy(pmap_t) __stub; 101 1.3 matt void pmap_copy(pmap_t, pmap_t, vaddr_t, vsize_t, vaddr_t) __stub; 102 1.3 matt void pmap_update(pmap_t) __stub; 103 1.3 matt int pmap_enter(pmap_t, vaddr_t, paddr_t, vm_prot_t, u_int) __stub; 104 1.3 matt void pmap_remove(pmap_t, vaddr_t, vaddr_t) __stub; 105 1.3 matt void pmap_kenter_pa(vaddr_t, paddr_t, vm_prot_t, u_int) __stub; 106 1.3 matt void pmap_kremove(vaddr_t, vsize_t) __stub; 107 1.3 matt bool pmap_extract(pmap_t, vaddr_t, paddr_t *) __stub; 108 1.3 matt 109 1.3 matt void pmap_protect(pmap_t, vaddr_t, vaddr_t, vm_prot_t) __stub; 110 1.3 matt void pmap_unwire(pmap_t, vaddr_t) __stub; 111 1.3 matt void pmap_page_protect(struct vm_page *, vm_prot_t) __stub; 112 1.3 matt bool pmap_query_bit(struct vm_page *, int) __stub; 113 1.3 matt bool pmap_clear_bit(struct vm_page *, int) __stub; 114 1.3 matt 115 1.3 matt void pmap_activate(struct lwp *) __stub; 116 1.3 matt void pmap_deactivate(struct lwp *) __stub; 117 1.3 matt 118 1.3 matt void pmap_pinit(pmap_t) __stub; 119 1.3 matt void pmap_procwr(struct proc *, vaddr_t, size_t) __stub; 120 1.3 matt 121 1.3 matt #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 122 1.3 matt void pmap_pte_print(volatile struct pte *) __stub; 123 1.3 matt void pmap_pteg_check(void) __stub; 124 1.3 matt void pmap_print_mmuregs(void) __stub; 125 1.3 matt void pmap_print_pte(pmap_t, vaddr_t) __stub; 126 1.3 matt void pmap_pteg_dist(void) __stub; 127 1.3 matt #endif 128 1.3 matt #if defined(DEBUG) || defined(PMAPCHECK) 129 1.3 matt void pmap_pvo_verify(void) __stub; 130 1.3 matt #endif 131 1.3 matt vaddr_t pmap_steal_memory(vsize_t, vaddr_t *, vaddr_t *) __stub; 132 1.3 matt void pmap_bootstrap(paddr_t, paddr_t) __stub; 133 1.12 thorpej void pmap_bootstrap1(paddr_t, paddr_t) __stub; 134 1.12 thorpej void pmap_bootstrap2(void) __stub; 135 1.3 matt 136 1.3 matt int 137 1.3 matt pmap_pte_spill(struct pmap *pm, vaddr_t va, bool exec) 138 1.3 matt { 139 1.3 matt return (*pmapops->pmapop_pte_spill)(pm, va, exec); 140 1.3 matt } 141 1.3 matt 142 1.3 matt void 143 1.3 matt pmap_real_memory(paddr_t *start, psize_t *size) 144 1.3 matt { 145 1.3 matt (*pmapops->pmapop_real_memory)(start, size); 146 1.3 matt } 147 1.3 matt 148 1.3 matt void 149 1.3 matt pmap_init(void) 150 1.3 matt { 151 1.3 matt (*pmapops->pmapop_init)(); 152 1.3 matt } 153 1.3 matt 154 1.3 matt void 155 1.3 matt pmap_virtual_space(vaddr_t *startp, vaddr_t *endp) 156 1.3 matt { 157 1.3 matt (*pmapops->pmapop_virtual_space)(startp, endp); 158 1.3 matt } 159 1.3 matt 160 1.3 matt pmap_t 161 1.3 matt pmap_create(void) 162 1.3 matt { 163 1.3 matt return (*pmapops->pmapop_create)(); 164 1.3 matt } 165 1.3 matt 166 1.3 matt void 167 1.3 matt pmap_reference(pmap_t pm) 168 1.3 matt { 169 1.3 matt (*pmapops->pmapop_reference)(pm); 170 1.3 matt } 171 1.3 matt 172 1.3 matt void 173 1.3 matt pmap_destroy(pmap_t pm) 174 1.3 matt { 175 1.3 matt (*pmapops->pmapop_destroy)(pm); 176 1.3 matt } 177 1.3 matt 178 1.3 matt void 179 1.3 matt pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vaddr_t dst_va, vsize_t len, 180 1.3 matt vaddr_t src_va) 181 1.3 matt { 182 1.3 matt (*pmapops->pmapop_copy)(dst_pmap, src_pmap, dst_va, len, src_va); 183 1.3 matt } 184 1.3 matt 185 1.3 matt void 186 1.3 matt pmap_update(pmap_t pm) 187 1.3 matt { 188 1.3 matt (*pmapops->pmapop_update)(pm); 189 1.3 matt } 190 1.3 matt 191 1.3 matt int 192 1.3 matt pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 193 1.3 matt { 194 1.3 matt return (*pmapops->pmapop_enter)(pm, va, pa, prot, flags); 195 1.3 matt } 196 1.3 matt 197 1.3 matt void 198 1.3 matt pmap_remove(pmap_t pm, vaddr_t start, vaddr_t end) 199 1.3 matt { 200 1.3 matt (*pmapops->pmapop_remove)(pm, start, end); 201 1.3 matt } 202 1.3 matt 203 1.3 matt void 204 1.3 matt pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 205 1.3 matt { 206 1.3 matt (*pmapops->pmapop_kenter_pa)(va, pa, prot, flags); 207 1.3 matt } 208 1.3 matt 209 1.3 matt void 210 1.3 matt pmap_kremove(vaddr_t start, vsize_t end) 211 1.3 matt { 212 1.3 matt (*pmapops->pmapop_kremove)(start, end); 213 1.3 matt } 214 1.3 matt 215 1.3 matt bool 216 1.3 matt pmap_extract(pmap_t pm, vaddr_t va, paddr_t *pap) 217 1.3 matt { 218 1.3 matt return (*pmapops->pmapop_extract)(pm, va, pap); 219 1.3 matt } 220 1.3 matt 221 1.3 matt void 222 1.3 matt pmap_protect(pmap_t pm, vaddr_t start, vaddr_t end, vm_prot_t prot) 223 1.3 matt { 224 1.3 matt (*pmapops->pmapop_protect)(pm, start, end, prot); 225 1.3 matt } 226 1.3 matt 227 1.3 matt void 228 1.3 matt pmap_unwire(pmap_t pm, vaddr_t va) 229 1.3 matt { 230 1.3 matt (*pmapops->pmapop_unwire)(pm, va); 231 1.3 matt } 232 1.3 matt 233 1.3 matt void 234 1.3 matt pmap_page_protect(struct vm_page *pg, vm_prot_t prot) 235 1.3 matt { 236 1.3 matt (*pmapops->pmapop_page_protect)(pg, prot); 237 1.3 matt } 238 1.3 matt 239 1.13 riastrad void 240 1.13 riastrad pmap_pv_protect(paddr_t pa, vm_prot_t prot) 241 1.13 riastrad { 242 1.13 riastrad (*pmapops->pmapop_pv_protect)(pa, prot); 243 1.13 riastrad } 244 1.13 riastrad 245 1.3 matt bool 246 1.3 matt pmap_query_bit(struct vm_page *pg, int ptebit) 247 1.3 matt { 248 1.3 matt return (*pmapops->pmapop_query_bit)(pg, ptebit); 249 1.3 matt } 250 1.3 matt 251 1.3 matt bool 252 1.3 matt pmap_clear_bit(struct vm_page *pg, int ptebit) 253 1.3 matt { 254 1.3 matt return (*pmapops->pmapop_clear_bit)(pg, ptebit); 255 1.3 matt } 256 1.3 matt 257 1.3 matt void 258 1.3 matt pmap_activate(struct lwp *l) 259 1.3 matt { 260 1.3 matt (*pmapops->pmapop_activate)(l); 261 1.3 matt } 262 1.3 matt 263 1.3 matt void 264 1.3 matt pmap_deactivate(struct lwp *l) 265 1.3 matt { 266 1.3 matt (*pmapops->pmapop_deactivate)(l); 267 1.3 matt } 268 1.3 matt 269 1.3 matt void 270 1.3 matt pmap_pinit(pmap_t pm) 271 1.3 matt { 272 1.3 matt (*pmapops->pmapop_pinit)(pm); 273 1.3 matt } 274 1.3 matt 275 1.3 matt void 276 1.3 matt pmap_procwr(struct proc *p, vaddr_t va, size_t len) 277 1.3 matt { 278 1.3 matt (*pmapops->pmapop_procwr)(p, va, len); 279 1.3 matt } 280 1.3 matt 281 1.3 matt #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 282 1.3 matt void 283 1.3 matt pmap_pte_print(volatile struct pte *ptep) 284 1.3 matt { 285 1.3 matt (*pmapops->pmapop_pte_print)(ptep); 286 1.3 matt } 287 1.3 matt 288 1.3 matt void 289 1.3 matt pmap_pteg_check(void) 290 1.3 matt { 291 1.3 matt (*pmapops->pmapop_pteg_check)(); 292 1.3 matt } 293 1.3 matt 294 1.3 matt void 295 1.3 matt pmap_print_mmuregs(void) 296 1.3 matt { 297 1.3 matt (*pmapops->pmapop_print_mmuregs)(); 298 1.3 matt } 299 1.3 matt 300 1.3 matt void 301 1.3 matt pmap_print_pte(pmap_t pm, vaddr_t va) 302 1.3 matt { 303 1.3 matt (*pmapops->pmapop_print_pte)(pm, va); 304 1.3 matt } 305 1.3 matt 306 1.3 matt void 307 1.3 matt pmap_pteg_dist(void) 308 1.3 matt { 309 1.3 matt (*pmapops->pmapop_pteg_dist)(); 310 1.3 matt } 311 1.3 matt #endif 312 1.3 matt 313 1.3 matt #if defined(DEBUG) || defined(PMAPCHECK) 314 1.3 matt void 315 1.3 matt pmap_pvo_verify(void) 316 1.3 matt { 317 1.7 rjs (*pmapops->pmapop_pvo_verify)(); 318 1.3 matt } 319 1.3 matt #endif 320 1.3 matt 321 1.3 matt vaddr_t 322 1.3 matt pmap_steal_memory(vsize_t vsize, vaddr_t *vstartp, vaddr_t *vendp) 323 1.3 matt { 324 1.3 matt return (*pmapops->pmapop_steal_memory)(vsize, vstartp, vendp); 325 1.3 matt } 326 1.3 matt 327 1.3 matt void 328 1.3 matt pmap_bootstrap(paddr_t startkernel, paddr_t endkernel) 329 1.3 matt { 330 1.3 matt (*pmapops->pmapop_bootstrap)(startkernel, endkernel); 331 1.3 matt } 332 1.12 thorpej 333 1.12 thorpej void 334 1.12 thorpej pmap_bootstrap1(paddr_t startkernel, paddr_t endkernel) 335 1.12 thorpej { 336 1.12 thorpej (*pmapops->pmapop_bootstrap1)(startkernel, endkernel); 337 1.12 thorpej } 338 1.12 thorpej 339 1.12 thorpej void 340 1.12 thorpej pmap_bootstrap2(void) 341 1.12 thorpej { 342 1.12 thorpej (*pmapops->pmapop_bootstrap2)(); 343 1.12 thorpej } 344 1.3 matt #endif 345