diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2005-09-26 19:06:03 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-09-26 19:06:03 -0400 |
commit | c5bd50a9533533d7b9ac3469fa679b2368e7e26c (patch) | |
tree | 166aee9c0d1525ee8c4a7228015f2d4e37634c77 /arch | |
parent | 80dc0d6b44ce0f01df58d8899e46612690ed7d81 (diff) |
[SPARC64]: Simplify Spitfire D-cache page flush.
It tries to batch up the tag loads and comparisons, and
then the stores. And this is just complicated instead
of efficient.
Also, make the symbol of the Cheetah version more grepable.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc64/mm/ultra.S | 69 |
1 files changed, 23 insertions, 46 deletions
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index b2ee9b53227f..5ff5e42fb9d4 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,20 +176,10 @@ __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 |
182 | |||
206 | .align 32 | 183 | .align 32 |
207 | __prefill_dtlb: | 184 | __prefill_dtlb: |
208 | rdpr %pstate, %g7 | 185 | rdpr %pstate, %g7 |
@@ -283,7 +260,7 @@ __cheetah_flush_tlb_pending: /* 26 insns */ | |||
283 | wrpr %g7, 0x0, %pstate | 260 | wrpr %g7, 0x0, %pstate |
284 | 261 | ||
285 | #ifdef DCACHE_ALIASING_POSSIBLE | 262 | #ifdef DCACHE_ALIASING_POSSIBLE |
286 | flush_dcpage_cheetah: /* 11 insns */ | 263 | __cheetah_flush_dcache_page: /* 11 insns */ |
287 | sethi %uhi(PAGE_OFFSET), %g1 | 264 | sethi %uhi(PAGE_OFFSET), %g1 |
288 | sllx %g1, 32, %g1 | 265 | sllx %g1, 32, %g1 |
289 | sub %o0, %g1, %o0 | 266 | sub %o0, %g1, %o0 |
@@ -329,8 +306,8 @@ cheetah_patch_cachetlbops: | |||
329 | #ifdef DCACHE_ALIASING_POSSIBLE | 306 | #ifdef DCACHE_ALIASING_POSSIBLE |
330 | sethi %hi(__flush_dcache_page), %o0 | 307 | sethi %hi(__flush_dcache_page), %o0 |
331 | or %o0, %lo(__flush_dcache_page), %o0 | 308 | or %o0, %lo(__flush_dcache_page), %o0 |
332 | sethi %hi(flush_dcpage_cheetah), %o1 | 309 | sethi %hi(__cheetah_flush_dcache_page), %o1 |
333 | or %o1, %lo(flush_dcpage_cheetah), %o1 | 310 | or %o1, %lo(__cheetah_flush_dcache_page), %o1 |
334 | call cheetah_patch_one | 311 | call cheetah_patch_one |
335 | mov 11, %o2 | 312 | mov 11, %o2 |
336 | #endif /* DCACHE_ALIASING_POSSIBLE */ | 313 | #endif /* DCACHE_ALIASING_POSSIBLE */ |