diff options
author | LEROY Christophe <christophe.leroy@c-s.fr> | 2014-09-19 04:36:09 -0400 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-11-07 19:10:43 -0500 |
commit | 4094f28f90adab007eca9babf28f606a40a83032 (patch) | |
tree | 4a9d47ec744360da9391ad705693ad8f5993c664 | |
parent | d3e40262e7d05236bf4c2c4fdf007589ba8af97a (diff) |
powerpc/8xx: set PTE bit 22 off TLBmiss
No need to re-set this bit at each TLB miss. Let's set it in the PTE.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Scott Wood <scottwood@freescale.com>
-rw-r--r-- | arch/powerpc/include/asm/pgtable-ppc32.h | 20 | ||||
-rw-r--r-- | arch/powerpc/include/asm/pte-8xx.h | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_8xx.S | 10 |
3 files changed, 27 insertions, 10 deletions
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h index 945e47adf7db..234e07c47803 100644 --- a/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/arch/powerpc/include/asm/pgtable-ppc32.h | |||
@@ -170,6 +170,25 @@ static inline unsigned long pte_update(pte_t *p, | |||
170 | #ifdef PTE_ATOMIC_UPDATES | 170 | #ifdef PTE_ATOMIC_UPDATES |
171 | unsigned long old, tmp; | 171 | unsigned long old, tmp; |
172 | 172 | ||
173 | #ifdef CONFIG_PPC_8xx | ||
174 | unsigned long tmp2; | ||
175 | |||
176 | __asm__ __volatile__("\ | ||
177 | 1: lwarx %0,0,%4\n\ | ||
178 | andc %1,%0,%5\n\ | ||
179 | or %1,%1,%6\n\ | ||
180 | /* 0x200 == Extended encoding, bit 22 */ \ | ||
181 | /* Bit 22 has to be 1 if neither _PAGE_USER nor _PAGE_RW are set */ \ | ||
182 | rlwimi %1,%1,32-2,0x200\n /* get _PAGE_USER */ \ | ||
183 | rlwinm %3,%1,32-1,0x200\n /* get _PAGE_RW */ \ | ||
184 | or %1,%3,%1\n\ | ||
185 | xori %1,%1,0x200\n" | ||
186 | " stwcx. %1,0,%4\n\ | ||
187 | bne- 1b" | ||
188 | : "=&r" (old), "=&r" (tmp), "=m" (*p), "=&r" (tmp2) | ||
189 | : "r" (p), "r" (clr), "r" (set), "m" (*p) | ||
190 | : "cc" ); | ||
191 | #else /* CONFIG_PPC_8xx */ | ||
173 | __asm__ __volatile__("\ | 192 | __asm__ __volatile__("\ |
174 | 1: lwarx %0,0,%3\n\ | 193 | 1: lwarx %0,0,%3\n\ |
175 | andc %1,%0,%4\n\ | 194 | andc %1,%0,%4\n\ |
@@ -180,6 +199,7 @@ static inline unsigned long pte_update(pte_t *p, | |||
180 | : "=&r" (old), "=&r" (tmp), "=m" (*p) | 199 | : "=&r" (old), "=&r" (tmp), "=m" (*p) |
181 | : "r" (p), "r" (clr), "r" (set), "m" (*p) | 200 | : "r" (p), "r" (clr), "r" (set), "m" (*p) |
182 | : "cc" ); | 201 | : "cc" ); |
202 | #endif /* CONFIG_PPC_8xx */ | ||
183 | #else /* PTE_ATOMIC_UPDATES */ | 203 | #else /* PTE_ATOMIC_UPDATES */ |
184 | unsigned long old = pte_val(*p); | 204 | unsigned long old = pte_val(*p); |
185 | *p = __pte((old & ~clr) | set); | 205 | *p = __pte((old & ~clr) | set); |
diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h index d44826e4ff97..daa4616e61c4 100644 --- a/arch/powerpc/include/asm/pte-8xx.h +++ b/arch/powerpc/include/asm/pte-8xx.h | |||
@@ -48,19 +48,22 @@ | |||
48 | */ | 48 | */ |
49 | #define _PAGE_RW 0x0400 /* lsb PP bits, inverted in HW */ | 49 | #define _PAGE_RW 0x0400 /* lsb PP bits, inverted in HW */ |
50 | #define _PAGE_USER 0x0800 /* msb PP bits */ | 50 | #define _PAGE_USER 0x0800 /* msb PP bits */ |
51 | /* set when neither _PAGE_USER nor _PAGE_RW are set */ | ||
52 | #define _PAGE_KNLRO 0x0200 | ||
51 | 53 | ||
52 | #define _PMD_PRESENT 0x0001 | 54 | #define _PMD_PRESENT 0x0001 |
53 | #define _PMD_BAD 0x0ff0 | 55 | #define _PMD_BAD 0x0ff0 |
54 | #define _PMD_PAGE_MASK 0x000c | 56 | #define _PMD_PAGE_MASK 0x000c |
55 | #define _PMD_PAGE_8M 0x000c | 57 | #define _PMD_PAGE_8M 0x000c |
56 | 58 | ||
57 | #define _PTE_NONE_MASK _PAGE_ACCESSED | 59 | #define _PTE_NONE_MASK _PAGE_KNLRO |
58 | 60 | ||
59 | /* Until my rework is finished, 8xx still needs atomic PTE updates */ | 61 | /* Until my rework is finished, 8xx still needs atomic PTE updates */ |
60 | #define PTE_ATOMIC_UPDATES 1 | 62 | #define PTE_ATOMIC_UPDATES 1 |
61 | 63 | ||
62 | /* We need to add _PAGE_SHARED to kernel pages */ | 64 | /* We need to add _PAGE_SHARED to kernel pages */ |
63 | #define _PAGE_KERNEL_RO (_PAGE_SHARED) | 65 | #define _PAGE_KERNEL_RO (_PAGE_SHARED | _PAGE_KNLRO) |
66 | #define _PAGE_KERNEL_ROX (_PAGE_EXEC | _PAGE_KNLRO) | ||
64 | #define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE) | 67 | #define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE) |
65 | 68 | ||
66 | #endif /* __KERNEL__ */ | 69 | #endif /* __KERNEL__ */ |
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 6e9124177f19..8d6e6830a675 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S | |||
@@ -447,14 +447,8 @@ DataStoreTLBMiss: | |||
447 | and r11, r11, r10 | 447 | and r11, r11, r10 |
448 | rlwimi r10, r11, 0, _PAGE_PRESENT | 448 | rlwimi r10, r11, 0, _PAGE_PRESENT |
449 | #endif | 449 | #endif |
450 | /* Honour kernel RO, User NA */ | 450 | /* invert RW */ |
451 | /* 0x200 == Extended encoding, bit 22 */ | 451 | xori r10, r10, _PAGE_RW |
452 | rlwimi r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */ | ||
453 | /* r11 = (r10 & _PAGE_RW) >> 1 */ | ||
454 | rlwinm r11, r10, 32-1, 0x200 | ||
455 | or r10, r11, r10 | ||
456 | /* invert RW and 0x200 bits */ | ||
457 | xori r10, r10, _PAGE_RW | 0x200 | ||
458 | 452 | ||
459 | /* The Linux PTE won't go exactly into the MMU TLB. | 453 | /* The Linux PTE won't go exactly into the MMU TLB. |
460 | * Software indicator bits 22 and 28 must be clear. | 454 | * Software indicator bits 22 and 28 must be clear. |