Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[sfrench/cifs-2.6.git] / arch / frv / mm / tlb-miss.S
1 /* tlb-miss.S: TLB miss handlers
2  *
3  * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #include <linux/sys.h>
13 #include <linux/linkage.h>
14 #include <asm/page.h>
15 #include <asm/pgtable.h>
16 #include <asm/spr-regs.h>
17
18         .section        .text..tlbmiss
19         .balign         4
20
21         .globl          __entry_insn_mmu_miss
22 __entry_insn_mmu_miss:
23         break
24         nop
25
26         .globl          __entry_insn_mmu_exception
27 __entry_insn_mmu_exception:
28         break
29         nop
30
31         .globl          __entry_data_mmu_miss
32 __entry_data_mmu_miss:
33         break
34         nop
35
36         .globl          __entry_data_mmu_exception
37 __entry_data_mmu_exception:
38         break
39         nop
40
41 ###############################################################################
42 #
43 # handle a lookup failure of one sort or another in a kernel TLB handler
44 # On entry:
45 #   GR29 - faulting address
46 #   SCR2 - saved CCR
47 #
48 ###############################################################################
49         .type           __tlb_kernel_fault,@function
50 __tlb_kernel_fault:
51         # see if we're supposed to re-enable single-step mode upon return
52         sethi.p         %hi(__break_tlb_miss_return_break),gr30
53         setlo           %lo(__break_tlb_miss_return_break),gr30
54         movsg           pcsr,gr31
55
56         subcc           gr31,gr30,gr0,icc0
57         beq             icc0,#0,__tlb_kernel_fault_sstep
58
59         movsg           scr2,gr30
60         movgs           gr30,ccr
61         movgs           gr29,scr2                       /* save EAR0 value */
62         sethi.p         %hi(__kernel_current_task),gr29
63         setlo           %lo(__kernel_current_task),gr29
64         ldi.p           @(gr29,#0),gr29                 /* restore GR29 */
65
66         bra             __entry_kernel_handle_mmu_fault
67
68         # we've got to re-enable single-stepping
69 __tlb_kernel_fault_sstep:
70         sethi.p         %hi(__break_tlb_miss_real_return_info),gr30
71         setlo           %lo(__break_tlb_miss_real_return_info),gr30
72         lddi            @(gr30,0),gr30
73         movgs           gr30,pcsr
74         movgs           gr31,psr
75
76         movsg           scr2,gr30
77         movgs           gr30,ccr
78         movgs           gr29,scr2                       /* save EAR0 value */
79         sethi.p         %hi(__kernel_current_task),gr29
80         setlo           %lo(__kernel_current_task),gr29
81         ldi.p           @(gr29,#0),gr29                 /* restore GR29 */
82         bra             __entry_kernel_handle_mmu_fault_sstep
83
84         .size           __tlb_kernel_fault, .-__tlb_kernel_fault
85
86 ###############################################################################
87 #
88 # handle a lookup failure of one sort or another in a user TLB handler
89 # On entry:
90 #   GR28 - faulting address
91 #   SCR2 - saved CCR
92 #
93 ###############################################################################
94         .type           __tlb_user_fault,@function
95 __tlb_user_fault:
96         # see if we're supposed to re-enable single-step mode upon return
97         sethi.p         %hi(__break_tlb_miss_return_break),gr30
98         setlo           %lo(__break_tlb_miss_return_break),gr30
99         movsg           pcsr,gr31
100         subcc           gr31,gr30,gr0,icc0
101         beq             icc0,#0,__tlb_user_fault_sstep
102
103         movsg           scr2,gr30
104         movgs           gr30,ccr
105         bra             __entry_uspace_handle_mmu_fault
106
107         # we've got to re-enable single-stepping
108 __tlb_user_fault_sstep:
109         sethi.p         %hi(__break_tlb_miss_real_return_info),gr30
110         setlo           %lo(__break_tlb_miss_real_return_info),gr30
111         lddi            @(gr30,0),gr30
112         movgs           gr30,pcsr
113         movgs           gr31,psr
114         movsg           scr2,gr30
115         movgs           gr30,ccr
116         bra             __entry_uspace_handle_mmu_fault_sstep
117
118         .size           __tlb_user_fault, .-__tlb_user_fault
119
120 ###############################################################################
121 #
122 # Kernel instruction TLB miss handler
123 # On entry:
124 #   GR1   - kernel stack pointer
125 #   GR28  - saved exception frame pointer
126 #   GR29  - faulting address
127 #   GR31  - EAR0 ^ SCR0
128 #   SCR0  - base of virtual range covered by cached PGE from last ITLB miss (or 0xffffffff)
129 #   DAMR3 - mapped page directory
130 #   DAMR4 - mapped page table as matched by SCR0
131 #
132 ###############################################################################
133         .globl          __entry_kernel_insn_tlb_miss
134         .type           __entry_kernel_insn_tlb_miss,@function
135 __entry_kernel_insn_tlb_miss:
136 #if 0
137         sethi.p         %hi(0xe1200004),gr30
138         setlo           %lo(0xe1200004),gr30
139         st              gr0,@(gr30,gr0)
140         sethi.p         %hi(0xffc00100),gr30
141         setlo           %lo(0xffc00100),gr30
142         sth             gr30,@(gr30,gr0)
143         membar
144 #endif
145
146         movsg           ccr,gr30                        /* save CCR */
147         movgs           gr30,scr2
148
149         # see if the cached page table mapping is appropriate
150         srlicc.p        gr31,#26,gr0,icc0
151         setlos          0x3ffc,gr30
152         srli.p          gr29,#12,gr31                   /* use EAR0[25:14] as PTE index */
153         bne             icc0,#0,__itlb_k_PTD_miss
154
155 __itlb_k_PTD_mapped:
156         # access the PTD with EAR0[25:14]
157         # - DAMLR4 points to the virtual address of the appropriate page table
158         # - the PTD holds 4096 PTEs
159         # - the PTD must be accessed uncached
160         # - the PTE must be marked accessed if it was valid
161         #
162         and             gr31,gr30,gr31
163         movsg           damlr4,gr30
164         add             gr30,gr31,gr31
165         ldi             @(gr31,#0),gr30                 /* fetch the PTE */
166         andicc          gr30,#_PAGE_PRESENT,gr0,icc0
167         ori.p           gr30,#_PAGE_ACCESSED,gr30
168         beq             icc0,#0,__tlb_kernel_fault      /* jump if PTE invalid */
169         sti.p           gr30,@(gr31,#0)                 /* update the PTE */
170         andi            gr30,#~_PAGE_ACCESSED,gr30
171
172         # we're using IAMR1 as an extra TLB entry
173         # - punt the entry here (if valid) to the real TLB and then replace with the new PTE
174         # - need to check DAMR1 lest we cause an multiple-DAT-hit exception
175         # - IAMPR1 has no WP bit, and we mustn't lose WP information
176         movsg           iampr1,gr31
177         andicc          gr31,#xAMPRx_V,gr0,icc0
178         setlos.p        0xfffff000,gr31
179         beq             icc0,#0,__itlb_k_nopunt         /* punt not required */
180
181         movsg           iamlr1,gr31
182         movgs           gr31,tplr                       /* set TPLR.CXN */
183         tlbpr           gr31,gr0,#4,#0                  /* delete matches from TLB, IAMR1, DAMR1 */
184
185         movsg           dampr1,gr31
186         ori             gr31,#xAMPRx_V,gr31             /* entry was invalidated by tlbpr #4 */
187         movgs           gr31,tppr
188         movsg           iamlr1,gr31                     /* set TPLR.CXN */
189         movgs           gr31,tplr
190         tlbpr           gr31,gr0,#2,#0                  /* save to the TLB */
191         movsg           tpxr,gr31                       /* check the TLB write error flag */
192         andicc.p        gr31,#TPXR_E,gr0,icc0
193         setlos          #0xfffff000,gr31
194         bne             icc0,#0,__tlb_kernel_fault
195
196 __itlb_k_nopunt:
197
198         # assemble the new TLB entry
199         and             gr29,gr31,gr29
200         movsg           cxnr,gr31
201         or              gr29,gr31,gr29
202         movgs           gr29,iamlr1                     /* xAMLR = address | context number */
203         movgs           gr30,iampr1
204         movgs           gr29,damlr1
205         movgs           gr30,dampr1
206
207         # return, restoring registers
208         movsg           scr2,gr30
209         movgs           gr30,ccr
210         sethi.p         %hi(__kernel_current_task),gr29
211         setlo           %lo(__kernel_current_task),gr29
212         ldi             @(gr29,#0),gr29
213         rett            #0
214         beq             icc0,#3,0                       /* prevent icache prefetch */
215
216         # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
217         # appropriate page table and map that instead
218         #   - access the PGD with EAR0[31:26]
219         #   - DAMLR3 points to the virtual address of the page directory
220         #   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
221 __itlb_k_PTD_miss:
222         srli            gr29,#26,gr31                   /* calculate PGE offset */
223         slli            gr31,#8,gr31                    /* and clear bottom bits */
224
225         movsg           damlr3,gr30
226         ld              @(gr31,gr30),gr30               /* access the PGE */
227
228         andicc.p        gr30,#_PAGE_PRESENT,gr0,icc0
229         andicc          gr30,#xAMPRx_SS,gr0,icc1
230
231         # map this PTD instead and record coverage address
232         ori.p           gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
233         beq             icc0,#0,__tlb_kernel_fault      /* jump if PGE not present */
234         slli.p          gr31,#18,gr31
235         bne             icc1,#0,__itlb_k_bigpage
236         movgs           gr30,dampr4
237         movgs           gr31,scr0
238
239         # we can now resume normal service
240         setlos          0x3ffc,gr30
241         srli.p          gr29,#12,gr31                   /* use EAR0[25:14] as PTE index */
242         bra             __itlb_k_PTD_mapped
243
244 __itlb_k_bigpage:
245         break
246         nop
247
248         .size           __entry_kernel_insn_tlb_miss, .-__entry_kernel_insn_tlb_miss
249
250 ###############################################################################
251 #
252 # Kernel data TLB miss handler
253 # On entry:
254 #   GR1   - kernel stack pointer
255 #   GR28  - saved exception frame pointer
256 #   GR29  - faulting address
257 #   GR31  - EAR0 ^ SCR1
258 #   SCR1  - base of virtual range covered by cached PGE from last DTLB miss (or 0xffffffff)
259 #   DAMR3 - mapped page directory
260 #   DAMR5 - mapped page table as matched by SCR1
261 #
262 ###############################################################################
263         .globl          __entry_kernel_data_tlb_miss
264         .type           __entry_kernel_data_tlb_miss,@function
265 __entry_kernel_data_tlb_miss:
266 #if 0
267         sethi.p         %hi(0xe1200004),gr30
268         setlo           %lo(0xe1200004),gr30
269         st              gr0,@(gr30,gr0)
270         sethi.p         %hi(0xffc00100),gr30
271         setlo           %lo(0xffc00100),gr30
272         sth             gr30,@(gr30,gr0)
273         membar
274 #endif
275
276         movsg           ccr,gr30                        /* save CCR */
277         movgs           gr30,scr2
278
279         # see if the cached page table mapping is appropriate
280         srlicc.p        gr31,#26,gr0,icc0
281         setlos          0x3ffc,gr30
282         srli.p          gr29,#12,gr31                   /* use EAR0[25:14] as PTE index */
283         bne             icc0,#0,__dtlb_k_PTD_miss
284
285 __dtlb_k_PTD_mapped:
286         # access the PTD with EAR0[25:14]
287         # - DAMLR5 points to the virtual address of the appropriate page table
288         # - the PTD holds 4096 PTEs
289         # - the PTD must be accessed uncached
290         # - the PTE must be marked accessed if it was valid
291         #
292         and             gr31,gr30,gr31
293         movsg           damlr5,gr30
294         add             gr30,gr31,gr31
295         ldi             @(gr31,#0),gr30                 /* fetch the PTE */
296         andicc          gr30,#_PAGE_PRESENT,gr0,icc0
297         ori.p           gr30,#_PAGE_ACCESSED,gr30
298         beq             icc0,#0,__tlb_kernel_fault      /* jump if PTE invalid */
299         sti.p           gr30,@(gr31,#0)                 /* update the PTE */
300         andi            gr30,#~_PAGE_ACCESSED,gr30
301
302         # we're using DAMR1 as an extra TLB entry
303         # - punt the entry here (if valid) to the real TLB and then replace with the new PTE
304         # - need to check IAMR1 lest we cause an multiple-DAT-hit exception
305         movsg           dampr1,gr31
306         andicc          gr31,#xAMPRx_V,gr0,icc0
307         setlos.p        0xfffff000,gr31
308         beq             icc0,#0,__dtlb_k_nopunt         /* punt not required */
309
310         movsg           damlr1,gr31
311         movgs           gr31,tplr                       /* set TPLR.CXN */
312         tlbpr           gr31,gr0,#4,#0                  /* delete matches from TLB, IAMR1, DAMR1 */
313
314         movsg           dampr1,gr31
315         ori             gr31,#xAMPRx_V,gr31             /* entry was invalidated by tlbpr #4 */
316         movgs           gr31,tppr
317         movsg           damlr1,gr31                     /* set TPLR.CXN */
318         movgs           gr31,tplr
319         tlbpr           gr31,gr0,#2,#0                  /* save to the TLB */
320         movsg           tpxr,gr31                       /* check the TLB write error flag */
321         andicc.p        gr31,#TPXR_E,gr0,icc0
322         setlos          #0xfffff000,gr31
323         bne             icc0,#0,__tlb_kernel_fault
324
325 __dtlb_k_nopunt:
326
327         # assemble the new TLB entry
328         and             gr29,gr31,gr29
329         movsg           cxnr,gr31
330         or              gr29,gr31,gr29
331         movgs           gr29,iamlr1                     /* xAMLR = address | context number */
332         movgs           gr30,iampr1
333         movgs           gr29,damlr1
334         movgs           gr30,dampr1
335
336         # return, restoring registers
337         movsg           scr2,gr30
338         movgs           gr30,ccr
339         sethi.p         %hi(__kernel_current_task),gr29
340         setlo           %lo(__kernel_current_task),gr29
341         ldi             @(gr29,#0),gr29
342         rett            #0
343         beq             icc0,#3,0                       /* prevent icache prefetch */
344
345         # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
346         # appropriate page table and map that instead
347         #   - access the PGD with EAR0[31:26]
348         #   - DAMLR3 points to the virtual address of the page directory
349         #   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
350 __dtlb_k_PTD_miss:
351         srli            gr29,#26,gr31                   /* calculate PGE offset */
352         slli            gr31,#8,gr31                    /* and clear bottom bits */
353
354         movsg           damlr3,gr30
355         ld              @(gr31,gr30),gr30               /* access the PGE */
356
357         andicc.p        gr30,#_PAGE_PRESENT,gr0,icc0
358         andicc          gr30,#xAMPRx_SS,gr0,icc1
359
360         # map this PTD instead and record coverage address
361         ori.p           gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
362         beq             icc0,#0,__tlb_kernel_fault      /* jump if PGE not present */
363         slli.p          gr31,#18,gr31
364         bne             icc1,#0,__dtlb_k_bigpage
365         movgs           gr30,dampr5
366         movgs           gr31,scr1
367
368         # we can now resume normal service
369         setlos          0x3ffc,gr30
370         srli.p          gr29,#12,gr31                   /* use EAR0[25:14] as PTE index */
371         bra             __dtlb_k_PTD_mapped
372
373 __dtlb_k_bigpage:
374         break
375         nop
376
377         .size           __entry_kernel_data_tlb_miss, .-__entry_kernel_data_tlb_miss
378
379 ###############################################################################
380 #
381 # Userspace instruction TLB miss handler (with PGE prediction)
382 # On entry:
383 #   GR28  - faulting address
384 #   GR31  - EAR0 ^ SCR0
385 #   SCR0  - base of virtual range covered by cached PGE from last ITLB miss (or 0xffffffff)
386 #   DAMR3 - mapped page directory
387 #   DAMR4 - mapped page table as matched by SCR0
388 #
389 ###############################################################################
390         .globl          __entry_user_insn_tlb_miss
391         .type           __entry_user_insn_tlb_miss,@function
392 __entry_user_insn_tlb_miss:
393 #if 0
394         sethi.p         %hi(0xe1200004),gr30
395         setlo           %lo(0xe1200004),gr30
396         st              gr0,@(gr30,gr0)
397         sethi.p         %hi(0xffc00100),gr30
398         setlo           %lo(0xffc00100),gr30
399         sth             gr30,@(gr30,gr0)
400         membar
401 #endif
402
403         movsg           ccr,gr30                        /* save CCR */
404         movgs           gr30,scr2
405
406         # see if the cached page table mapping is appropriate
407         srlicc.p        gr31,#26,gr0,icc0
408         setlos          0x3ffc,gr30
409         srli.p          gr28,#12,gr31                   /* use EAR0[25:14] as PTE index */
410         bne             icc0,#0,__itlb_u_PTD_miss
411
412 __itlb_u_PTD_mapped:
413         # access the PTD with EAR0[25:14]
414         # - DAMLR4 points to the virtual address of the appropriate page table
415         # - the PTD holds 4096 PTEs
416         # - the PTD must be accessed uncached
417         # - the PTE must be marked accessed if it was valid
418         #
419         and             gr31,gr30,gr31
420         movsg           damlr4,gr30
421         add             gr30,gr31,gr31
422         ldi             @(gr31,#0),gr30                 /* fetch the PTE */
423         andicc          gr30,#_PAGE_PRESENT,gr0,icc0
424         ori.p           gr30,#_PAGE_ACCESSED,gr30
425         beq             icc0,#0,__tlb_user_fault        /* jump if PTE invalid */
426         sti.p           gr30,@(gr31,#0)                 /* update the PTE */
427         andi            gr30,#~_PAGE_ACCESSED,gr30
428
429         # we're using IAMR1/DAMR1 as an extra TLB entry
430         # - punt the entry here (if valid) to the real TLB and then replace with the new PTE
431         movsg           dampr1,gr31
432         andicc          gr31,#xAMPRx_V,gr0,icc0
433         setlos.p        0xfffff000,gr31
434         beq             icc0,#0,__itlb_u_nopunt         /* punt not required */
435
436         movsg           dampr1,gr31
437         movgs           gr31,tppr
438         movsg           damlr1,gr31                     /* set TPLR.CXN */
439         movgs           gr31,tplr
440         tlbpr           gr31,gr0,#2,#0                  /* save to the TLB */
441         movsg           tpxr,gr31                       /* check the TLB write error flag */
442         andicc.p        gr31,#TPXR_E,gr0,icc0
443         setlos          #0xfffff000,gr31
444         bne             icc0,#0,__tlb_user_fault
445
446 __itlb_u_nopunt:
447
448         # assemble the new TLB entry
449         and             gr28,gr31,gr28
450         movsg           cxnr,gr31
451         or              gr28,gr31,gr28
452         movgs           gr28,iamlr1                     /* xAMLR = address | context number */
453         movgs           gr30,iampr1
454         movgs           gr28,damlr1
455         movgs           gr30,dampr1
456
457         # return, restoring registers
458         movsg           scr2,gr30
459         movgs           gr30,ccr
460         rett            #0
461         beq             icc0,#3,0                       /* prevent icache prefetch */
462
463         # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
464         # appropriate page table and map that instead
465         #   - access the PGD with EAR0[31:26]
466         #   - DAMLR3 points to the virtual address of the page directory
467         #   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
468 __itlb_u_PTD_miss:
469         srli            gr28,#26,gr31                   /* calculate PGE offset */
470         slli            gr31,#8,gr31                    /* and clear bottom bits */
471
472         movsg           damlr3,gr30
473         ld              @(gr31,gr30),gr30               /* access the PGE */
474
475         andicc.p        gr30,#_PAGE_PRESENT,gr0,icc0
476         andicc          gr30,#xAMPRx_SS,gr0,icc1
477
478         # map this PTD instead and record coverage address
479         ori.p           gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
480         beq             icc0,#0,__tlb_user_fault        /* jump if PGE not present */
481         slli.p          gr31,#18,gr31
482         bne             icc1,#0,__itlb_u_bigpage
483         movgs           gr30,dampr4
484         movgs           gr31,scr0
485
486         # we can now resume normal service
487         setlos          0x3ffc,gr30
488         srli.p          gr28,#12,gr31                   /* use EAR0[25:14] as PTE index */
489         bra             __itlb_u_PTD_mapped
490
491 __itlb_u_bigpage:
492         break
493         nop
494
495         .size           __entry_user_insn_tlb_miss, .-__entry_user_insn_tlb_miss
496
497 ###############################################################################
498 #
499 # Userspace data TLB miss handler
500 # On entry:
501 #   GR28  - faulting address
502 #   GR31  - EAR0 ^ SCR1
503 #   SCR1  - base of virtual range covered by cached PGE from last DTLB miss (or 0xffffffff)
504 #   DAMR3 - mapped page directory
505 #   DAMR5 - mapped page table as matched by SCR1
506 #
507 ###############################################################################
508         .globl          __entry_user_data_tlb_miss
509         .type           __entry_user_data_tlb_miss,@function
510 __entry_user_data_tlb_miss:
511 #if 0
512         sethi.p         %hi(0xe1200004),gr30
513         setlo           %lo(0xe1200004),gr30
514         st              gr0,@(gr30,gr0)
515         sethi.p         %hi(0xffc00100),gr30
516         setlo           %lo(0xffc00100),gr30
517         sth             gr30,@(gr30,gr0)
518         membar
519 #endif
520
521         movsg           ccr,gr30                        /* save CCR */
522         movgs           gr30,scr2
523
524         # see if the cached page table mapping is appropriate
525         srlicc.p        gr31,#26,gr0,icc0
526         setlos          0x3ffc,gr30
527         srli.p          gr28,#12,gr31                   /* use EAR0[25:14] as PTE index */
528         bne             icc0,#0,__dtlb_u_PTD_miss
529
530 __dtlb_u_PTD_mapped:
531         # access the PTD with EAR0[25:14]
532         # - DAMLR5 points to the virtual address of the appropriate page table
533         # - the PTD holds 4096 PTEs
534         # - the PTD must be accessed uncached
535         # - the PTE must be marked accessed if it was valid
536         #
537         and             gr31,gr30,gr31
538         movsg           damlr5,gr30
539
540 __dtlb_u_using_iPTD:
541         add             gr30,gr31,gr31
542         ldi             @(gr31,#0),gr30                 /* fetch the PTE */
543         andicc          gr30,#_PAGE_PRESENT,gr0,icc0
544         ori.p           gr30,#_PAGE_ACCESSED,gr30
545         beq             icc0,#0,__tlb_user_fault        /* jump if PTE invalid */
546         sti.p           gr30,@(gr31,#0)                 /* update the PTE */
547         andi            gr30,#~_PAGE_ACCESSED,gr30
548
549         # we're using DAMR1 as an extra TLB entry
550         # - punt the entry here (if valid) to the real TLB and then replace with the new PTE
551         movsg           dampr1,gr31
552         andicc          gr31,#xAMPRx_V,gr0,icc0
553         setlos.p        0xfffff000,gr31
554         beq             icc0,#0,__dtlb_u_nopunt         /* punt not required */
555
556         movsg           dampr1,gr31
557         movgs           gr31,tppr
558         movsg           damlr1,gr31                     /* set TPLR.CXN */
559         movgs           gr31,tplr
560         tlbpr           gr31,gr0,#2,#0                  /* save to the TLB */
561         movsg           tpxr,gr31                       /* check the TLB write error flag */
562         andicc.p        gr31,#TPXR_E,gr0,icc0
563         setlos          #0xfffff000,gr31
564         bne             icc0,#0,__tlb_user_fault
565
566 __dtlb_u_nopunt:
567
568         # assemble the new TLB entry
569         and             gr28,gr31,gr28
570         movsg           cxnr,gr31
571         or              gr28,gr31,gr28
572         movgs           gr28,iamlr1                     /* xAMLR = address | context number */
573         movgs           gr30,iampr1
574         movgs           gr28,damlr1
575         movgs           gr30,dampr1
576
577         # return, restoring registers
578         movsg           scr2,gr30
579         movgs           gr30,ccr
580         rett            #0
581         beq             icc0,#3,0                       /* prevent icache prefetch */
582
583         # the PTE we want wasn't in the PTD we have mapped, so we need to go looking for a more
584         # appropriate page table and map that instead
585         #   - first of all, check the insn PGE cache - we may well get a hit there
586         #   - access the PGD with EAR0[31:26]
587         #   - DAMLR3 points to the virtual address of the page directory
588         #   - the PGD holds 64 PGEs and each PGE/PME points to a set of page tables
589 __dtlb_u_PTD_miss:
590         movsg           scr0,gr31                       /* consult the insn-PGE-cache key */
591         xor             gr28,gr31,gr31
592         srlicc          gr31,#26,gr0,icc0
593         srli            gr28,#12,gr31                   /* use EAR0[25:14] as PTE index */
594         bne             icc0,#0,__dtlb_u_iPGE_miss
595
596         # what we're looking for is covered by the insn-PGE-cache
597         setlos          0x3ffc,gr30
598         and             gr31,gr30,gr31
599         movsg           damlr4,gr30
600         bra             __dtlb_u_using_iPTD
601
602 __dtlb_u_iPGE_miss:
603         srli            gr28,#26,gr31                   /* calculate PGE offset */
604         slli            gr31,#8,gr31                    /* and clear bottom bits */
605
606         movsg           damlr3,gr30
607         ld              @(gr31,gr30),gr30               /* access the PGE */
608
609         andicc.p        gr30,#_PAGE_PRESENT,gr0,icc0
610         andicc          gr30,#xAMPRx_SS,gr0,icc1
611
612         # map this PTD instead and record coverage address
613         ori.p           gr30,#xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V,gr30
614         beq             icc0,#0,__tlb_user_fault        /* jump if PGE not present */
615         slli.p          gr31,#18,gr31
616         bne             icc1,#0,__dtlb_u_bigpage
617         movgs           gr30,dampr5
618         movgs           gr31,scr1
619
620         # we can now resume normal service
621         setlos          0x3ffc,gr30
622         srli.p          gr28,#12,gr31                   /* use EAR0[25:14] as PTE index */
623         bra             __dtlb_u_PTD_mapped
624
625 __dtlb_u_bigpage:
626         break
627         nop
628
629         .size           __entry_user_data_tlb_miss, .-__entry_user_data_tlb_miss