diff options
Diffstat (limited to 'arch/sparc64/mm/ultra.S')
-rw-r--r-- | arch/sparc64/mm/ultra.S | 112 |
1 files changed, 22 insertions, 90 deletions
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index b2ee9b53227f..e4c9151fa116 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S | |||
@@ -144,42 +144,29 @@ __flush_icache_page: /* %o0 = phys_page */ | |||
144 | 144 | ||
145 | #define DTAG_MASK 0x3 | 145 | #define DTAG_MASK 0x3 |
146 | 146 | ||
147 | /* This routine is Spitfire specific so the hardcoded | ||
148 | * D-cache size and line-size are OK. | ||
149 | */ | ||
147 | .align 64 | 150 | .align 64 |
148 | .globl __flush_dcache_page | 151 | .globl __flush_dcache_page |
149 | __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ | 152 | __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ |
150 | sethi %uhi(PAGE_OFFSET), %g1 | 153 | sethi %uhi(PAGE_OFFSET), %g1 |
151 | sllx %g1, 32, %g1 | 154 | sllx %g1, 32, %g1 |
152 | sub %o0, %g1, %o0 | 155 | sub %o0, %g1, %o0 ! physical address |
153 | clr %o4 | 156 | srlx %o0, 11, %o0 ! make D-cache TAG |
154 | srlx %o0, 11, %o0 | 157 | sethi %hi(1 << 14), %o2 ! D-cache size |
155 | sethi %hi(1 << 14), %o2 | 158 | sub %o2, (1 << 5), %o2 ! D-cache line size |
156 | 1: ldxa [%o4] ASI_DCACHE_TAG, %o3 ! LSU Group | 159 | 1: ldxa [%o2] ASI_DCACHE_TAG, %o3 ! load D-cache TAG |
157 | add %o4, (1 << 5), %o4 ! IEU0 | 160 | andcc %o3, DTAG_MASK, %g0 ! Valid? |
158 | ldxa [%o4] ASI_DCACHE_TAG, %g1 ! LSU Group | 161 | be,pn %xcc, 2f ! Nope, branch |
159 | add %o4, (1 << 5), %o4 ! IEU0 | 162 | andn %o3, DTAG_MASK, %o3 ! Clear valid bits |
160 | ldxa [%o4] ASI_DCACHE_TAG, %g2 ! LSU Group o3 available | 163 | cmp %o3, %o0 ! TAG match? |
161 | add %o4, (1 << 5), %o4 ! IEU0 | 164 | bne,pt %xcc, 2f ! Nope, branch |
162 | andn %o3, DTAG_MASK, %o3 ! IEU1 | 165 | nop |
163 | ldxa [%o4] ASI_DCACHE_TAG, %g3 ! LSU Group | 166 | stxa %g0, [%o2] ASI_DCACHE_TAG ! Invalidate TAG |
164 | add %o4, (1 << 5), %o4 ! IEU0 | 167 | membar #Sync |
165 | andn %g1, DTAG_MASK, %g1 ! IEU1 | 168 | 2: brnz,pt %o2, 1b |
166 | cmp %o0, %o3 ! IEU1 Group | 169 | sub %o2, (1 << 5), %o2 ! D-cache line size |
167 | be,a,pn %xcc, dflush1 ! CTI | ||
168 | sub %o4, (4 << 5), %o4 ! IEU0 (Group) | ||
169 | cmp %o0, %g1 ! IEU1 Group | ||
170 | andn %g2, DTAG_MASK, %g2 ! IEU0 | ||
171 | be,a,pn %xcc, dflush2 ! CTI | ||
172 | sub %o4, (3 << 5), %o4 ! IEU0 (Group) | ||
173 | cmp %o0, %g2 ! IEU1 Group | ||
174 | andn %g3, DTAG_MASK, %g3 ! IEU0 | ||
175 | be,a,pn %xcc, dflush3 ! CTI | ||
176 | sub %o4, (2 << 5), %o4 ! IEU0 (Group) | ||
177 | cmp %o0, %g3 ! IEU1 Group | ||
178 | be,a,pn %xcc, dflush4 ! CTI | ||
179 | sub %o4, (1 << 5), %o4 ! IEU0 | ||
180 | 2: cmp %o4, %o2 ! IEU1 Group | ||
181 | bne,pt %xcc, 1b ! CTI | ||
182 | nop ! IEU0 | ||
183 | 170 | ||
184 | /* The I-cache does not snoop local stores so we | 171 | /* The I-cache does not snoop local stores so we |
185 | * better flush that too when necessary. | 172 | * better flush that too when necessary. |
@@ -189,48 +176,9 @@ __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ | |||
189 | retl | 176 | retl |
190 | nop | 177 | nop |
191 | 178 | ||
192 | dflush1:stxa %g0, [%o4] ASI_DCACHE_TAG | ||
193 | add %o4, (1 << 5), %o4 | ||
194 | dflush2:stxa %g0, [%o4] ASI_DCACHE_TAG | ||
195 | add %o4, (1 << 5), %o4 | ||
196 | dflush3:stxa %g0, [%o4] ASI_DCACHE_TAG | ||
197 | add %o4, (1 << 5), %o4 | ||
198 | dflush4:stxa %g0, [%o4] ASI_DCACHE_TAG | ||
199 | add %o4, (1 << 5), %o4 | ||
200 | membar #Sync | ||
201 | ba,pt %xcc, 2b | ||
202 | nop | ||
203 | #endif /* DCACHE_ALIASING_POSSIBLE */ | 179 | #endif /* DCACHE_ALIASING_POSSIBLE */ |
204 | 180 | ||
205 | .previous .text | 181 | .previous |
206 | .align 32 | ||
207 | __prefill_dtlb: | ||
208 | rdpr %pstate, %g7 | ||
209 | wrpr %g7, PSTATE_IE, %pstate | ||
210 | mov TLB_TAG_ACCESS, %g1 | ||
211 | stxa %o5, [%g1] ASI_DMMU | ||
212 | stxa %o2, [%g0] ASI_DTLB_DATA_IN | ||
213 | flush %g6 | ||
214 | retl | ||
215 | wrpr %g7, %pstate | ||
216 | __prefill_itlb: | ||
217 | rdpr %pstate, %g7 | ||
218 | wrpr %g7, PSTATE_IE, %pstate | ||
219 | mov TLB_TAG_ACCESS, %g1 | ||
220 | stxa %o5, [%g1] ASI_IMMU | ||
221 | stxa %o2, [%g0] ASI_ITLB_DATA_IN | ||
222 | flush %g6 | ||
223 | retl | ||
224 | wrpr %g7, %pstate | ||
225 | |||
226 | .globl __update_mmu_cache | ||
227 | __update_mmu_cache: /* %o0=hw_context, %o1=address, %o2=pte, %o3=fault_code */ | ||
228 | srlx %o1, PAGE_SHIFT, %o1 | ||
229 | andcc %o3, FAULT_CODE_DTLB, %g0 | ||
230 | sllx %o1, PAGE_SHIFT, %o5 | ||
231 | bne,pt %xcc, __prefill_dtlb | ||
232 | or %o5, %o0, %o5 | ||
233 | ba,a,pt %xcc, __prefill_itlb | ||
234 | 182 | ||
235 | /* Cheetah specific versions, patched at boot time. */ | 183 | /* Cheetah specific versions, patched at boot time. */ |
236 | __cheetah_flush_tlb_mm: /* 18 insns */ | 184 | __cheetah_flush_tlb_mm: /* 18 insns */ |
@@ -283,7 +231,7 @@ __cheetah_flush_tlb_pending: /* 26 insns */ | |||
283 | wrpr %g7, 0x0, %pstate | 231 | wrpr %g7, 0x0, %pstate |
284 | 232 | ||
285 | #ifdef DCACHE_ALIASING_POSSIBLE | 233 | #ifdef DCACHE_ALIASING_POSSIBLE |
286 | flush_dcpage_cheetah: /* 11 insns */ | 234 | __cheetah_flush_dcache_page: /* 11 insns */ |
287 | sethi %uhi(PAGE_OFFSET), %g1 | 235 | sethi %uhi(PAGE_OFFSET), %g1 |
288 | sllx %g1, 32, %g1 | 236 | sllx %g1, 32, %g1 |
289 | sub %o0, %g1, %o0 | 237 | sub %o0, %g1, %o0 |
@@ -329,8 +277,8 @@ cheetah_patch_cachetlbops: | |||
329 | #ifdef DCACHE_ALIASING_POSSIBLE | 277 | #ifdef DCACHE_ALIASING_POSSIBLE |
330 | sethi %hi(__flush_dcache_page), %o0 | 278 | sethi %hi(__flush_dcache_page), %o0 |
331 | or %o0, %lo(__flush_dcache_page), %o0 | 279 | or %o0, %lo(__flush_dcache_page), %o0 |
332 | sethi %hi(flush_dcpage_cheetah), %o1 | 280 | sethi %hi(__cheetah_flush_dcache_page), %o1 |
333 | or %o1, %lo(flush_dcpage_cheetah), %o1 | 281 | or %o1, %lo(__cheetah_flush_dcache_page), %o1 |
334 | call cheetah_patch_one | 282 | call cheetah_patch_one |
335 | mov 11, %o2 | 283 | mov 11, %o2 |
336 | #endif /* DCACHE_ALIASING_POSSIBLE */ | 284 | #endif /* DCACHE_ALIASING_POSSIBLE */ |
@@ -505,22 +453,6 @@ xcall_flush_dcache_page_spitfire: /* %g1 == physical page address | |||
505 | nop | 453 | nop |
506 | nop | 454 | nop |
507 | 455 | ||
508 | .globl xcall_promstop | ||
509 | xcall_promstop: | ||
510 | rdpr %pstate, %g2 | ||
511 | wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate | ||
512 | rdpr %pil, %g2 | ||
513 | wrpr %g0, 15, %pil | ||
514 | sethi %hi(109f), %g7 | ||
515 | b,pt %xcc, etrap_irq | ||
516 | 109: or %g7, %lo(109b), %g7 | ||
517 | flushw | ||
518 | call prom_stopself | ||
519 | nop | ||
520 | /* We should not return, just spin if we do... */ | ||
521 | 1: b,a,pt %xcc, 1b | ||
522 | nop | ||
523 | |||
524 | .data | 456 | .data |
525 | 457 | ||
526 | errata32_hwbug: | 458 | errata32_hwbug: |