~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sparc/mm/hypersparc.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * hypersparc.S: High speed Hypersparc mmu/cache operations.
  4  *
  5  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  6  */
  7 
  8 #include <asm/ptrace.h>
  9 #include <asm/psr.h>
 10 #include <asm/asm-offsets.h>
 11 #include <asm/asi.h>
 12 #include <asm/page.h>
 13 #include <asm/pgtable.h>
 14 #include <asm/pgtsrmmu.h>
 15 #include <linux/init.h>
 16 
 17         .text
 18         .align  4
 19 
 20         .globl  hypersparc_flush_cache_all, hypersparc_flush_cache_mm
 21         .globl  hypersparc_flush_cache_range, hypersparc_flush_cache_page
 22         .globl  hypersparc_flush_page_to_ram
 23         .globl  hypersparc_flush_page_for_dma, hypersparc_flush_sig_insns
 24         .globl  hypersparc_flush_tlb_all, hypersparc_flush_tlb_mm
 25         .globl  hypersparc_flush_tlb_range, hypersparc_flush_tlb_page
 26 
 27 hypersparc_flush_cache_all:
 28         WINDOW_FLUSH(%g4, %g5)
 29         sethi   %hi(vac_cache_size), %g4
 30         ld      [%g4 + %lo(vac_cache_size)], %g5
 31         sethi   %hi(vac_line_size), %g1
 32         ld      [%g1 + %lo(vac_line_size)], %g2
 33 1:      
 34         subcc   %g5, %g2, %g5                   ! hyper_flush_unconditional_combined
 35         bne     1b
 36          sta    %g0, [%g5] ASI_M_FLUSH_CTX
 37         retl
 38          sta    %g0, [%g0] ASI_M_FLUSH_IWHOLE   ! hyper_flush_whole_icache
 39 
 40         /* We expand the window flush to get maximum performance. */
 41 hypersparc_flush_cache_mm:
 42 #ifndef CONFIG_SMP
 43         ld      [%o0 + AOFF_mm_context], %g1
 44         cmp     %g1, -1
 45         be      hypersparc_flush_cache_mm_out
 46 #endif
 47         WINDOW_FLUSH(%g4, %g5)
 48 
 49         sethi   %hi(vac_line_size), %g1
 50         ld      [%g1 + %lo(vac_line_size)], %o1
 51         sethi   %hi(vac_cache_size), %g2
 52         ld      [%g2 + %lo(vac_cache_size)], %o0
 53         add     %o1, %o1, %g1
 54         add     %o1, %g1, %g2
 55         add     %o1, %g2, %g3
 56         add     %o1, %g3, %g4
 57         add     %o1, %g4, %g5
 58         add     %o1, %g5, %o4
 59         add     %o1, %o4, %o5
 60 
 61         /* BLAMMO! */
 62 1:
 63         subcc   %o0, %o5, %o0                           ! hyper_flush_cache_user
 64         sta     %g0, [%o0 + %g0] ASI_M_FLUSH_USER
 65         sta     %g0, [%o0 + %o1] ASI_M_FLUSH_USER
 66         sta     %g0, [%o0 + %g1] ASI_M_FLUSH_USER
 67         sta     %g0, [%o0 + %g2] ASI_M_FLUSH_USER
 68         sta     %g0, [%o0 + %g3] ASI_M_FLUSH_USER
 69         sta     %g0, [%o0 + %g4] ASI_M_FLUSH_USER
 70         sta     %g0, [%o0 + %g5] ASI_M_FLUSH_USER
 71         bne     1b
 72          sta    %g0, [%o0 + %o4] ASI_M_FLUSH_USER
 73 hypersparc_flush_cache_mm_out:
 74         retl
 75          nop
 76 
 77         /* The things we do for performance... */
 78 hypersparc_flush_cache_range:
 79         ld      [%o0 + VMA_VM_MM], %o0
 80 #ifndef CONFIG_SMP
 81         ld      [%o0 + AOFF_mm_context], %g1
 82         cmp     %g1, -1
 83         be      hypersparc_flush_cache_range_out
 84 #endif
 85         WINDOW_FLUSH(%g4, %g5)
 86 
 87         sethi   %hi(vac_line_size), %g1
 88         ld      [%g1 + %lo(vac_line_size)], %o4
 89         sethi   %hi(vac_cache_size), %g2
 90         ld      [%g2 + %lo(vac_cache_size)], %o3
 91 
 92         /* Here comes the fun part... */
 93         add     %o2, (PAGE_SIZE - 1), %o2
 94         andn    %o1, (PAGE_SIZE - 1), %o1
 95         add     %o4, %o4, %o5
 96         andn    %o2, (PAGE_SIZE - 1), %o2
 97         add     %o4, %o5, %g1
 98         sub     %o2, %o1, %g4
 99         add     %o4, %g1, %g2
