1 /* $NetBSD: pmap_kernel.c,v 1.12 2021/03/02 01:47:44 thorpej 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.12 2021/03/02 01:47:44 thorpej 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_extern.h> 43 44 #ifdef ALTIVEC 45 int pmap_use_altivec; 46 #endif 47 volatile struct pteg *pmap_pteg_table; 48 unsigned int pmap_pteg_cnt; 49 unsigned int pmap_pteg_mask; 50 51 struct pmap kernel_pmap_; 52 struct pmap *const kernel_pmap_ptr = &kernel_pmap_; 53 54 u_int 55 powerpc_mmap_flags(paddr_t pa) 56 { 57 u_int flags = PMAP_NOCACHE; 58 59 if (pa & POWERPC_MMAP_FLAG_PREFETCHABLE) 60 flags |= PMAP_MD_PREFETCHABLE; 61 if (pa & POWERPC_MMAP_FLAG_CACHEABLE) 62 flags &= ~PMAP_NOCACHE; 63 return flags; 64 } 65 66 #ifdef PMAP_NEEDS_FIXUP 67 #include <powerpc/instr.h> 68 69 const struct pmap_ops *pmapops; 70 71 #define __stub __section(".stub") __noprofile 72 73 int pmap_pte_spill(struct pmap *, vaddr_t, bool) __stub; 74 void pmap_real_memory(paddr_t *, psize_t *) __stub; 75 void pmap_init(void) __stub; 76 void pmap_virtual_space(vaddr_t *, vaddr_t *) __stub; 77 pmap_t pmap_create(void) __stub; 78 void pmap_reference(pmap_t) __stub; 79 void pmap_destroy(pmap_t) __stub; 80 void pmap_copy(pmap_t, pmap_t, vaddr_t, vsize_t, vaddr_t) __stub; 81 void pmap_update(pmap_t) __stub; 82 int pmap_enter(pmap_t, vaddr_t, paddr_t, vm_prot_t, u_int) __stub; 83 void pmap_remove(pmap_t, vaddr_t, vaddr_t) __stub; 84 void pmap_kenter_pa(vaddr_t, paddr_t, vm_prot_t, u_int) __stub; 85 void pmap_kremove(vaddr_t, vsize_t) __stub; 86 bool pmap_extract(pmap_t, vaddr_t, paddr_t *) __stub; 87 88 void pmap_protect(pmap_t, vaddr_t, vaddr_t, vm_prot_t) __stub; 89 void pmap_unwire(pmap_t, vaddr_t) __stub; 90 void pmap_page_protect(struct vm_page *, vm_prot_t) __stub; 91 bool pmap_query_bit(struct vm_page *, int) __stub; 92 bool pmap_clear_bit(struct vm_page *, int) __stub; 93 94 void pmap_activate(struct lwp *) __stub; 95 void pmap_deactivate(struct lwp *) __stub; 96 97 void pmap_pinit(pmap_t) __stub; 98 void pmap_procwr(struct proc *, vaddr_t, size_t) __stub; 99 100 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 101 void pmap_pte_print(volatile struct pte *) __stub; 102 void pmap_pteg_check(void) __stub; 103 void pmap_print_mmuregs(void) __stub; 104 void pmap_print_pte(pmap_t, vaddr_t) __stub; 105 void pmap_pteg_dist(void) __stub; 106 #endif 107 #if defined(DEBUG) || defined(PMAPCHECK) 108 void pmap_pvo_verify(void) __stub; 109 #endif 110 vaddr_t pmap_steal_memory(vsize_t, vaddr_t *, vaddr_t *) __stub; 111 void pmap_bootstrap(paddr_t, paddr_t) __stub; 112 void pmap_bootstrap1(paddr_t, paddr_t) __stub; 113 void pmap_bootstrap2(void) __stub; 114 115 int 116 pmap_pte_spill(struct pmap *pm, vaddr_t va, bool exec) 117 { 118 return (*pmapops->pmapop_pte_spill)(pm, va, exec); 119 } 120 121 void 122 pmap_real_memory(paddr_t *start, psize_t *size) 123 { 124 (*pmapops->pmapop_real_memory)(start, size); 125 } 126 127 void 128 pmap_init(void) 129 { 130 (*pmapops->pmapop_init)(); 131 } 132 133 void 134 pmap_virtual_space(vaddr_t *startp, vaddr_t *endp) 135 { 136 (*pmapops->pmapop_virtual_space)(startp, endp); 137 } 138 139 pmap_t 140 pmap_create(void) 141 { 142 return (*pmapops->pmapop_create)(); 143 } 144 145 void 146 pmap_reference(pmap_t pm) 147 { 148 (*pmapops->pmapop_reference)(pm); 149 } 150 151 void 152 pmap_destroy(pmap_t pm) 153 { 154 (*pmapops->pmapop_destroy)(pm); 155 } 156 157 void 158 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vaddr_t dst_va, vsize_t len, 159 vaddr_t src_va) 160 { 161 (*pmapops->pmapop_copy)(dst_pmap, src_pmap, dst_va, len, src_va); 162 } 163 164 void 165 pmap_update(pmap_t pm) 166 { 167 (*pmapops->pmapop_update)(pm); 168 } 169 170 int 171 pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 172 { 173 return (*pmapops->pmapop_enter)(pm, va, pa, prot, flags); 174 } 175 176 void 177 pmap_remove(pmap_t pm, vaddr_t start, vaddr_t end) 178 { 179 (*pmapops->pmapop_remove)(pm, start, end); 180 } 181 182 void 183 pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 184 { 185 (*pmapops->pmapop_kenter_pa)(va, pa, prot, flags); 186 } 187 188 void 189 pmap_kremove(vaddr_t start, vsize_t end) 190 { 191 (*pmapops->pmapop_kremove)(start, end); 192 } 193 194 bool 195 pmap_extract(pmap_t pm, vaddr_t va, paddr_t *pap) 196 { 197 return (*pmapops->pmapop_extract)(pm, va, pap); 198 } 199 200 void 201 pmap_protect(pmap_t pm, vaddr_t start, vaddr_t end, vm_prot_t prot) 202 { 203 (*pmapops->pmapop_protect)(pm, start, end, prot); 204 } 205 206 void 207 pmap_unwire(pmap_t pm, vaddr_t va) 208 { 209 (*pmapops->pmapop_unwire)(pm, va); 210 } 211 212 void 213 pmap_page_protect(struct vm_page *pg, vm_prot_t prot) 214 { 215 (*pmapops->pmapop_page_protect)(pg, prot); 216 } 217 218 bool 219 pmap_query_bit(struct vm_page *pg, int ptebit) 220 { 221 return (*pmapops->pmapop_query_bit)(pg, ptebit); 222 } 223 224 bool 225 pmap_clear_bit(struct vm_page *pg, int ptebit) 226 { 227 return (*pmapops->pmapop_clear_bit)(pg, ptebit); 228 } 229 230 void 231 pmap_activate(struct lwp *l) 232 { 233 (*pmapops->pmapop_activate)(l); 234 } 235 236 void 237 pmap_deactivate(struct lwp *l) 238 { 239 (*pmapops->pmapop_deactivate)(l); 240 } 241 242 void 243 pmap_pinit(pmap_t pm) 244 { 245 (*pmapops->pmapop_pinit)(pm); 246 } 247 248 void 249 pmap_procwr(struct proc *p, vaddr_t va, size_t len) 250 { 251 (*pmapops->pmapop_procwr)(p, va, len); 252 } 253 254 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 255 void 256 pmap_pte_print(volatile struct pte *ptep) 257 { 258 (*pmapops->pmapop_pte_print)(ptep); 259 } 260 261 void 262 pmap_pteg_check(void) 263 { 264 (*pmapops->pmapop_pteg_check)(); 265 } 266 267 void 268 pmap_print_mmuregs(void) 269 { 270 (*pmapops->pmapop_print_mmuregs)(); 271 } 272 273 void 274 pmap_print_pte(pmap_t pm, vaddr_t va) 275 { 276 (*pmapops->pmapop_print_pte)(pm, va); 277 } 278 279 void 280 pmap_pteg_dist(void) 281 { 282 (*pmapops->pmapop_pteg_dist)(); 283 } 284 #endif 285 286 #if defined(DEBUG) || defined(PMAPCHECK) 287 void 288 pmap_pvo_verify(void) 289 { 290 (*pmapops->pmapop_pvo_verify)(); 291 } 292 #endif 293 294 vaddr_t 295 pmap_steal_memory(vsize_t vsize, vaddr_t *vstartp, vaddr_t *vendp) 296 { 297 return (*pmapops->pmapop_steal_memory)(vsize, vstartp, vendp); 298 } 299 300 void 301 pmap_bootstrap(paddr_t startkernel, paddr_t endkernel) 302 { 303 (*pmapops->pmapop_bootstrap)(startkernel, endkernel); 304 } 305 306 void 307 pmap_bootstrap1(paddr_t startkernel, paddr_t endkernel) 308 { 309 (*pmapops->pmapop_bootstrap1)(startkernel, endkernel); 310 } 311 312 void 313 pmap_bootstrap2(void) 314 { 315 (*pmapops->pmapop_bootstrap2)(); 316 } 317 #endif 318