Deleted Added
full compact
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 ---