diff options
-rw-r--r-- | sys/arch/powerpc64/include/pte.h | 4 | ||||
-rw-r--r-- | sys/arch/powerpc64/powerpc64/pmap.c | 32 |
2 files changed, 23 insertions, 13 deletions
diff --git a/sys/arch/powerpc64/include/pte.h b/sys/arch/powerpc64/include/pte.h index 71e941aca3f..cbc26be8f27 100644 --- a/sys/arch/powerpc64/include/pte.h +++ b/sys/arch/powerpc64/include/pte.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pte.h,v 1.4 2020/07/01 16:05:48 kettenis Exp $ */ +/* $OpenBSD: pte.h,v 1.5 2020/07/14 17:03:13 kettenis Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -32,7 +32,7 @@ struct pte { /* High doubleword: */ #define PTE_VALID 0x0000000000000001ULL #define PTE_HID 0x0000000000000002ULL -#define PTE_WIRED 0x0000000000000004ULL /* SW */ +#define PTE_WIRED 0x0000000000000008ULL /* SW */ #define PTE_AVPN 0x3fffffffffffff80ULL #define PTE_VSID_SHIFT 12 diff --git a/sys/arch/powerpc64/powerpc64/pmap.c b/sys/arch/powerpc64/powerpc64/pmap.c index bb65b91f463..737d8b42640 100644 --- a/sys/arch/powerpc64/powerpc64/pmap.c +++ b/sys/arch/powerpc64/powerpc64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.29 2020/07/10 16:09:58 kettenis Exp $ */ +/* $OpenBSD: pmap.c,v 1.30 2020/07/14 17:03:13 kettenis Exp $ */ /* * Copyright (c) 2015 Martin Pieuchot @@ -530,7 +530,7 @@ pte_lookup(uint64_t vsid, vaddr_t va) pte_hi = (avpn & PTE_AVPN) | PTE_VALID; for (i = 0; i < 8; i++) { - if (pte[i].pte_hi == pte_hi) + if ((pte[i].pte_hi & ~PTE_WIRED) == pte_hi) return &pte[i]; } @@ -540,7 +540,7 @@ pte_lookup(uint64_t vsid, vaddr_t va) pte_hi |= PTE_HID; for (i = 0; i < 8; i++) { - if (pte[i].pte_hi == pte_hi) + if ((pte[i].pte_hi & ~PTE_WIRED) == pte_hi) return &pte[i]; } @@ -604,7 +604,7 @@ pte_insert(struct pte_desc *pted) struct pte *pte; vaddr_t va; uint64_t vsid, hash; - int off, idx, i; + int off, try, idx, i; int s; PMAP_HASH_LOCK(s); @@ -660,8 +660,6 @@ pte_insert(struct pte_desc *pted) pte[i].pte_hi |= (PTE_HID|PTE_VALID); ptesync(); /* Ensure updates completed. */ - if (i > 6) - printf("%s: secondary %d\n", __func__, i); goto out; } @@ -669,11 +667,23 @@ pte_insert(struct pte_desc *pted) /* need decent replacement algorithm */ off = mftb(); - pted->pted_va |= off & (PTED_VA_PTEGIDX_M|PTED_VA_HID_M); - idx ^= (PTED_HID(pted) ? pmap_ptab_mask : 0); - pte = pmap_ptable + (idx * 8); - pte += PTED_PTEGIDX(pted); /* increment by index into pteg */ + for (try = 0; try < 16; try++) { + pted->pted_va &= ~(PTED_VA_HID_M|PTED_VA_PTEGIDX_M); + pted->pted_va |= off & (PTED_VA_PTEGIDX_M|PTED_VA_HID_M); + + idx ^= (PTED_HID(pted) ? pmap_ptab_mask : 0); + pte = pmap_ptable + (idx * 8); + pte += PTED_PTEGIDX(pted); /* increment by index into pteg */ + + if ((pte->pte_hi & PTE_WIRED) == 0) + break; + } + /* + * Since we only wire unmanaged kernel mappings, we should + * always find a slot that we can replace. + */ + KASSERT(try < 16); if (pte->pte_hi & PTE_VALID) { uint64_t avpn, vpn; @@ -1152,7 +1162,7 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot) /* Calculate PTE */ pmap_fill_pte(pm, va, pa, &pted, prot, cache); - pted.pted_va |= PTED_VA_WIRED_M; + pted.pted_pte.pte_hi |= PTE_WIRED; /* Insert into HTAB */ pte_insert(&pted); |