svn commit: r292900 - head/sys/powerpc/booke
Justin Hibbits
jhibbits at FreeBSD.org
Wed Dec 30 02:23:15 UTC 2015
Author: jhibbits
Date: Wed Dec 30 02:23:14 2015
New Revision: 292900
URL: https://svnweb.freebsd.org/changeset/base/292900
Log:
Rewrite tid_flush() in C.
There's no need for it to be in asm. Also, by writing in C, and marking it
static in pmap.c, it saves a branch to the function itself, as it's only used in
one location. The generated asm is virtually identical to the handwritten code.
Modified:
head/sys/powerpc/booke/locore.S
head/sys/powerpc/booke/pmap.c
Modified: head/sys/powerpc/booke/locore.S
==============================================================================
--- head/sys/powerpc/booke/locore.S Wed Dec 30 02:15:12 2015 (r292899)
+++ head/sys/powerpc/booke/locore.S Wed Dec 30 02:23:14 2015 (r292900)
@@ -658,77 +658,6 @@ __boot_page_padding:
/************************************************************************/
/*
- * void tid_flush(tlbtid_t tid);
- *
- * Invalidate all TLB0 entries which match the given TID. Note this is
- * dedicated for cases when invalidation(s) should NOT be propagated to other
- * CPUs.
- *
- * void tid_flush(tlbtid_t tid, int tlb0_ways, int tlb0_entries_per_way);
- *
- * XXX: why isn't this in C?
- */
-ENTRY(tid_flush)
- cmpwi %r3, TID_KERNEL
- beq tid_flush_end /* don't evict kernel translations */
-
- /* Disable interrupts */
- mfmsr %r10
- wrteei 0
-
- li %r6, 0 /* ways counter */
-loop_ways:
- li %r7, 0 /* entries [per way] counter */
-loop_entries:
- /* Select TLB0 and ESEL (way) */
- lis %r8, MAS0_TLBSEL0 at h
- rlwimi %r8, %r6, 16, 14, 15
- mtspr SPR_MAS0, %r8
- isync
-
- /* Select EPN (entry within the way) */
- rlwinm %r8, %r7, 12, 13, 19
- mtspr SPR_MAS2, %r8
- isync
- tlbre
-
- /* Check if valid entry */
- mfspr %r8, SPR_MAS1
- andis. %r9, %r8, MAS1_VALID at h
- beq next_entry /* invalid entry */
-
- /* Check if this is our TID */
- rlwinm %r9, %r8, 16, 24, 31
-
- cmplw %r9, %r3
- bne next_entry /* not our TID */
-
- /* Clear VALID bit */
- rlwinm %r8, %r8, 0, 1, 31
- mtspr SPR_MAS1, %r8
- isync
- tlbwe
- isync
- msync
-
-next_entry:
- addi %r7, %r7, 1
- cmpw %r7, %r5
- bne loop_entries
-
- /* Next way */
- addi %r6, %r6, 1
- cmpw %r6, %r4
- bne loop_ways
-
- /* Restore MSR (possibly re-enable interrupts) */
- mtmsr %r10
- isync
-
-tid_flush_end:
- blr
-
-/*
* Cache disable/enable/inval sequences according
* to section 2.16 of E500CORE RM.
*/
Modified: head/sys/powerpc/booke/pmap.c
==============================================================================
--- head/sys/powerpc/booke/pmap.c Wed Dec 30 02:15:12 2015 (r292899)
+++ head/sys/powerpc/booke/pmap.c Wed Dec 30 02:23:14 2015 (r292900)
@@ -161,7 +161,6 @@ unsigned int kernel_ptbls; /* Number of
#define PMAP_REMOVE_DONE(pmap) \
((pmap) != kernel_pmap && (pmap)->pm_stats.resident_count == 0)
-extern void tid_flush(tlbtid_t tid, int tlb0_ways, int tlb0_entries_per_way);
extern int elf32_nxstack;
/**************************************************************************/
@@ -195,6 +194,7 @@ static unsigned int tlb1_idx;
static vm_offset_t tlb1_map_base = VM_MAX_KERNEL_ADDRESS;
static tlbtid_t tid_alloc(struct pmap *);
+static void tid_flush(tlbtid_t tid);
static void tlb_print_entry(int, uint32_t, uint32_t, uint32_t, uint32_t);
@@ -2915,7 +2915,7 @@ tid_alloc(pmap_t pmap)
tidbusy[thiscpu][tid]->pm_tid[thiscpu] = TID_NONE;
/* Flush all entries from TLB0 matching this TID. */
- tid_flush(tid, tlb0_ways, tlb0_entries_per_way);
+ tid_flush(tid);
}
tidbusy[thiscpu][tid] = pmap;
@@ -3426,3 +3426,48 @@ tlb1_iomapped(int i, vm_paddr_t pa, vm_s
*va = (tlb1[i].mas2 & MAS2_EPN_MASK) + (pa - pa_start);
return (0);
}
+
+/*
+ * Invalidate all TLB0 entries which match the given TID. Note this is
+ * dedicated for cases when invalidations should NOT be propagated to other
+ * CPUs.
+ */
+static void
+tid_flush(tlbtid_t tid)
+{
+ register_t msr;
+ uint32_t mas0, mas1, mas2;
+ int entry, way;
+
+
+ /* Don't evict kernel translations */
+ if (tid == TID_KERNEL)
+ return;
+
+ msr = mfmsr();
+ __asm __volatile("wrteei 0");
+
+ for (way = 0; way < TLB0_WAYS; way++)
+ for (entry = 0; entry < TLB0_ENTRIES_PER_WAY; entry++) {
+
+ mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(way);
+ mtspr(SPR_MAS0, mas0);
+ __asm __volatile("isync");
+
+ mas2 = entry << MAS2_TLB0_ENTRY_IDX_SHIFT;
+ mtspr(SPR_MAS2, mas2);
+
+ __asm __volatile("isync; tlbre");
+
+ mas1 = mfspr(SPR_MAS1);
+
+ if (!(mas1 & MAS1_VALID))
+ continue;
+ if (((mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT) != tid)
+ continue;
+ mas1 &= ~MAS1_VALID;
+ mtspr(SPR_MAS1, mas1);
+ __asm __volatile("isync; tlbwe; isync; msync");
+ }
+ mtmsr(msr);
+}
More information about the svn-src-all
mailing list