diff options
author | Andreas Färber <andreas.faerber@web.de> | 2010-11-21 21:53:54 +0000 |
---|---|---|
committer | Andreas Färber <afaerber@suse.de> | 2010-11-21 21:53:54 +0000 |
commit | e15a84d0ecbdd4088665de7145ff44d1bd69e240 (patch) | |
tree | e7f8b8ac08fa472545947f51841d904081d03c79 | |
parent | cde2fc75f086847927886cdf6df8475127f6e9b4 (diff) | |
download | openbios-e15a84d0ecbdd4088665de7145ff44d1bd69e240.zip openbios-e15a84d0ecbdd4088665de7145ff44d1bd69e240.tar.gz openbios-e15a84d0ecbdd4088665de7145ff44d1bd69e240.tar.bz2 |
ppc: Set up SLBs for ppc64
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: Segher Boessenkool <segher@kernel.crashing.org>
Signed-off-by: Andreas Färber <andreas.faerber@web.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@966 f158a5a8-5612-0410-a976-696ce0be7e32
-rw-r--r-- | arch/ppc/qemu/ofmem.c | 24 | ||||
-rw-r--r-- | 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 */ |