Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / unicore32 / mm / cache-ucv2.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * linux/arch/unicore32/mm/cache-ucv2.S
4  *
5  * Code specific to PKUnity SoC and UniCore ISA
6  *
7  * Copyright (C) 2001-2010 GUAN Xue-tao
8  *
9  *  This is the "shell" of the UniCore-v2 processor support.
10  */
11 #include <linux/linkage.h>
12 #include <linux/init.h>
13 #include <asm/assembler.h>
14 #include <asm/page.h>
15
16 #include "proc-macros.S"
17
18 /*
19  *      __cpuc_flush_icache_all()
20  *      __cpuc_flush_kern_all()
21  *      __cpuc_flush_user_all()
22  *
23  *      Flush the entire cache.
24  */
25 ENTRY(__cpuc_flush_icache_all)
26         /*FALLTHROUGH*/
27 ENTRY(__cpuc_flush_kern_all)
28         /*FALLTHROUGH*/
29 ENTRY(__cpuc_flush_user_all)
30         mov     r0, #0
31         movc    p0.c5, r0, #14                  @ Dcache flush all
32         nop8
33
34         mov     r0, #0
35         movc    p0.c5, r0, #20                  @ Icache invalidate all
36         nop8
37
38         mov     pc, lr
39
40 /*
41  *      __cpuc_flush_user_range(start, end, flags)
42  *
43  *      Flush a range of TLB entries in the specified address space.
44  *
45  *      - start - start address (may not be aligned)
46  *      - end   - end address (exclusive, may not be aligned)
47  *      - flags - vm_area_struct flags describing address space
48  */
49 ENTRY(__cpuc_flush_user_range)
50         cxor.a  r2, #0
51         beq     __cpuc_dma_flush_range
52
53 #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
54         andn    r0, r0, #CACHE_LINESIZE - 1     @ Safety check
55         sub     r1, r1, r0
56         csub.a  r1, #MAX_AREA_SIZE
57         bsg     2f
58
59         andn    r1, r1, #CACHE_LINESIZE - 1
60         add     r1, r1, #CACHE_LINESIZE
61
62 101:    dcacheline_flush        r0, r11, r12
63
64         add     r0, r0, #CACHE_LINESIZE
65         sub.a   r1, r1, #CACHE_LINESIZE
66         bns     101b
67         b       3f
68 #endif
69 2:      mov     ip, #0
70         movc    p0.c5, ip, #14                  @ Dcache flush all
71         nop8
72
73 3:      mov     ip, #0
74         movc    p0.c5, ip, #20                  @ Icache invalidate all
75         nop8
76
77         mov     pc, lr
78
79 /*
80  *      __cpuc_coherent_kern_range(start,end)
81  *      __cpuc_coherent_user_range(start,end)
82  *
83  *      Ensure that the I and D caches are coherent within specified
84  *      region.  This is typically used when code has been written to
85  *      a memory region, and will be executed.
86  *
87  *      - start   - virtual start address of region
88  *      - end     - virtual end address of region
89  */
90 ENTRY(__cpuc_coherent_kern_range)
91         /* FALLTHROUGH */
92 ENTRY(__cpuc_coherent_user_range)
93 #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
94         andn    r0, r0, #CACHE_LINESIZE - 1     @ Safety check
95         sub     r1, r1, r0
96         csub.a  r1, #MAX_AREA_SIZE
97         bsg     2f
98
99         andn    r1, r1, #CACHE_LINESIZE - 1
100         add     r1, r1, #CACHE_LINESIZE
101
102         @ r0 va2pa r10
103         mov     r9, #PAGE_SZ
104         sub     r9, r9, #1                      @ PAGE_MASK
105 101:    va2pa   r0, r10, r11, r12, r13, 2f      @ r10 is PA
106         b       103f
107 102:    cand.a  r0, r9
108         beq     101b
109
110 103:    movc    p0.c5, r10, #11                 @ Dcache clean line of R10
111         nop8
112
113         add     r0, r0, #CACHE_LINESIZE
114         add     r10, r10, #CACHE_LINESIZE
115         sub.a   r1, r1, #CACHE_LINESIZE
116         bns     102b
117         b       3f
118 #endif
119 2:      mov     ip, #0
120         movc    p0.c5, ip, #10                  @ Dcache clean all
121         nop8
122
123 3:      mov     ip, #0
124         movc    p0.c5, ip, #20                  @ Icache invalidate all
125         nop8
126
127         mov     pc, lr
128
129 /*
130  *      __cpuc_flush_kern_dcache_area(void *addr, size_t size)
131  *
132  *      - addr  - kernel address
133  *      - size  - region size
134  */
135 ENTRY(__cpuc_flush_kern_dcache_area)
136         mov     ip, #0
137         movc    p0.c5, ip, #14                  @ Dcache flush all
138         nop8
139         mov     pc, lr
140
141 /*
142  *      __cpuc_dma_clean_range(start,end)
143  *      - start   - virtual start address of region
144  *      - end     - virtual end address of region
145  */
146 ENTRY(__cpuc_dma_clean_range)
147 #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
148         andn    r0, r0, #CACHE_LINESIZE - 1
149         sub     r1, r1, r0
150         andn    r1, r1, #CACHE_LINESIZE - 1
151         add     r1, r1, #CACHE_LINESIZE
152
153         csub.a  r1, #MAX_AREA_SIZE
154         bsg     2f
155
156         @ r0 va2pa r10
157         mov     r9, #PAGE_SZ
158         sub     r9, r9, #1                      @ PAGE_MASK
159 101:    va2pa   r0, r10, r11, r12, r13, 2f      @ r10 is PA
160         b       1f
161 102:    cand.a  r0, r9
162         beq     101b
163
164 1:      movc    p0.c5, r10, #11                 @ Dcache clean line of R10
165         nop8
166         add     r0, r0, #CACHE_LINESIZE
167         add     r10, r10, #CACHE_LINESIZE
168         sub.a   r1, r1, #CACHE_LINESIZE
169         bns     102b
170         mov     pc, lr
171 #endif
172 2:      mov     ip, #0
173         movc    p0.c5, ip, #10                  @ Dcache clean all
174         nop8
175
176         mov     pc, lr
177
178 /*
179  *      __cpuc_dma_inv_range(start,end)
180  *      __cpuc_dma_flush_range(start,end)
181  *      - start   - virtual start address of region
182  *      - end     - virtual end address of region
183  */
184 __cpuc_dma_inv_range:
185         /* FALLTHROUGH */
186 ENTRY(__cpuc_dma_flush_range)
187 #ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
188         andn    r0, r0, #CACHE_LINESIZE - 1
189         sub     r1, r1, r0
190         andn    r1, r1, #CACHE_LINESIZE - 1
191         add     r1, r1, #CACHE_LINESIZE
192
193         csub.a  r1, #MAX_AREA_SIZE
194         bsg     2f
195
196         @ r0 va2pa r10
197 101:    dcacheline_flush        r0, r11, r12
198
199         add     r0, r0, #CACHE_LINESIZE
200         sub.a   r1, r1, #CACHE_LINESIZE
201         bns     101b
202         mov     pc, lr
203 #endif
204 2:      mov     ip, #0
205         movc    p0.c5, ip, #14                  @ Dcache flush all
206         nop8
207
208         mov     pc, lr
209