sparc32: Kill off software 32-bit multiply/divide routines.
[pandora-kernel.git] / arch / sparc / kernel / entry.S
1 /* arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
2  *
3  * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
4  * Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
5  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
6  * Copyright (C) 1996-1999 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
7  * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au)
8  */
9
10 #include <linux/linkage.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/contregs.h>
17 #include <asm/ptrace.h>
18 #include <asm/asm-offsets.h>
19 #include <asm/psr.h>
20 #include <asm/vaddrs.h>
21 #include <asm/page.h>
22 #include <asm/pgtable.h>
23 #include <asm/winmacro.h>
24 #include <asm/signal.h>
25 #include <asm/obio.h>
26 #include <asm/mxcc.h>
27 #include <asm/thread_info.h>
28 #include <asm/param.h>
29 #include <asm/unistd.h>
30
31 #include <asm/asmmacro.h>
32
33 #define curptr      g6
34
35 /* These are just handy. */
36 #define _SV     save    %sp, -STACKFRAME_SZ, %sp
37 #define _RS     restore 
38
39 #define FLUSH_ALL_KERNEL_WINDOWS \
40         _SV; _SV; _SV; _SV; _SV; _SV; _SV; \
41         _RS; _RS; _RS; _RS; _RS; _RS; _RS;
42
43         .text
44
45 #ifdef CONFIG_KGDB
46         .align  4
47         .globl          arch_kgdb_breakpoint
48         .type           arch_kgdb_breakpoint,#function
49 arch_kgdb_breakpoint:
50         ta              0x7d
51         retl
52          nop
53         .size           arch_kgdb_breakpoint,.-arch_kgdb_breakpoint
54 #endif
55
56 #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
57         .align  4
58         .globl  floppy_hardint
59 floppy_hardint:
60         /*
61          * This code cannot touch registers %l0 %l1 and %l2
62          * because SAVE_ALL depends on their values. It depends
63          * on %l3 also, but we regenerate it before a call.
64          * Other registers are:
65          * %l3 -- base address of fdc registers
66          * %l4 -- pdma_vaddr
67          * %l5 -- scratch for ld/st address
68          * %l6 -- pdma_size
69          * %l7 -- scratch [floppy byte, ld/st address, aux. data]
70          */
71
72         /* Do we have work to do? */
73         sethi   %hi(doing_pdma), %l7
74         ld      [%l7 + %lo(doing_pdma)], %l7
75         cmp     %l7, 0
76         be      floppy_dosoftint
77          nop
78
79         /* Load fdc register base */
80         sethi   %hi(fdc_status), %l3
81         ld      [%l3 + %lo(fdc_status)], %l3
82
83         /* Setup register addresses */
84         sethi   %hi(pdma_vaddr), %l5    ! transfer buffer
85         ld      [%l5 + %lo(pdma_vaddr)], %l4
86         sethi   %hi(pdma_size), %l5     ! bytes to go
87         ld      [%l5 + %lo(pdma_size)], %l6
88 next_byte:
89         ldub    [%l3], %l7
90
91         andcc   %l7, 0x80, %g0          ! Does fifo still have data
92         bz      floppy_fifo_emptied     ! fifo has been emptied...
93          andcc  %l7, 0x20, %g0          ! in non-dma mode still?
94         bz      floppy_overrun          ! nope, overrun
95          andcc  %l7, 0x40, %g0          ! 0=write 1=read
96         bz      floppy_write
97          sub    %l6, 0x1, %l6
98
99         /* Ok, actually read this byte */
100         ldub    [%l3 + 1], %l7
101         orcc    %g0, %l6, %g0
102         stb     %l7, [%l4]
103         bne     next_byte
104          add    %l4, 0x1, %l4
105
106         b       floppy_tdone
107          nop
108
109 floppy_write:
110         /* Ok, actually write this byte */
111         ldub    [%l4], %l7
112         orcc    %g0, %l6, %g0
113         stb     %l7, [%l3 + 1]
114         bne     next_byte
115          add    %l4, 0x1, %l4
116
117         /* fall through... */
118 floppy_tdone:
119         sethi   %hi(pdma_vaddr), %l5
120         st      %l4, [%l5 + %lo(pdma_vaddr)]
121         sethi   %hi(pdma_size), %l5
122         st      %l6, [%l5 + %lo(pdma_size)]
123         /* Flip terminal count pin */
124         set     auxio_register, %l7
125         ld      [%l7], %l7
126
127         ldub    [%l7], %l5
128
129         or      %l5, 0xc2, %l5
130         stb     %l5, [%l7]
131         andn    %l5, 0x02, %l5
132
133 2:
134         /* Kill some time so the bits set */
135         WRITE_PAUSE
136         WRITE_PAUSE
137
138         stb     %l5, [%l7]
139
140         /* Prevent recursion */
141         sethi   %hi(doing_pdma), %l7
142         b       floppy_dosoftint
143          st     %g0, [%l7 + %lo(doing_pdma)]
144
145         /* We emptied the FIFO, but we haven't read everything
146          * as of yet.  Store the current transfer address and
147          * bytes left to read so we can continue when the next
148          * fast IRQ comes in.
149          */
150 floppy_fifo_emptied:
151         sethi   %hi(pdma_vaddr), %l5
152         st      %l4, [%l5 + %lo(pdma_vaddr)]
153         sethi   %hi(pdma_size), %l7
154         st      %l6, [%l7 + %lo(pdma_size)]
155
156         /* Restore condition codes */
157         wr      %l0, 0x0, %psr
158         WRITE_PAUSE
159
160         jmp     %l1
161         rett    %l2
162
163 floppy_overrun:
164         sethi   %hi(pdma_vaddr), %l5
165         st      %l4, [%l5 + %lo(pdma_vaddr)]
166         sethi   %hi(pdma_size), %l5
167         st      %l6, [%l5 + %lo(pdma_size)]
168         /* Prevent recursion */
169         sethi   %hi(doing_pdma), %l7
170         st      %g0, [%l7 + %lo(doing_pdma)]
171
172         /* fall through... */
173 floppy_dosoftint:
174         rd      %wim, %l3
175         SAVE_ALL
176
177         /* Set all IRQs off. */
178         or      %l0, PSR_PIL, %l4
179         wr      %l4, 0x0, %psr
180         WRITE_PAUSE
181         wr      %l4, PSR_ET, %psr
182         WRITE_PAUSE
183
184         mov     11, %o0                 ! floppy irq level (unused anyway)
185         mov     %g0, %o1                ! devid is not used in fast interrupts
186         call    sparc_floppy_irq
187          add    %sp, STACKFRAME_SZ, %o2 ! struct pt_regs *regs
188
189         RESTORE_ALL
190         
191 #endif /* (CONFIG_BLK_DEV_FD) */
192
193         /* Bad trap handler */
194         .globl  bad_trap_handler
195 bad_trap_handler:
196         SAVE_ALL
197
198         wr      %l0, PSR_ET, %psr
199         WRITE_PAUSE
200
201         add     %sp, STACKFRAME_SZ, %o0 ! pt_regs
202         call    do_hw_interrupt
203          mov    %l7, %o1                ! trap number
204
205         RESTORE_ALL
206         
207 /* For now all IRQ's not registered get sent here. handler_irq() will
208  * see if a routine is registered to handle this interrupt and if not
209  * it will say so on the console.
210  */
211
212         .align  4
213         .globl  real_irq_entry, patch_handler_irq
214 real_irq_entry:
215         SAVE_ALL
216
217 #ifdef CONFIG_SMP
218         .globl  patchme_maybe_smp_msg
219
220         cmp     %l7, 11
221 patchme_maybe_smp_msg:
222         bgu     maybe_smp4m_msg
223          nop
224 #endif
225
226 real_irq_continue:
227         or      %l0, PSR_PIL, %g2
228         wr      %g2, 0x0, %psr
229         WRITE_PAUSE
230         wr      %g2, PSR_ET, %psr
231         WRITE_PAUSE
232         mov     %l7, %o0                ! irq level
233 patch_handler_irq:
234         call    handler_irq
235          add    %sp, STACKFRAME_SZ, %o1 ! pt_regs ptr
236         or      %l0, PSR_PIL, %g2       ! restore PIL after handler_irq
237         wr      %g2, PSR_ET, %psr       ! keep ET up
238         WRITE_PAUSE
239
240         RESTORE_ALL
241
242 #ifdef CONFIG_SMP
243         /* SMP per-cpu ticker interrupts are handled specially. */
244 smp4m_ticker:
245         bne     real_irq_continue+4
246          or     %l0, PSR_PIL, %g2
247         wr      %g2, 0x0, %psr
248         WRITE_PAUSE
249         wr      %g2, PSR_ET, %psr
250         WRITE_PAUSE
251         call    smp4m_percpu_timer_interrupt
252          add    %sp, STACKFRAME_SZ, %o0
253         wr      %l0, PSR_ET, %psr
254         WRITE_PAUSE
255         RESTORE_ALL
256
257         /* Here is where we check for possible SMP IPI passed to us
258          * on some level other than 15 which is the NMI and only used
259          * for cross calls.  That has a separate entry point below.
260          *
261          * IPIs are sent on Level 12, 13 and 14. See IRQ_IPI_*.
262          */
263 maybe_smp4m_msg:
264         GET_PROCESSOR4M_ID(o3)
265         sethi   %hi(sun4m_irq_percpu), %l5
266         sll     %o3, 2, %o3
267         or      %l5, %lo(sun4m_irq_percpu), %o5
268         sethi   %hi(0x70000000), %o2    ! Check all soft-IRQs
269         ld      [%o5 + %o3], %o1
270         ld      [%o1 + 0x00], %o3       ! sun4m_irq_percpu[cpu]->pending
271         andcc   %o3, %o2, %g0
272         be,a    smp4m_ticker
273          cmp    %l7, 14
274         /* Soft-IRQ IPI */
275         st      %o2, [%o1 + 0x04]       ! sun4m_irq_percpu[cpu]->clear=0x70000000
276         WRITE_PAUSE
277         ld      [%o1 + 0x00], %g0       ! sun4m_irq_percpu[cpu]->pending
278         WRITE_PAUSE
279         or      %l0, PSR_PIL, %l4
280         wr      %l4, 0x0, %psr
281         WRITE_PAUSE
282         wr      %l4, PSR_ET, %psr
283         WRITE_PAUSE
284         srl     %o3, 28, %o2            ! shift for simpler checks below
285 maybe_smp4m_msg_check_single:
286         andcc   %o2, 0x1, %g0
287         beq,a   maybe_smp4m_msg_check_mask
288          andcc  %o2, 0x2, %g0
289         call    smp_call_function_single_interrupt
290          nop
291         andcc   %o2, 0x2, %g0
292 maybe_smp4m_msg_check_mask:
293         beq,a   maybe_smp4m_msg_check_resched
294          andcc  %o2, 0x4, %g0
295         call    smp_call_function_interrupt
296          nop
297         andcc   %o2, 0x4, %g0
298 maybe_smp4m_msg_check_resched:
299         /* rescheduling is done in RESTORE_ALL regardless, but incr stats */
300         beq,a   maybe_smp4m_msg_out
301          nop
302         call    smp_resched_interrupt
303          nop
304 maybe_smp4m_msg_out:
305         RESTORE_ALL
306
307         .align  4
308         .globl  linux_trap_ipi15_sun4m
309 linux_trap_ipi15_sun4m:
310         SAVE_ALL
311         sethi   %hi(0x80000000), %o2
312         GET_PROCESSOR4M_ID(o0)
313         sethi   %hi(sun4m_irq_percpu), %l5
314         or      %l5, %lo(sun4m_irq_percpu), %o5
315         sll     %o0, 2, %o0
316         ld      [%o5 + %o0], %o5
317         ld      [%o5 + 0x00], %o3       ! sun4m_irq_percpu[cpu]->pending
318         andcc   %o3, %o2, %g0
319         be      sun4m_nmi_error         ! Must be an NMI async memory error
320          st     %o2, [%o5 + 0x04]       ! sun4m_irq_percpu[cpu]->clear=0x80000000
321         WRITE_PAUSE
322         ld      [%o5 + 0x00], %g0       ! sun4m_irq_percpu[cpu]->pending
323         WRITE_PAUSE
324         or      %l0, PSR_PIL, %l4
325         wr      %l4, 0x0, %psr
326         WRITE_PAUSE
327         wr      %l4, PSR_ET, %psr
328         WRITE_PAUSE
329         call    smp4m_cross_call_irq
330          nop
331         b       ret_trap_lockless_ipi
332          clr    %l6
333
334         .globl  smp4d_ticker
335         /* SMP per-cpu ticker interrupts are handled specially. */
336 smp4d_ticker:
337         SAVE_ALL
338         or      %l0, PSR_PIL, %g2
339         sethi   %hi(CC_ICLR), %o0
340         sethi   %hi(1 << 14), %o1
341         or      %o0, %lo(CC_ICLR), %o0
342         stha    %o1, [%o0] ASI_M_MXCC   /* Clear PIL 14 in MXCC's ICLR */
343         wr      %g2, 0x0, %psr
344         WRITE_PAUSE
345         wr      %g2, PSR_ET, %psr
346         WRITE_PAUSE
347         call    smp4d_percpu_timer_interrupt
348          add    %sp, STACKFRAME_SZ, %o0
349         wr      %l0, PSR_ET, %psr
350         WRITE_PAUSE
351         RESTORE_ALL
352
353         .align  4
354         .globl  linux_trap_ipi15_sun4d
355 linux_trap_ipi15_sun4d:
356         SAVE_ALL
357         sethi   %hi(CC_BASE), %o4
358         sethi   %hi(MXCC_ERR_ME|MXCC_ERR_PEW|MXCC_ERR_ASE|MXCC_ERR_PEE), %o2
359         or      %o4, (CC_EREG - CC_BASE), %o0
360         ldda    [%o0] ASI_M_MXCC, %o0
361         andcc   %o0, %o2, %g0
362         bne     1f
363          sethi  %hi(BB_STAT2), %o2
364         lduba   [%o2] ASI_M_CTL, %o2
365         andcc   %o2, BB_STAT2_MASK, %g0
366         bne     2f
367          or     %o4, (CC_ICLR - CC_BASE), %o0
368         sethi   %hi(1 << 15), %o1
369         stha    %o1, [%o0] ASI_M_MXCC   /* Clear PIL 15 in MXCC's ICLR */
370         or      %l0, PSR_PIL, %l4
371         wr      %l4, 0x0, %psr
372         WRITE_PAUSE
373         wr      %l4, PSR_ET, %psr
374         WRITE_PAUSE
375         call    smp4d_cross_call_irq
376          nop
377         b       ret_trap_lockless_ipi
378          clr    %l6
379
380 1:      /* MXCC error */
381 2:      /* BB error */
382         /* Disable PIL 15 */
383         set     CC_IMSK, %l4
384         lduha   [%l4] ASI_M_MXCC, %l5
385         sethi   %hi(1 << 15), %l7
386         or      %l5, %l7, %l5
387         stha    %l5, [%l4] ASI_M_MXCC
388         /* FIXME */
389 1:      b,a     1b
390
391 #ifdef CONFIG_SPARC_LEON
392         .globl  smpleon_ipi
393         .extern leon_ipi_interrupt
394         /* SMP per-cpu IPI interrupts are handled specially. */
395 smpleon_ipi:
396         SAVE_ALL
397         or      %l0, PSR_PIL, %g2
398         wr      %g2, 0x0, %psr
399         WRITE_PAUSE
400         wr      %g2, PSR_ET, %psr
401         WRITE_PAUSE
402         call    leonsmp_ipi_interrupt
403          add    %sp, STACKFRAME_SZ, %o1 ! pt_regs
404         wr      %l0, PSR_ET, %psr
405         WRITE_PAUSE
406         RESTORE_ALL
407
408         .align  4
409         .globl  linux_trap_ipi15_leon
410 linux_trap_ipi15_leon:
411         SAVE_ALL
412         or      %l0, PSR_PIL, %l4
413         wr      %l4, 0x0, %psr
414         WRITE_PAUSE
415         wr      %l4, PSR_ET, %psr
416         WRITE_PAUSE
417         call    leon_cross_call_irq
418          nop
419         b       ret_trap_lockless_ipi
420          clr    %l6
421
422 #endif /* CONFIG_SPARC_LEON */
423
424 #endif /* CONFIG_SMP */
425
426         /* This routine handles illegal instructions and privileged
427          * instruction attempts from user code.
428          */
429         .align  4
430         .globl  bad_instruction
431 bad_instruction:
432         sethi   %hi(0xc1f80000), %l4
433         ld      [%l1], %l5
434         sethi   %hi(0x81d80000), %l7
435         and     %l5, %l4, %l5
436         cmp     %l5, %l7
437         be      1f
438         SAVE_ALL
439
440         wr      %l0, PSR_ET, %psr               ! re-enable traps
441         WRITE_PAUSE
442
443         add     %sp, STACKFRAME_SZ, %o0
444         mov     %l1, %o1
445         mov     %l2, %o2
446         call    do_illegal_instruction
447          mov    %l0, %o3
448
449         RESTORE_ALL
450
451 1:      /* unimplemented flush - just skip */
452         jmpl    %l2, %g0
453          rett   %l2 + 4
454
455         .align  4
456         .globl  priv_instruction
457 priv_instruction:
458         SAVE_ALL
459
460         wr      %l0, PSR_ET, %psr
461         WRITE_PAUSE
462
463         add     %sp, STACKFRAME_SZ, %o0
464         mov     %l1, %o1
465         mov     %l2, %o2
466         call    do_priv_instruction
467          mov    %l0, %o3
468
469         RESTORE_ALL
470
471         /* This routine handles unaligned data accesses. */
472         .align  4
473         .globl  mna_handler
474 mna_handler:
475         andcc   %l0, PSR_PS, %g0
476         be      mna_fromuser
477          nop
478
479         SAVE_ALL
480
481         wr      %l0, PSR_ET, %psr
482         WRITE_PAUSE
483
484         ld      [%l1], %o1
485         call    kernel_unaligned_trap
486          add    %sp, STACKFRAME_SZ, %o0
487
488         RESTORE_ALL
489
490 mna_fromuser:
491         SAVE_ALL
492
493         wr      %l0, PSR_ET, %psr               ! re-enable traps
494         WRITE_PAUSE
495
496         ld      [%l1], %o1
497         call    user_unaligned_trap
498          add    %sp, STACKFRAME_SZ, %o0
499
500         RESTORE_ALL
501
502         /* This routine handles floating point disabled traps. */
503         .align  4
504         .globl  fpd_trap_handler
505 fpd_trap_handler:
506         SAVE_ALL
507
508         wr      %l0, PSR_ET, %psr               ! re-enable traps
509         WRITE_PAUSE
510
511         add     %sp, STACKFRAME_SZ, %o0
512         mov     %l1, %o1
513         mov     %l2, %o2
514         call    do_fpd_trap
515          mov    %l0, %o3
516
517         RESTORE_ALL
518
519         /* This routine handles Floating Point Exceptions. */
520         .align  4
521         .globl  fpe_trap_handler
522 fpe_trap_handler:
523         set     fpsave_magic, %l5
524         cmp     %l1, %l5
525         be      1f
526          sethi  %hi(fpsave), %l5
527         or      %l5, %lo(fpsave), %l5
528         cmp     %l1, %l5
529         bne     2f
530          sethi  %hi(fpsave_catch2), %l5
531         or      %l5, %lo(fpsave_catch2), %l5
532         wr      %l0, 0x0, %psr
533         WRITE_PAUSE
534         jmp     %l5
535          rett   %l5 + 4
536 1:      
537         sethi   %hi(fpsave_catch), %l5
538         or      %l5, %lo(fpsave_catch), %l5
539         wr      %l0, 0x0, %psr
540         WRITE_PAUSE
541         jmp     %l5
542          rett   %l5 + 4
543
544 2:
545         SAVE_ALL
546
547         wr      %l0, PSR_ET, %psr               ! re-enable traps
548         WRITE_PAUSE
549
550         add     %sp, STACKFRAME_SZ, %o0
551         mov     %l1, %o1
552         mov     %l2, %o2
553         call    do_fpe_trap
554          mov    %l0, %o3
555
556         RESTORE_ALL
557
558         /* This routine handles Tag Overflow Exceptions. */
559         .align  4
560         .globl  do_tag_overflow
561 do_tag_overflow:
562         SAVE_ALL
563
564         wr      %l0, PSR_ET, %psr               ! re-enable traps
565         WRITE_PAUSE
566
567         add     %sp, STACKFRAME_SZ, %o0
568         mov     %l1, %o1
569         mov     %l2, %o2
570         call    handle_tag_overflow
571          mov    %l0, %o3
572
573         RESTORE_ALL
574
575         /* This routine handles Watchpoint Exceptions. */
576         .align  4
577         .globl  do_watchpoint
578 do_watchpoint:
579         SAVE_ALL
580
581         wr      %l0, PSR_ET, %psr               ! re-enable traps
582         WRITE_PAUSE
583
584         add     %sp, STACKFRAME_SZ, %o0
585         mov     %l1, %o1
586         mov     %l2, %o2
587         call    handle_watchpoint
588          mov    %l0, %o3
589
590         RESTORE_ALL
591
592         /* This routine handles Register Access Exceptions. */
593         .align  4
594         .globl  do_reg_access
595 do_reg_access:
596         SAVE_ALL
597
598         wr      %l0, PSR_ET, %psr               ! re-enable traps
599         WRITE_PAUSE
600
601         add     %sp, STACKFRAME_SZ, %o0
602         mov     %l1, %o1
603         mov     %l2, %o2
604         call    handle_reg_access
605          mov    %l0, %o3
606
607         RESTORE_ALL
608
609         /* This routine handles Co-Processor Disabled Exceptions. */
610         .align  4
611         .globl  do_cp_disabled
612 do_cp_disabled:
613         SAVE_ALL
614
615         wr      %l0, PSR_ET, %psr               ! re-enable traps
616         WRITE_PAUSE
617
618         add     %sp, STACKFRAME_SZ, %o0
619         mov     %l1, %o1
620         mov     %l2, %o2
621         call    handle_cp_disabled
622          mov    %l0, %o3
623
624         RESTORE_ALL
625
626         /* This routine handles Co-Processor Exceptions. */
627         .align  4
628         .globl  do_cp_exception
629 do_cp_exception:
630         SAVE_ALL
631
632         wr      %l0, PSR_ET, %psr               ! re-enable traps
633         WRITE_PAUSE
634
635         add     %sp, STACKFRAME_SZ, %o0
636         mov     %l1, %o1
637         mov     %l2, %o2
638         call    handle_cp_exception
639          mov    %l0, %o3
640
641         RESTORE_ALL
642
643         /* This routine handles Hardware Divide By Zero Exceptions. */
644         .align  4
645         .globl  do_hw_divzero
646 do_hw_divzero:
647         SAVE_ALL
648
649         wr      %l0, PSR_ET, %psr               ! re-enable traps
650         WRITE_PAUSE
651
652         add     %sp, STACKFRAME_SZ, %o0
653         mov     %l1, %o1
654         mov     %l2, %o2
655         call    handle_hw_divzero
656          mov    %l0, %o3
657
658         RESTORE_ALL
659
660         .align  4
661         .globl  do_flush_windows
662 do_flush_windows:
663         SAVE_ALL
664
665         wr      %l0, PSR_ET, %psr
666         WRITE_PAUSE
667
668         andcc   %l0, PSR_PS, %g0
669         bne     dfw_kernel
670          nop
671
672         call    flush_user_windows
673          nop
674
675         /* Advance over the trap instruction. */
676         ld      [%sp + STACKFRAME_SZ + PT_NPC], %l1
677         add     %l1, 0x4, %l2
678         st      %l1, [%sp + STACKFRAME_SZ + PT_PC]
679         st      %l2, [%sp + STACKFRAME_SZ + PT_NPC]
680
681         RESTORE_ALL
682
683         .globl  flush_patch_one
684
685         /* We get these for debugging routines using __builtin_return_address() */
686 dfw_kernel:
687 flush_patch_one:
688         FLUSH_ALL_KERNEL_WINDOWS
689
690         /* Advance over the trap instruction. */
691         ld      [%sp + STACKFRAME_SZ + PT_NPC], %l1
692         add     %l1, 0x4, %l2
693         st      %l1, [%sp + STACKFRAME_SZ + PT_PC]
694         st      %l2, [%sp + STACKFRAME_SZ + PT_NPC]
695
696         RESTORE_ALL
697
698         /* The getcc software trap.  The user wants the condition codes from
699          * the %psr in register %g1.
700          */
701
702         .align  4
703         .globl  getcc_trap_handler
704 getcc_trap_handler:
705         srl     %l0, 20, %g1    ! give user
706         and     %g1, 0xf, %g1   ! only ICC bits in %psr
707         jmp     %l2             ! advance over trap instruction
708         rett    %l2 + 0x4       ! like this...
709
710         /* The setcc software trap.  The user has condition codes in %g1
711          * that it would like placed in the %psr.  Be careful not to flip
712          * any unintentional bits!
713          */
714
715         .align  4
716         .globl  setcc_trap_handler
717 setcc_trap_handler:
718         sll     %g1, 0x14, %l4
719         set     PSR_ICC, %l5
720         andn    %l0, %l5, %l0   ! clear ICC bits in %psr
721         and     %l4, %l5, %l4   ! clear non-ICC bits in user value
722         or      %l4, %l0, %l4   ! or them in... mix mix mix
723
724         wr      %l4, 0x0, %psr  ! set new %psr
725         WRITE_PAUSE             ! TI scumbags...
726
727         jmp     %l2             ! advance over trap instruction
728         rett    %l2 + 0x4       ! like this...
729
730 sun4m_nmi_error:
731         /* NMI async memory error handling. */
732         sethi   %hi(0x80000000), %l4
733         sethi   %hi(sun4m_irq_global), %o5
734         ld      [%o5 + %lo(sun4m_irq_global)], %l5
735         st      %l4, [%l5 + 0x0c]       ! sun4m_irq_global->mask_set=0x80000000
736         WRITE_PAUSE
737         ld      [%l5 + 0x00], %g0       ! sun4m_irq_global->pending
738         WRITE_PAUSE
739         or      %l0, PSR_PIL, %l4
740         wr      %l4, 0x0, %psr
741         WRITE_PAUSE
742         wr      %l4, PSR_ET, %psr
743         WRITE_PAUSE
744         call    sun4m_nmi
745          nop
746         st      %l4, [%l5 + 0x08]       ! sun4m_irq_global->mask_clear=0x80000000
747         WRITE_PAUSE
748         ld      [%l5 + 0x00], %g0       ! sun4m_irq_global->pending
749         WRITE_PAUSE
750         RESTORE_ALL
751
752 #ifndef CONFIG_SMP
753         .align  4
754         .globl  linux_trap_ipi15_sun4m
755 linux_trap_ipi15_sun4m:
756         SAVE_ALL
757
758         ba      sun4m_nmi_error
759          nop
760 #endif /* CONFIG_SMP */
761
762         .align  4
763         .globl  srmmu_fault
764 srmmu_fault:
765         mov     0x400, %l5
766         mov     0x300, %l4
767
768         lda     [%l5] ASI_M_MMUREGS, %l6        ! read sfar first
769         lda     [%l4] ASI_M_MMUREGS, %l5        ! read sfsr last
770
771         andn    %l6, 0xfff, %l6
772         srl     %l5, 6, %l5                     ! and encode all info into l7
773
774         and     %l5, 2, %l5
775         or      %l5, %l6, %l6
776
777         or      %l6, %l7, %l7                   ! l7 = [addr,write,txtfault]
778
779         SAVE_ALL
780
781         mov     %l7, %o1
782         mov     %l7, %o2
783         and     %o1, 1, %o1             ! arg2 = text_faultp
784         mov     %l7, %o3
785         and     %o2, 2, %o2             ! arg3 = writep
786         andn    %o3, 0xfff, %o3         ! arg4 = faulting address
787
788         wr      %l0, PSR_ET, %psr
789         WRITE_PAUSE
790
791         call    do_sparc_fault
792          add    %sp, STACKFRAME_SZ, %o0 ! arg1 = pt_regs ptr
793
794         RESTORE_ALL
795
796         .align  4
797         .globl  sys_nis_syscall
798 sys_nis_syscall:
799         mov     %o7, %l5
800         add     %sp, STACKFRAME_SZ, %o0         ! pt_regs *regs arg
801         call    c_sys_nis_syscall
802          mov    %l5, %o7
803
804         .align  4
805         .globl  sys_execve
806 sys_execve:
807         mov     %o7, %l5
808         add     %sp, STACKFRAME_SZ, %o0         ! pt_regs *regs arg
809         call    sparc_execve
810          mov    %l5, %o7
811
812         .globl  sunos_execv
813 sunos_execv:
814         st      %g0, [%sp + STACKFRAME_SZ + PT_I2]
815
816         call    sparc_execve
817          add    %sp, STACKFRAME_SZ, %o0
818
819         b       ret_sys_call
820          ld     [%sp + STACKFRAME_SZ + PT_I0], %o0
821
822         .align  4
823         .globl  sys_sparc_pipe
824 sys_sparc_pipe:
825         mov     %o7, %l5
826         add     %sp, STACKFRAME_SZ, %o0         ! pt_regs *regs arg
827         call    sparc_pipe
828          mov    %l5, %o7
829
830         .align  4
831         .globl  sys_sigaltstack
832 sys_sigaltstack:
833         mov     %o7, %l5
834         mov     %fp, %o2
835         call    do_sigaltstack
836          mov    %l5, %o7
837
838         .align  4
839         .globl  sys_sigstack
840 sys_sigstack:
841         mov     %o7, %l5
842         mov     %fp, %o2
843         call    do_sys_sigstack
844          mov    %l5, %o7
845
846         .align  4
847         .globl  sys_sigreturn
848 sys_sigreturn:
849         call    do_sigreturn
850          add    %sp, STACKFRAME_SZ, %o0
851
852         ld      [%curptr + TI_FLAGS], %l5
853         andcc   %l5, _TIF_SYSCALL_TRACE, %g0
854         be      1f
855          nop
856
857         call    syscall_trace
858          nop
859
860 1:
861         /* We don't want to muck with user registers like a
862          * normal syscall, just return.
863          */
864         RESTORE_ALL
865
866         .align  4
867         .globl  sys_rt_sigreturn
868 sys_rt_sigreturn:
869         call    do_rt_sigreturn
870          add    %sp, STACKFRAME_SZ, %o0
871
872         ld      [%curptr + TI_FLAGS], %l5
873         andcc   %l5, _TIF_SYSCALL_TRACE, %g0
874         be      1f
875          nop
876
877         add     %sp, STACKFRAME_SZ, %o0
878         call    syscall_trace
879          mov    1, %o1
880
881 1:
882         /* We are returning to a signal handler. */
883         RESTORE_ALL
884
885         /* Now that we have a real sys_clone, sys_fork() is
886          * implemented in terms of it.  Our _real_ implementation
887          * of SunOS vfork() will use sys_vfork().
888          *
889          * XXX These three should be consolidated into mostly shared
890          * XXX code just like on sparc64... -DaveM
891          */
892         .align  4
893         .globl  sys_fork, flush_patch_two
894 sys_fork:
895         mov     %o7, %l5
896 flush_patch_two:
897         FLUSH_ALL_KERNEL_WINDOWS;
898         ld      [%curptr + TI_TASK], %o4
899         rd      %psr, %g4
900         WRITE_PAUSE
901         mov     SIGCHLD, %o0                    ! arg0: clone flags
902         rd      %wim, %g5
903         WRITE_PAUSE
904         mov     %fp, %o1                        ! arg1: usp
905         std     %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
906         add     %sp, STACKFRAME_SZ, %o2         ! arg2: pt_regs ptr
907         mov     0, %o3
908         call    sparc_do_fork
909          mov    %l5, %o7
910
911         /* Whee, kernel threads! */
912         .globl  sys_clone, flush_patch_three
913 sys_clone:
914         mov     %o7, %l5
915 flush_patch_three:
916         FLUSH_ALL_KERNEL_WINDOWS;
917         ld      [%curptr + TI_TASK], %o4
918         rd      %psr, %g4
919         WRITE_PAUSE
920
921         /* arg0,1: flags,usp  -- loaded already */
922         cmp     %o1, 0x0                        ! Is new_usp NULL?
923         rd      %wim, %g5
924         WRITE_PAUSE
925         be,a    1f
926          mov    %fp, %o1                        ! yes, use callers usp
927         andn    %o1, 7, %o1                     ! no, align to 8 bytes
928 1:
929         std     %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
930         add     %sp, STACKFRAME_SZ, %o2         ! arg2: pt_regs ptr
931         mov     0, %o3
932         call    sparc_do_fork
933          mov    %l5, %o7
934
935         /* Whee, real vfork! */
936         .globl  sys_vfork, flush_patch_four
937 sys_vfork:
938 flush_patch_four:
939         FLUSH_ALL_KERNEL_WINDOWS;
940         ld      [%curptr + TI_TASK], %o4
941         rd      %psr, %g4
942         WRITE_PAUSE
943         rd      %wim, %g5
944         WRITE_PAUSE
945         std     %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
946         sethi   %hi(0x4000 | 0x0100 | SIGCHLD), %o0
947         mov     %fp, %o1
948         or      %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0
949         sethi   %hi(sparc_do_fork), %l1
950         mov     0, %o3
951         jmpl    %l1 + %lo(sparc_do_fork), %g0
952          add    %sp, STACKFRAME_SZ, %o2
953
954         .align  4
955 linux_sparc_ni_syscall:
956         sethi   %hi(sys_ni_syscall), %l7
957         b       syscall_is_too_hard
958          or     %l7, %lo(sys_ni_syscall), %l7
959
960 linux_fast_syscall:
961         andn    %l7, 3, %l7
962         mov     %i0, %o0
963         mov     %i1, %o1
964         mov     %i2, %o2
965         jmpl    %l7 + %g0, %g0
966          mov    %i3, %o3
967
968 linux_syscall_trace:
969         add     %sp, STACKFRAME_SZ, %o0
970         call    syscall_trace
971          mov    0, %o1
972         cmp     %o0, 0
973         bne     3f
974          mov    -ENOSYS, %o0
975         mov     %i0, %o0
976         mov     %i1, %o1
977         mov     %i2, %o2
978         mov     %i3, %o3
979         b       2f
980          mov    %i4, %o4
981
982         .globl  ret_from_fork
983 ret_from_fork:
984         call    schedule_tail
985          ld     [%g3 + TI_TASK], %o0
986         b       ret_sys_call
987          ld     [%sp + STACKFRAME_SZ + PT_I0], %o0
988
989         /* Linux native system calls enter here... */
990         .align  4
991         .globl  linux_sparc_syscall
992 linux_sparc_syscall:
993         sethi   %hi(PSR_SYSCALL), %l4
994         or      %l0, %l4, %l0
995         /* Direct access to user regs, must faster. */
996         cmp     %g1, NR_syscalls
997         bgeu    linux_sparc_ni_syscall
998          sll    %g1, 2, %l4
999         ld      [%l7 + %l4], %l7
1000         andcc   %l7, 1, %g0
1001         bne     linux_fast_syscall
1002          /* Just do first insn from SAVE_ALL in the delay slot */
1003
1004 syscall_is_too_hard:
1005         SAVE_ALL_HEAD
1006          rd     %wim, %l3
1007
1008         wr      %l0, PSR_ET, %psr
1009         mov     %i0, %o0
1010         mov     %i1, %o1
1011         mov     %i2, %o2
1012
1013         ld      [%curptr + TI_FLAGS], %l5
1014         mov     %i3, %o3
1015         andcc   %l5, _TIF_SYSCALL_TRACE, %g0
1016         mov     %i4, %o4
1017         bne     linux_syscall_trace
1018          mov    %i0, %l5
1019 2:
1020         call    %l7
1021          mov    %i5, %o5
1022
1023 3:
1024         st      %o0, [%sp + STACKFRAME_SZ + PT_I0]
1025
1026 ret_sys_call:
1027         ld      [%curptr + TI_FLAGS], %l6
1028         cmp     %o0, -ERESTART_RESTARTBLOCK
1029         ld      [%sp + STACKFRAME_SZ + PT_PSR], %g3
1030         set     PSR_C, %g2
1031         bgeu    1f
1032          andcc  %l6, _TIF_SYSCALL_TRACE, %g0
1033
1034         /* System call success, clear Carry condition code. */
1035         andn    %g3, %g2, %g3
1036         clr     %l6
1037         st      %g3, [%sp + STACKFRAME_SZ + PT_PSR]     
1038         bne     linux_syscall_trace2
1039          ld     [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */
1040         add     %l1, 0x4, %l2                   /* npc = npc+4 */
1041         st      %l1, [%sp + STACKFRAME_SZ + PT_PC]
1042         b       ret_trap_entry
1043          st     %l2, [%sp + STACKFRAME_SZ + PT_NPC]
1044 1:
1045         /* System call failure, set Carry condition code.
1046          * Also, get abs(errno) to return to the process.
1047          */
1048         sub     %g0, %o0, %o0
1049         or      %g3, %g2, %g3
1050         st      %o0, [%sp + STACKFRAME_SZ + PT_I0]
1051         mov     1, %l6
1052         st      %g3, [%sp + STACKFRAME_SZ + PT_PSR]
1053         bne     linux_syscall_trace2
1054          ld     [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */
1055         add     %l1, 0x4, %l2                   /* npc = npc+4 */
1056         st      %l1, [%sp + STACKFRAME_SZ + PT_PC]
1057         b       ret_trap_entry
1058          st     %l2, [%sp + STACKFRAME_SZ + PT_NPC]
1059
1060 linux_syscall_trace2:
1061         add     %sp, STACKFRAME_SZ, %o0
1062         mov     1, %o1
1063         call    syscall_trace
1064          add    %l1, 0x4, %l2                   /* npc = npc+4 */
1065         st      %l1, [%sp + STACKFRAME_SZ + PT_PC]
1066         b       ret_trap_entry
1067          st     %l2, [%sp + STACKFRAME_SZ + PT_NPC]
1068
1069
1070 /* Saving and restoring the FPU state is best done from lowlevel code.
1071  *
1072  * void fpsave(unsigned long *fpregs, unsigned long *fsr,
1073  *             void *fpqueue, unsigned long *fpqdepth)
1074  */
1075
1076         .globl  fpsave
1077 fpsave:
1078         st      %fsr, [%o1]     ! this can trap on us if fpu is in bogon state
1079         ld      [%o1], %g1
1080         set     0x2000, %g4
1081         andcc   %g1, %g4, %g0
1082         be      2f
1083          mov    0, %g2
1084
1085         /* We have an fpqueue to save. */
1086 1:
1087         std     %fq, [%o2]
1088 fpsave_magic:
1089         st      %fsr, [%o1]
1090         ld      [%o1], %g3
1091         andcc   %g3, %g4, %g0
1092         add     %g2, 1, %g2
1093         bne     1b
1094          add    %o2, 8, %o2
1095
1096 2:
1097         st      %g2, [%o3]
1098
1099         std     %f0, [%o0 + 0x00]
1100         std     %f2, [%o0 + 0x08]
1101         std     %f4, [%o0 + 0x10]
1102         std     %f6, [%o0 + 0x18]
1103         std     %f8, [%o0 + 0x20]
1104         std     %f10, [%o0 + 0x28]
1105         std     %f12, [%o0 + 0x30]
1106         std     %f14, [%o0 + 0x38]
1107         std     %f16, [%o0 + 0x40]
1108         std     %f18, [%o0 + 0x48]
1109         std     %f20, [%o0 + 0x50]
1110         std     %f22, [%o0 + 0x58]
1111         std     %f24, [%o0 + 0x60]
1112         std     %f26, [%o0 + 0x68]
1113         std     %f28, [%o0 + 0x70]
1114         retl
1115          std    %f30, [%o0 + 0x78]
1116
1117         /* Thanks for Theo Deraadt and the authors of the Sprite/netbsd/openbsd
1118          * code for pointing out this possible deadlock, while we save state
1119          * above we could trap on the fsr store so our low level fpu trap
1120          * code has to know how to deal with this.
1121          */
1122 fpsave_catch:
1123         b       fpsave_magic + 4
1124          st     %fsr, [%o1]
1125
1126 fpsave_catch2:
1127         b       fpsave + 4
1128          st     %fsr, [%o1]
1129
1130         /* void fpload(unsigned long *fpregs, unsigned long *fsr); */
1131
1132         .globl  fpload
1133 fpload:
1134         ldd     [%o0 + 0x00], %f0
1135         ldd     [%o0 + 0x08], %f2
1136         ldd     [%o0 + 0x10], %f4
1137         ldd     [%o0 + 0x18], %f6
1138         ldd     [%o0 + 0x20], %f8
1139         ldd     [%o0 + 0x28], %f10
1140         ldd     [%o0 + 0x30], %f12
1141         ldd     [%o0 + 0x38], %f14
1142         ldd     [%o0 + 0x40], %f16
1143         ldd     [%o0 + 0x48], %f18
1144         ldd     [%o0 + 0x50], %f20
1145         ldd     [%o0 + 0x58], %f22
1146         ldd     [%o0 + 0x60], %f24
1147         ldd     [%o0 + 0x68], %f26
1148         ldd     [%o0 + 0x70], %f28
1149         ldd     [%o0 + 0x78], %f30
1150         ld      [%o1], %fsr
1151         retl
1152          nop
1153
1154         /* __ndelay and __udelay take two arguments:
1155          * 0 - nsecs or usecs to delay
1156          * 1 - per_cpu udelay_val (loops per jiffy)
1157          *
1158          * Note that ndelay gives HZ times higher resolution but has a 10ms
1159          * limit.  udelay can handle up to 1s.
1160          */
1161         .globl  __ndelay
1162 __ndelay:
1163         save    %sp, -STACKFRAME_SZ, %sp
1164         mov     %i0, %o0                ! round multiplier up so large ns ok
1165         mov     0x1ae, %o1              ! 2**32 / (1 000 000 000 / HZ)
1166         umul    %o0, %o1, %o0
1167         rd      %y, %o1
1168         mov     %i1, %o1                ! udelay_val
1169         umul    %o0, %o1, %o0
1170         rd      %y, %o1
1171         ba      delay_continue
1172          mov    %o1, %o0                ! >>32 later for better resolution
1173
1174         .globl  __udelay
1175 __udelay:
1176         save    %sp, -STACKFRAME_SZ, %sp
1177         mov     %i0, %o0
1178         sethi   %hi(0x10c7), %o1        ! round multiplier up so large us ok
1179         or      %o1, %lo(0x10c7), %o1   ! 2**32 / 1 000 000
1180         umul    %o0, %o1, %o0
1181         rd      %y, %o1
1182         mov     %i1, %o1                ! udelay_val
1183         umul    %o0, %o1, %o0
1184         rd      %y, %o1
1185         sethi   %hi(0x028f4b62), %l0    ! Add in rounding constant * 2**32,
1186         or      %g0, %lo(0x028f4b62), %l0
1187         addcc   %o0, %l0, %o0           ! 2**32 * 0.009 999
1188         bcs,a   3f
1189          add    %o1, 0x01, %o1
1190 3:
1191         mov     HZ, %o0                 ! >>32 earlier for wider range
1192         umul    %o0, %o1, %o0
1193         rd      %y, %o1
1194
1195 delay_continue:
1196         cmp     %o0, 0x0
1197 1:
1198         bne     1b
1199          subcc  %o0, 1, %o0
1200         
1201         ret
1202         restore
1203
1204         /* Handle a software breakpoint */
1205         /* We have to inform parent that child has stopped */
1206         .align 4
1207         .globl breakpoint_trap
1208 breakpoint_trap:
1209         rd      %wim,%l3
1210         SAVE_ALL
1211         wr      %l0, PSR_ET, %psr
1212         WRITE_PAUSE
1213
1214         st      %i0, [%sp + STACKFRAME_SZ + PT_G0] ! for restarting syscalls
1215         call    sparc_breakpoint
1216          add    %sp, STACKFRAME_SZ, %o0
1217
1218         RESTORE_ALL
1219
1220 #ifdef CONFIG_KGDB
1221         .align  4
1222         .globl  kgdb_trap_low
1223         .type   kgdb_trap_low,#function
1224 kgdb_trap_low:
1225         rd      %wim,%l3
1226         SAVE_ALL
1227         wr      %l0, PSR_ET, %psr
1228         WRITE_PAUSE
1229
1230         call    kgdb_trap
1231          add    %sp, STACKFRAME_SZ, %o0
1232
1233         RESTORE_ALL
1234         .size   kgdb_trap_low,.-kgdb_trap_low
1235 #endif
1236
1237         .align  4
1238         .globl  flush_patch_exception
1239 flush_patch_exception:
1240         FLUSH_ALL_KERNEL_WINDOWS;
1241         ldd     [%o0], %o6
1242         jmpl    %o7 + 0xc, %g0                  ! see asm-sparc/processor.h
1243          mov    1, %g1                          ! signal EFAULT condition
1244
1245         .align  4
1246         .globl  kill_user_windows, kuw_patch1_7win
1247         .globl  kuw_patch1
1248 kuw_patch1_7win:        sll     %o3, 6, %o3
1249
1250         /* No matter how much overhead this routine has in the worst
1251          * case scenerio, it is several times better than taking the
1252          * traps with the old method of just doing flush_user_windows().
1253          */
1254 kill_user_windows:
1255         ld      [%g6 + TI_UWINMASK], %o0        ! get current umask
1256         orcc    %g0, %o0, %g0                   ! if no bits set, we are done
1257         be      3f                              ! nothing to do
1258          rd     %psr, %o5                       ! must clear interrupts
1259         or      %o5, PSR_PIL, %o4               ! or else that could change
1260         wr      %o4, 0x0, %psr                  ! the uwinmask state
1261         WRITE_PAUSE                             ! burn them cycles
1262 1:
1263         ld      [%g6 + TI_UWINMASK], %o0        ! get consistent state
1264         orcc    %g0, %o0, %g0                   ! did an interrupt come in?
1265         be      4f                              ! yep, we are done
1266          rd     %wim, %o3                       ! get current wim
1267         srl     %o3, 1, %o4                     ! simulate a save
1268 kuw_patch1:
1269         sll     %o3, 7, %o3                     ! compute next wim
1270         or      %o4, %o3, %o3                   ! result
1271         andncc  %o0, %o3, %o0                   ! clean this bit in umask
1272         bne     kuw_patch1                      ! not done yet
1273          srl    %o3, 1, %o4                     ! begin another save simulation
1274         wr      %o3, 0x0, %wim                  ! set the new wim
1275         st      %g0, [%g6 + TI_UWINMASK]        ! clear uwinmask
1276 4:
1277         wr      %o5, 0x0, %psr                  ! re-enable interrupts
1278         WRITE_PAUSE                             ! burn baby burn
1279 3:
1280         retl                                    ! return
1281          st     %g0, [%g6 + TI_W_SAVED]         ! no windows saved
1282
1283         .align  4
1284         .globl  restore_current
1285 restore_current:
1286         LOAD_CURRENT(g6, o0)
1287         retl
1288          nop
1289
1290 #ifdef CONFIG_PCIC_PCI
1291 #include <asm/pcic.h>
1292
1293         .align  4
1294         .globl  linux_trap_ipi15_pcic
1295 linux_trap_ipi15_pcic:
1296         rd      %wim, %l3
1297         SAVE_ALL
1298
1299         /*
1300          * First deactivate NMI
1301          * or we cannot drop ET, cannot get window spill traps.
1302          * The busy loop is necessary because the PIO error
1303          * sometimes does not go away quickly and we trap again.
1304          */
1305         sethi   %hi(pcic_regs), %o1
1306         ld      [%o1 + %lo(pcic_regs)], %o2
1307
1308         ! Get pending status for printouts later.
1309         ld      [%o2 + PCI_SYS_INT_PENDING], %o0
1310
1311         mov     PCI_SYS_INT_PENDING_CLEAR_ALL, %o1
1312         stb     %o1, [%o2 + PCI_SYS_INT_PENDING_CLEAR]
1313 1:
1314         ld      [%o2 + PCI_SYS_INT_PENDING], %o1
1315         andcc   %o1, ((PCI_SYS_INT_PENDING_PIO|PCI_SYS_INT_PENDING_PCI)>>24), %g0
1316         bne     1b
1317          nop
1318
1319         or      %l0, PSR_PIL, %l4
1320         wr      %l4, 0x0, %psr
1321         WRITE_PAUSE
1322         wr      %l4, PSR_ET, %psr
1323         WRITE_PAUSE
1324
1325         call    pcic_nmi
1326          add    %sp, STACKFRAME_SZ, %o1 ! struct pt_regs *regs
1327         RESTORE_ALL
1328
1329         .globl  pcic_nmi_trap_patch
1330 pcic_nmi_trap_patch:
1331         sethi   %hi(linux_trap_ipi15_pcic), %l3
1332         jmpl    %l3 + %lo(linux_trap_ipi15_pcic), %g0
1333          rd     %psr, %l0
1334         .word   0
1335
1336 #endif /* CONFIG_PCIC_PCI */
1337
1338         .globl  flushw_all
1339 flushw_all:
1340         save    %sp, -0x40, %sp
1341         save    %sp, -0x40, %sp
1342         save    %sp, -0x40, %sp
1343         save    %sp, -0x40, %sp
1344         save    %sp, -0x40, %sp
1345         save    %sp, -0x40, %sp
1346         save    %sp, -0x40, %sp
1347         restore
1348         restore
1349         restore
1350         restore
1351         restore
1352         restore
1353         ret
1354          restore
1355
1356 #ifdef CONFIG_SMP
1357 ENTRY(hard_smp_processor_id)
1358 661:    rd              %tbr, %g1
1359         srl             %g1, 12, %o0
1360         and             %o0, 3, %o0
1361         .section        .cpuid_patch, "ax"
1362         /* Instruction location. */
1363         .word           661b
1364         /* SUN4D implementation. */
1365         lda             [%g0] ASI_M_VIKING_TMP1, %o0
1366         nop
1367         nop
1368         /* LEON implementation. */
1369         rd              %asr17, %o0
1370         srl             %o0, 0x1c, %o0
1371         nop
1372         .previous
1373         retl
1374          nop
1375 ENDPROC(hard_smp_processor_id)
1376 #endif
1377
1378 /* End of entry.S */