]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/sparc64/kernel/entry.S
[SPARC64]: Do not call winfix_dax blindly
[linux-2.6-omap-h63xx.git] / arch / sparc64 / kernel / entry.S
1 /* $Id: entry.S,v 1.144 2002/02/09 19:49:30 davem Exp $
2  * arch/sparc64/kernel/entry.S:  Sparc64 trap low-level entry points.
3  *
4  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
5  * Copyright (C) 1996 Eddie C. Dost        (ecd@skynet.be)
6  * Copyright (C) 1996 Miguel de Icaza      (miguel@nuclecu.unam.mx)
7  * Copyright (C) 1996,98,99 Jakub Jelinek  (jj@sunsite.mff.cuni.cz)
8  */
9
10 #include <linux/config.h>
11 #include <linux/errno.h>
12
13 #include <asm/head.h>
14 #include <asm/asi.h>
15 #include <asm/smp.h>
16 #include <asm/ptrace.h>
17 #include <asm/page.h>
18 #include <asm/signal.h>
19 #include <asm/pgtable.h>
20 #include <asm/processor.h>
21 #include <asm/visasm.h>
22 #include <asm/estate.h>
23 #include <asm/auxio.h>
24
25 #define curptr      g6
26
27 #define NR_SYSCALLS 284      /* Each OS is different... */
28
29         .text
30         .align          32
31
32         .globl          sparc64_vpte_patchme1
33         .globl          sparc64_vpte_patchme2
34 /*
35  * On a second level vpte miss, check whether the original fault is to the OBP 
36  * range (note that this is only possible for instruction miss, data misses to
37  * obp range do not use vpte). If so, go back directly to the faulting address.
38  * This is because we want to read the tpc, otherwise we have no way of knowing
39  * the 8k aligned faulting address if we are using >8k kernel pagesize. This
40  * also ensures no vpte range addresses are dropped into tlb while obp is
41  * executing (see inherit_locked_prom_mappings() rant).
42  */
43 sparc64_vpte_nucleus:
44         /* Load 0xf0000000, which is LOW_OBP_ADDRESS.  */
45         mov             0xf, %g5
46         sllx            %g5, 28, %g5
47
48         /* Is addr >= LOW_OBP_ADDRESS?  */
49         cmp             %g4, %g5
50         blu,pn          %xcc, sparc64_vpte_patchme1
51          mov            0x1, %g5
52
53         /* Load 0x100000000, which is HI_OBP_ADDRESS.  */
54         sllx            %g5, 32, %g5
55
56         /* Is addr < HI_OBP_ADDRESS?  */
57         cmp             %g4, %g5
58         blu,pn          %xcc, obp_iaddr_patch
59          nop
60
61         /* These two instructions are patched by paginig_init().  */
62 sparc64_vpte_patchme1:
63         sethi           %hi(0), %g5
64 sparc64_vpte_patchme2:
65         or              %g5, %lo(0), %g5
66
67         /* With kernel PGD in %g5, branch back into dtlb_backend.  */
68         ba,pt           %xcc, sparc64_kpte_continue
69          andn           %g1, 0x3, %g1   /* Finish PMD offset adjustment.  */
70
71 vpte_noent:
72         /* Restore previous TAG_ACCESS, %g5 is zero, and we will
73          * skip over the trap instruction so that the top level
74          * TLB miss handler will thing this %g5 value is just an
75          * invalid PTE, thus branching to full fault processing.
76          */
77         mov             TLB_SFSR, %g1
78         stxa            %g4, [%g1 + %g1] ASI_DMMU
79         done
80
81         .globl          obp_iaddr_patch
82 obp_iaddr_patch:
83         /* These two instructions patched by inherit_prom_mappings().  */
84         sethi           %hi(0), %g5
85         or              %g5, %lo(0), %g5
86
87         /* Behave as if we are at TL0.  */
88         wrpr            %g0, 1, %tl
89         rdpr            %tpc, %g4       /* Find original faulting iaddr */
90         srlx            %g4, 13, %g4    /* Throw out context bits */
91         sllx            %g4, 13, %g4    /* g4 has vpn + ctx0 now */
92
93         /* Restore previous TAG_ACCESS.  */
94         mov             TLB_SFSR, %g1
95         stxa            %g4, [%g1 + %g1] ASI_IMMU
96
97         /* Get PMD offset.  */
98         srlx            %g4, 23, %g6
99         and             %g6, 0x7ff, %g6
100         sllx            %g6, 2, %g6
101
102         /* Load PMD, is it valid?  */
103         lduwa           [%g5 + %g6] ASI_PHYS_USE_EC, %g5
104         brz,pn          %g5, longpath
105          sllx           %g5, 11, %g5
106
107         /* Get PTE offset.  */
108         srlx            %g4, 13, %g6
109         and             %g6, 0x3ff, %g6
110         sllx            %g6, 3, %g6
111
112         /* Load PTE.  */
113         ldxa            [%g5 + %g6] ASI_PHYS_USE_EC, %g5
114         brgez,pn        %g5, longpath
115          nop
116
117         /* TLB load and return from trap.  */
118         stxa            %g5, [%g0] ASI_ITLB_DATA_IN
119         retry
120
121         .globl          obp_daddr_patch
122 obp_daddr_patch:
123         /* These two instructions patched by inherit_prom_mappings().  */
124         sethi           %hi(0), %g5
125         or              %g5, %lo(0), %g5
126
127         /* Get PMD offset.  */
128         srlx            %g4, 23, %g6
129         and             %g6, 0x7ff, %g6
130         sllx            %g6, 2, %g6
131
132         /* Load PMD, is it valid?  */
133         lduwa           [%g5 + %g6] ASI_PHYS_USE_EC, %g5
134         brz,pn          %g5, longpath
135          sllx           %g5, 11, %g5
136
137         /* Get PTE offset.  */
138         srlx            %g4, 13, %g6
139         and             %g6, 0x3ff, %g6
140         sllx            %g6, 3, %g6
141
142         /* Load PTE.  */
143         ldxa            [%g5 + %g6] ASI_PHYS_USE_EC, %g5
144         brgez,pn        %g5, longpath
145          nop
146
147         /* TLB load and return from trap.  */
148         stxa            %g5, [%g0] ASI_DTLB_DATA_IN
149         retry
150
151 /*
152  * On a first level data miss, check whether this is to the OBP range (note
153  * that such accesses can be made by prom, as well as by kernel using
154  * prom_getproperty on "address"), and if so, do not use vpte access ...
155  * rather, use information saved during inherit_prom_mappings() using 8k
156  * pagesize.
157  */
158 kvmap:
159         /* Load 0xf0000000, which is LOW_OBP_ADDRESS.  */
160         mov             0xf, %g5
161         sllx            %g5, 28, %g5
162
163         /* Is addr >= LOW_OBP_ADDRESS?  */
164         cmp             %g4, %g5
165         blu,pn          %xcc, vmalloc_addr
166          mov            0x1, %g5
167
168         /* Load 0x100000000, which is HI_OBP_ADDRESS.  */
169         sllx            %g5, 32, %g5
170
171         /* Is addr < HI_OBP_ADDRESS?  */
172         cmp             %g4, %g5
173         blu,pn          %xcc, obp_daddr_patch
174          nop
175
176 vmalloc_addr:
177         /* If we get here, a vmalloc addr accessed, load kernel VPTE.  */
178         ldxa            [%g3 + %g6] ASI_N, %g5
179         brgez,pn        %g5, longpath
180          nop
181
182         /* PTE is valid, load into TLB and return from trap.  */
183         stxa            %g5, [%g0] ASI_DTLB_DATA_IN     ! Reload TLB
184         retry
185
186         /* This is trivial with the new code... */
187         .globl          do_fpdis
188 do_fpdis:
189         sethi           %hi(TSTATE_PEF), %g4                                    ! IEU0
190         rdpr            %tstate, %g5
191         andcc           %g5, %g4, %g0
192         be,pt           %xcc, 1f
193          nop
194         rd              %fprs, %g5
195         andcc           %g5, FPRS_FEF, %g0
196         be,pt           %xcc, 1f
197          nop
198
199         /* Legal state when DCR_IFPOE is set in Cheetah %dcr. */
200         sethi           %hi(109f), %g7
201         ba,pt           %xcc, etrap
202 109:     or             %g7, %lo(109b), %g7
203         add             %g0, %g0, %g0
204         ba,a,pt         %xcc, rtrap_clr_l6
205
206 1:      ldub            [%g6 + TI_FPSAVED], %g5                                 ! Load  Group
207         wr              %g0, FPRS_FEF, %fprs                                    ! LSU   Group+4bubbles
208         andcc           %g5, FPRS_FEF, %g0                                      ! IEU1  Group
209         be,a,pt         %icc, 1f                                                ! CTI
210          clr            %g7                                                     ! IEU0
211         ldx             [%g6 + TI_GSR], %g7                                     ! Load  Group
212 1:      andcc           %g5, FPRS_DL, %g0                                       ! IEU1
213         bne,pn          %icc, 2f                                                ! CTI
214          fzero          %f0                                                     ! FPA
215         andcc           %g5, FPRS_DU, %g0                                       ! IEU1  Group
216         bne,pn          %icc, 1f                                                ! CTI
217          fzero          %f2                                                     ! FPA
218         faddd           %f0, %f2, %f4
219         fmuld           %f0, %f2, %f6
220         faddd           %f0, %f2, %f8
221         fmuld           %f0, %f2, %f10
222         faddd           %f0, %f2, %f12
223         fmuld           %f0, %f2, %f14
224         faddd           %f0, %f2, %f16
225         fmuld           %f0, %f2, %f18
226         faddd           %f0, %f2, %f20
227         fmuld           %f0, %f2, %f22
228         faddd           %f0, %f2, %f24
229         fmuld           %f0, %f2, %f26
230         faddd           %f0, %f2, %f28
231         fmuld           %f0, %f2, %f30
232         faddd           %f0, %f2, %f32
233         fmuld           %f0, %f2, %f34
234         faddd           %f0, %f2, %f36
235         fmuld           %f0, %f2, %f38
236         faddd           %f0, %f2, %f40
237         fmuld           %f0, %f2, %f42
238         faddd           %f0, %f2, %f44
239         fmuld           %f0, %f2, %f46
240         faddd           %f0, %f2, %f48
241         fmuld           %f0, %f2, %f50
242         faddd           %f0, %f2, %f52
243         fmuld           %f0, %f2, %f54
244         faddd           %f0, %f2, %f56
245         fmuld           %f0, %f2, %f58
246         b,pt            %xcc, fpdis_exit2
247          faddd          %f0, %f2, %f60
248 1:      mov             SECONDARY_CONTEXT, %g3
249         add             %g6, TI_FPREGS + 0x80, %g1
250         faddd           %f0, %f2, %f4
251         fmuld           %f0, %f2, %f6
252         ldxa            [%g3] ASI_DMMU, %g5
253 cplus_fptrap_insn_1:
254         sethi           %hi(0), %g2
255         stxa            %g2, [%g3] ASI_DMMU
256         membar          #Sync
257         add             %g6, TI_FPREGS + 0xc0, %g2
258         faddd           %f0, %f2, %f8
259         fmuld           %f0, %f2, %f10
260         ldda            [%g1] ASI_BLK_S, %f32   ! grrr, where is ASI_BLK_NUCLEUS 8-(
261         ldda            [%g2] ASI_BLK_S, %f48
262         faddd           %f0, %f2, %f12
263         fmuld           %f0, %f2, %f14
264         faddd           %f0, %f2, %f16
265         fmuld           %f0, %f2, %f18
266         faddd           %f0, %f2, %f20
267         fmuld           %f0, %f2, %f22
268         faddd           %f0, %f2, %f24
269         fmuld           %f0, %f2, %f26
270         faddd           %f0, %f2, %f28
271         fmuld           %f0, %f2, %f30
272         membar          #Sync
273         b,pt            %xcc, fpdis_exit
274          nop
275 2:      andcc           %g5, FPRS_DU, %g0
276         bne,pt          %icc, 3f
277          fzero          %f32
278         mov             SECONDARY_CONTEXT, %g3
279         fzero           %f34
280         ldxa            [%g3] ASI_DMMU, %g5
281         add             %g6, TI_FPREGS, %g1
282 cplus_fptrap_insn_2:
283         sethi           %hi(0), %g2
284         stxa            %g2, [%g3] ASI_DMMU
285         membar          #Sync
286         add             %g6, TI_FPREGS + 0x40, %g2
287         faddd           %f32, %f34, %f36
288         fmuld           %f32, %f34, %f38
289         ldda            [%g1] ASI_BLK_S, %f0    ! grrr, where is ASI_BLK_NUCLEUS 8-(
290         ldda            [%g2] ASI_BLK_S, %f16
291         faddd           %f32, %f34, %f40
292         fmuld           %f32, %f34, %f42
293         faddd           %f32, %f34, %f44
294         fmuld           %f32, %f34, %f46
295         faddd           %f32, %f34, %f48
296         fmuld           %f32, %f34, %f50
297         faddd           %f32, %f34, %f52
298         fmuld           %f32, %f34, %f54
299         faddd           %f32, %f34, %f56
300         fmuld           %f32, %f34, %f58
301         faddd           %f32, %f34, %f60
302         fmuld           %f32, %f34, %f62
303         membar          #Sync
304         ba,pt           %xcc, fpdis_exit
305          nop
306 3:      mov             SECONDARY_CONTEXT, %g3
307         add             %g6, TI_FPREGS, %g1
308         ldxa            [%g3] ASI_DMMU, %g5
309 cplus_fptrap_insn_3:
310         sethi           %hi(0), %g2
311         stxa            %g2, [%g3] ASI_DMMU
312         membar          #Sync
313         mov             0x40, %g2
314         ldda            [%g1] ASI_BLK_S, %f0            ! grrr, where is ASI_BLK_NUCLEUS 8-(
315         ldda            [%g1 + %g2] ASI_BLK_S, %f16
316         add             %g1, 0x80, %g1
317         ldda            [%g1] ASI_BLK_S, %f32
318         ldda            [%g1 + %g2] ASI_BLK_S, %f48
319         membar          #Sync
320 fpdis_exit:
321         stxa            %g5, [%g3] ASI_DMMU
322         membar          #Sync
323 fpdis_exit2:
324         wr              %g7, 0, %gsr
325         ldx             [%g6 + TI_XFSR], %fsr
326         rdpr            %tstate, %g3
327         or              %g3, %g4, %g3           ! anal...
328         wrpr            %g3, %tstate
329         wr              %g0, FPRS_FEF, %fprs    ! clean DU/DL bits
330         retry
331
332         .align          32
333 fp_other_bounce:
334         call            do_fpother
335          add            %sp, PTREGS_OFF, %o0
336         ba,pt           %xcc, rtrap
337          clr            %l6
338
339         .globl          do_fpother_check_fitos
340         .align          32
341 do_fpother_check_fitos:
342         sethi           %hi(fp_other_bounce - 4), %g7
343         or              %g7, %lo(fp_other_bounce - 4), %g7
344
345         /* NOTE: Need to preserve %g7 until we fully commit
346          *       to the fitos fixup.
347          */
348         stx             %fsr, [%g6 + TI_XFSR]
349         rdpr            %tstate, %g3
350         andcc           %g3, TSTATE_PRIV, %g0
351         bne,pn          %xcc, do_fptrap_after_fsr
352          nop
353         ldx             [%g6 + TI_XFSR], %g3
354         srlx            %g3, 14, %g1
355         and             %g1, 7, %g1
356         cmp             %g1, 2                  ! Unfinished FP-OP
357         bne,pn          %xcc, do_fptrap_after_fsr
358          sethi          %hi(1 << 23), %g1       ! Inexact
359         andcc           %g3, %g1, %g0
360         bne,pn          %xcc, do_fptrap_after_fsr
361          rdpr           %tpc, %g1
362         lduwa           [%g1] ASI_AIUP, %g3     ! This cannot ever fail
363 #define FITOS_MASK      0xc1f83fe0
364 #define FITOS_COMPARE   0x81a01880
365         sethi           %hi(FITOS_MASK), %g1
366         or              %g1, %lo(FITOS_MASK), %g1
367         and             %g3, %g1, %g1
368         sethi           %hi(FITOS_COMPARE), %g2
369         or              %g2, %lo(FITOS_COMPARE), %g2
370         cmp             %g1, %g2
371         bne,pn          %xcc, do_fptrap_after_fsr
372          nop
373         std             %f62, [%g6 + TI_FPREGS + (62 * 4)]
374         sethi           %hi(fitos_table_1), %g1
375         and             %g3, 0x1f, %g2
376         or              %g1, %lo(fitos_table_1),  %g1
377         sllx            %g2, 2, %g2
378         jmpl            %g1 + %g2, %g0
379          ba,pt          %xcc, fitos_emul_continue
380
381 fitos_table_1:
382         fitod           %f0, %f62
383         fitod           %f1, %f62
384         fitod           %f2, %f62
385         fitod           %f3, %f62
386         fitod           %f4, %f62
387         fitod           %f5, %f62
388         fitod           %f6, %f62
389         fitod           %f7, %f62
390         fitod           %f8, %f62
391         fitod           %f9, %f62
392         fitod           %f10, %f62
393         fitod           %f11, %f62
394         fitod           %f12, %f62
395         fitod           %f13, %f62
396         fitod           %f14, %f62
397         fitod           %f15, %f62
398         fitod           %f16, %f62
399         fitod           %f17, %f62
400         fitod           %f18, %f62
401         fitod           %f19, %f62
402         fitod           %f20, %f62
403         fitod           %f21, %f62
404         fitod           %f22, %f62
405         fitod           %f23, %f62
406         fitod           %f24, %f62
407         fitod           %f25, %f62
408         fitod           %f26, %f62
409         fitod           %f27, %f62
410         fitod           %f28, %f62
411         fitod           %f29, %f62
412         fitod           %f30, %f62
413         fitod           %f31, %f62
414
415 fitos_emul_continue:
416         sethi           %hi(fitos_table_2), %g1
417         srl             %g3, 25, %g2
418         or              %g1, %lo(fitos_table_2), %g1
419         and             %g2, 0x1f, %g2
420         sllx            %g2, 2, %g2
421         jmpl            %g1 + %g2, %g0
422          ba,pt          %xcc, fitos_emul_fini
423
424 fitos_table_2:
425         fdtos           %f62, %f0
426         fdtos           %f62, %f1
427         fdtos           %f62, %f2
428         fdtos           %f62, %f3
429         fdtos           %f62, %f4
430         fdtos           %f62, %f5
431         fdtos           %f62, %f6
432         fdtos           %f62, %f7
433         fdtos           %f62, %f8
434         fdtos           %f62, %f9
435         fdtos           %f62, %f10
436         fdtos           %f62, %f11
437         fdtos           %f62, %f12
438         fdtos           %f62, %f13
439         fdtos           %f62, %f14
440         fdtos           %f62, %f15
441         fdtos           %f62, %f16
442         fdtos           %f62, %f17
443         fdtos           %f62, %f18
444         fdtos           %f62, %f19
445         fdtos           %f62, %f20
446         fdtos           %f62, %f21
447         fdtos           %f62, %f22
448         fdtos           %f62, %f23
449         fdtos           %f62, %f24
450         fdtos           %f62, %f25
451         fdtos           %f62, %f26
452         fdtos           %f62, %f27
453         fdtos           %f62, %f28
454         fdtos           %f62, %f29
455         fdtos           %f62, %f30
456         fdtos           %f62, %f31
457
458 fitos_emul_fini:
459         ldd             [%g6 + TI_FPREGS + (62 * 4)], %f62
460         done
461
462         .globl          do_fptrap
463         .align          32
464 do_fptrap:
465         stx             %fsr, [%g6 + TI_XFSR]
466 do_fptrap_after_fsr:
467         ldub            [%g6 + TI_FPSAVED], %g3
468         rd              %fprs, %g1
469         or              %g3, %g1, %g3
470         stb             %g3, [%g6 + TI_FPSAVED]
471         rd              %gsr, %g3
472         stx             %g3, [%g6 + TI_GSR]
473         mov             SECONDARY_CONTEXT, %g3
474         ldxa            [%g3] ASI_DMMU, %g5
475 cplus_fptrap_insn_4:
476         sethi           %hi(0), %g2
477         stxa            %g2, [%g3] ASI_DMMU
478         membar          #Sync
479         add             %g6, TI_FPREGS, %g2
480         andcc           %g1, FPRS_DL, %g0
481         be,pn           %icc, 4f
482          mov            0x40, %g3
483         stda            %f0, [%g2] ASI_BLK_S
484         stda            %f16, [%g2 + %g3] ASI_BLK_S
485         andcc           %g1, FPRS_DU, %g0
486         be,pn           %icc, 5f
487 4:       add            %g2, 128, %g2
488         stda            %f32, [%g2] ASI_BLK_S
489         stda            %f48, [%g2 + %g3] ASI_BLK_S
490 5:      mov             SECONDARY_CONTEXT, %g1
491         membar          #Sync
492         stxa            %g5, [%g1] ASI_DMMU
493         membar          #Sync
494         ba,pt           %xcc, etrap
495          wr             %g0, 0, %fprs
496
497 cplus_fptrap_1:
498         sethi           %hi(CTX_CHEETAH_PLUS_CTX0), %g2
499
500         .globl          cheetah_plus_patch_fpdis
501 cheetah_plus_patch_fpdis:
502         /* We configure the dTLB512_0 for 4MB pages and the
503          * dTLB512_1 for 8K pages when in context zero.
504          */
505         sethi                   %hi(cplus_fptrap_1), %o0
506         lduw                    [%o0 + %lo(cplus_fptrap_1)], %o1
507
508         set                     cplus_fptrap_insn_1, %o2
509         stw                     %o1, [%o2]
510         flush                   %o2
511         set                     cplus_fptrap_insn_2, %o2
512         stw                     %o1, [%o2]
513         flush                   %o2
514         set                     cplus_fptrap_insn_3, %o2
515         stw                     %o1, [%o2]
516         flush                   %o2
517         set                     cplus_fptrap_insn_4, %o2
518         stw                     %o1, [%o2]
519         flush                   %o2
520
521         retl
522          nop
523
524         /* The registers for cross calls will be:
525          *
526          * DATA 0: [low 32-bits]  Address of function to call, jmp to this
527          *         [high 32-bits] MMU Context Argument 0, place in %g5
528          * DATA 1: Address Argument 1, place in %g6
529          * DATA 2: Address Argument 2, place in %g7
530          *
531          * With this method we can do most of the cross-call tlb/cache
532          * flushing very quickly.
533          *
534          * Current CPU's IRQ worklist table is locked into %g1,
535          * don't touch.
536          */
537         .text
538         .align          32
539         .globl          do_ivec
540 do_ivec:
541         mov             0x40, %g3
542         ldxa            [%g3 + %g0] ASI_INTR_R, %g3
543         sethi           %hi(KERNBASE), %g4
544         cmp             %g3, %g4
545         bgeu,pn         %xcc, do_ivec_xcall
546          srlx           %g3, 32, %g5
547         stxa            %g0, [%g0] ASI_INTR_RECEIVE
548         membar          #Sync
549
550         sethi           %hi(ivector_table), %g2
551         sllx            %g3, 5, %g3
552         or              %g2, %lo(ivector_table), %g2
553         add             %g2, %g3, %g3
554         ldub            [%g3 + 0x04], %g4       /* pil */
555         mov             1, %g2
556         sllx            %g2, %g4, %g2
557         sllx            %g4, 2, %g4
558
559         lduw            [%g6 + %g4], %g5        /* g5 = irq_work(cpu, pil) */
560         stw             %g5, [%g3 + 0x00]       /* bucket->irq_chain = g5 */
561         stw             %g3, [%g6 + %g4]        /* irq_work(cpu, pil) = bucket */
562         wr              %g2, 0x0, %set_softint
563         retry
564 do_ivec_xcall:
565         mov             0x50, %g1
566         ldxa            [%g1 + %g0] ASI_INTR_R, %g1
567         srl             %g3, 0, %g3
568
569         mov             0x60, %g7
570         ldxa            [%g7 + %g0] ASI_INTR_R, %g7
571         stxa            %g0, [%g0] ASI_INTR_RECEIVE
572         membar          #Sync
573         ba,pt           %xcc, 1f
574          nop
575
576         .align          32
577 1:      jmpl            %g3, %g0
578          nop
579
580         .globl          save_alternate_globals
581 save_alternate_globals: /* %o0 = save_area */
582         rdpr            %pstate, %o5
583         andn            %o5, PSTATE_IE, %o1
584         wrpr            %o1, PSTATE_AG, %pstate
585         stx             %g0, [%o0 + 0x00]
586         stx             %g1, [%o0 + 0x08]
587         stx             %g2, [%o0 + 0x10]
588         stx             %g3, [%o0 + 0x18]
589         stx             %g4, [%o0 + 0x20]
590         stx             %g5, [%o0 + 0x28]
591         stx             %g6, [%o0 + 0x30]
592         stx             %g7, [%o0 + 0x38]
593         wrpr            %o1, PSTATE_IG, %pstate
594         stx             %g0, [%o0 + 0x40]
595         stx             %g1, [%o0 + 0x48]
596         stx             %g2, [%o0 + 0x50]
597         stx             %g3, [%o0 + 0x58]
598         stx             %g4, [%o0 + 0x60]
599         stx             %g5, [%o0 + 0x68]
600         stx             %g6, [%o0 + 0x70]
601         stx             %g7, [%o0 + 0x78]
602         wrpr            %o1, PSTATE_MG, %pstate
603         stx             %g0, [%o0 + 0x80]
604         stx             %g1, [%o0 + 0x88]
605         stx             %g2, [%o0 + 0x90]
606         stx             %g3, [%o0 + 0x98]
607         stx             %g4, [%o0 + 0xa0]
608         stx             %g5, [%o0 + 0xa8]
609         stx             %g6, [%o0 + 0xb0]
610         stx             %g7, [%o0 + 0xb8]
611         wrpr            %o5, 0x0, %pstate
612         retl
613          nop
614
615         .globl          restore_alternate_globals
616 restore_alternate_globals: /* %o0 = save_area */
617         rdpr            %pstate, %o5
618         andn            %o5, PSTATE_IE, %o1
619         wrpr            %o1, PSTATE_AG, %pstate
620         ldx             [%o0 + 0x00], %g0
621         ldx             [%o0 + 0x08], %g1
622         ldx             [%o0 + 0x10], %g2
623         ldx             [%o0 + 0x18], %g3
624         ldx             [%o0 + 0x20], %g4
625         ldx             [%o0 + 0x28], %g5
626         ldx             [%o0 + 0x30], %g6
627         ldx             [%o0 + 0x38], %g7
628         wrpr            %o1, PSTATE_IG, %pstate
629         ldx             [%o0 + 0x40], %g0
630         ldx             [%o0 + 0x48], %g1
631         ldx             [%o0 + 0x50], %g2
632         ldx             [%o0 + 0x58], %g3
633         ldx             [%o0 + 0x60], %g4
634         ldx             [%o0 + 0x68], %g5
635         ldx             [%o0 + 0x70], %g6
636         ldx             [%o0 + 0x78], %g7
637         wrpr            %o1, PSTATE_MG, %pstate
638         ldx             [%o0 + 0x80], %g0
639         ldx             [%o0 + 0x88], %g1
640         ldx             [%o0 + 0x90], %g2
641         ldx             [%o0 + 0x98], %g3
642         ldx             [%o0 + 0xa0], %g4
643         ldx             [%o0 + 0xa8], %g5
644         ldx             [%o0 + 0xb0], %g6
645         ldx             [%o0 + 0xb8], %g7
646         wrpr            %o5, 0x0, %pstate
647         retl
648          nop
649
650         .globl          getcc, setcc
651 getcc:
652         ldx             [%o0 + PT_V9_TSTATE], %o1
653         srlx            %o1, 32, %o1
654         and             %o1, 0xf, %o1
655         retl
656          stx            %o1, [%o0 + PT_V9_G1]
657 setcc:
658         ldx             [%o0 + PT_V9_TSTATE], %o1
659         ldx             [%o0 + PT_V9_G1], %o2
660         or              %g0, %ulo(TSTATE_ICC), %o3
661         sllx            %o3, 32, %o3
662         andn            %o1, %o3, %o1
663         sllx            %o2, 32, %o2
664         and             %o2, %o3, %o2
665         or              %o1, %o2, %o1
666         retl
667          stx            %o1, [%o0 + PT_V9_TSTATE]
668
669         .globl          utrap, utrap_ill
670 utrap:  brz,pn          %g1, etrap
671          nop
672         save            %sp, -128, %sp
673         rdpr            %tstate, %l6
674         rdpr            %cwp, %l7
675         andn            %l6, TSTATE_CWP, %l6
676         wrpr            %l6, %l7, %tstate
677         rdpr            %tpc, %l6
678         rdpr            %tnpc, %l7
679         wrpr            %g1, 0, %tnpc
680         done
681 utrap_ill:
682         call            bad_trap
683          add            %sp, PTREGS_OFF, %o0
684         ba,pt           %xcc, rtrap
685          clr            %l6
686
687         /* XXX Here is stuff we still need to write... -DaveM XXX */
688         .globl          netbsd_syscall
689 netbsd_syscall:
690         retl
691          nop
692
693         .globl          __do_data_access_exception
694         .globl          __do_data_access_exception_tl1
695 __do_data_access_exception_tl1:
696         rdpr            %pstate, %g4
697         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
698         mov             TLB_SFSR, %g3
699         mov             DMMU_SFAR, %g5
700         ldxa            [%g3] ASI_DMMU, %g4     ! Get SFSR
701         ldxa            [%g5] ASI_DMMU, %g5     ! Get SFAR
702         stxa            %g0, [%g3] ASI_DMMU     ! Clear SFSR.FaultValid bit
703         membar          #Sync
704         rdpr            %tt, %g3
705         cmp             %g3, 0x80               ! first win spill/fill trap
706         blu,pn          %xcc, 1f
707          cmp            %g3, 0xff               ! last win spill/fill trap
708         bgu,pn          %xcc, 1f
709          nop
710         ba,pt           %xcc, winfix_dax
711          rdpr           %tpc, %g3
712 1:      sethi           %hi(109f), %g7
713         ba,pt           %xcc, etraptl1
714 109:     or             %g7, %lo(109b), %g7
715         mov             %l4, %o1
716         mov             %l5, %o2
717         call            data_access_exception_tl1
718          add            %sp, PTREGS_OFF, %o0
719         ba,pt           %xcc, rtrap
720          clr            %l6
721
722 __do_data_access_exception:
723         rdpr            %pstate, %g4
724         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
725         mov             TLB_SFSR, %g3
726         mov             DMMU_SFAR, %g5
727         ldxa            [%g3] ASI_DMMU, %g4     ! Get SFSR
728         ldxa            [%g5] ASI_DMMU, %g5     ! Get SFAR
729         stxa            %g0, [%g3] ASI_DMMU     ! Clear SFSR.FaultValid bit
730         membar          #Sync
731         sethi           %hi(109f), %g7
732         ba,pt           %xcc, etrap
733 109:     or             %g7, %lo(109b), %g7
734         mov             %l4, %o1
735         mov             %l5, %o2
736         call            data_access_exception
737          add            %sp, PTREGS_OFF, %o0
738         ba,pt           %xcc, rtrap
739          clr            %l6
740
741         .globl          __do_instruction_access_exception
742         .globl          __do_instruction_access_exception_tl1
743 __do_instruction_access_exception_tl1:
744         rdpr            %pstate, %g4
745         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
746         mov             TLB_SFSR, %g3
747         ldxa            [%g3] ASI_IMMU, %g4     ! Get SFSR
748         rdpr            %tpc, %g5               ! IMMU has no SFAR, use TPC
749         stxa            %g0, [%g3] ASI_IMMU     ! Clear FaultValid bit
750         membar          #Sync
751         sethi           %hi(109f), %g7
752         ba,pt           %xcc, etraptl1
753 109:     or             %g7, %lo(109b), %g7
754         mov             %l4, %o1
755         mov             %l5, %o2
756         call            instruction_access_exception_tl1
757          add            %sp, PTREGS_OFF, %o0
758         ba,pt           %xcc, rtrap
759          clr            %l6
760
761 __do_instruction_access_exception:
762         rdpr            %pstate, %g4
763         wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
764         mov             TLB_SFSR, %g3
765         ldxa            [%g3] ASI_IMMU, %g4     ! Get SFSR
766         rdpr            %tpc, %g5               ! IMMU has no SFAR, use TPC
767         stxa            %g0, [%g3] ASI_IMMU     ! Clear FaultValid bit
768         membar          #Sync
769         sethi           %hi(109f), %g7
770         ba,pt           %xcc, etrap
771 109:     or             %g7, %lo(109b), %g7
772         mov             %l4, %o1
773         mov             %l5, %o2
774         call            instruction_access_exception
775          add            %sp, PTREGS_OFF, %o0
776         ba,pt           %xcc, rtrap
777          clr            %l6
778
779         /* This is the trap handler entry point for ECC correctable
780          * errors.  They are corrected, but we listen for the trap
781          * so that the event can be logged.
782          *
783          * Disrupting errors are either:
784          * 1) single-bit ECC errors during UDB reads to system
785          *    memory
786          * 2) data parity errors during write-back events
787          *
788          * As far as I can make out from the manual, the CEE trap
789          * is only for correctable errors during memory read
790          * accesses by the front-end of the processor.
791          *
792          * The code below is only for trap level 1 CEE events,
793          * as it is the only situation where we can safely record
794          * and log.  For trap level >1 we just clear the CE bit
795          * in the AFSR and return.
796          */
797
798         /* Our trap handling infrastructure allows us to preserve
799          * two 64-bit values during etrap for arguments to
800          * subsequent C code.  Therefore we encode the information
801          * as follows:
802          *
803          * value 1) Full 64-bits of AFAR
804          * value 2) Low 33-bits of AFSR, then bits 33-->42
805          *          are UDBL error status and bits 43-->52
806          *          are UDBH error status
807          */
808         .align  64
809         .globl  cee_trap
810 cee_trap:
811         ldxa    [%g0] ASI_AFSR, %g1             ! Read AFSR
812         ldxa    [%g0] ASI_AFAR, %g2             ! Read AFAR
813         sllx    %g1, 31, %g1                    ! Clear reserved bits
814         srlx    %g1, 31, %g1                    ! in AFSR
815
816         /* NOTE: UltraSparc-I/II have high and low UDB error
817          *       registers, corresponding to the two UDB units
818          *       present on those chips.  UltraSparc-IIi only
819          *       has a single UDB, called "SDB" in the manual.
820          *       For IIi the upper UDB register always reads
821          *       as zero so for our purposes things will just
822          *       work with the checks below.
823          */
824         ldxa    [%g0] ASI_UDBL_ERROR_R, %g3     ! Read UDB-Low error status
825         andcc   %g3, (1 << 8), %g4              ! Check CE bit
826         sllx    %g3, (64 - 10), %g3             ! Clear reserved bits
827         srlx    %g3, (64 - 10), %g3             ! in UDB-Low error status
828
829         sllx    %g3, (33 + 0), %g3              ! Shift up to encoding area
830         or      %g1, %g3, %g1                   ! Or it in
831         be,pn   %xcc, 1f                        ! Branch if CE bit was clear
832          nop
833         stxa    %g4, [%g0] ASI_UDB_ERROR_W      ! Clear CE sticky bit in UDBL
834         membar  #Sync                           ! Synchronize ASI stores
835 1:      mov     0x18, %g5                       ! Addr of UDB-High error status
836         ldxa    [%g5] ASI_UDBH_ERROR_R, %g3     ! Read it
837
838         andcc   %g3, (1 << 8), %g4              ! Check CE bit
839         sllx    %g3, (64 - 10), %g3             ! Clear reserved bits
840         srlx    %g3, (64 - 10), %g3             ! in UDB-High error status
841         sllx    %g3, (33 + 10), %g3             ! Shift up to encoding area
842         or      %g1, %g3, %g1                   ! Or it in
843         be,pn   %xcc, 1f                        ! Branch if CE bit was clear
844          nop
845         nop
846
847         stxa    %g4, [%g5] ASI_UDB_ERROR_W      ! Clear CE sticky bit in UDBH
848         membar  #Sync                           ! Synchronize ASI stores
849 1:      mov     1, %g5                          ! AFSR CE bit is
850         sllx    %g5, 20, %g5                    ! bit 20
851         stxa    %g5, [%g0] ASI_AFSR             ! Clear CE sticky bit in AFSR
852         membar  #Sync                           ! Synchronize ASI stores
853         sllx    %g2, (64 - 41), %g2             ! Clear reserved bits
854         srlx    %g2, (64 - 41), %g2             ! in latched AFAR
855
856         andn    %g2, 0x0f, %g2                  ! Finish resv bit clearing
857         mov     %g1, %g4                        ! Move AFSR+UDB* into save reg
858         mov     %g2, %g5                        ! Move AFAR into save reg
859         rdpr    %pil, %g2
860         wrpr    %g0, 15, %pil
861         ba,pt   %xcc, etrap_irq
862          rd     %pc, %g7
863         mov     %l4, %o0
864
865         mov     %l5, %o1
866         call    cee_log
867          add    %sp, PTREGS_OFF, %o2
868         ba,a,pt %xcc, rtrap_irq
869
870         /* Capture I/D/E-cache state into per-cpu error scoreboard.
871          *
872          * %g1:         (TL>=0) ? 1 : 0
873          * %g2:         scratch
874          * %g3:         scratch
875          * %g4:         AFSR
876          * %g5:         AFAR
877          * %g6:         current thread ptr
878          * %g7:         scratch
879          */
880 #define CHEETAH_LOG_ERROR                                               \
881         /* Put "TL1" software bit into AFSR. */                         \
882         and             %g1, 0x1, %g1;                                  \
883         sllx            %g1, 63, %g2;                                   \
884         or              %g4, %g2, %g4;                                  \
885         /* Get log entry pointer for this cpu at this trap level. */    \
886         BRANCH_IF_JALAPENO(g2,g3,50f)                                   \
887         ldxa            [%g0] ASI_SAFARI_CONFIG, %g2;                   \
888         srlx            %g2, 17, %g2;                                   \
889         ba,pt           %xcc, 60f;                                      \
890          and            %g2, 0x3ff, %g2;                                \
891 50:     ldxa            [%g0] ASI_JBUS_CONFIG, %g2;                     \
892         srlx            %g2, 17, %g2;                                   \
893         and             %g2, 0x1f, %g2;                                 \
894 60:     sllx            %g2, 9, %g2;                                    \
895         sethi           %hi(cheetah_error_log), %g3;                    \
896         ldx             [%g3 + %lo(cheetah_error_log)], %g3;            \
897         brz,pn          %g3, 80f;                                       \
898          nop;                                                           \
899         add             %g3, %g2, %g3;                                  \
900         sllx            %g1, 8, %g1;                                    \
901         add             %g3, %g1, %g1;                                  \
902         /* %g1 holds pointer to the top of the logging scoreboard */    \
903         ldx             [%g1 + 0x0], %g7;                               \
904         cmp             %g7, -1;                                        \
905         bne,pn          %xcc, 80f;                                      \
906          nop;                                                           \
907         stx             %g4, [%g1 + 0x0];                               \
908         stx             %g5, [%g1 + 0x8];                               \
909         add             %g1, 0x10, %g1;                                 \
910         /* %g1 now points to D-cache logging area */                    \
911         set             0x3ff8, %g2;    /* DC_addr mask         */      \
912         and             %g5, %g2, %g2;  /* DC_addr bits of AFAR */      \
913         srlx            %g5, 12, %g3;                                   \
914         or              %g3, 1, %g3;    /* PHYS tag + valid     */      \
915 10:     ldxa            [%g2] ASI_DCACHE_TAG, %g7;                      \
916         cmp             %g3, %g7;       /* TAG match?           */      \
917         bne,pt          %xcc, 13f;                                      \
918          nop;                                                           \
919         /* Yep, what we want, capture state. */                         \
920         stx             %g2, [%g1 + 0x20];                              \
921         stx             %g7, [%g1 + 0x28];                              \
922         /* A membar Sync is required before and after utag access. */   \
923         membar          #Sync;                                          \
924         ldxa            [%g2] ASI_DCACHE_UTAG, %g7;                     \
925         membar          #Sync;                                          \
926         stx             %g7, [%g1 + 0x30];                              \
927         ldxa            [%g2] ASI_DCACHE_SNOOP_TAG, %g7;                \
928         stx             %g7, [%g1 + 0x38];                              \
929         clr             %g3;                                            \
930 12:     ldxa            [%g2 + %g3] ASI_DCACHE_DATA, %g7;               \
931         stx             %g7, [%g1];                                     \
932         add             %g3, (1 << 5), %g3;                             \
933         cmp             %g3, (4 << 5);                                  \
934         bl,pt           %xcc, 12b;                                      \
935          add            %g1, 0x8, %g1;                                  \
936         ba,pt           %xcc, 20f;                                      \
937          add            %g1, 0x20, %g1;                                 \
938 13:     sethi           %hi(1 << 14), %g7;                              \
939         add             %g2, %g7, %g2;                                  \
940         srlx            %g2, 14, %g7;                                   \
941         cmp             %g7, 4;                                         \
942         bl,pt           %xcc, 10b;                                      \
943          nop;                                                           \
944         add             %g1, 0x40, %g1;                                 \
945 20:     /* %g1 now points to I-cache logging area */                    \
946         set             0x1fe0, %g2;    /* IC_addr mask         */      \
947         and             %g5, %g2, %g2;  /* IC_addr bits of AFAR */      \
948         sllx            %g2, 1, %g2;    /* IC_addr[13:6]==VA[12:5] */   \
949         srlx            %g5, (13 - 8), %g3; /* Make PTAG */             \
950         andn            %g3, 0xff, %g3; /* Mask off undefined bits */   \
951 21:     ldxa            [%g2] ASI_IC_TAG, %g7;                          \
952         andn            %g7, 0xff, %g7;                                 \
953         cmp             %g3, %g7;                                       \
954         bne,pt          %xcc, 23f;                                      \
955          nop;                                                           \
956         /* Yep, what we want, capture state. */                         \
957         stx             %g2, [%g1 + 0x40];                              \
958         stx             %g7, [%g1 + 0x48];                              \
959         add             %g2, (1 << 3), %g2;                             \
960         ldxa            [%g2] ASI_IC_TAG, %g7;                          \
961         add             %g2, (1 << 3), %g2;                             \
962         stx             %g7, [%g1 + 0x50];                              \
963         ldxa            [%g2] ASI_IC_TAG, %g7;                          \
964         add             %g2, (1 << 3), %g2;                             \
965         stx             %g7, [%g1 + 0x60];                              \
966         ldxa            [%g2] ASI_IC_TAG, %g7;                          \
967         stx             %g7, [%g1 + 0x68];                              \
968         sub             %g2, (3 << 3), %g2;                             \
969         ldxa            [%g2] ASI_IC_STAG, %g7;                         \
970         stx             %g7, [%g1 + 0x58];                              \
971         clr             %g3;                                            \
972         srlx            %g2, 2, %g2;                                    \
973 22:     ldxa            [%g2 + %g3] ASI_IC_INSTR, %g7;                  \
974         stx             %g7, [%g1];                                     \
975         add             %g3, (1 << 3), %g3;                             \
976         cmp             %g3, (8 << 3);                                  \
977         bl,pt           %xcc, 22b;                                      \
978          add            %g1, 0x8, %g1;                                  \
979         ba,pt           %xcc, 30f;                                      \
980          add            %g1, 0x30, %g1;                                 \
981 23:     sethi           %hi(1 << 14), %g7;                              \
982         add             %g2, %g7, %g2;                                  \
983         srlx            %g2, 14, %g7;                                   \
984         cmp             %g7, 4;                                         \
985         bl,pt           %xcc, 21b;                                      \
986          nop;                                                           \
987         add             %g1, 0x70, %g1;                                 \
988 30:     /* %g1 now points to E-cache logging area */                    \
989         andn            %g5, (32 - 1), %g2;     /* E-cache subblock */  \
990         stx             %g2, [%g1 + 0x20];                              \
991         ldxa            [%g2] ASI_EC_TAG_DATA, %g7;                     \
992         stx             %g7, [%g1 + 0x28];                              \
993         ldxa            [%g2] ASI_EC_R, %g0;                            \
994         clr             %g3;                                            \
995 31:     ldxa            [%g3] ASI_EC_DATA, %g7;                         \
996         stx             %g7, [%g1 + %g3];                               \
997         add             %g3, 0x8, %g3;                                  \
998         cmp             %g3, 0x20;                                      \
999         bl,pt           %xcc, 31b;                                      \
1000          nop;                                                           \
1001 80:     /* DONE */
1002
1003         /* These get patched into the trap table at boot time
1004          * once we know we have a cheetah processor.
1005          */
1006         .globl          cheetah_fecc_trap_vector, cheetah_fecc_trap_vector_tl1
1007 cheetah_fecc_trap_vector:
1008         membar          #Sync
1009         ldxa            [%g0] ASI_DCU_CONTROL_REG, %g1
1010         andn            %g1, DCU_DC | DCU_IC, %g1
1011         stxa            %g1, [%g0] ASI_DCU_CONTROL_REG
1012         membar          #Sync
1013         sethi           %hi(cheetah_fast_ecc), %g2
1014         jmpl            %g2 + %lo(cheetah_fast_ecc), %g0
1015          mov            0, %g1
1016 cheetah_fecc_trap_vector_tl1:
1017         membar          #Sync
1018         ldxa            [%g0] ASI_DCU_CONTROL_REG, %g1
1019         andn            %g1, DCU_DC | DCU_IC, %g1
1020         stxa            %g1, [%g0] ASI_DCU_CONTROL_REG
1021         membar          #Sync
1022         sethi           %hi(cheetah_fast_ecc), %g2
1023         jmpl            %g2 + %lo(cheetah_fast_ecc), %g0
1024          mov            1, %g1
1025         .globl  cheetah_cee_trap_vector, cheetah_cee_trap_vector_tl1
1026 cheetah_cee_trap_vector:
1027         membar          #Sync
1028         ldxa            [%g0] ASI_DCU_CONTROL_REG, %g1
1029         andn            %g1, DCU_IC, %g1
1030         stxa            %g1, [%g0] ASI_DCU_CONTROL_REG
1031         membar          #Sync
1032         sethi           %hi(cheetah_cee), %g2
1033         jmpl            %g2 + %lo(cheetah_cee), %g0
1034          mov            0, %g1
1035 cheetah_cee_trap_vector_tl1:
1036         membar          #Sync
1037         ldxa            [%g0] ASI_DCU_CONTROL_REG, %g1
1038         andn            %g1, DCU_IC, %g1
1039         stxa            %g1, [%g0] ASI_DCU_CONTROL_REG
1040         membar          #Sync
1041         sethi           %hi(cheetah_cee), %g2
1042         jmpl            %g2 + %lo(cheetah_cee), %g0
1043          mov            1, %g1
1044         .globl  cheetah_deferred_trap_vector, cheetah_deferred_trap_vector_tl1
1045 cheetah_deferred_trap_vector:
1046         membar          #Sync
1047         ldxa            [%g0] ASI_DCU_CONTROL_REG, %g1;
1048         andn            %g1, DCU_DC | DCU_IC, %g1;
1049         stxa            %g1, [%g0] ASI_DCU_CONTROL_REG;
1050         membar          #Sync;
1051         sethi           %hi(cheetah_deferred_trap), %g2
1052         jmpl            %g2 + %lo(cheetah_deferred_trap), %g0
1053          mov            0, %g1
1054 cheetah_deferred_trap_vector_tl1:
1055         membar          #Sync;
1056         ldxa            [%g0] ASI_DCU_CONTROL_REG, %g1;
1057         andn            %g1, DCU_DC | DCU_IC, %g1;
1058         stxa            %g1, [%g0] ASI_DCU_CONTROL_REG;
1059         membar          #Sync;
1060         sethi           %hi(cheetah_deferred_trap), %g2
1061         jmpl            %g2 + %lo(cheetah_deferred_trap), %g0
1062          mov            1, %g1
1063
1064         /* Cheetah+ specific traps. These are for the new I/D cache parity
1065          * error traps.  The first argument to cheetah_plus_parity_handler
1066          * is encoded as follows:
1067          *
1068          * Bit0:        0=dcache,1=icache
1069          * Bit1:        0=recoverable,1=unrecoverable
1070          */
1071         .globl          cheetah_plus_dcpe_trap_vector, cheetah_plus_dcpe_trap_vector_tl1
1072 cheetah_plus_dcpe_trap_vector:
1073         membar          #Sync
1074         sethi           %hi(do_cheetah_plus_data_parity), %g7
1075         jmpl            %g7 + %lo(do_cheetah_plus_data_parity), %g0
1076          nop
1077         nop
1078         nop
1079         nop
1080         nop
1081
1082 do_cheetah_plus_data_parity:
1083         ba,pt           %xcc, etrap
1084          rd             %pc, %g7
1085         mov             0x0, %o0
1086         call            cheetah_plus_parity_error
1087          add            %sp, PTREGS_OFF, %o1
1088         ba,pt           %xcc, rtrap
1089          clr            %l6
1090
1091 cheetah_plus_dcpe_trap_vector_tl1:
1092         membar          #Sync
1093         wrpr            PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate
1094         sethi           %hi(do_dcpe_tl1), %g3
1095         jmpl            %g3 + %lo(do_dcpe_tl1), %g0
1096          nop
1097         nop
1098         nop
1099         nop
1100
1101         .globl          cheetah_plus_icpe_trap_vector, cheetah_plus_icpe_trap_vector_tl1
1102 cheetah_plus_icpe_trap_vector:
1103         membar          #Sync
1104         sethi           %hi(do_cheetah_plus_insn_parity), %g7
1105         jmpl            %g7 + %lo(do_cheetah_plus_insn_parity), %g0
1106          nop
1107         nop
1108         nop
1109         nop
1110         nop
1111
1112 do_cheetah_plus_insn_parity:
1113         ba,pt           %xcc, etrap
1114          rd             %pc, %g7
1115         mov             0x1, %o0
1116         call            cheetah_plus_parity_error
1117          add            %sp, PTREGS_OFF, %o1
1118         ba,pt           %xcc, rtrap
1119          clr            %l6
1120
1121 cheetah_plus_icpe_trap_vector_tl1:
1122         membar          #Sync
1123         wrpr            PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate
1124         sethi           %hi(do_icpe_tl1), %g3
1125         jmpl            %g3 + %lo(do_icpe_tl1), %g0
1126          nop
1127         nop
1128         nop
1129         nop
1130
1131         /* If we take one of these traps when tl >= 1, then we
1132          * jump to interrupt globals.  If some trap level above us
1133          * was also using interrupt globals, we cannot recover.
1134          * We may use all interrupt global registers except %g6.
1135          */
1136         .globl          do_dcpe_tl1, do_icpe_tl1
1137 do_dcpe_tl1:
1138         rdpr            %tl, %g1                ! Save original trap level
1139         mov             1, %g2                  ! Setup TSTATE checking loop
1140         sethi           %hi(TSTATE_IG), %g3     ! TSTATE mask bit
1141 1:      wrpr            %g2, %tl                ! Set trap level to check
1142         rdpr            %tstate, %g4            ! Read TSTATE for this level
1143         andcc           %g4, %g3, %g0           ! Interrupt globals in use?
1144         bne,a,pn        %xcc, do_dcpe_tl1_fatal ! Yep, irrecoverable
1145          wrpr           %g1, %tl                ! Restore original trap level
1146         add             %g2, 1, %g2             ! Next trap level
1147         cmp             %g2, %g1                ! Hit them all yet?
1148         ble,pt          %icc, 1b                ! Not yet
1149          nop
1150         wrpr            %g1, %tl                ! Restore original trap level
1151 do_dcpe_tl1_nonfatal:   /* Ok we may use interrupt globals safely. */
1152         /* Reset D-cache parity */
1153         sethi           %hi(1 << 16), %g1       ! D-cache size
1154         mov             (1 << 5), %g2           ! D-cache line size
1155         sub             %g1, %g2, %g1           ! Move down 1 cacheline
1156 1:      srl             %g1, 14, %g3            ! Compute UTAG
1157         membar          #Sync
1158         stxa            %g3, [%g1] ASI_DCACHE_UTAG
1159         membar          #Sync
1160         sub             %g2, 8, %g3             ! 64-bit data word within line
1161 2:      membar          #Sync
1162         stxa            %g0, [%g1 + %g3] ASI_DCACHE_DATA
1163         membar          #Sync
1164         subcc           %g3, 8, %g3             ! Next 64-bit data word
1165         bge,pt          %icc, 2b
1166          nop
1167         subcc           %g1, %g2, %g1           ! Next cacheline
1168         bge,pt          %icc, 1b
1169          nop
1170         ba,pt           %xcc, dcpe_icpe_tl1_common
1171          nop
1172
1173 do_dcpe_tl1_fatal:
1174         sethi           %hi(1f), %g7
1175         ba,pt           %xcc, etraptl1
1176 1:      or              %g7, %lo(1b), %g7
1177         mov             0x2, %o0
1178         call            cheetah_plus_parity_error
1179          add            %sp, PTREGS_OFF, %o1
1180         ba,pt           %xcc, rtrap
1181          clr            %l6
1182
1183 do_icpe_tl1:
1184         rdpr            %tl, %g1                ! Save original trap level
1185         mov             1, %g2                  ! Setup TSTATE checking loop
1186         sethi           %hi(TSTATE_IG), %g3     ! TSTATE mask bit
1187 1:      wrpr            %g2, %tl                ! Set trap level to check
1188         rdpr            %tstate, %g4            ! Read TSTATE for this level
1189         andcc           %g4, %g3, %g0           ! Interrupt globals in use?
1190         bne,a,pn        %xcc, do_icpe_tl1_fatal ! Yep, irrecoverable
1191          wrpr           %g1, %tl                ! Restore original trap level
1192         add             %g2, 1, %g2             ! Next trap level
1193         cmp             %g2, %g1                ! Hit them all yet?
1194         ble,pt          %icc, 1b                ! Not yet
1195          nop
1196         wrpr            %g1, %tl                ! Restore original trap level
1197 do_icpe_tl1_nonfatal:   /* Ok we may use interrupt globals safely. */
1198         /* Flush I-cache */
1199         sethi           %hi(1 << 15), %g1       ! I-cache size
1200         mov             (1 << 5), %g2           ! I-cache line size
1201         sub             %g1, %g2, %g1
1202 1:      or              %g1, (2 << 3), %g3
1203         stxa            %g0, [%g3] ASI_IC_TAG
1204         membar          #Sync
1205         subcc           %g1, %g2, %g1
1206         bge,pt          %icc, 1b
1207          nop
1208         ba,pt           %xcc, dcpe_icpe_tl1_common
1209          nop
1210
1211 do_icpe_tl1_fatal:
1212         sethi           %hi(1f), %g7
1213         ba,pt           %xcc, etraptl1
1214 1:      or              %g7, %lo(1b), %g7
1215         mov             0x3, %o0
1216         call            cheetah_plus_parity_error
1217          add            %sp, PTREGS_OFF, %o1
1218         ba,pt           %xcc, rtrap
1219          clr            %l6
1220         
1221 dcpe_icpe_tl1_common:
1222         /* Flush D-cache, re-enable D/I caches in DCU and finally
1223          * retry the trapping instruction.
1224          */
1225         sethi           %hi(1 << 16), %g1       ! D-cache size
1226         mov             (1 << 5), %g2           ! D-cache line size
1227         sub             %g1, %g2, %g1
1228 1:      stxa            %g0, [%g1] ASI_DCACHE_TAG
1229         membar          #Sync
1230         subcc           %g1, %g2, %g1
1231         bge,pt          %icc, 1b
1232          nop
1233         ldxa            [%g0] ASI_DCU_CONTROL_REG, %g1
1234         or              %g1, (DCU_DC | DCU_IC), %g1
1235         stxa            %g1, [%g0] ASI_DCU_CONTROL_REG
1236         membar          #Sync
1237         retry
1238
1239         /* Cheetah FECC trap handling, we get here from tl{0,1}_fecc
1240          * in the trap table.  That code has done a memory barrier
1241          * and has disabled both the I-cache and D-cache in the DCU
1242          * control register.  The I-cache is disabled so that we may
1243          * capture the corrupted cache line, and the D-cache is disabled
1244          * because corrupt data may have been placed there and we don't
1245          * want to reference it.
1246          *
1247          * %g1 is one if this trap occurred at %tl >= 1.
1248          *
1249          * Next, we turn off error reporting so that we don't recurse.
1250          */
1251         .globl          cheetah_fast_ecc
1252 cheetah_fast_ecc:
1253         ldxa            [%g0] ASI_ESTATE_ERROR_EN, %g2
1254         andn            %g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2
1255         stxa            %g2, [%g0] ASI_ESTATE_ERROR_EN
1256         membar          #Sync
1257
1258         /* Fetch and clear AFSR/AFAR */
1259         ldxa            [%g0] ASI_AFSR, %g4
1260         ldxa            [%g0] ASI_AFAR, %g5
1261         stxa            %g4, [%g0] ASI_AFSR
1262         membar          #Sync
1263
1264         CHEETAH_LOG_ERROR
1265
1266         rdpr            %pil, %g2
1267         wrpr            %g0, 15, %pil
1268         ba,pt           %xcc, etrap_irq
1269          rd             %pc, %g7
1270         mov             %l4, %o1
1271         mov             %l5, %o2
1272         call            cheetah_fecc_handler
1273          add            %sp, PTREGS_OFF, %o0
1274         ba,a,pt         %xcc, rtrap_irq
1275
1276         /* Our caller has disabled I-cache and performed membar Sync. */
1277         .globl          cheetah_cee
1278 cheetah_cee:
1279         ldxa            [%g0] ASI_ESTATE_ERROR_EN, %g2
1280         andn            %g2, ESTATE_ERROR_CEEN, %g2
1281         stxa            %g2, [%g0] ASI_ESTATE_ERROR_EN
1282         membar          #Sync
1283
1284         /* Fetch and clear AFSR/AFAR */
1285         ldxa            [%g0] ASI_AFSR, %g4
1286         ldxa            [%g0] ASI_AFAR, %g5
1287         stxa            %g4, [%g0] ASI_AFSR
1288         membar          #Sync
1289
1290         CHEETAH_LOG_ERROR
1291
1292         rdpr            %pil, %g2
1293         wrpr            %g0, 15, %pil
1294         ba,pt           %xcc, etrap_irq
1295          rd             %pc, %g7
1296         mov             %l4, %o1
1297         mov             %l5, %o2
1298         call            cheetah_cee_handler
1299          add            %sp, PTREGS_OFF, %o0
1300         ba,a,pt         %xcc, rtrap_irq
1301
1302         /* Our caller has disabled I-cache+D-cache and performed membar Sync. */
1303         .globl          cheetah_deferred_trap
1304 cheetah_deferred_trap:
1305         ldxa            [%g0] ASI_ESTATE_ERROR_EN, %g2
1306         andn            %g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2
1307         stxa            %g2, [%g0] ASI_ESTATE_ERROR_EN
1308         membar          #Sync
1309
1310         /* Fetch and clear AFSR/AFAR */
1311         ldxa            [%g0] ASI_AFSR, %g4
1312         ldxa            [%g0] ASI_AFAR, %g5
1313         stxa            %g4, [%g0] ASI_AFSR
1314         membar          #Sync
1315
1316         CHEETAH_LOG_ERROR
1317
1318         rdpr            %pil, %g2
1319         wrpr            %g0, 15, %pil
1320         ba,pt           %xcc, etrap_irq
1321          rd             %pc, %g7
1322         mov             %l4, %o1
1323         mov             %l5, %o2
1324         call            cheetah_deferred_handler
1325          add            %sp, PTREGS_OFF, %o0
1326         ba,a,pt         %xcc, rtrap_irq
1327
1328         .globl          __do_privact
1329 __do_privact:
1330         mov             TLB_SFSR, %g3
1331         stxa            %g0, [%g3] ASI_DMMU     ! Clear FaultValid bit
1332         membar          #Sync
1333         sethi           %hi(109f), %g7
1334         ba,pt           %xcc, etrap
1335 109:    or              %g7, %lo(109b), %g7
1336         call            do_privact
1337          add            %sp, PTREGS_OFF, %o0
1338         ba,pt           %xcc, rtrap
1339          clr            %l6
1340
1341         .globl          do_mna
1342 do_mna:
1343         rdpr            %tl, %g3
1344         cmp             %g3, 1
1345
1346         /* Setup %g4/%g5 now as they are used in the
1347          * winfixup code.
1348          */
1349         mov             TLB_SFSR, %g3
1350         mov             DMMU_SFAR, %g4
1351         ldxa            [%g4] ASI_DMMU, %g4
1352         ldxa            [%g3] ASI_DMMU, %g5
1353         stxa            %g0, [%g3] ASI_DMMU     ! Clear FaultValid bit
1354         membar          #Sync
1355         bgu,pn          %icc, winfix_mna
1356          rdpr           %tpc, %g3
1357
1358 1:      sethi           %hi(109f), %g7
1359         ba,pt           %xcc, etrap
1360 109:     or             %g7, %lo(109b), %g7
1361         mov             %l4, %o1
1362         mov             %l5, %o2
1363         call            mem_address_unaligned
1364          add            %sp, PTREGS_OFF, %o0
1365         ba,pt           %xcc, rtrap
1366          clr            %l6
1367
1368         .globl          do_lddfmna
1369 do_lddfmna:
1370         sethi           %hi(109f), %g7
1371         mov             TLB_SFSR, %g4
1372         ldxa            [%g4] ASI_DMMU, %g5
1373         stxa            %g0, [%g4] ASI_DMMU     ! Clear FaultValid bit
1374         membar          #Sync
1375         mov             DMMU_SFAR, %g4
1376         ldxa            [%g4] ASI_DMMU, %g4
1377         ba,pt           %xcc, etrap
1378 109:     or             %g7, %lo(109b), %g7
1379         mov             %l4, %o1
1380         mov             %l5, %o2
1381         call            handle_lddfmna
1382          add            %sp, PTREGS_OFF, %o0
1383         ba,pt           %xcc, rtrap
1384          clr            %l6
1385
1386         .globl          do_stdfmna
1387 do_stdfmna:
1388         sethi           %hi(109f), %g7
1389         mov             TLB_SFSR, %g4
1390         ldxa            [%g4] ASI_DMMU, %g5
1391         stxa            %g0, [%g4] ASI_DMMU     ! Clear FaultValid bit
1392         membar          #Sync
1393         mov             DMMU_SFAR, %g4
1394         ldxa            [%g4] ASI_DMMU, %g4
1395         ba,pt           %xcc, etrap
1396 109:     or             %g7, %lo(109b), %g7
1397         mov             %l4, %o1
1398         mov             %l5, %o2
1399         call            handle_stdfmna
1400          add            %sp, PTREGS_OFF, %o0
1401         ba,pt           %xcc, rtrap
1402          clr            %l6
1403
1404         .globl  breakpoint_trap
1405 breakpoint_trap:
1406         call            sparc_breakpoint
1407          add            %sp, PTREGS_OFF, %o0
1408         ba,pt           %xcc, rtrap
1409          nop
1410
1411 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
1412     defined(CONFIG_SOLARIS_EMUL_MODULE)
1413         /* SunOS uses syscall zero as the 'indirect syscall' it looks
1414          * like indir_syscall(scall_num, arg0, arg1, arg2...);  etc.
1415          * This is complete brain damage.
1416          */
1417         .globl  sunos_indir
1418 sunos_indir:
1419         srl             %o0, 0, %o0
1420         mov             %o7, %l4
1421         cmp             %o0, NR_SYSCALLS
1422         blu,a,pt        %icc, 1f
1423          sll            %o0, 0x2, %o0
1424         sethi           %hi(sunos_nosys), %l6
1425         b,pt            %xcc, 2f
1426          or             %l6, %lo(sunos_nosys), %l6
1427 1:      sethi           %hi(sunos_sys_table), %l7
1428         or              %l7, %lo(sunos_sys_table), %l7
1429         lduw            [%l7 + %o0], %l6
1430 2:      mov             %o1, %o0
1431         mov             %o2, %o1
1432         mov             %o3, %o2
1433         mov             %o4, %o3
1434         mov             %o5, %o4
1435         call            %l6
1436          mov            %l4, %o7
1437
1438         .globl  sunos_getpid
1439 sunos_getpid:
1440         call    sys_getppid
1441          nop
1442         call    sys_getpid
1443          stx    %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1444         b,pt    %xcc, ret_sys_call
1445          stx    %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1446
1447         /* SunOS getuid() returns uid in %o0 and euid in %o1 */
1448         .globl  sunos_getuid
1449 sunos_getuid:
1450         call    sys32_geteuid16
1451          nop
1452         call    sys32_getuid16
1453          stx    %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1454         b,pt    %xcc, ret_sys_call
1455          stx    %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1456
1457         /* SunOS getgid() returns gid in %o0 and egid in %o1 */
1458         .globl  sunos_getgid
1459 sunos_getgid:
1460         call    sys32_getegid16
1461          nop
1462         call    sys32_getgid16
1463          stx    %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1464         b,pt    %xcc, ret_sys_call
1465          stx    %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1466 #endif
1467
1468         /* SunOS's execv() call only specifies the argv argument, the
1469          * environment settings are the same as the calling processes.
1470          */
1471         .globl  sunos_execv
1472 sys_execve:
1473         sethi           %hi(sparc_execve), %g1
1474         ba,pt           %xcc, execve_merge
1475          or             %g1, %lo(sparc_execve), %g1
1476 #ifdef CONFIG_COMPAT
1477         .globl  sys_execve
1478 sunos_execv:
1479         stx             %g0, [%sp + PTREGS_OFF + PT_V9_I2]
1480         .globl  sys32_execve
1481 sys32_execve:
1482         sethi           %hi(sparc32_execve), %g1
1483         or              %g1, %lo(sparc32_execve), %g1
1484 #endif
1485 execve_merge:
1486         flushw
1487         jmpl            %g1, %g0
1488          add            %sp, PTREGS_OFF, %o0
1489
1490         .globl  sys_pipe, sys_sigpause, sys_nis_syscall
1491         .globl  sys_sigsuspend, sys_rt_sigsuspend
1492         .globl  sys_rt_sigreturn
1493         .globl  sys_ptrace
1494         .globl  sys_sigaltstack
1495         .align  32
1496 sys_pipe:       ba,pt           %xcc, sparc_pipe
1497                  add            %sp, PTREGS_OFF, %o0
1498 sys_nis_syscall:ba,pt           %xcc, c_sys_nis_syscall
1499                  add            %sp, PTREGS_OFF, %o0
1500 sys_memory_ordering:
1501                 ba,pt           %xcc, sparc_memory_ordering
1502                  add            %sp, PTREGS_OFF, %o1
1503 sys_sigaltstack:ba,pt           %xcc, do_sigaltstack
1504                  add            %i6, STACK_BIAS, %o2
1505 #ifdef CONFIG_COMPAT
1506         .globl  sys32_sigstack
1507 sys32_sigstack: ba,pt           %xcc, do_sys32_sigstack
1508                  mov            %i6, %o2
1509         .globl  sys32_sigaltstack
1510 sys32_sigaltstack:
1511                 ba,pt           %xcc, do_sys32_sigaltstack
1512                  mov            %i6, %o2
1513 #endif
1514                 .align          32
1515 sys_sigsuspend: add             %sp, PTREGS_OFF, %o0
1516                 call            do_sigsuspend
1517                  add            %o7, 1f-.-4, %o7
1518                 nop
1519 sys_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
1520                 add             %sp, PTREGS_OFF, %o2
1521                 call            do_rt_sigsuspend
1522                  add            %o7, 1f-.-4, %o7
1523                 nop
1524 #ifdef CONFIG_COMPAT
1525         .globl  sys32_rt_sigsuspend
1526 sys32_rt_sigsuspend: /* NOTE: %o0,%o1 have a correct value already */
1527                 srl             %o0, 0, %o0
1528                 add             %sp, PTREGS_OFF, %o2
1529                 call            do_rt_sigsuspend32
1530                  add            %o7, 1f-.-4, %o7
1531 #endif
1532                 /* NOTE: %o0 has a correct value already */
1533 sys_sigpause:   add             %sp, PTREGS_OFF, %o1
1534                 call            do_sigpause
1535                  add            %o7, 1f-.-4, %o7
1536                 nop
1537 #ifdef CONFIG_COMPAT
1538         .globl  sys32_sigreturn
1539 sys32_sigreturn:
1540                 add             %sp, PTREGS_OFF, %o0
1541                 call            do_sigreturn32
1542                  add            %o7, 1f-.-4, %o7
1543                 nop
1544 #endif
1545 sys_rt_sigreturn:
1546                 add             %sp, PTREGS_OFF, %o0
1547                 call            do_rt_sigreturn
1548                  add            %o7, 1f-.-4, %o7
1549                 nop
1550 #ifdef CONFIG_COMPAT
1551         .globl  sys32_rt_sigreturn
1552 sys32_rt_sigreturn:
1553                 add             %sp, PTREGS_OFF, %o0
1554                 call            do_rt_sigreturn32
1555                  add            %o7, 1f-.-4, %o7
1556                 nop
1557 #endif
1558 sys_ptrace:     add             %sp, PTREGS_OFF, %o0
1559                 call            do_ptrace
1560                  add            %o7, 1f-.-4, %o7
1561                 nop
1562                 .align          32
1563 1:              ldx             [%curptr + TI_FLAGS], %l5
1564                 andcc           %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
1565                 be,pt           %icc, rtrap
1566                  clr            %l6
1567                 add             %sp, PTREGS_OFF, %o0
1568                 call            syscall_trace
1569                  mov            1, %o1
1570
1571                 ba,pt           %xcc, rtrap
1572                  clr            %l6
1573
1574         /* This is how fork() was meant to be done, 8 instruction entry.
1575          *
1576          * I questioned the following code briefly, let me clear things
1577          * up so you must not reason on it like I did.
1578          *
1579          * Know the fork_kpsr etc. we use in the sparc32 port?  We don't
1580          * need it here because the only piece of window state we copy to
1581          * the child is the CWP register.  Even if the parent sleeps,
1582          * we are safe because we stuck it into pt_regs of the parent
1583          * so it will not change.
1584          *
1585          * XXX This raises the question, whether we can do the same on
1586          * XXX sparc32 to get rid of fork_kpsr _and_ fork_kwim.  The
1587          * XXX answer is yes.  We stick fork_kpsr in UREG_G0 and
1588          * XXX fork_kwim in UREG_G1 (global registers are considered
1589          * XXX volatile across a system call in the sparc ABI I think
1590          * XXX if it isn't we can use regs->y instead, anyone who depends
1591          * XXX upon the Y register being preserved across a fork deserves
1592          * XXX to lose).
1593          *
1594          * In fact we should take advantage of that fact for other things
1595          * during system calls...
1596          */
1597         .globl  sys_fork, sys_vfork, sys_clone, sparc_exit
1598         .globl  ret_from_syscall
1599         .align  32
1600 sys_vfork:      /* Under Linux, vfork and fork are just special cases of clone. */
1601                 sethi           %hi(0x4000 | 0x0100 | SIGCHLD), %o0
1602                 or              %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0
1603                 ba,pt           %xcc, sys_clone
1604 sys_fork:        clr            %o1
1605                 mov             SIGCHLD, %o0
1606 sys_clone:      flushw
1607                 movrz           %o1, %fp, %o1
1608                 mov             0, %o3
1609                 ba,pt           %xcc, sparc_do_fork
1610                  add            %sp, PTREGS_OFF, %o2
1611 ret_from_syscall:
1612                 /* Clear current_thread_info()->new_child, and
1613                  * check performance counter stuff too.
1614                  */
1615                 stb             %g0, [%g6 + TI_NEW_CHILD]
1616                 ldx             [%g6 + TI_FLAGS], %l0
1617                 call            schedule_tail
1618                  mov            %g7, %o0
1619                 andcc           %l0, _TIF_PERFCTR, %g0
1620                 be,pt           %icc, 1f
1621                  nop
1622                 ldx             [%g6 + TI_PCR], %o7
1623                 wr              %g0, %o7, %pcr
1624
1625                 /* Blackbird errata workaround.  See commentary in
1626                  * smp.c:smp_percpu_timer_interrupt() for more
1627                  * information.
1628                  */
1629                 ba,pt           %xcc, 99f
1630                  nop
1631                 .align          64
1632 99:             wr              %g0, %g0, %pic
1633                 rd              %pic, %g0
1634
1635 1:              b,pt            %xcc, ret_sys_call
1636                  ldx            [%sp + PTREGS_OFF + PT_V9_I0], %o0
1637 sparc_exit:     wrpr            %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate
1638                 rdpr            %otherwin, %g1
1639                 rdpr            %cansave, %g3
1640                 add             %g3, %g1, %g3
1641                 wrpr            %g3, 0x0, %cansave
1642                 wrpr            %g0, 0x0, %otherwin
1643                 wrpr            %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE), %pstate
1644                 ba,pt           %xcc, sys_exit
1645                  stb            %g0, [%g6 + TI_WSAVED]
1646
1647 linux_sparc_ni_syscall:
1648         sethi           %hi(sys_ni_syscall), %l7
1649         b,pt            %xcc, 4f
1650          or             %l7, %lo(sys_ni_syscall), %l7
1651
1652 linux_syscall_trace32:
1653         add             %sp, PTREGS_OFF, %o0
1654         call            syscall_trace
1655          clr            %o1
1656         srl             %i0, 0, %o0
1657         srl             %i4, 0, %o4
1658         srl             %i1, 0, %o1
1659         srl             %i2, 0, %o2
1660         b,pt            %xcc, 2f
1661          srl            %i3, 0, %o3
1662
1663 linux_syscall_trace:
1664         add             %sp, PTREGS_OFF, %o0
1665         call            syscall_trace
1666          clr            %o1
1667         mov             %i0, %o0
1668         mov             %i1, %o1
1669         mov             %i2, %o2
1670         mov             %i3, %o3
1671         b,pt            %xcc, 2f
1672          mov            %i4, %o4
1673
1674
1675         /* Linux 32-bit and SunOS system calls enter here... */
1676         .align  32
1677         .globl  linux_sparc_syscall32
1678 linux_sparc_syscall32:
1679         /* Direct access to user regs, much faster. */
1680         cmp             %g1, NR_SYSCALLS                        ! IEU1  Group
1681         bgeu,pn         %xcc, linux_sparc_ni_syscall            ! CTI
1682          srl            %i0, 0, %o0                             ! IEU0
1683         sll             %g1, 2, %l4                             ! IEU0  Group
1684         srl             %i4, 0, %o4                             ! IEU1
1685         lduw            [%l7 + %l4], %l7                        ! Load
1686         srl             %i1, 0, %o1                             ! IEU0  Group
1687         ldx             [%curptr + TI_FLAGS], %l0               ! Load
1688
1689         srl             %i5, 0, %o5                             ! IEU1
1690         srl             %i2, 0, %o2                             ! IEU0  Group
1691         andcc           %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
1692         bne,pn          %icc, linux_syscall_trace32             ! CTI
1693          mov            %i0, %l5                                ! IEU1
1694         call            %l7                                     ! CTI   Group brk forced
1695          srl            %i3, 0, %o3                             ! IEU0
1696         ba,a,pt         %xcc, 3f
1697
1698         /* Linux native and SunOS system calls enter here... */
1699         .align  32
1700         .globl  linux_sparc_syscall, ret_sys_call
1701 linux_sparc_syscall:
1702         /* Direct access to user regs, much faster. */
1703         cmp             %g1, NR_SYSCALLS                        ! IEU1  Group
1704         bgeu,pn         %xcc, linux_sparc_ni_syscall            ! CTI
1705          mov            %i0, %o0                                ! IEU0
1706         sll             %g1, 2, %l4                             ! IEU0  Group
1707         mov             %i1, %o1                                ! IEU1
1708         lduw            [%l7 + %l4], %l7                        ! Load
1709 4:      mov             %i2, %o2                                ! IEU0  Group
1710         ldx             [%curptr + TI_FLAGS], %l0               ! Load
1711
1712         mov             %i3, %o3                                ! IEU1
1713         mov             %i4, %o4                                ! IEU0  Group
1714         andcc           %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
1715         bne,pn          %icc, linux_syscall_trace               ! CTI   Group
1716          mov            %i0, %l5                                ! IEU0
1717 2:      call            %l7                                     ! CTI   Group brk forced
1718          mov            %i5, %o5                                ! IEU0
1719         nop
1720
1721 3:      stx             %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1722 ret_sys_call:
1723         ldx             [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
1724         ldx             [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
1725         sra             %o0, 0, %o0
1726         mov             %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
1727         sllx            %g2, 32, %g2
1728
1729         /* Check if force_successful_syscall_return()
1730          * was invoked.
1731          */
1732         ldub            [%curptr + TI_SYS_NOERROR], %l0
1733         brz,pt          %l0, 1f
1734          nop
1735         ba,pt           %xcc, 80f
1736          stb            %g0, [%curptr + TI_SYS_NOERROR]
1737
1738 1:
1739         cmp             %o0, -ERESTART_RESTARTBLOCK
1740         bgeu,pn         %xcc, 1f
1741          andcc          %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
1742 80:
1743         /* System call success, clear Carry condition code. */
1744         andn            %g3, %g2, %g3
1745         stx             %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]  
1746         bne,pn          %icc, linux_syscall_trace2
1747          add            %l1, 0x4, %l2                   ! npc = npc+4
1748         stx             %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
1749         ba,pt           %xcc, rtrap_clr_l6
1750          stx            %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
1751
1752 1:
1753         /* System call failure, set Carry condition code.
1754          * Also, get abs(errno) to return to the process.
1755          */
1756         andcc           %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6  
1757         sub             %g0, %o0, %o0
1758         or              %g3, %g2, %g3
1759         stx             %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1760         mov             1, %l6
1761         stx             %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
1762         bne,pn          %icc, linux_syscall_trace2
1763          add            %l1, 0x4, %l2                   ! npc = npc+4
1764         stx             %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
1765
1766         b,pt            %xcc, rtrap
1767          stx            %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
1768 linux_syscall_trace2:
1769         add             %sp, PTREGS_OFF, %o0
1770         call            syscall_trace
1771          mov            1, %o1
1772         stx             %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
1773         ba,pt           %xcc, rtrap
1774          stx            %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
1775
1776         .align          32
1777         .globl          __flushw_user
1778 __flushw_user:
1779         rdpr            %otherwin, %g1
1780         brz,pn          %g1, 2f
1781          clr            %g2
1782 1:      save            %sp, -128, %sp
1783         rdpr            %otherwin, %g1
1784         brnz,pt         %g1, 1b
1785          add            %g2, 1, %g2
1786 1:      sub             %g2, 1, %g2
1787         brnz,pt         %g2, 1b
1788          restore        %g0, %g0, %g0
1789 2:      retl
1790          nop