mmu_oea64.c (269485) | mmu_oea64.c (269728) |
---|---|
1/*- 2 * Copyright (c) 2001 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Matt Thomas <matt@3am-software.com> of Allegro Networks, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 70 unchanged lines hidden (view full) --- 79 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 80 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 81 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 82 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 83 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 84 */ 85 86#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Matt Thomas <matt@3am-software.com> of Allegro Networks, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 70 unchanged lines hidden (view full) --- 79 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 80 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 81 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 82 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 83 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 84 */ 85 86#include <sys/cdefs.h> |
87__FBSDID("$FreeBSD: head/sys/powerpc/aim/mmu_oea64.c 269485 2014-08-03 20:40:51Z alc $"); | 87__FBSDID("$FreeBSD: head/sys/powerpc/aim/mmu_oea64.c 269728 2014-08-08 17:12:03Z kib $"); |
88 89/* 90 * Manages physical address maps. 91 * 92 * Since the information managed by this module is also stored by the 93 * logical address mapping module, this module may throw away valid virtual 94 * to physical mappings at almost any time. However, invalidations of 95 * mappings must be done as requested. --- 166 unchanged lines hidden (view full) --- 262uint64_t moea64_large_page_mask = 0; 263uint64_t moea64_large_page_size = 0; 264int moea64_large_page_shift = 0; 265 266/* 267 * PVO calls. 268 */ 269static int moea64_pvo_enter(mmu_t, pmap_t, uma_zone_t, struct pvo_head *, | 88 89/* 90 * Manages physical address maps. 91 * 92 * Since the information managed by this module is also stored by the 93 * logical address mapping module, this module may throw away valid virtual 94 * to physical mappings at almost any time. However, invalidations of 95 * mappings must be done as requested. --- 166 unchanged lines hidden (view full) --- 262uint64_t moea64_large_page_mask = 0; 263uint64_t moea64_large_page_size = 0; 264int moea64_large_page_shift = 0; 265 266/* 267 * PVO calls. 268 */ 269static int moea64_pvo_enter(mmu_t, pmap_t, uma_zone_t, struct pvo_head *, |
270 vm_offset_t, vm_offset_t, uint64_t, int); | 270 vm_offset_t, vm_offset_t, uint64_t, int, int8_t); |
271static void moea64_pvo_remove(mmu_t, struct pvo_entry *); 272static struct pvo_entry *moea64_pvo_find_va(pmap_t, vm_offset_t); 273 274/* 275 * Utility routines. 276 */ 277static boolean_t moea64_query_bit(mmu_t, vm_page_t, u_int64_t); 278static u_int moea64_clear_bit(mmu_t, vm_page_t, u_int64_t); 279static void moea64_kremove(mmu_t, vm_offset_t); 280static void moea64_syncicache(mmu_t, pmap_t pmap, vm_offset_t va, 281 vm_offset_t pa, vm_size_t sz); 282 283/* 284 * Kernel MMU interface 285 */ 286void moea64_clear_modify(mmu_t, vm_page_t); 287void moea64_copy_page(mmu_t, vm_page_t, vm_page_t); 288void moea64_copy_pages(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset, 289 vm_page_t *mb, vm_offset_t b_offset, int xfersize); | 271static void moea64_pvo_remove(mmu_t, struct pvo_entry *); 272static struct pvo_entry *moea64_pvo_find_va(pmap_t, vm_offset_t); 273 274/* 275 * Utility routines. 276 */ 277static boolean_t moea64_query_bit(mmu_t, vm_page_t, u_int64_t); 278static u_int moea64_clear_bit(mmu_t, vm_page_t, u_int64_t); 279static void moea64_kremove(mmu_t, vm_offset_t); 280static void moea64_syncicache(mmu_t, pmap_t pmap, vm_offset_t va, 281 vm_offset_t pa, vm_size_t sz); 282 283/* 284 * Kernel MMU interface 285 */ 286void moea64_clear_modify(mmu_t, vm_page_t); 287void moea64_copy_page(mmu_t, vm_page_t, vm_page_t); 288void moea64_copy_pages(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset, 289 vm_page_t *mb, vm_offset_t b_offset, int xfersize); |
290void moea64_enter(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t, boolean_t); | 290int moea64_enter(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t, 291 u_int flags, int8_t psind); |
291void moea64_enter_object(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_page_t, 292 vm_prot_t); 293void moea64_enter_quick(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t); 294vm_paddr_t moea64_extract(mmu_t, pmap_t, vm_offset_t); 295vm_page_t moea64_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t); 296void moea64_init(mmu_t); 297boolean_t moea64_is_modified(mmu_t, vm_page_t); 298boolean_t moea64_is_prefaultable(mmu_t, pmap_t, vm_offset_t); --- 323 unchanged lines hidden (view full) --- 622 pte_lo |= LPTE_G; 623 } 624 if (pa + moea64_large_page_size > 625 pregions[i].mr_start + pregions[i].mr_size) 626 pte_lo |= LPTE_G; 627 628 moea64_pvo_enter(mmup, kernel_pmap, moea64_upvo_zone, 629 NULL, pa, pa, pte_lo, | 292void moea64_enter_object(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_page_t, 293 vm_prot_t); 294void moea64_enter_quick(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t); 295vm_paddr_t moea64_extract(mmu_t, pmap_t, vm_offset_t); 296vm_page_t moea64_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t); 297void moea64_init(mmu_t); 298boolean_t moea64_is_modified(mmu_t, vm_page_t); 299boolean_t moea64_is_prefaultable(mmu_t, pmap_t, vm_offset_t); --- 323 unchanged lines hidden (view full) --- 623 pte_lo |= LPTE_G; 624 } 625 if (pa + moea64_large_page_size > 626 pregions[i].mr_start + pregions[i].mr_size) 627 pte_lo |= LPTE_G; 628 629 moea64_pvo_enter(mmup, kernel_pmap, moea64_upvo_zone, 630 NULL, pa, pa, pte_lo, |
630 PVO_WIRED | PVO_LARGE); | 631 PVO_WIRED | PVO_LARGE, 0); |
631 } 632 } 633 PMAP_UNLOCK(kernel_pmap); 634 UNLOCK_TABLE_WR(); 635 } else { 636 size = sizeof(struct pvo_head) * moea64_pteg_count; 637 off = (vm_offset_t)(moea64_pvo_table); 638 for (pa = off; pa < off + size; pa += PAGE_SIZE) --- 584 unchanged lines hidden (view full) --- 1223} 1224 1225/* 1226 * Map the given physical page at the specified virtual address in the 1227 * target pmap with the protection requested. If specified the page 1228 * will be wired down. 1229 */ 1230 | 632 } 633 } 634 PMAP_UNLOCK(kernel_pmap); 635 UNLOCK_TABLE_WR(); 636 } else { 637 size = sizeof(struct pvo_head) * moea64_pteg_count; 638 off = (vm_offset_t)(moea64_pvo_table); 639 for (pa = off; pa < off + size; pa += PAGE_SIZE) --- 584 unchanged lines hidden (view full) --- 1224} 1225 1226/* 1227 * Map the given physical page at the specified virtual address in the 1228 * target pmap with the protection requested. If specified the page 1229 * will be wired down. 1230 */ 1231 |
1231void | 1232int |
1232moea64_enter(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, | 1233moea64_enter(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, |
1233 vm_prot_t prot, boolean_t wired) | 1234 vm_prot_t prot, u_int flags, int8_t psind) |
1234{ 1235 struct pvo_head *pvo_head; 1236 uma_zone_t zone; 1237 uint64_t pte_lo; 1238 u_int pvo_flags; 1239 int error; 1240 1241 if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m)) --- 17 unchanged lines hidden (view full) --- 1259 (m->oflags & VPO_UNMANAGED) == 0) 1260 vm_page_aflag_set(m, PGA_WRITEABLE); 1261 } else 1262 pte_lo |= LPTE_BR; 1263 1264 if ((prot & VM_PROT_EXECUTE) == 0) 1265 pte_lo |= LPTE_NOEXEC; 1266 | 1235{ 1236 struct pvo_head *pvo_head; 1237 uma_zone_t zone; 1238 uint64_t pte_lo; 1239 u_int pvo_flags; 1240 int error; 1241 1242 if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m)) --- 17 unchanged lines hidden (view full) --- 1260 (m->oflags & VPO_UNMANAGED) == 0) 1261 vm_page_aflag_set(m, PGA_WRITEABLE); 1262 } else 1263 pte_lo |= LPTE_BR; 1264 1265 if ((prot & VM_PROT_EXECUTE) == 0) 1266 pte_lo |= LPTE_NOEXEC; 1267 |
1267 if (wired) | 1268 if ((flags & PMAP_ENTER_WIRED) != 0) |
1268 pvo_flags |= PVO_WIRED; 1269 | 1269 pvo_flags |= PVO_WIRED; 1270 |
1270 LOCK_TABLE_WR(); 1271 PMAP_LOCK(pmap); 1272 error = moea64_pvo_enter(mmu, pmap, zone, pvo_head, va, 1273 VM_PAGE_TO_PHYS(m), pte_lo, pvo_flags); 1274 PMAP_UNLOCK(pmap); 1275 UNLOCK_TABLE_WR(); | 1271 for (;;) { 1272 LOCK_TABLE_WR(); 1273 PMAP_LOCK(pmap); 1274 error = moea64_pvo_enter(mmu, pmap, zone, pvo_head, va, 1275 VM_PAGE_TO_PHYS(m), pte_lo, pvo_flags, psind); 1276 PMAP_UNLOCK(pmap); 1277 UNLOCK_TABLE_WR(); 1278 if (error != ENOMEM) 1279 break; 1280 if ((flags & PMAP_ENTER_NOSLEEP) != 0) 1281 return (KERN_RESOURCE_SHORTAGE); 1282 VM_OBJECT_ASSERT_UNLOCKED(m->object); 1283 VM_WAIT; 1284 } |
1276 1277 /* 1278 * Flush the page from the instruction cache if this page is 1279 * mapped executable and cacheable. 1280 */ 1281 if (pmap != kernel_pmap && !(m->aflags & PGA_EXECUTABLE) && 1282 (pte_lo & (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) { 1283 vm_page_aflag_set(m, PGA_EXECUTABLE); 1284 moea64_syncicache(mmu, pmap, va, VM_PAGE_TO_PHYS(m), PAGE_SIZE); 1285 } | 1285 1286 /* 1287 * Flush the page from the instruction cache if this page is 1288 * mapped executable and cacheable. 1289 */ 1290 if (pmap != kernel_pmap && !(m->aflags & PGA_EXECUTABLE) && 1291 (pte_lo & (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) { 1292 vm_page_aflag_set(m, PGA_EXECUTABLE); 1293 moea64_syncicache(mmu, pmap, va, VM_PAGE_TO_PHYS(m), PAGE_SIZE); 1294 } |
1295 return (KERN_SUCCESS); |
|
1286} 1287 1288static void 1289moea64_syncicache(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_offset_t pa, 1290 vm_size_t sz) 1291{ 1292 1293 /* --- 48 unchanged lines hidden (view full) --- 1342 vm_pindex_t diff, psize; 1343 1344 VM_OBJECT_ASSERT_LOCKED(m_start->object); 1345 1346 psize = atop(end - start); 1347 m = m_start; 1348 while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) { 1349 moea64_enter(mmu, pm, start + ptoa(diff), m, prot & | 1296} 1297 1298static void 1299moea64_syncicache(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_offset_t pa, 1300 vm_size_t sz) 1301{ 1302 1303 /* --- 48 unchanged lines hidden (view full) --- 1352 vm_pindex_t diff, psize; 1353 1354 VM_OBJECT_ASSERT_LOCKED(m_start->object); 1355 1356 psize = atop(end - start); 1357 m = m_start; 1358 while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) { 1359 moea64_enter(mmu, pm, start + ptoa(diff), m, prot & |
1350 (VM_PROT_READ | VM_PROT_EXECUTE), FALSE); | 1360 (VM_PROT_READ | VM_PROT_EXECUTE), PMAP_ENTER_NOSLEEP, 0); |
1351 m = TAILQ_NEXT(m, listq); 1352 } 1353} 1354 1355void 1356moea64_enter_quick(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_page_t m, 1357 vm_prot_t prot) 1358{ 1359 | 1361 m = TAILQ_NEXT(m, listq); 1362 } 1363} 1364 1365void 1366moea64_enter_quick(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_page_t m, 1367 vm_prot_t prot) 1368{ 1369 |
1360 moea64_enter(mmu, pm, va, m, 1361 prot & (VM_PROT_READ | VM_PROT_EXECUTE), FALSE); | 1370 moea64_enter(mmu, pm, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE), 1371 PMAP_ENTER_NOSLEEP, 0); |
1362} 1363 1364vm_paddr_t 1365moea64_extract(mmu_t mmu, pmap_t pm, vm_offset_t va) 1366{ 1367 struct pvo_entry *pvo; 1368 vm_paddr_t pa; 1369 --- 71 unchanged lines hidden (view full) --- 1441 1442 va = VM_PAGE_TO_PHYS(m); 1443 1444 LOCK_TABLE_WR(); 1445 if (needed_lock) 1446 PMAP_LOCK(kernel_pmap); 1447 1448 moea64_pvo_enter(installed_mmu, kernel_pmap, moea64_upvo_zone, | 1372} 1373 1374vm_paddr_t 1375moea64_extract(mmu_t mmu, pmap_t pm, vm_offset_t va) 1376{ 1377 struct pvo_entry *pvo; 1378 vm_paddr_t pa; 1379 --- 71 unchanged lines hidden (view full) --- 1451 1452 va = VM_PAGE_TO_PHYS(m); 1453 1454 LOCK_TABLE_WR(); 1455 if (needed_lock) 1456 PMAP_LOCK(kernel_pmap); 1457 1458 moea64_pvo_enter(installed_mmu, kernel_pmap, moea64_upvo_zone, |
1449 NULL, va, VM_PAGE_TO_PHYS(m), LPTE_M, PVO_WIRED | PVO_BOOTSTRAP); | 1459 NULL, va, VM_PAGE_TO_PHYS(m), LPTE_M, PVO_WIRED | PVO_BOOTSTRAP, 1460 0); |
1450 1451 if (needed_lock) 1452 PMAP_UNLOCK(kernel_pmap); 1453 UNLOCK_TABLE_WR(); 1454 1455 if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0) 1456 bzero((void *)va, PAGE_SIZE); 1457 --- 205 unchanged lines hidden (view full) --- 1663 uint64_t pte_lo; 1664 int error; 1665 1666 pte_lo = moea64_calc_wimg(pa, ma); 1667 1668 LOCK_TABLE_WR(); 1669 PMAP_LOCK(kernel_pmap); 1670 error = moea64_pvo_enter(mmu, kernel_pmap, moea64_upvo_zone, | 1461 1462 if (needed_lock) 1463 PMAP_UNLOCK(kernel_pmap); 1464 UNLOCK_TABLE_WR(); 1465 1466 if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0) 1467 bzero((void *)va, PAGE_SIZE); 1468 --- 205 unchanged lines hidden (view full) --- 1674 uint64_t pte_lo; 1675 int error; 1676 1677 pte_lo = moea64_calc_wimg(pa, ma); 1678 1679 LOCK_TABLE_WR(); 1680 PMAP_LOCK(kernel_pmap); 1681 error = moea64_pvo_enter(mmu, kernel_pmap, moea64_upvo_zone, |
1671 NULL, va, pa, pte_lo, PVO_WIRED); | 1682 NULL, va, pa, pte_lo, PVO_WIRED, 0); |
1672 PMAP_UNLOCK(kernel_pmap); 1673 UNLOCK_TABLE_WR(); 1674 1675 if (error != 0 && error != ENOENT) 1676 panic("moea64_kenter: failed to enter va %#zx pa %#zx: %d", va, 1677 pa, error); 1678} 1679 --- 481 unchanged lines hidden (view full) --- 2161 return (s); 2162 } 2163 panic("moea64_bootstrap_alloc: could not allocate memory"); 2164} 2165 2166static int 2167moea64_pvo_enter(mmu_t mmu, pmap_t pm, uma_zone_t zone, 2168 struct pvo_head *pvo_head, vm_offset_t va, vm_offset_t pa, | 1683 PMAP_UNLOCK(kernel_pmap); 1684 UNLOCK_TABLE_WR(); 1685 1686 if (error != 0 && error != ENOENT) 1687 panic("moea64_kenter: failed to enter va %#zx pa %#zx: %d", va, 1688 pa, error); 1689} 1690 --- 481 unchanged lines hidden (view full) --- 2172 return (s); 2173 } 2174 panic("moea64_bootstrap_alloc: could not allocate memory"); 2175} 2176 2177static int 2178moea64_pvo_enter(mmu_t mmu, pmap_t pm, uma_zone_t zone, 2179 struct pvo_head *pvo_head, vm_offset_t va, vm_offset_t pa, |
2169 uint64_t pte_lo, int flags) | 2180 uint64_t pte_lo, int flags, int8_t psind __unused) |
2170{ 2171 struct pvo_entry *pvo; 2172 uintptr_t pt; 2173 uint64_t vsid; 2174 int first; 2175 u_int ptegidx; 2176 int i; 2177 int bootstrap; --- 520 unchanged lines hidden --- | 2181{ 2182 struct pvo_entry *pvo; 2183 uintptr_t pt; 2184 uint64_t vsid; 2185 int first; 2186 u_int ptegidx; 2187 int i; 2188 int bootstrap; --- 520 unchanged lines hidden --- |