1
2
3
4
5
6
7
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
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
31 st r0, @-sp
32 st r1, @-sp
33 st r2, @-sp
34 st r3, @-sp
35
36 seth r3,
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,
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,
55 or3 r2, r2,
56#else
57 ldi r1,
58 seth r2,
59 or3 r2, r2,
60 and r1, sp
61 ld r1, @(16, r1) ; current_thread_info->cpu
62 slli r1,
63 add r2, r1
64#endif
65 seth r1,
66 or3 r1, r1,
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,
82 and3 r0, r0,
83 mvfc r1, bpc
84 and r1, r3
85 or r0, r1 ; r0: PFN + ASID
86#ifndef CONFIG_SMP
87 seth r2,
88 or3 r2, r2,
89#else
90 ldi r1,
91 seth r2,
92 or3 r2, r2,
93 and r1, sp
94 ld r1, @(16, r1) ; current_thread_info->cpu
95 slli r1,
96 add r2, r1
97#endif
98 seth r1,
99 or3 r1, r1,
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,
115#else
116 ld r3, @r2
117 srli r1,
118#endif
119 add r1, r3
120 ; tlb_entry_{d|i}_dat++;
121 addi r3,
122 and3 r3, r3,
123#ifdef CONFIG_ISA_DUAL_ISSUE
124 st r3, @r2 || slli r1,
125#else
126 st r3, @r2
127 slli r1,
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,
142 srl3 r3, r0,
143#ifdef CONFIG_ISA_DUAL_ISSUE
144 not r2, r2 || slli r3,
145#else
146 not r2, r2
147 slli r3,
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
154 beqz r3, 3f ; pmd_none(*pmd) ?
155
156 and3 r2, r3,
157 add3 r2, r2,
158 bnez r2, 3f ; pmd_bad(*pmd) ?
159 ldi r2,
160
161 ; pte = pte_offset(pmd, address);
162 and r2, r3 ; r2: pte base addr
163 srl3 r3, r0,
164 and3 r3, r3,
165 or r3, r2
166 seth r2,
167 or r3, r2 ; r3: pte addr
168
169 ; pte_data = (unsigned long)pte_val(*pte);
170 ld r2, @r3 ; r2: pte data
171 and3 r3, r2,
172 beqz r3, 3f
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,
207#else
208 ldi r2,
209 bra 5b
210#endif
211
212
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,
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,
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,
233 ld r4, @(low(tlb_entry_i_dat),r3)
234 sll3 r2, r4,
235 seth r1,
236 or3 r1, r1,
237 add r2, r1 ; r2: entry
238 addi r4,
239 and3 r4, r4,
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,
247 ld r4, @(low(tlb_entry_d_dat),r3)
248 sll3 r2, r4,
249 seth r1,
250 or3 r1, r1,
251 add r2, r1 ; r2: entry
252 addi r4,
253 and3 r4, r4,
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,
262 not r1, r1
263 ld r1, @r1
264 srl3 r4, r0,
265 sll3 r3, r4,
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;
271 and3 r1, r1,
272 ldi r4,
273 bne r1, r4, 3f ; pmd_bad(*pmd) ?
274
275 .fillinsn
2764:
277 ; pte = pte_offset(pmd, address);
278 ld r4, @r3 ; r4: pte
279 ldi r3,
280 and r4, r3
281 srl3 r3, r0,
282 and3 r3, r3,
283 add r4, r3
284 seth r3,
285 add r4, r3 ; r4: pte
286 ; pte_data = (unsigned long)pte_val(*pte);
287 ld r1, @r4 ; r1: pte_data
288 and3 r3, r1,
289 beqz r3, 3f
290
291 .fillinsn
292;; set tlb
293; r0: address, r1: pte_data, r2: entry
294; r3,r4: (free)
2955:
296 ldi r3,
297 and r3, r0
298 seth r4,
299 ld r4, @(low(MASID),r4) ; r4: MASID
300 and3 r4, r4,
301 or r3, r4
302 st r3, @r2
303 st r1, @(4,r2) ; set_tlb_data(entry, pte_data);
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
313 .fillinsn
3143:
315 ldi r1,
316 bra 5b
317
318#else
319
320#endif
321
322ENTRY(init_tlb)
323;; Set MMU Register
324 seth r0,
325 or3 r0, r0,
326 ldi r1,
327 st r1, @(MPSZ_offset,r0) ; Set MPSZ Reg(Page size 4KB:0 16KB:1 64KB:2)
328 ldi r1,
329 st r1, @(MASID_offset,r0) ; Set ASID Zero
330
331;; Set TLB
332 seth r0,
333 or3 r0, r0,
334 seth r1,
335 or3 r1, r1,
336 ldi r2,
337 ldi r3,
338 addi r0,
339 addi r1,
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,
346 bnez r3, clear_tlb
347;;
348 jmp r14
349
350ENTRY(m32r_itlb_entrys)
351ENTRY(m32r_otlb_entrys)
352
353#endif
354
355 .end
356