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