xprtrdma: Fix DMAR failure in frwr_op_map() after reconnect
[linux/fpc-iii.git] / arch / powerpc / kernel / fsl_booke_entry_mapping.S
blob83dd0f6776b3e61bba5f7786db49a4e3df1b2f1b
2 /* 1. Find the index of the entry we're executing in */
3         bl      invstr                          /* Find our address */
4 invstr: mflr    r6                              /* Make it accessible */
5         mfmsr   r7
6         rlwinm  r4,r7,27,31,31                  /* extract MSR[IS] */
7         mfspr   r7, SPRN_PID0
8         slwi    r7,r7,16
9         or      r7,r7,r4
10         mtspr   SPRN_MAS6,r7
11         tlbsx   0,r6                            /* search MSR[IS], SPID=PID0 */
12         mfspr   r7,SPRN_MAS1
13         andis.  r7,r7,MAS1_VALID@h
14         bne     match_TLB
16         mfspr   r7,SPRN_MMUCFG
17         rlwinm  r7,r7,21,28,31                  /* extract MMUCFG[NPIDS] */
18         cmpwi   r7,3
19         bne     match_TLB                       /* skip if NPIDS != 3 */
21         mfspr   r7,SPRN_PID1
22         slwi    r7,r7,16
23         or      r7,r7,r4
24         mtspr   SPRN_MAS6,r7
25         tlbsx   0,r6                            /* search MSR[IS], SPID=PID1 */
26         mfspr   r7,SPRN_MAS1
27         andis.  r7,r7,MAS1_VALID@h
28         bne     match_TLB
29         mfspr   r7, SPRN_PID2
30         slwi    r7,r7,16
31         or      r7,r7,r4
32         mtspr   SPRN_MAS6,r7
33         tlbsx   0,r6                            /* Fall through, we had to match */
35 match_TLB:
36         mfspr   r7,SPRN_MAS0
37         rlwinm  r3,r7,16,20,31                  /* Extract MAS0(Entry) */
39         mfspr   r7,SPRN_MAS1                    /* Insure IPROT set */
40         oris    r7,r7,MAS1_IPROT@h
41         mtspr   SPRN_MAS1,r7
42         tlbwe
44 /* 2. Invalidate all entries except the entry we're executing in */
45         mfspr   r9,SPRN_TLB1CFG
46         andi.   r9,r9,0xfff
47         li      r6,0                            /* Set Entry counter to 0 */
48 1:      lis     r7,0x1000                       /* Set MAS0(TLBSEL) = 1 */
49         rlwimi  r7,r6,16,4,15                   /* Setup MAS0 = TLBSEL | ESEL(r6) */
50         mtspr   SPRN_MAS0,r7
51         tlbre
52         mfspr   r7,SPRN_MAS1
53         rlwinm  r7,r7,0,2,31                    /* Clear MAS1 Valid and IPROT */
54         cmpw    r3,r6
55         beq     skpinv                          /* Dont update the current execution TLB */
56         mtspr   SPRN_MAS1,r7
57         tlbwe
58         isync
59 skpinv: addi    r6,r6,1                         /* Increment */
60         cmpw    r6,r9                           /* Are we done? */
61         bne     1b                              /* If not, repeat */
63         /* Invalidate TLB0 */
64         li      r6,0x04
65         tlbivax 0,r6
66         TLBSYNC
67         /* Invalidate TLB1 */
68         li      r6,0x0c
69         tlbivax 0,r6
70         TLBSYNC
72 /* 3. Setup a temp mapping and jump to it */
73         andi.   r5, r3, 0x1     /* Find an entry not used and is non-zero */
74         addi    r5, r5, 0x1
75         lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
76         rlwimi  r7,r3,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r3) */
77         mtspr   SPRN_MAS0,r7
78         tlbre
80         /* grab and fixup the RPN */
81         mfspr   r6,SPRN_MAS1    /* extract MAS1[SIZE] */
82         rlwinm  r6,r6,25,27,31
83         li      r8,-1
84         addi    r6,r6,10
85         slw     r6,r8,r6        /* convert to mask */
87         bl      1f              /* Find our address */
88 1:      mflr    r7
90         mfspr   r8,SPRN_MAS3
91 #ifdef CONFIG_PHYS_64BIT
92         mfspr   r23,SPRN_MAS7
93 #endif
94         and     r8,r6,r8
95         subfic  r9,r6,-4096
96         and     r9,r9,r7
98         or      r25,r8,r9
99         ori     r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)
101         /* Just modify the entry ID and EPN for the temp mapping */
102         lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
103         rlwimi  r7,r5,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r5) */
104         mtspr   SPRN_MAS0,r7
105         xori    r6,r4,1         /* Setup TMP mapping in the other Address space */
106         slwi    r6,r6,12
107         oris    r6,r6,(MAS1_VALID|MAS1_IPROT)@h
108         ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
109         mtspr   SPRN_MAS1,r6
110         mfspr   r6,SPRN_MAS2
111         li      r7,0            /* temp EPN = 0 */
112         rlwimi  r7,r6,0,20,31
113         mtspr   SPRN_MAS2,r7
114         mtspr   SPRN_MAS3,r8
115         tlbwe
117         xori    r6,r4,1
118         slwi    r6,r6,5         /* setup new context with other address space */
119         bl      1f              /* Find our address */
120 1:      mflr    r9
121         rlwimi  r7,r9,0,20,31
122         addi    r7,r7,(2f - 1b)
123         mtspr   SPRN_SRR0,r7
124         mtspr   SPRN_SRR1,r6
125         rfi
127 /* 4. Clear out PIDs & Search info */
128         li      r6,0
129         mtspr   SPRN_MAS6,r6
130         mtspr   SPRN_PID0,r6
132         mfspr   r7,SPRN_MMUCFG
133         rlwinm  r7,r7,21,28,31                  /* extract MMUCFG[NPIDS] */
134         cmpwi   r7,3
135         bne     2f                              /* skip if NPIDS != 3 */
137         mtspr   SPRN_PID1,r6
138         mtspr   SPRN_PID2,r6
140 /* 5. Invalidate mapping we started in */
142         lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
143         rlwimi  r7,r3,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r3) */
144         mtspr   SPRN_MAS0,r7
145         tlbre
146         mfspr   r6,SPRN_MAS1
147         rlwinm  r6,r6,0,2,0     /* clear IPROT */
148         mtspr   SPRN_MAS1,r6
149         tlbwe
150         /* Invalidate TLB1 */
151         li      r9,0x0c
152         tlbivax 0,r9
153         TLBSYNC
156  * The mapping only needs to be cache-coherent on SMP, except on
157  * Freescale e500mc derivatives where it's also needed for coherent DMA.
158  */
159 #if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
160 #define M_IF_NEEDED     MAS2_M
161 #else
162 #define M_IF_NEEDED     0
163 #endif
165 #if defined(ENTRY_MAPPING_BOOT_SETUP)
167 /* 6. Setup KERNELBASE mapping in TLB1[0] */
168         lis     r6,0x1000               /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
169         mtspr   SPRN_MAS0,r6
170         lis     r6,(MAS1_VALID|MAS1_IPROT)@h
171         ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
172         mtspr   SPRN_MAS1,r6
173         lis     r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@h
174         ori     r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@l
175         mtspr   SPRN_MAS2,r6
176         mtspr   SPRN_MAS3,r8
177         tlbwe
179 /* 7. Jump to KERNELBASE mapping */
180         lis     r6,(KERNELBASE & ~0xfff)@h
181         ori     r6,r6,(KERNELBASE & ~0xfff)@l
182         rlwinm  r7,r25,0,0x03ffffff
183         add     r6,r7,r6
185 #elif defined(ENTRY_MAPPING_KEXEC_SETUP)
187  * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp
188  * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This
189  * will cover the first 2GiB of memory.
190  */
192         lis r10, (MAS1_VALID|MAS1_IPROT)@h
193         ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l
194         li  r11, 0
195         li  r0, 8
196         mtctr   r0
198 next_tlb_setup:
199         addi    r0, r11, 3
200         rlwinm  r0, r0, 16, 4, 15  // Compute esel
201         rlwinm  r9, r11, 28, 0, 3   // Compute [ER]PN
202         oris    r0, r0, (MAS0_TLBSEL(1))@h
203         mtspr   SPRN_MAS0,r0
204         mtspr   SPRN_MAS1,r10
205         mtspr   SPRN_MAS2,r9
206         ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR)
207         mtspr   SPRN_MAS3,r9
208         tlbwe
209         addi    r11, r11, 1
210         bdnz+   next_tlb_setup
212 /* 7. Jump to our 1:1 mapping */
213         mr      r6, r25
214 #else
215         #error You need to specify the mapping or not use this at all.
216 #endif
218         lis     r7,MSR_KERNEL@h
219         ori     r7,r7,MSR_KERNEL@l
220         bl      1f                      /* Find our address */
221 1:      mflr    r9
222         rlwimi  r6,r9,0,20,31
223         addi    r6,r6,(2f - 1b)
224         mtspr   SPRN_SRR0,r6
225         mtspr   SPRN_SRR1,r7
226         rfi                             /* start execution out of TLB1[0] entry */
228 /* 8. Clear out the temp mapping */
229 2:      lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
230         rlwimi  r7,r5,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r5) */
231         mtspr   SPRN_MAS0,r7
232         tlbre
233         mfspr   r8,SPRN_MAS1
234         rlwinm  r8,r8,0,2,0     /* clear IPROT */
235         mtspr   SPRN_MAS1,r8
236         tlbwe
237         /* Invalidate TLB1 */
238         li      r9,0x0c
239         tlbivax 0,r9
240         TLBSYNC