License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[linux-block.git] / arch / m32r / mm / mmu.S
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
1da177e4
LT
2/*
3 * linux/arch/m32r/mm/mmu.S
4 *
5 * Copyright (C) 2001 by Hiroyuki Kondo
6 */
7
1da177e4
LT
8#include <linux/linkage.h>
9#include <asm/assembler.h>
10#include <asm/smp.h>
11
12 .text
13#ifdef CONFIG_MMU
14
15#include <asm/mmu_context.h>
16#include <asm/page.h>
17#include <asm/pgtable.h>
18#include <asm/m32r.h>
19
20/*
21 * TLB Miss Exception handler
22 */
23 .balign 16
24ENTRY(tme_handler)
25 .global tlb_entry_i_dat
26 .global tlb_entry_d_dat
27
28 SWITCH_TO_KERNEL_STACK
29
30#if defined(CONFIG_ISA_M32R2)
31 st r0, @-sp
32 st r1, @-sp
33 st r2, @-sp
34 st r3, @-sp
35
36 seth r3, #high(MMU_REG_BASE)
37 ld r1, @(MESTS_offset, r3) ; r1: status (MESTS reg.)
38 ld r0, @(MDEVP_offset, r3) ; r0: PFN + ASID (MDEVP reg.)
39 st r1, @(MESTS_offset, r3) ; clear status (MESTS reg.)
40 and3 r1, r1, #(MESTS_IT)
41 bnez r1, 1f ; instruction TLB miss?
42
43;; data TLB miss
44;; input
45;; r0: PFN + ASID (MDEVP reg.)
46;; r1 - r3: free
47;; output
48;; r0: PFN + ASID
49;; r1: TLB entry base address
50;; r2: &tlb_entry_{i|d}_dat
51;; r3: free
52
53#ifndef CONFIG_SMP
54 seth r2, #high(tlb_entry_d_dat)
55 or3 r2, r2, #low(tlb_entry_d_dat)
56#else /* CONFIG_SMP */
57 ldi r1, #-8192
58 seth r2, #high(tlb_entry_d_dat)
59 or3 r2, r2, #low(tlb_entry_d_dat)
60 and r1, sp
61 ld r1, @(16, r1) ; current_thread_info->cpu
62 slli r1, #2
63 add r2, r1
64#endif /* !CONFIG_SMP */
65 seth r1, #high(DTLB_BASE)
66 or3 r1, r1, #low(DTLB_BASE)
67 bra 2f
68
69 .balign 16
70 .fillinsn
711:
72;; instrucntion TLB miss
73;; input
74;; r0: MDEVP reg. (included ASID)
75;; r1 - r3: free
76;; output
77;; r0: PFN + ASID
78;; r1: TLB entry base address
79;; r2: &tlb_entry_{i|d}_dat
80;; r3: free
81 ldi r3, #-4096
82 and3 r0, r0, #(MMU_CONTEXT_ASID_MASK)
83 mvfc r1, bpc
84 and r1, r3
85 or r0, r1 ; r0: PFN + ASID
86#ifndef CONFIG_SMP
87 seth r2, #high(tlb_entry_i_dat)
88 or3 r2, r2, #low(tlb_entry_i_dat)
89#else /* CONFIG_SMP */
90 ldi r1, #-8192
91 seth r2, #high(tlb_entry_i_dat)
92 or3 r2, r2, #low(tlb_entry_i_dat)
93 and r1, sp
94 ld r1, @(16, r1) ; current_thread_info->cpu
95 slli r1, #2
96 add r2, r1
97#endif /* !CONFIG_SMP */
98 seth r1, #high(ITLB_BASE)
99 or3 r1, r1, #low(ITLB_BASE)
100
101 .fillinsn
1022:
103;; select TLB entry
104;; input
105;; r0: PFN + ASID
106;; r1: TLB entry base address
107;; r2: &tlb_entry_{i|d}_dat
108;; r3: free
109;; output
110;; r0: PFN + ASID
111;; r1: TLB entry address
112;; r2, r3: free
113#ifdef CONFIG_ISA_DUAL_ISSUE
114 ld r3, @r2 || srli r1, #3
115#else
116 ld r3, @r2
117 srli r1, #3
118#endif
119 add r1, r3
120 ; tlb_entry_{d|i}_dat++;
121 addi r3, #1
122 and3 r3, r3, #(NR_TLB_ENTRIES - 1)
123#ifdef CONFIG_ISA_DUAL_ISSUE
124 st r3, @r2 || slli r1, #3
125#else
126 st r3, @r2
127 slli r1, #3
128#endif
129
130;; load pte
131;; input
132;; r0: PFN + ASID
133;; r1: TLB entry address
134;; r2, r3: free
135;; output
136;; r0: PFN + ASID
137;; r1: TLB entry address
138;; r2: pte_data
139;; r3: free
140 ; pgd = *(unsigned long *)MPTB;
141 ld24 r2, #(-MPTB - 1)
142 srl3 r3, r0, #22
143#ifdef CONFIG_ISA_DUAL_ISSUE
144 not r2, r2 || slli r3, #2 ; r3: pgd offset
145#else
146 not r2, r2
147 slli r3, #2
148#endif
149 ld r2, @r2 ; r2: pgd base addr (MPTB reg.)
150 or r3, r2 ; r3: pmd addr
151
152 ; pmd = pmd_offset(pgd, address);
153 ld r3, @r3 ; r3: pmd data
1da177e4
LT
154 beqz r3, 3f ; pmd_none(*pmd) ?
155
2cff5e1a
HT
156 and3 r2, r3, #0xfff
157 add3 r2, r2, #-355 ; _KERNPG_TABLE(=0x163)
158 bnez r2, 3f ; pmd_bad(*pmd) ?
159 ldi r2, #-4096
160
1da177e4
LT
161 ; pte = pte_offset(pmd, address);
162 and r2, r3 ; r2: pte base addr
163 srl3 r3, r0, #10
164 and3 r3, r3, #0xffc ; r3: pte offset
165 or r3, r2
166 seth r2, #0x8000
167 or r3, r2 ; r3: pte addr
168
169 ; pte_data = (unsigned long)pte_val(*pte);
170 ld r2, @r3 ; r2: pte data
0d4f6468
HT
171 and3 r3, r2, #2 ; _PAGE_PRESENT(=2) check
172 beqz r3, 3f
1da177e4
LT
173
174 .fillinsn
1755:
176;; set tlb
177;; input
178;; r0: PFN + ASID
179;; r1: TLB entry address
180;; r2: pte_data
181;; r3: free
182 st r0, @r1 ; set_tlb_tag(entry++, address);
183 st r2, @+r1 ; set_tlb_data(entry, pte_data);
184
185 .fillinsn
1866:
187 ld r3, @sp+
188 ld r2, @sp+
189 ld r1, @sp+
190 ld r0, @sp+
191 rte
192
193 .fillinsn
1943:
195;; error
196;; input
197;; r0: PFN + ASID
198;; r1: TLB entry address
199;; r2, r3: free
200;; output
201;; r0: PFN + ASID
202;; r1: TLB entry address
203;; r2: pte_data
204;; r3: free
205#ifdef CONFIG_ISA_DUAL_ISSUE
206 bra 5b || ldi r2, #2
207#else
208 ldi r2, #2 ; r2: pte_data = 0 | _PAGE_PRESENT(=2)
209 bra 5b
210#endif
211
212#elif defined (CONFIG_ISA_M32R)
213
214 st sp, @-sp
215 st r0, @-sp
216 st r1, @-sp
217 st r2, @-sp
218 st r3, @-sp
219 st r4, @-sp
220
221 seth r3, #high(MMU_REG_BASE)
222 ld r0, @(MDEVA_offset,r3) ; r0: address (MDEVA reg.)
223 mvfc r2, bpc ; r2: bpc
224 ld r1, @(MESTS_offset,r3) ; r1: status (MESTS reg.)
225 st r1, @(MESTS_offset,r3) ; clear status (MESTS reg.)
226 and3 r1, r1, #(MESTS_IT)
227 beqz r1, 1f ; data TLB miss?
228
229;; instrucntion TLB miss
230 mv r0, r2 ; address = bpc;
231 ; entry = (unsigned long *)ITLB_BASE+tlb_entry_i*2;
232 seth r3, #shigh(tlb_entry_i_dat)
233 ld r4, @(low(tlb_entry_i_dat),r3)
234 sll3 r2, r4, #3
235 seth r1, #high(ITLB_BASE)
236 or3 r1, r1, #low(ITLB_BASE)
237 add r2, r1 ; r2: entry
238 addi r4, #1 ; tlb_entry_i++;
239 and3 r4, r4, #(NR_TLB_ENTRIES-1)
240 st r4, @(low(tlb_entry_i_dat),r3)
241 bra 2f
242 .fillinsn
2431:
244;; data TLB miss
245 ; entry = (unsigned long *)DTLB_BASE+tlb_entry_d*2;
246 seth r3, #shigh(tlb_entry_d_dat)
247 ld r4, @(low(tlb_entry_d_dat),r3)
248 sll3 r2, r4, #3
249 seth r1, #high(DTLB_BASE)
250 or3 r1, r1, #low(DTLB_BASE)
251 add r2, r1 ; r2: entry
252 addi r4, #1 ; tlb_entry_d++;
253 and3 r4, r4, #(NR_TLB_ENTRIES-1)
254 st r4, @(low(tlb_entry_d_dat),r3)
255 .fillinsn
2562:
257;; load pte
258; r0: address, r2: entry
259; r1,r3,r4: (free)
260 ; pgd = *(unsigned long *)MPTB;
261 ld24 r1, #(-MPTB-1)
262 not r1, r1
263 ld r1, @r1
264 srl3 r4, r0, #22
265 sll3 r3, r4, #2
266 add r3, r1 ; r3: pgd
267 ; pmd = pmd_offset(pgd, address);
268 ld r1, @r3 ; r1: pmd
269 beqz r1, 3f ; pmd_none(*pmd) ?
270;
2cff5e1a
HT
271 and3 r1, r1, #0x3ff
272 ldi r4, #0x163 ; _KERNPG_TABLE(=0x163)
273 bne r1, r4, 3f ; pmd_bad(*pmd) ?
0d4f6468 274
1da177e4
LT
275 .fillinsn
2764:
277 ; pte = pte_offset(pmd, address);
278 ld r4, @r3 ; r4: pte
279 ldi r3, #-4096
280 and r4, r3
281 srl3 r3, r0, #10
282 and3 r3, r3, #0xffc
283 add r4, r3
284 seth r3, #0x8000
285 add r4, r3 ; r4: pte
286 ; pte_data = (unsigned long)pte_val(*pte);
287 ld r1, @r4 ; r1: pte_data
0d4f6468
HT
288 and3 r3, r1, #2 ; _PAGE_PRESENT(=2) check
289 beqz r3, 3f
1da177e4 290
0d4f6468 291 .fillinsn
1da177e4
LT
292;; set tlb
293; r0: address, r1: pte_data, r2: entry
294; r3,r4: (free)
2955:
296 ldi r3, #-4096 ; set_tlb_tag(entry++, address);
297 and r3, r0
298 seth r4, #shigh(MASID)
299 ld r4, @(low(MASID),r4) ; r4: MASID
300 and3 r4, r4, #(MMU_CONTEXT_ASID_MASK)
301 or r3, r4
302 st r3, @r2
0d4f6468 303 st r1, @(4,r2) ; set_tlb_data(entry, pte_data);
1da177e4
LT
304
305 ld r4, @sp+
306 ld r3, @sp+
307 ld r2, @sp+
308 ld r1, @sp+
309 ld r0, @sp+
310 ld sp, @sp+
311 rte
312
0d4f6468
HT
313 .fillinsn
3143:
315 ldi r1, #2 ; r1: pte_data = 0 | _PAGE_PRESENT(=2)
316 bra 5b
317
1da177e4
LT
318#else
319#error unknown isa configuration
320#endif
321
322ENTRY(init_tlb)
323;; Set MMU Register
324 seth r0, #high(MMU_REG_BASE) ; Set MMU_REG_BASE higher
325 or3 r0, r0, #low(MMU_REG_BASE) ; Set MMU_REG_BASE lower
326 ldi r1, #0
327 st r1, @(MPSZ_offset,r0) ; Set MPSZ Reg(Page size 4KB:0 16KB:1 64KB:2)
328 ldi r1, #0
329 st r1, @(MASID_offset,r0) ; Set ASID Zero
330
331;; Set TLB
332 seth r0, #high(ITLB_BASE) ; Set ITLB_BASE higher
333 or3 r0, r0, #low(ITLB_BASE) ; Set ITLB_BASE lower
334 seth r1, #high(DTLB_BASE) ; Set DTLB_BASE higher
335 or3 r1, r1, #low(DTLB_BASE) ; Set DTLB_BASE lower
336 ldi r2, #0
337 ldi r3, #NR_TLB_ENTRIES
338 addi r0, #-4
339 addi r1, #-4
340clear_tlb:
341 st r2, @+r0 ; VPA <- 0
342 st r2, @+r0 ; PPA <- 0
343 st r2, @+r1 ; VPA <- 0
344 st r2, @+r1 ; PPA <- 0
345 addi r3, #-1
346 bnez r3, clear_tlb
347;;
348 jmp r14
349
350ENTRY(m32r_itlb_entrys)
351ENTRY(m32r_otlb_entrys)
352
353#endif /* CONFIG_MMU */
354
fabb626a 355 .end