[OpenBIOS] [PATCH v3] ppc: Set up SLBs for ppc64

Andreas Färber andreas.faerber at web.de
Sun Nov 21 21:51:45 CET 2010


Set up SLBs with slbmte instead of mtsrin, suggested by Alex.

v3:
* Continue to use mtmsrin on ppc for simplicity.
* Add comment on slbia, suggested by Segher.
* Add inline functions {slbia,slbmte}, requested by Alex.
* Add inline function mfpvr before Alex asks for it. :)

v2:
* Don't initialize 64 SLBs, then invalidate them, as in IBM's application note
  for the 970. Use slbia instead, recommended by Alex.
* Conditionalize when to use SLB or SR.

Cc: Alexander Graf <agraf at suse.de>
Cc: Segher Boessenkool <segher at kernel.crashing.org>
Signed-off-by: Andreas Färber <andreas.faerber at web.de>
---
 arch/ppc/qemu/ofmem.c        |   24 ++++++++++++++++++++----
 include/arch/ppc/processor.h |   17 +++++++++++++++++
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c
index 72694b3..e871623 100644
--- a/arch/ppc/qemu/ofmem.c
+++ b/arch/ppc/qemu/ofmem.c
@@ -336,9 +336,7 @@ hash_page_32( ucell ea, ucell phys, ucell mode )
 
 static int is_ppc64(void)
 {
-	unsigned int pvr;
-	asm volatile("mfspr %0, 0x11f" : "=r" (pvr) );
-
+	unsigned int pvr = mfpvr();
 	return ((pvr >= 0x330000) && (pvr < 0x70330000));
 }
 
@@ -387,7 +385,10 @@ void
 setup_mmu( unsigned long ramsize )
 {
 	ofmem_t *ofmem;
-	unsigned long sdr1, sr_base;
+	unsigned long sdr1;
+#ifndef __powerpc64__
+	unsigned long sr_base;
+#endif
 	unsigned long hash_base;
 	unsigned long hash_mask = 0xfff00000; /* alignment for ppc64 */
 	int i;
@@ -399,6 +400,19 @@ setup_mmu( unsigned long ramsize )
 	sdr1 = hash_base | ((HASH_SIZE-1) >> 16);
 	asm volatile("mtsdr1 %0" :: "r" (sdr1) );
 
+#ifdef __powerpc64__
+
+	/* Segment Lookaside Buffer */
+
+	slbia(); /* Invalidate all SLBs except SLB 0 */
+	for (i = 0; i < 16; i++) {
+		unsigned long rs = ((0x400 + i) << 12) | (0x10 << 7);
+		unsigned long rb = ((unsigned long)i << 28) | (1 << 27) | i;
+		slbmte(rs, rb);
+	}
+
+#else
+
 	/* Segment Register */
 
 	sr_base = SEGR_USER | SEGR_BASE ;
@@ -407,6 +421,8 @@ setup_mmu( unsigned long ramsize )
 		asm volatile("mtsrin %0,%1" :: "r" (sr_base + i), "r" (j) );
 	}
 
+#endif
+
 	ofmem = ofmem_arch_get_private();
 	memset(ofmem, 0, sizeof(ofmem_t));
 	ofmem->ramsize = ramsize;
diff --git a/include/arch/ppc/processor.h b/include/arch/ppc/processor.h
index c7d5be6..c2f1284 100644
--- a/include/arch/ppc/processor.h
+++ b/include/arch/ppc/processor.h
@@ -425,6 +425,23 @@ static inline void mtmsr(unsigned long msr)
 #endif
 }
 
+static inline unsigned int mfpvr(void)
+{
+    unsigned int pvr;
+    asm volatile("mfspr %0, 0x11f" : "=r" (pvr) );
+    return pvr;
+}
+
+static inline void slbia(void)
+{
+    asm volatile("slbia" ::: "memory");
+}
+
+static inline void slbmte(unsigned long rs, unsigned long rb)
+{
+    asm volatile("slbmte %0,%1 ; isync" :: "r" (rs), "r" (rb) : "memory");
+}
+
 #endif /* !__ASSEMBLER__ */
 
 #endif   /* _H_PROCESSOR */
-- 
1.7.3




More information about the OpenBIOS mailing list