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