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