summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arch/powerpc64/include/pte.h4
-rw-r--r--sys/arch/powerpc64/powerpc64/pmap.c32
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);