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