summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/powerpc/aim/moea64_native.c45
-rw-r--r--sys/powerpc/aim/slb.c4
2 files changed, 19 insertions, 30 deletions
diff --git a/sys/powerpc/aim/moea64_native.c b/sys/powerpc/aim/moea64_native.c
index 93187ca..41e8593 100644
--- a/sys/powerpc/aim/moea64_native.c
+++ b/sys/powerpc/aim/moea64_native.c
@@ -133,36 +133,31 @@ __FBSDID("$FreeBSD$");
#define VSID_HASH_MASK 0x0000007fffffffffULL
-/*
- * The tlbie instruction must be executed in 64-bit mode
- * so we have to twiddle MSR[SF] around every invocation.
- * Just to add to the fun, exceptions must be off as well
- * so that we can't trap in 64-bit mode. What a pain.
- */
-static struct mtx tlbie_mutex;
-
static __inline void
TLBIE(uint64_t vpn) {
#ifndef __powerpc64__
register_t vpn_hi, vpn_lo;
register_t msr;
- register_t scratch;
+ register_t scratch, intr;
#endif
+ static volatile u_int tlbie_lock = 0;
+
vpn <<= ADDR_PIDX_SHFT;
vpn &= ~(0xffffULL << 48);
+ /* Hobo spinlock: we need stronger guarantees than mutexes provide */
+ while (!atomic_cmpset_int(&tlbie_lock, 0, 1));
+ isync(); /* Flush instruction queue once lock acquired */
+
#ifdef __powerpc64__
- mtx_lock(&tlbie_mutex);
__asm __volatile("tlbie %0" :: "r"(vpn) : "memory");
- mtx_unlock(&tlbie_mutex);
- __asm __volatile("eieio; tlbsync; ptesync");
+ __asm __volatile("eieio; tlbsync; ptesync" ::: "memory");
#else
vpn_hi = (uint32_t)(vpn >> 32);
vpn_lo = (uint32_t)vpn;
- /* Note: spin mutex is to disable exceptions while fiddling MSR */
- mtx_lock_spin(&tlbie_mutex);
+ intr = intr_disable();
__asm __volatile("\
mfmsr %0; \
mr %1, %0; \
@@ -179,8 +174,11 @@ TLBIE(uint64_t vpn) {
ptesync;"
: "=r"(msr), "=r"(scratch) : "r"(vpn_hi), "r"(vpn_lo), "r"(32), "r"(1)
: "memory");
- mtx_unlock_spin(&tlbie_mutex);
+ intr_enable();
#endif
+
+ /* No barriers or special ops -- taken care of by ptesync above */
+ tlbie_lock = 0;
}
#define DISABLE_TRANS(msr) msr = mfmsr(); mtmsr(msr & ~PSL_DR)
@@ -261,9 +259,9 @@ moea64_pte_clear_native(mmu_t mmu, uintptr_t pt_cookie, struct lpte *pvo_pt,
* As shown in Section 7.6.3.2.3
*/
pt->pte_lo &= ~ptebit;
- sched_pin();
+ critical_enter();
TLBIE(vpn);
- sched_unpin();
+ critical_exit();
}
static void
@@ -297,12 +295,12 @@ moea64_pte_unset_native(mmu_t mmu, uintptr_t pt_cookie, struct lpte *pvo_pt,
* Invalidate the pte.
*/
isync();
- sched_pin();
+ critical_enter();
pvo_pt->pte_hi &= ~LPTE_VALID;
pt->pte_hi &= ~LPTE_VALID;
PTESYNC();
TLBIE(vpn);
- sched_unpin();
+ critical_exit();
/*
* Save the reg & chg bits.
@@ -405,15 +403,6 @@ moea64_bootstrap_native(mmu_t mmup, vm_offset_t kernelstart,
CTR1(KTR_PMAP, "moea64_bootstrap: PTEG table at %p", moea64_pteg_table);
- /*
- * Initialize the TLBIE lock. TLBIE can only be executed by one CPU.
- */
-#ifdef __powerpc64__
- mtx_init(&tlbie_mutex, "tlbie", NULL, MTX_DEF);
-#else
- mtx_init(&tlbie_mutex, "tlbie", NULL, MTX_SPIN);
-#endif
-
moea64_mid_bootstrap(mmup, kernelstart, kernelend);
/*
diff --git a/sys/powerpc/aim/slb.c b/sys/powerpc/aim/slb.c
index 7f4b2ef..162c7fb 100644
--- a/sys/powerpc/aim/slb.c
+++ b/sys/powerpc/aim/slb.c
@@ -139,7 +139,7 @@ make_new_leaf(uint64_t esid, uint64_t slbv, struct slbtnode *parent)
* that a lockless searcher always sees a valid path through
* the tree.
*/
- powerpc_sync();
+ mb();
idx = esid2idx(esid, parent->ua_level);
parent->u.ua_child[idx] = child;
@@ -187,7 +187,7 @@ make_intermediate(uint64_t esid, struct slbtnode *parent)
idx = esid2idx(child->ua_base, inter->ua_level);
inter->u.ua_child[idx] = child;
setbit(&inter->ua_alloc, idx);
- powerpc_sync();
+ mb();
/* Set up parent to point to intermediate node ... */
idx = esid2idx(inter->ua_base, parent->ua_level);
OpenPOWER on IntegriCloud