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