powerpc: fix for long standing bug noticed by gcc 4.4.0
[linux-2.6] / arch / powerpc / mm / tlb_nohash_low.S
1 /*
2  * This file contains low-level functions for performing various
3  * types of TLB invalidations on various processors with no hash
4  * table.
5  *
6  * This file implements the following functions for all no-hash
7  * processors. Some aren't implemented for some variants. Some
8  * are inline in tlbflush.h
9  *
10  *      - tlbil_va
11  *      - tlbil_pid
12  *      - tlbil_all
13  *      - tlbivax_bcast (not yet)
14  *
15  * Code mostly moved over from misc_32.S
16  *
17  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
18  *
19  * Partially rewritten by Cort Dougan (cort@cs.nmt.edu)
20  * Paul Mackerras, Kumar Gala and Benjamin Herrenschmidt.
21  *
22  * This program is free software; you can redistribute it and/or
23  * modify it under the terms of the GNU General Public License
24  * as published by the Free Software Foundation; either version
25  * 2 of the License, or (at your option) any later version.
26  *
27  */
28
29 #include <asm/reg.h>
30 #include <asm/page.h>
31 #include <asm/cputable.h>
32 #include <asm/mmu.h>
33 #include <asm/ppc_asm.h>
34 #include <asm/asm-offsets.h>
35 #include <asm/processor.h>
36
37 #if defined(CONFIG_40x)
38
39 /*
40  * 40x implementation needs only tlbil_va
41  */
42 _GLOBAL(_tlbil_va)
43         /* We run the search with interrupts disabled because we have to change
44          * the PID and I don't want to preempt when that happens.
45          */
46         mfmsr   r5
47         mfspr   r6,SPRN_PID
48         wrteei  0
49         mtspr   SPRN_PID,r4
50         tlbsx.  r3, 0, r3
51         mtspr   SPRN_PID,r6
52         wrtee   r5
53         bne     1f
54         sync
55         /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is
56          * clear. Since 25 is the V bit in the TLB_TAG, loading this value
57          * will invalidate the TLB entry. */
58         tlbwe   r3, r3, TLB_TAG
59         isync
60 1:      blr
61
62 #elif defined(CONFIG_8xx)
63
64 /*
65  * Nothing to do for 8xx, everything is inline
66  */
67
68 #elif defined(CONFIG_44x)
69
70 /*
71  * 440 implementation uses tlbsx/we for tlbil_va and a full sweep
72  * of the TLB for everything else.
73  */
74 _GLOBAL(_tlbil_va)
75         mfspr   r5,SPRN_MMUCR
76         rlwimi  r5,r4,0,24,31                   /* Set TID */
77
78         /* We have to run the search with interrupts disabled, otherwise
79          * an interrupt which causes a TLB miss can clobber the MMUCR
80          * between the mtspr and the tlbsx.
81          *
82          * Critical and Machine Check interrupts take care of saving
83          * and restoring MMUCR, so only normal interrupts have to be
84          * taken care of.
85          */
86         mfmsr   r4
87         wrteei  0
88         mtspr   SPRN_MMUCR,r5
89         tlbsx.  r3, 0, r3
90         wrtee   r4
91         bne     1f
92         sync
93         /* There are only 64 TLB entries, so r3 < 64,
94          * which means bit 22, is clear.  Since 22 is
95          * the V bit in the TLB_PAGEID, loading this
96          * value will invalidate the TLB entry.
97          */
98         tlbwe   r3, r3, PPC44x_TLB_PAGEID
99         isync
100 1:      blr
101
102 _GLOBAL(_tlbil_all)
103 _GLOBAL(_tlbil_pid)
104         li      r3,0
105         sync
106
107         /* Load high watermark */
108         lis     r4,tlb_44x_hwater@ha
109         lwz     r5,tlb_44x_hwater@l(r4)
110
111 1:      tlbwe   r3,r3,PPC44x_TLB_PAGEID
112         addi    r3,r3,1
113         cmpw    0,r3,r5
114         ble     1b
115
116         isync
117         blr
118
119 #elif defined(CONFIG_FSL_BOOKE)
120 /*
121  * FSL BookE implementations.
122  *
123  * Since feature sections are using _SECTION_ELSE we need
124  * to have the larger code path before the _SECTION_ELSE
125  */
126
127 #define MMUCSR0_TLBFI   (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
128                          MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
129 /*
130  * Flush MMU TLB on the local processor
131  */
132 _GLOBAL(_tlbil_all)
133 BEGIN_MMU_FTR_SECTION
134         li      r3,(MMUCSR0_TLBFI)@l
135         mtspr   SPRN_MMUCSR0, r3
136 1:
137         mfspr   r3,SPRN_MMUCSR0
138         andi.   r3,r3,MMUCSR0_TLBFI@l
139         bne     1b
140 MMU_FTR_SECTION_ELSE
141         PPC_TLBILX_ALL(0,0)
142 ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
143         msync
144         isync
145         blr
146
147 _GLOBAL(_tlbil_pid)
148 BEGIN_MMU_FTR_SECTION
149         slwi    r3,r3,16
150         mfmsr   r10
151         wrteei  0
152         mfspr   r4,SPRN_MAS6    /* save MAS6 */
153         mtspr   SPRN_MAS6,r3
154         PPC_TLBILX_PID(0,0)
155         mtspr   SPRN_MAS6,r4    /* restore MAS6 */
156         wrtee   r10
157 MMU_FTR_SECTION_ELSE
158         li      r3,(MMUCSR0_TLBFI)@l
159         mtspr   SPRN_MMUCSR0, r3
160 1:
161         mfspr   r3,SPRN_MMUCSR0
162         andi.   r3,r3,MMUCSR0_TLBFI@l
163         bne     1b
164 ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBILX)
165         msync
166         isync
167         blr
168
169 /*
170  * Flush MMU TLB for a particular address, but only on the local processor
171  * (no broadcast)
172  */
173 _GLOBAL(_tlbil_va)
174         mfmsr   r10
175         wrteei  0
176         slwi    r4,r4,16
177         ori     r4,r4,(MAS6_ISIZE(BOOK3E_PAGESZ_4K))@l
178         mtspr   SPRN_MAS6,r4            /* assume AS=0 for now */
179 BEGIN_MMU_FTR_SECTION
180         tlbsx   0,r3
181         mfspr   r4,SPRN_MAS1            /* check valid */
182         andis.  r3,r4,MAS1_VALID@h
183         beq     1f
184         rlwinm  r4,r4,0,1,31
185         mtspr   SPRN_MAS1,r4
186         tlbwe
187 MMU_FTR_SECTION_ELSE
188         PPC_TLBILX_VA(0,r3)
189 ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
190         msync
191         isync
192 1:      wrtee   r10
193         blr
194 #else
195 #error Unsupported processor type !
196 #endif