1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * linux/arch/arm/mm/proc-sa110.S |
4 | * |
5 | * Copyright (C) 1997-2002 Russell King |
6 | * hacked for non-paged-MM by Hyok S. Choi, 2003. |
7 | * |
8 | * MMU functions for SA110 |
9 | * |
10 | * These are the low level assembler for performing cache and TLB |
11 | * functions on the StrongARM-110. |
12 | */ |
13 | #include <linux/linkage.h> |
14 | #include <linux/init.h> |
15 | #include <linux/pgtable.h> |
16 | #include <asm/assembler.h> |
17 | #include <asm/asm-offsets.h> |
18 | #include <asm/hwcap.h> |
19 | #include <mach/hardware.h> |
20 | #include <asm/pgtable-hwdef.h> |
21 | #include <asm/ptrace.h> |
22 | |
23 | #include "proc-macros.S" |
24 | |
25 | /* |
26 | * the cache line size of the I and D cache |
27 | */ |
28 | #define DCACHELINESIZE 32 |
29 | |
30 | .text |
31 | |
32 | /* |
33 | * cpu_sa110_proc_init() |
34 | */ |
35 | ENTRY(cpu_sa110_proc_init) |
36 | mov r0, #0 |
37 | mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching |
38 | ret lr |
39 | |
40 | /* |
41 | * cpu_sa110_proc_fin() |
42 | */ |
43 | ENTRY(cpu_sa110_proc_fin) |
44 | mov r0, #0 |
45 | mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching |
46 | mrc p15, 0, r0, c1, c0, 0 @ ctrl register |
47 | bic r0, r0, #0x1000 @ ...i............ |
48 | bic r0, r0, #0x000e @ ............wca. |
49 | mcr p15, 0, r0, c1, c0, 0 @ disable caches |
50 | ret lr |
51 | |
52 | /* |
53 | * cpu_sa110_reset(loc) |
54 | * |
55 | * Perform a soft reset of the system. Put the CPU into the |
56 | * same state as it would be if it had been reset, and branch |
57 | * to what would be the reset vector. |
58 | * |
59 | * loc: location to jump to for soft reset |
60 | */ |
61 | .align 5 |
62 | .pushsection .idmap.text, "ax" |
63 | ENTRY(cpu_sa110_reset) |
64 | mov ip, #0 |
65 | mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches |
66 | mcr p15, 0, ip, c7, c10, 4 @ drain WB |
67 | #ifdef CONFIG_MMU |
68 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs |
69 | #endif |
70 | mrc p15, 0, ip, c1, c0, 0 @ ctrl register |
71 | bic ip, ip, #0x000f @ ............wcam |
72 | bic ip, ip, #0x1100 @ ...i...s........ |
73 | mcr p15, 0, ip, c1, c0, 0 @ ctrl register |
74 | ret r0 |
75 | ENDPROC(cpu_sa110_reset) |
76 | .popsection |
77 | |
78 | /* |
79 | * cpu_sa110_do_idle(type) |
80 | * |
81 | * Cause the processor to idle |
82 | * |
83 | * type: call type: |
84 | * 0 = slow idle |
85 | * 1 = fast idle |
86 | * 2 = switch to slow processor clock |
87 | * 3 = switch to fast processor clock |
88 | */ |
89 | .align 5 |
90 | |
91 | ENTRY(cpu_sa110_do_idle) |
92 | mcr p15, 0, ip, c15, c2, 2 @ disable clock switching |
93 | ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc |
94 | ldr r1, [r1, #0] @ force switch to MCLK |
95 | mov r0, r0 @ safety |
96 | mov r0, r0 @ safety |
97 | mov r0, r0 @ safety |
98 | mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned |
99 | mov r0, r0 @ safety |
100 | mov r0, r0 @ safety |
101 | mov r0, r0 @ safety |
102 | mcr p15, 0, r0, c15, c1, 2 @ enable clock switching |
103 | ret lr |
104 | |
105 | /* ================================= CACHE ================================ */ |
106 | |
107 | /* |
108 | * cpu_sa110_dcache_clean_area(addr,sz) |
109 | * |
110 | * Clean the specified entry of any caches such that the MMU |
111 | * translation fetches will obtain correct data. |
112 | * |
113 | * addr: cache-unaligned virtual address |
114 | */ |
115 | .align 5 |
116 | ENTRY(cpu_sa110_dcache_clean_area) |
117 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry |
118 | add r0, r0, #DCACHELINESIZE |
119 | subs r1, r1, #DCACHELINESIZE |
120 | bhi 1b |
121 | ret lr |
122 | |
123 | /* =============================== PageTable ============================== */ |
124 | |
125 | /* |
126 | * cpu_sa110_switch_mm(pgd) |
127 | * |
128 | * Set the translation base pointer to be as described by pgd. |
129 | * |
130 | * pgd: new page tables |
131 | */ |
132 | .align 5 |
133 | ENTRY(cpu_sa110_switch_mm) |
134 | #ifdef CONFIG_MMU |
135 | str lr, [sp, #-4]! |
136 | bl v4wb_flush_kern_cache_all @ clears IP |
137 | mcr p15, 0, r0, c2, c0, 0 @ load page table pointer |
138 | mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs |
139 | ldr pc, [sp], #4 |
140 | #else |
141 | ret lr |
142 | #endif |
143 | |
144 | /* |
145 | * cpu_sa110_set_pte_ext(ptep, pte, ext) |
146 | * |
147 | * Set a PTE and flush it out |
148 | */ |
149 | .align 5 |
150 | ENTRY(cpu_sa110_set_pte_ext) |
151 | #ifdef CONFIG_MMU |
152 | armv3_set_pte_ext wc_disable=0 |
153 | mov r0, r0 |
154 | mcr p15, 0, r0, c7, c10, 1 @ clean D entry |
155 | mcr p15, 0, r0, c7, c10, 4 @ drain WB |
156 | #endif |
157 | ret lr |
158 | |
159 | .type __sa110_setup, #function |
160 | __sa110_setup: |
161 | mov r10, #0 |
162 | mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4 |
163 | mcr p15, 0, r10, c7, c10, 4 @ drain write buffer on v4 |
164 | #ifdef CONFIG_MMU |
165 | mcr p15, 0, r10, c8, c7 @ invalidate I,D TLBs on v4 |
166 | #endif |
167 | |
168 | adr r5, sa110_crval |
169 | ldmia r5, {r5, r6} |
170 | mrc p15, 0, r0, c1, c0 @ get control register v4 |
171 | bic r0, r0, r5 |
172 | orr r0, r0, r6 |
173 | ret lr |
174 | .size __sa110_setup, . - __sa110_setup |
175 | |
176 | /* |
177 | * R |
178 | * .RVI ZFRS BLDP WCAM |
179 | * ..01 0001 ..11 1101 |
180 | * |
181 | */ |
182 | .type sa110_crval, #object |
183 | sa110_crval: |
184 | crval clear=0x00003f3f, mmuset=0x0000113d, ucset=0x00001130 |
185 | |
186 | __INITDATA |
187 | |
188 | @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) |
189 | define_processor_functions sa110, dabort=v4_early_abort, pabort=legacy_pabort |
190 | |
191 | .section ".rodata" |
192 | |
193 | string cpu_arch_name, "armv4" |
194 | string cpu_elf_name, "v4" |
195 | string cpu_sa110_name, "StrongARM-110" |
196 | |
197 | .align |
198 | |
199 | .section ".proc.info.init" , "a" |
200 | |
201 | .type __sa110_proc_info,#object |
202 | __sa110_proc_info: |
203 | .long 0x4401a100 |
204 | .long 0xfffffff0 |
205 | .long PMD_TYPE_SECT | \ |
206 | PMD_SECT_BUFFERABLE | \ |
207 | PMD_SECT_CACHEABLE | \ |
208 | PMD_SECT_AP_WRITE | \ |
209 | PMD_SECT_AP_READ |
210 | .long PMD_TYPE_SECT | \ |
211 | PMD_SECT_AP_WRITE | \ |
212 | PMD_SECT_AP_READ |
213 | initfn __sa110_setup, __sa110_proc_info |
214 | .long cpu_arch_name |
215 | .long cpu_elf_name |
216 | .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT |
217 | .long cpu_sa110_name |
218 | .long sa110_processor_functions |
219 | .long v4wb_tlb_fns |
220 | .long v4wb_user_fns |
221 | .long v4wb_cache_fns |
222 | .size __sa110_proc_info, . - __sa110_proc_info |
223 | |