100         sll     %o3, 2, %g5
101         add     %o4, %g2, %g3
102         cmp     %g4, %g5
103         add     %o4, %g3, %g4
104         blu     0f
105          add    %o4, %g4, %g5
106         add     %o4, %g5, %g7
107 
108         /* Flush entire user space, believe it or not this is quicker
109          * than page at a time flushings for range > (cache_size<<2).
110          */
111 1:
112         subcc   %o3, %g7, %o3
113         sta     %g0, [%o3 + %g0] ASI_M_FLUSH_USER
114         sta     %g0, [%o3 + %o4] ASI_M_FLUSH_USER
115         sta     %g0, [%o3 + %o5] ASI_M_FLUSH_USER
116         sta     %g0, [%o3 + %g1] ASI_M_FLUSH_USER
117         sta     %g0, [%o3 + %g2] ASI_M_FLUSH_USER
118         sta     %g0, [%o3 + %g3] ASI_M_FLUSH_USER
119         sta     %g0, [%o3 + %g4] ASI_M_FLUSH_USER
120         bne     1b
121          sta    %g0, [%o3 + %g5] ASI_M_FLUSH_USER
122         retl
123          nop
124 
125         /* Below our threshold, flush one page at a time. */
126 0:
127         ld      [%o0 + AOFF_mm_context], %o0
128         mov     SRMMU_CTX_REG, %g7
129         lda     [%g7] ASI_M_MMUREGS, %o3
130         sta     %o0, [%g7] ASI_M_MMUREGS
131         add     %o2, -PAGE_SIZE, %o0
132 1:
133         or      %o0, 0x400, %g7
134         lda     [%g7] ASI_M_FLUSH_PROBE, %g7
135         orcc    %g7, 0, %g0
136         be,a    3f
137          mov    %o0, %o2
138         add     %o4, %g5, %g7
139 2:
140         sub     %o2, %g7, %o2
141         sta     %g0, [%o2 + %g0] ASI_M_FLUSH_PAGE
142         sta     %g0, [%o2 + %o4] ASI_M_FLUSH_PAGE
143         sta     %g0, [%o2 + %o5] ASI_M_FLUSH_PAGE
144         sta     %g0, [%o2 + %g1] ASI_M_FLUSH_PAGE
145         sta     %g0, [%o2 + %g2] ASI_M_FLUSH_PAGE
146         sta     %g0, [%o2 + %g3] ASI_M_FLUSH_PAGE
147         andcc   %o2, 0xffc, %g0
148         sta     %g0, [%o2 + %g4] ASI_M_FLUSH_PAGE
149         bne     2b
150          sta    %g0, [%o2 + %g5] ASI_M_FLUSH_PAGE
151 3:
152         cmp     %o2, %o1
153         bne     1b
154          add    %o2, -PAGE_SIZE, %o0
155         mov     SRMMU_FAULT_STATUS, %g5
156         lda     [%g5] ASI_M_MMUREGS, %g0
157         mov     SRMMU_CTX_REG, %g7
158         sta     %o3, [%g7] ASI_M_MMUREGS
159 hypersparc_flush_cache_range_out:
160         retl
161          nop
162 
163         /* HyperSparc requires a valid mapping where we are about to flush
164          * in order to check for a physical tag match during the flush.
165          */
166         /* Verified, my ass... */
167 hypersparc_flush_cache_page:
168         ld      [%o0 + VMA_VM_MM], %o0
169         ld      [%o0 + AOFF_mm_context], %g2
170 #ifndef CONFIG_SMP
171         cmp     %g2, -1
172         be      hypersparc_flush_cache_page_out
173 #endif
174         WINDOW_FLUSH(%g4, %g5)
175 
176         sethi   %hi(vac_line_size), %g1
177         ld      [%g1 + %lo(vac_line_size)], %o4
178         mov     SRMMU_CTX_REG, %o3
179         andn    %o1, (PAGE_SIZE - 1), %o1
180         lda     [%o3] ASI_M_MMUREGS, %o2
181         sta     %g2, [%o3] ASI_M_MMUREGS
182         or      %o1, 0x400, %o5
183         lda     [%o5] ASI_M_FLUSH_PROBE, %g1
184         orcc    %g0, %g1, %g0
185         be      2f
186          add    %o4, %o4, %o5
187         sub     %o1, -PAGE_SIZE, %o1
188         add     %o4, %o5, %g1
189         add     %o4, %g1, %g2
190         add     %o4, %g2, %g3
191         add     %o4, %g3, %g4
192         add     %o4, %g4, %g5
193         add     %o4, %g5, %g7
194 
195         /* BLAMMO! */
196 1:
197         sub     %o1, %g7, %o1
198         sta     %g0, [%o1 + %g0] ASI_M_FLUSH_PAGE
199         sta     %g0, [%o1 + %o4] ASI_M_FLUSH_PAGE
200         sta     %g0, [%o1 + %o5] ASI_M_FLUSH_PAGE
201         sta     %g0, [%o1 + %g1] ASI_M_FLUSH_PAGE
202         sta     %g0, [%o1 + %g2] ASI_M_FLUSH_PAGE
203         sta     %g0, [%o1 + %g3] ASI_M_FLUSH_PAGE
204         andcc   %o1, 0xffc, %g0
205         sta     %g0, [%o1 + %g4] ASI_M_FLUSH_PAGE
206         bne     1b
207          sta    %g0, [%o1 + %g5] ASI_M_FLUSH_PAGE
208 2:
209         mov     SRMMU_FAULT_STATUS, %g7
210         mov     SRMMU_CTX_REG, %g4
211         lda     [%g7] ASI_M_MMUREGS, %g0
212         sta     %o2, [%g4] ASI_M_MMUREGS
213 hypersparc_flush_cache_page_out:
214         retl
215          nop
216 
217 hypersparc_flush_sig_insns:
218         flush   %o1
219         retl
220          flush  %o1 + 4
221 
222         /* HyperSparc is copy-back. */
223 hypersparc_flush_page_to_ram:
224         sethi   %hi(vac_line_size), %g1
225         ld      [%g1 + %lo(vac_line_size)], %o4
226         andn    %o0, (PAGE_SIZE - 1), %o0
227         add     %o4, %o4, %o5
228         or      %o0, 0x400, %g7
229         lda     [%g7] ASI_M_FLUSH_PROBE, %g5
230         add     %o4, %o5, %g1
231         orcc    %g5, 0, %g0
232         be      2f
233          add    %o4, %g1, %g2
234         add     %o4, %g2, %g3
235         sub     %o0, -PAGE_SIZE, %o0
236         add     %o4, %g3, %g4
237         add     %o4, %g4, %g5
238         add     %o4, %g5, %g7
239 
240         /* BLAMMO! */
241 1:
242         sub     %o0, %g7, %o0
243         sta     %g0, [%o0 + %g0] ASI_M_FLUSH_PAGE
244         sta     %g0, [%o0 + %o4] ASI_M_FLUSH_PAGE
245         sta     %g0, [%o0 + %o5] ASI_M_FLUSH_PAGE
246         sta     %g0, [%o0 + %g1] ASI_M_FLUSH_PAGE
247         sta     %g0, [%o0 + %g2] ASI_M_FLUSH_PAGE
248         sta     %g0, [%o0 + %g3] ASI_M_FLUSH_PAGE
249         andcc   %o0, 0xffc, %g0
250         sta     %g0, [%o0 + %g4] ASI_M_FLUSH_PAGE
251         bne     1b
252          sta    %g0, [%o0 + %g5] ASI_M_FLUSH_PAGE
253 2:
254         mov     SRMMU_FAULT_STATUS, %g1
255         retl
256          lda    [%g1] ASI_M_MMUREGS, %g0
257 
258         /* HyperSparc is IO cache coherent. */
259 hypersparc_flush_page_for_dma:
260         retl
261          nop
262 
263         /* It was noted that at boot time a TLB flush all in a delay slot
264          * can deliver an illegal instruction to the processor if the timing
265          * is just right...
266          */
267 hypersparc_flush_tlb_all:
268         mov     0x400, %g1
269         sta     %g0, [%g1] ASI_M_FLUSH_PROBE
270         retl
271          nop
272 
273 hypersparc_flush_tlb_mm:
274         mov     SRMMU_CTX_REG, %g1
275         ld      [%o0 + AOFF_mm_context], %o1
276         lda     [%g1] ASI_M_MMUREGS, %g5
277 #ifndef CONFIG_SMP
278         cmp     %o1, -1
279         be      hypersparc_flush_tlb_mm_out
280 #endif
281          mov    0x300, %g2
282         sta     %o1, [%g1] ASI_M_MMUREGS
283         sta     %g0, [%g2] ASI_M_FLUSH_PROBE
284 hypersparc_flush_tlb_mm_out:
285         retl
286          sta    %g5, [%g1] ASI_M_MMUREGS
287 
288 hypersparc_flush_tlb_range:
289         ld      [%o0 + VMA_VM_MM], %o0
290         mov     SRMMU_CTX_REG, %g1
291         ld      [%o0 + AOFF_mm_context], %o3
292         lda     [%g1] ASI_M_MMUREGS, %g5
293 #ifndef CONFIG_SMP
294         cmp     %o3, -1
295         be      hypersparc_flush_tlb_range_out
296 #endif
297          sethi  %hi(~((1 << PGDIR_SHIFT) - 1)), %o4
298         sta     %o3, [%g1] ASI_M_MMUREGS
299         and     %o1, %o4, %o1
300         add     %o1, 0x200, %o1
301         sta     %g0, [%o1] ASI_M_FLUSH_PROBE
302 1:
303         sub     %o1, %o4, %o1
304         cmp     %o1, %o2
305         blu,a   1b
306          sta    %g0, [%o1] ASI_M_FLUSH_PROBE
307 hypersparc_flush_tlb_range_out:
308         retl
309          sta    %g5, [%g1] ASI_M_MMUREGS
310 
311 hypersparc_flush_tlb_page:
312         ld      [%o0 + VMA_VM_MM], %o0
313         mov     SRMMU_CTX_REG, %g1
314         ld      [%o0 + AOFF_mm_context], %o3
315         andn    %o1, (PAGE_SIZE - 1), %o1
316 #ifndef CONFIG_SMP
317         cmp     %o3, -1
318         be      hypersparc_flush_tlb_page_out
319 #endif
320          lda    [%g1] ASI_M_MMUREGS, %g5
321         sta     %o3, [%g1] ASI_M_MMUREGS
322         sta     %g0, [%o1] ASI_M_FLUSH_PROBE
323 hypersparc_flush_tlb_page_out:
324         retl
325          sta    %g5, [%g1] ASI_M_MMUREGS
326 
327         __INIT
328         
329         /* High speed page clear/copy. */
330 hypersparc_bzero_1page:
331 /* NOTE: This routine has to be shorter than 40insns --jj */
332         clr     %g1
333         mov     32, %g2
334         mov     64, %g3
335         mov     96, %g4
336         mov     128, %g5
337         mov     160, %g7
338         mov     192, %o2
339         mov     224, %o3
340         mov     16, %o1
341 1:
342         stda    %g0, [%o0 + %g0] ASI_M_BFILL
343         stda    %g0, [%o0 + %g2] ASI_M_BFILL
344         stda    %g0, [%o0 + %g3] ASI_M_BFILL
345         stda    %g0, [%o0 + %g4] ASI_M_BFILL
346         stda    %g0, [%o0 + %g5] ASI_M_BFILL
347         stda    %g0, [%o0 + %g7] ASI_M_BFILL
348         stda    %g0, [%o0 + %o2] ASI_M_BFILL
349         stda    %g0, [%o0 + %o3] ASI_M_BFILL
350         subcc   %o1, 1, %o1
351         bne     1b
352          add    %o0, 256, %o0
353 
354         retl
355          nop
356 
357 hypersparc_copy_1page:
358 /* NOTE: This routine has to be shorter than 70insns --jj */
359         sub     %o1, %o0, %o2           ! difference
360         mov     16, %g1
361 1:
362         sta     %o0, [%o0 + %o2] ASI_M_BCOPY
363         add     %o0, 32, %o0
364         sta     %o0, [%o0 + %o2] ASI_M_BCOPY
365         add     %o0, 32, %o0
366         sta     %o0, [%o0 + %o2] ASI_M_BCOPY
367         add     %o0, 32, %o0
368         sta     %o0, [%o0 + %o2] ASI_M_BCOPY
369         add     %o0, 32, %o0
370         sta     %o0, [%o0 + %o2] ASI_M_BCOPY
371         add     %o0, 32, %o0
372         sta     %o0, [%o0 + %o2] ASI_M_BCOPY
373         add     %o0, 32, %o0
374         sta     %o0, [%o0 + %o2] ASI_M_BCOPY
375         add     %o0, 32, %o0
376         sta     %o0, [%o0 + %o2] ASI_M_BCOPY
377         subcc   %g1, 1, %g1
378         bne     1b
379          add    %o0, 32, %o0
380 
381         retl
382          nop
383 
384         .globl  hypersparc_setup_blockops
385 hypersparc_setup_blockops:
386         sethi   %hi(bzero_1page), %o0
387         or      %o0, %lo(bzero_1page), %o0
388         sethi   %hi(hypersparc_bzero_1page), %o1
389         or      %o1, %lo(hypersparc_bzero_1page), %o1
390         sethi   %hi(hypersparc_copy_1page), %o2
391         or      %o2, %lo(hypersparc_copy_1page), %o2
392         ld      [%o1], %o4
393 1:
394         add     %o1, 4, %o1
395         st      %o4, [%o0]
396         add     %o0, 4, %o0
397         cmp     %o1, %o2
398         bne     1b
399          ld     [%o1], %o4
400         sethi   %hi(__copy_1page), %o0
401         or      %o0, %lo(__copy_1page), %o0
402         sethi   %hi(hypersparc_setup_blockops), %o2
403         or      %o2, %lo(hypersparc_setup_blockops), %o2
404         ld      [%o1], %o4
405 1:
406         add     %o1, 4, %o1
407         st      %o4, [%o0]
408         add     %o0, 4, %o0
409         cmp     %o1, %o2
410         bne     1b
411          ld     [%o1], %o4
412         sta     %g0, [%g0] ASI_M_FLUSH_IWHOLE
413         retl
414          nop

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php