[OpenBIOS] [RFC v2] ppc: SDR1 fixes

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


Clean up use of SDR1 fields.

IBM's "The Programming Environments for 32-Bit Microprocessors":
  The HTABMASK field in SDR1 contains a mask value that determines
  how many bits from the hash are used in the page table index. This mask
  must be of the form 0b00...011...1; that is, a string of 0 bits followed by
  a string of 1bits. The 1 bits determine how many additional bits (at least 10)
  from the hash are used in the index; HTABORG must have this same number of
  low-order bits equal to 0.

IBM's "The Programming Environments Manual for 64-bit Microprocessors" 3.0:
  The HTABSIZE field in SDR1 contains an integer value that determines
  how many bits from the hash are used in the page table index. This number
  must not exceed 28. HTABSIZE is used to generate a mask of the form
  0b00...011...1; that is, a string of 0 bits followed by a string of 1-bits.
  The 1-bits determine how many additional bits (beyond the minimum of 11)
  from the hash are used in the index. The HTABORG must have this same number
  of low-order bits equal to 0.

Adjust masks and shifts to 64-bit SDR1.

v2:
* Use HTABSIZE for ppc64, fix HTABMASK usage for ppc.
  Error spotted by Segher.

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>
---
 Note: This breaks 32-bit ppc at least.
 
 arch/ppc/qemu/ofmem.c |   31 ++++++++++++++++++++++---------
 1 files changed, 22 insertions(+), 9 deletions(-)
 
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c
index fd417c2..6f2b86d 100644
--- a/arch/ppc/qemu/ofmem.c
+++ b/arch/ppc/qemu/ofmem.c
@@ -48,7 +48,8 @@ extern void setup_mmu( unsigned long code_base );
 #define OF_CODE_START	0xfff00000UL
 #define IO_BASE			0x80000000
 
-#define HASH_SIZE		(2 << 15)
+#define HASH_BITS		15
+#define HASH_SIZE		(2 << HASH_BITS)
 #define OFMEM_SIZE		(2 * 1024 * 1024)
 
 #define	SEGR_USER		BIT(2)
@@ -57,21 +58,29 @@ extern void setup_mmu( unsigned long code_base );
 static inline unsigned long
 get_hash_base( void )
 {
-	unsigned long sdr1;
+    unsigned long sdr1;
 
-	asm volatile("mfsdr1 %0" : "=r" (sdr1) );
+    asm volatile("mfsdr1 %0" : "=r" (sdr1) );
 
-	return (sdr1 & 0xffff0000);
+#ifdef __powerpc64__
+    return (sdr1 & 0x3FFFFFFFFFFC0000UL);
+#else
+    return (sdr1 & 0xffff0000UL);
+#endif
 }
 
 static inline unsigned long
 get_hash_size( void )
 {
-	unsigned long sdr1;
+    unsigned long sdr1;
 
-	asm volatile("mfsdr1 %0" : "=r" (sdr1) );
+    asm volatile("mfsdr1 %0" : "=r" (sdr1));
 
-	return ((sdr1 << 16) | 0x0000ffff) + 1;
+#ifdef __powerpc64__
+    return 1UL << (sdr1 & 0x1f);
+#else
+    return (((sdr1 & 0x1ff) << 10) | 0x3ff) + 1;
+#endif
 }
 
 static inline unsigned long
@@ -389,14 +398,18 @@ setup_mmu( unsigned long ramsize )
 	ofmem_t *ofmem;
 	unsigned long sdr1, sr_base, msr;
 	unsigned long hash_base;
-	unsigned long hash_mask = 0xfff00000; /* alignment for ppc64 */
+	unsigned long hash_mask = ~0x000fffffUL; /* alignment for ppc64 */
 	int i;
 
 	/* SDR1: Storage Description Register 1 */
 
 	hash_base = (ramsize - 0x00100000 - HASH_SIZE) & hash_mask;
 	memset((void *)hash_base, 0, HASH_SIZE);
-	sdr1 = hash_base | ((HASH_SIZE-1) >> 16);
+#ifdef __powerpc64__
+	sdr1 = hash_base | HASH_BITS;
+#else
+	sdr1 = hash_base | ((HASH_SIZE - 1) >> 10);
+#endif
 	asm volatile("mtsdr1 %0" :: "r" (sdr1) );
 
 	/* Segment Register */
-- 
1.7.3




More information about the OpenBIOS mailing list