1
2
3
4
5
6
7 #include <linux/config.h>
8 #include <linux/errno.h>
9
10 #include <asm/head.h>
11 #include <asm/asi.h>
12 #include <asm/smp.h>
13 #include <asm/kgdb.h>
14 #include <asm/contregs.h>
15 #include <asm/ptrace.h>
16 #include <asm/psr.h>
17 #include <asm/cprefix.h>
18 #include <asm/vaddrs.h>
19 #include <asm/memreg.h>
20 #include <asm/page.h>
21 #include <asm/winmacro.h>
22 #include <asm/signal.h>
23
24 #include <asm/asmmacro.h>
25
26 #define NR_SYSCALLS 255
27
28
29
30
31
32
33 .data
34 .align 4
35
36 in_trap_handler:
37 .word 0
38
39 .text
40 .align 4
41
42 ! This function is called when any SPARC trap (except window overflow or
43 ! underflow) occurs. It makes sure that the invalid register window is still
44 ! available before jumping into C code. It will also restore the world if you
45 ! return from handle_exception.
46
47 .globl C_LABEL(trap_low)
48 C_LABEL(trap_low):
49 rd %wim, %l3
50 SAVE_ALL
51 ENTER_SYSCALL
52
53 sethi %hi(in_trap_handler), %l4
54 ld [%lo(in_trap_handler) + %l4], %l5
55 inc %l5
56 st %l5, [%lo(in_trap_handler) + %l4]
57
58
59 LOAD_PT_GLOBALS(sp)
60 LOAD_PT_INS(sp)
61 ld [%sp + REGWIN_SZ + PT_Y], %l4
62 ld [%sp + REGWIN_SZ + PT_WIM], %l3
63 ld [%sp + REGWIN_SZ + PT_PSR], %l0
64 ld [%sp + REGWIN_SZ + PT_PC], %l1
65 ld [%sp + REGWIN_SZ + PT_NPC], %l2
66 rd %tbr, %l5
67
68
69 sub %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals
70 ! + hidden arg + arg spill
71 ! + doubleword alignment
72 ! + registers[72] local var
73 SAVE_KGDB_GLOBALS(sp)
74 SAVE_KGDB_INS(sp)
75 SAVE_KGDB_SREGS(sp, l4, l0, l3, l5, l1, l2)
76
77
78 or %l0, PSR_PIL, %l0
79 wr %l0, 0, %psr
80 wr %l0, PSR_ET, %psr
81 WRITE_PAUSE
82
83 call C_LABEL(handle_exception)
84 add %sp, REGWIN_SZ, %o0 ! Pass address of registers
85
86
87 LOAD_KGDB_GLOBALS(sp)
88 LOAD_KGDB_INS(sp)
89 LOAD_KGDB_SREGS(sp, l0, l2)
90 wr %l0, 0x0, %y
91
92 sethi %hi(in_trap_handler), %l4
93 ld [%lo(in_trap_handler) + %l4], %l5
94 dec %l5
95 st %l5, [%lo(in_trap_handler) + %l4]
96
97 add %sp,(16+1+6+1+72)*4,%sp ! Undo the kgdb trap frame.
98
99
100
101
102 STORE_PT_INS(sp)
103 STORE_PT_GLOBALS(sp)
104 STORE_PT_YREG(sp, g2)
105 STORE_PT_PRIV(sp, l1, l2, l3)
106
107 RESTORE_ALL
108
109
110 #ifdef CONFIG_BLK_DEV_FD
111 #ifdef TRACE_FLOPPY_HARDINT
112
113 .data
114 .align 4
115 .globl C_LABEL(floppy_hardint_trace)
116 C_LABEL(floppy_hardint_trace):
117 .skip 32
118 .globl C_LABEL(floppy_hardint_index)
119 C_LABEL(floppy_hardint_index):
120 .word 0
121 #endif
122
123 .text
124 .align 4
125 .globl C_LABEL(floppy_hardint)
126 C_LABEL(floppy_hardint):
127
128
129
130
131
132
133
134
135 #ifdef TRACE_FLOPPY_HARDINT
136 sethi %hi(C_LABEL(floppy_hardint_trace)), %l5
137 or %l5, %lo(C_LABEL(floppy_hardint_trace)), %l5
138 ld [%l5 + 32], %l7
139 add %l7, 1, %l7
140 and %l7, 31, %l7
141 st %l7, [%l5 + 32]
142 sub %l7, 1, %l7
143 and %l7, 31, %l7
144 add %l7, %l5, %l5
145 or %g0, 0xf, %l7
146 stb %l7, [%l5]
147 #endif
148
149
150 sethi %hi(C_LABEL(doing_pdma)), %l4
151 ld [%l4 + %lo(C_LABEL(doing_pdma))], %l4
152 cmp %l4, 0
153 be floppy_dosoftint
154 nop
155
156
157 sethi %hi(C_LABEL(fdc_status)), %l3
158 ld [%l3 + %lo(C_LABEL(fdc_status))], %l3
159
160
161 sethi %hi(C_LABEL(pdma_vaddr)), %l5 ! transfer buffer
162 ld [%l5 + %lo(C_LABEL(pdma_vaddr))], %l4
163 sethi %hi(C_LABEL(pdma_size)), %l5 ! bytes to go
164 ld [%l5 + %lo(C_LABEL(pdma_size))], %l6
165 next_byte:
166 #ifdef TRACE_FLOPPY_HARDINT
167 sethi %hi(C_LABEL(floppy_hardint_trace)), %l5
168 or %l5, %lo(C_LABEL(floppy_hardint_trace)), %l5
169 ld [%l5 + 32], %l7
170 add %l7, 1, %l7
171 and %l7, 31, %l7
172 st %l7, [%l5 + 32]
173 sub %l7, 1, %l7
174 and %l7, 31, %l7
175 add %l7, %l5, %l5
176 ldub [%l3], %l7
177 stb %l7, [%l5]
178 #else
179 ldub [%l3], %l7
180 #endif
181
182 andcc %l7, 0x80, %g0 ! Does fifo still have data
183 bz floppy_fifo_emptied ! fifo has been emptied...
184 andcc %l7, 0x20, %g0 ! in non-dma mode still?
185 bz floppy_overrun ! nope, overrun
186 andcc %l7, 0x40, %g0 ! 0=write 1=read
187 bz floppy_write
188 sub %l6, 0x1, %l6
189
190
191 ldub [%l3 + 1], %l7
192 orcc %g0, %l6, %g0
193 stb %l7, [%l4]
194 bne next_byte
195 add %l4, 0x1, %l4
196
197 b floppy_tdone
198 nop
199
200 floppy_write:
201
202 ldub [%l4], %l7
203 orcc %g0, %l6, %g0
204 stb %l7, [%l3 + 1]
205 bne next_byte
206 add %l4, 0x1, %l4
207
208
209 floppy_tdone:
210 sethi %hi(C_LABEL(pdma_vaddr)), %l5
211 st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
212 sethi %hi(C_LABEL(pdma_size)), %l5
213 st %l6, [%l5 + %lo(C_LABEL(pdma_size))]
214
215 set C_LABEL(auxio_register), %l4
216 ld [%l4], %l4
217
218 set C_LABEL(sparc_cpu_model), %l5
219 ld [%l5], %l5
220 subcc %l5, 1, %g0
221 be 1f
222 ldub [%l4], %l5
223
224 or %l5, 0xc2, %l5
225 stb %l5, [%l4]
226 andn %l5, 0x02, %l5
227 b 2f
228 nop
229
230 1:
231 or %l5, 0xf4, %l5
232 stb %l5, [%l4]
233 andn %l5, 0x04, %l5
234
235 2:
236
237 WRITE_PAUSE
238 WRITE_PAUSE
239
240 stb %l5, [%l4]
241
242
243 sethi %hi(C_LABEL(doing_pdma)), %l4
244 b floppy_dosoftint
245 st %g0, [%l4 + %lo(C_LABEL(doing_pdma))]
246
247
248
249
250
251
252 floppy_fifo_emptied:
253 sethi %hi(C_LABEL(pdma_vaddr)), %l5
254 st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
255 sethi %hi(C_LABEL(pdma_size)), %l7
256 st %l6, [%l7 + %lo(C_LABEL(pdma_size))]
257
258
259 wr %l0, 0x0, %psr
260 WRITE_PAUSE
261
262 jmp %l1
263 rett %l2
264
265 floppy_overrun:
266 sethi %hi(C_LABEL(pdma_vaddr)), %l5
267 st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
268 sethi %hi(C_LABEL(pdma_size)), %l5
269 st %l6, [%l5 + %lo(C_LABEL(pdma_size))]
270
271 sethi %hi(C_LABEL(doing_pdma)), %l4
272 st %g0, [%l4 + %lo(C_LABEL(doing_pdma))]
273
274
275 floppy_dosoftint:
276 rd %wim, %l3
277 SAVE_ALL
278 ENTER_IRQ
279
280
281 or %l0, PSR_PIL, %l4
282 wr %l4, 0x0, %psr
283 wr %l4, PSR_ET, %psr
284 WRITE_PAUSE
285
286 mov 11, %o0 ! floppy irq level
287 call C_LABEL(floppy_interrupt)
288 add %sp, REGWIN_SZ, %o1 ! struct pt_regs *regs
289
290 LEAVE_IRQ
291 RESTORE_ALL
292
293 #endif
294
295
296 .globl bad_trap_handler
297 bad_trap_handler:
298 SAVE_ALL
299 ENTER_SYSCALL
300
301 wr %l0, PSR_ET, %psr
302 WRITE_PAUSE
303
304 mov %l7, %o0 ! trap number
305 mov %l0, %o1 ! psr
306 call C_LABEL(do_hw_interrupt)
307 mov %l1, %o2 ! pc
308
309 RESTORE_ALL
310
311
312
313
314
315
316 .align 4
317 .globl real_irq_entry
318 real_irq_entry:
319 SAVE_ALL
320 #ifdef __SMP__
321 cmp %l7, 9
322 bne 1f
323 nop
324
325 GET_PROCESSOR_MID(l4, l5)
326 set C_LABEL(sun4m_interrupts), %l5
327 ld [%l5], %l5
328 sethi %hi(0x02000000), %l6
329 sll %l4, 12, %l4
330 add %l5, %l4, %l5
331 ld [%l5], %l4
332 andcc %l4, %l6, %g0
333 be 1f
334 nop
335
336 b linux_trap_ipi9_sun4m
337 nop
338
339 1:
340 #endif
341 ENTER_IRQ
342
343 #ifdef __SMP__
344 cmp %l7, 13
345 bne 1f
346 nop
347
348
349 GET_PROCESSOR_MID(o3, o2)
350 set C_LABEL(sun4m_interrupts), %l5
351 ld [%l5], %o5
352 sethi %hi(0x20000000), %o4
353 sll %o3, 12, %o3
354 add %o5, %o3, %o5
355 ld [%o5], %o1 ! read processor irq pending reg
356 andcc %o1, %o4, %g0
357 be 1f
358 nop
359
360 b linux_trap_ipi13_sun4m
361 nop
362
363 1:
364
365 #endif
366
367
368 sethi %hi(C_LABEL(intr_count)), %l4
369 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
370 add %l5, 0x1, %l5
371 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
372
373
374
375
376
377 or %l0, PSR_PIL, %l4
378
379 wr %l4, 0x0, %psr
380 WRITE_PAUSE
381 wr %l4, PSR_ET, %psr
382 WRITE_PAUSE
383
384 mov %l7, %o0 ! irq level
385 call C_LABEL(handler_irq)
386 add %sp, REGWIN_SZ, %o1 ! pt_regs ptr
387
388 rie_checkbh:
389 sethi %hi(C_LABEL(intr_count)), %l4
390 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
391 subcc %l5, 0x1, %l5
392 bne 2f
393 nop
394
395 sethi %hi(C_LABEL(bh_active)), %l3
396 ld [%l3 + %lo(C_LABEL(bh_active))], %g2
397 sethi %hi(C_LABEL(bh_mask)), %l3
398 ld [%l3 + %lo(C_LABEL(bh_mask))], %g3
399 andcc %g2, %g3, %g0
400 be 2f
401 nop
402
403 call C_LABEL(do_bottom_half)
404 nop
405
406
407 b rie_checkbh
408 nop
409
410 2:
411 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
412
413 LEAVE_IRQ
414 RESTORE_ALL
415
416
417
418
419 .align 4
420 .globl bad_instruction
421 bad_instruction:
422 SAVE_ALL
423 ENTER_SYSCALL
424
425 wr %l0, PSR_ET, %psr ! re-enable traps
426 WRITE_PAUSE
427
428 add %sp, REGWIN_SZ, %o0
429 mov %l1, %o1
430 mov %l2, %o2
431 call C_LABEL(do_illegal_instruction)
432 mov %l0, %o3
433
434 RESTORE_ALL
435
436 .align 4
437 .globl priv_instruction
438 priv_instruction:
439 SAVE_ALL
440 ENTER_SYSCALL
441
442 wr %l0, PSR_ET, %psr
443 WRITE_PAUSE
444
445 add %sp, REGWIN_SZ, %o0
446 mov %l1, %o1
447 mov %l2, %o2
448 call C_LABEL(do_priv_instruction)
449 mov %l0, %o3
450
451 RESTORE_ALL
452
453
454
455 .align 4
456 .globl mna_handler
457 mna_handler:
458 SAVE_ALL
459 ENTER_SYSCALL
460
461 wr %l0, PSR_ET, %psr ! re-enable traps
462 WRITE_PAUSE
463
464 add %sp, REGWIN_SZ, %o0
465 mov %l1, %o1
466 mov %l2, %o2
467 call C_LABEL(do_memaccess_unaligned)
468 mov %l0, %o3
469
470 RESTORE_ALL
471
472
473 .align 4
474 .globl fpd_trap_handler
475 fpd_trap_handler:
476 SAVE_ALL
477 ENTER_SYSCALL
478
479 wr %l0, PSR_ET, %psr ! re-enable traps
480 WRITE_PAUSE
481
482 add %sp, REGWIN_SZ, %o0
483 mov %l1, %o1
484 mov %l2, %o2
485 call C_LABEL(do_fpd_trap)
486 mov %l0, %o3
487
488 RESTORE_ALL
489
490
491 .align 4
492 .globl fpe_trap_handler
493 fpe_trap_handler:
494 set fpsave_magic, %l5
495 cmp %l1, %l5
496 be 1f
497 sethi %hi(C_LABEL(fpsave)), %l5
498 or %l5, %lo(C_LABEL(fpsave)), %l5
499 cmp %l1, %l5
500 bne 2f
501 sethi %hi(fpsave_catch2), %l5
502 or %l5, %lo(fpsave_catch2), %l5
503 wr %l0, 0x0, %psr
504 WRITE_PAUSE
505 jmp %l5
506 rett %l5 + 4
507 1:
508 sethi %hi(fpsave_catch), %l5
509 or %l5, %lo(fpsave_catch), %l5
510 wr %l0, 0x0, %psr
511 WRITE_PAUSE
512 jmp %l5
513 rett %l5 + 4
514
515 2:
516 SAVE_ALL
517 ENTER_SYSCALL
518
519 wr %l0, PSR_ET, %psr ! re-enable traps
520 WRITE_PAUSE
521
522 add %sp, REGWIN_SZ, %o0
523 mov %l1, %o1
524 mov %l2, %o2
525 call C_LABEL(do_fpe_trap)
526 mov %l0, %o3
527
528 RESTORE_ALL
529
530
531 .align 4
532 .globl do_tag_overflow
533 do_tag_overflow:
534 SAVE_ALL
535 ENTER_SYSCALL
536
537 wr %l0, PSR_ET, %psr ! re-enable traps
538 WRITE_PAUSE
539
540 add %sp, REGWIN_SZ, %o0
541 mov %l1, %o1
542 mov %l2, %o2
543 call C_LABEL(handle_tag_overflow)
544 mov %l0, %o3
545
546 RESTORE_ALL
547
548
549 .align 4
550 .globl do_watchpoint
551 do_watchpoint:
552 SAVE_ALL
553 ENTER_SYSCALL
554
555 wr %l0, PSR_ET, %psr ! re-enable traps
556 WRITE_PAUSE
557
558 add %sp, REGWIN_SZ, %o0
559 mov %l1, %o1
560 mov %l2, %o2
561 call C_LABEL(handle_watchpoint)
562 mov %l0, %o3
563
564 RESTORE_ALL
565
566
567 .align 4
568 .globl do_reg_access
569 do_reg_access:
570 SAVE_ALL
571 ENTER_SYSCALL
572
573 wr %l0, PSR_ET, %psr ! re-enable traps
574 WRITE_PAUSE
575
576 add %sp, REGWIN_SZ, %o0
577 mov %l1, %o1
578 mov %l2, %o2
579 call C_LABEL(handle_reg_access)
580 mov %l0, %o3
581
582 RESTORE_ALL
583
584
585 .align 4
586 .globl do_cp_disabled
587 do_cp_disabled:
588 SAVE_ALL
589 ENTER_SYSCALL
590
591 wr %l0, PSR_ET, %psr ! re-enable traps
592 WRITE_PAUSE
593
594 add %sp, REGWIN_SZ, %o0
595 mov %l1, %o1
596 mov %l2, %o2
597 call C_LABEL(handle_cp_disabled)
598 mov %l0, %o3
599
600 RESTORE_ALL
601
602
603 .align 4
604 .globl do_bad_flush
605 do_bad_flush:
606 SAVE_ALL
607 ENTER_SYSCALL
608
609 wr %l0, PSR_ET, %psr ! re-enable traps
610 WRITE_PAUSE
611
612 add %sp, REGWIN_SZ, %o0
613 mov %l1, %o1
614 mov %l2, %o2
615 call C_LABEL(handle_bad_flush)
616 mov %l0, %o3
617
618 RESTORE_ALL
619
620
621 .align 4
622 .globl do_cp_exception
623 do_cp_exception:
624 SAVE_ALL
625 ENTER_SYSCALL
626
627 wr %l0, PSR_ET, %psr ! re-enable traps
628 WRITE_PAUSE
629
630 add %sp, REGWIN_SZ, %o0
631 mov %l1, %o1
632 mov %l2, %o2
633 call C_LABEL(handle_cp_exception)
634 mov %l0, %o3
635
636 RESTORE_ALL
637
638
639 .align 4
640 .globl do_hw_divzero
641 do_hw_divzero:
642 SAVE_ALL
643 ENTER_SYSCALL
644
645 wr %l0, PSR_ET, %psr ! re-enable traps
646 WRITE_PAUSE
647
648 add %sp, REGWIN_SZ, %o0
649 mov %l1, %o1
650 mov %l2, %o2
651 call C_LABEL(handle_hw_divzero)
652 mov %l0, %o3
653
654 RESTORE_ALL
655
656 .align 4
657 .globl do_flush_windows
658 do_flush_windows:
659 SAVE_ALL
660 ENTER_SYSCALL
661
662 wr %l0, PSR_ET, %psr
663 WRITE_PAUSE
664
665 andcc %l0, PSR_PS, %g0
666 bne dfw_kernel
667 nop
668
669 call C_LABEL(flush_user_windows)
670 nop
671
672
673 ld [%sp + REGWIN_SZ + PT_NPC], %l1
674 add %l1, 0x4, %l2
675 st %l1, [%sp + REGWIN_SZ + PT_PC]
676 st %l2, [%sp + REGWIN_SZ + PT_NPC]
677
678 RESTORE_ALL
679
680
681 dfw_kernel:
682 FLUSH_ALL_KERNEL_WINDOWS
683
684
685 ld [%sp + REGWIN_SZ + PT_NPC], %l1
686 add %l1, 0x4, %l2
687 st %l1, [%sp + REGWIN_SZ + PT_PC]
688 st %l2, [%sp + REGWIN_SZ + PT_NPC]
689
690 RESTORE_ALL
691
692
693
694
695
696 .align 4
697 .globl getcc_trap_handler
698 getcc_trap_handler:
699 srl %l0, 20, %g1 ! give user
700 and %g1, 0xf, %g1 ! only ICC bits in %psr
701 jmp %l2 ! advance over trap instruction
702 rett %l2 + 0x4 ! like this...
703
704
705
706
707
708
709 .align 4
710 .globl setcc_trap_handler
711 setcc_trap_handler:
712 sll %g1, 0x14, %l4
713 set PSR_ICC, %l5
714 andn %l0, %l5, %l0 ! clear ICC bits in current %psr
715 and %l4, %l5, %l4 ! clear non-ICC bits in user value
716 or %l4, %l0, %l4 ! or them in... mix mix mix
717
718 wr %l4, 0x0, %psr ! set new %psr
719 WRITE_PAUSE ! TI scumbags...
720
721 jmp %l2 ! advance over trap instruction
722 rett %l2 + 0x4 ! like this...
723
724 .align 4
725 .globl linux_trap_nmi_sun4c
726 linux_trap_nmi_sun4c:
727 SAVE_ALL
728 ENTER_SYSCALL
729
730
731
732
733 sethi %hi(C_LABEL(interrupt_enable)), %l5
734 ld [%l5 + %lo(C_LABEL(interrupt_enable))], %l5
735 ldub [%l5], %l6
736 andn %l6, INTS_ENAB, %l6
737 stb %l6, [%l5]
738
739
740 or %l0, PSR_PIL, %l0
741 wr %l0, PSR_ET, %psr
742 WRITE_PAUSE
743
744
745
746
747
748 sethi %hi(AC_SYNC_ERR), %o0
749 add %o0, 0x4, %o0
750 lda [%o0] ASI_CONTROL, %o2 ! sync vaddr
751 sub %o0, 0x4, %o0
752 lda [%o0] ASI_CONTROL, %o1 ! sync error
753 add %o0, 0xc, %o0
754 lda [%o0] ASI_CONTROL, %o4 ! async vaddr
755 sub %o0, 0x4, %o0
756 lda [%o0] ASI_CONTROL, %o3 ! async error
757 call C_LABEL(sparc_lvl15_nmi)
758 add %sp, REGWIN_SZ, %o0
759
760 RESTORE_ALL
761
762 #ifdef __SMP__
763
764 .align 4
765 .globl linux_trap_ipi9_sun4m
766 linux_trap_ipi9_sun4m:
767 sethi %hi(0x02000000), %o2
768 GET_PROCESSOR_MID(o0, o1)
769 set C_LABEL(sun4m_interrupts), %l5
770 ld [%l5], %o5
771 sll %o0, 12, %o0
772 add %o5, %o0, %o5
773 st %o2, [%o5 + 4]
774 WRITE_PAUSE
775
776 ld [%o5], %g0
777 WRITE_PAUSE
778
779
780 or %l0, PSR_PIL, %l4
781 wr %l4, 0x0, %psr
782 WRITE_PAUSE
783
784 wr %l4, PSR_ET, %psr
785 WRITE_PAUSE
786
787 call C_LABEL(smp_message_irq)
788 nop
789
790 RESTORE_ALL_FASTIRQ
791
792 .align 4
793 .globl linux_trap_ipi13_sun4m
794 linux_trap_ipi13_sun4m:
795
796
797
798 sethi %hi(C_LABEL(intr_count)), %l4
799 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
800 add %l5, 0x1, %l5
801 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
802
803 sethi %hi(0x20000000), %o2
804 GET_PROCESSOR_MID(o0, o1)
805 set C_LABEL(sun4m_interrupts), %l5
806 ld [%l5], %o5
807 sll %o0, 12, %o0
808 add %o5, %o0, %o5
809 st %o2, [%o5 + 4]
810 WRITE_PAUSE
811
812 ld [%o5], %g0
813 WRITE_PAUSE
814
815
816 or %l0, PSR_PIL, %l4
817 wr %l4, 0x0, %psr
818 WRITE_PAUSE
819
820 wr %l4, PSR_ET, %psr
821 WRITE_PAUSE
822
823 call C_LABEL(smp_reschedule_irq)
824 nop
825
826 sethi %hi(C_LABEL(intr_count)), %l4
827 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
828 sub %l5, 0x1, %l5
829 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
830
831 LEAVE_IRQ
832 RESTORE_ALL
833
834 .align 4
835 .globl linux_trap_ipi15_sun4m
836 linux_trap_ipi15_sun4m:
837 SAVE_ALL
838
839
840 sethi %hi(0xf0000000), %o2
841 set C_LABEL(sun4m_interrupts), %l5
842 set 0x4000, %o3
843 ld [%l5], %l5
844 add %l5, %o3, %l5
845 ld [%l5], %l6
846 andcc %o2, %l6, %o2
847 be 1f
848 nop
849
850
851 sethi %hi(0x80000000), %o2
852 st %o2, [%l5 + 0xc]
853 WRITE_PAUSE
854 ld [%l5], %g0
855 WRITE_PAUSE
856
857
858
859
860 or %l0, PSR_PIL, %l4 ! I am very paranoid...
861 wr %l4, 0x0, %psr
862 WRITE_PAUSE
863 wr %l4, PSR_ET, %psr
864 WRITE_PAUSE
865 call C_LABEL(sun4m_nmi)
866 nop
867
868 sethi %hi(0x80000000), %o2
869 st %o2, [%l5 + 0x8]
870 WRITE_PAUSE
871 ld [%l5], %g0
872 WRITE_PAUSE
873
874 RESTORE_ALL_FASTIRQ
875
876 1:
877 sethi %hi(0x80000000), %o2
878 GET_PROCESSOR_MID(o0, o1)
879 set C_LABEL(sun4m_interrupts), %l5
880 ld [%l5], %o5
881 sll %o0, 12, %o0
882 add %o5, %o0, %o5
883 st %o2, [%o5 + 4]
884 WRITE_PAUSE
885
886 ld [%o5], %g0
887 WRITE_PAUSE
888
889
890 or %l0, PSR_PIL, %l4
891 wr %l4, 0x0, %psr
892 WRITE_PAUSE
893
894 wr %l4, PSR_ET, %psr
895 WRITE_PAUSE
896
897 call C_LABEL(smp_message_irq)
898 nop
899
900 RESTORE_ALL_FASTIRQ
901
902 #endif
903
904 .align 4
905 .globl sun4c_fault
906 sun4c_fault:
907 SAVE_ALL
908 ENTER_SYSCALL
909
910
911 sethi %hi(AC_SYNC_ERR), %l4
912 add %l4, 0x4, %l5 ! AC_SYNC_VA in %l5
913 lda [%l5] ASI_CONTROL, %o3
914 lda [%l4] ASI_CONTROL, %l6
915 srl %l6, 15, %l6
916 and %l6, 1, %o2
917
918 wr %l0, PSR_ET, %psr
919 WRITE_PAUSE
920
921 mov %l7, %o1
922 call C_LABEL(do_sparc_fault)
923 add %sp, REGWIN_SZ, %o0
924
925 RESTORE_ALL
926
927 .align 4
928 .globl C_LABEL(srmmu_fault)
929 C_LABEL(srmmu_fault):
930 mov 0x400, %l5
931 mov 0x300, %l4
932
933 lda [%l5] ASI_M_MMUREGS, %l6 ! read sfar first
934 lda [%l4] ASI_M_MMUREGS, %l5 ! read sfsr last
935
936 andn %l6, 0xfff, %l6
937 srl %l5, 6, %l5 ! and encode all info into l7
938
939 and %l5, 2, %l5
940 or %l5, %l6, %l6
941
942 or %l6, %l7, %l7 ! l7 = [addr,write,txtfault]
943
944 SAVE_ALL
945 ENTER_SYSCALL
946
947 mov %l7, %o1
948 mov %l7, %o2
949 and %o1, 1, %o1 ! arg2 = text_faultp
950 mov %l7, %o3
951 and %o2, 2, %o2 ! arg3 = writep
952 andn %o3, 0xfff, %o3 ! arg4 = faulting address
953
954 wr %l0, PSR_ET, %psr
955 WRITE_PAUSE
956
957 call C_LABEL(do_sparc_fault)
958 add %sp, REGWIN_SZ, %o0 ! arg1 = pt_regs ptr
959
960 RESTORE_ALL
961
962
963
964
965
966 .globl C_LABEL(sunos_indir)
967 C_LABEL(sunos_indir):
968 ld [%sp + REGWIN_SZ + PT_I0], %g1
969 cmp %g1, NR_SYSCALLS
970 blu,a 1f
971 sll %g1, 0x2, %g1
972
973 set C_LABEL(sunos_nosys), %l6
974 b 2f
975 nop
976
977 1:
978 set C_LABEL(sunos_sys_table), %l7
979 ld [%l7 + %g1], %l6
980
981 2:
982 ld [%sp + REGWIN_SZ + PT_I1], %o0
983 ld [%sp + REGWIN_SZ + PT_I2], %o1
984 ld [%sp + REGWIN_SZ + PT_I3], %o2
985 mov %o7, %l5
986 ld [%sp + REGWIN_SZ + PT_I4], %o3
987 call %l6
988 ld [%sp + REGWIN_SZ + PT_I5], %o4
989
990 jmp %l5 + 0x8
991 nop
992
993 #if 0
994 .align 4
995 .globl C_LABEL(sys_ptrace)
996 C_LABEL(sys_ptrace):
997 call C_LABEL(do_ptrace)
998 add %sp, REGWIN_SZ, %o0
999
1000 RESTORE_ALL
1001 #endif
1002
1003 .align 4
1004 .globl C_LABEL(sys_execve)
1005 C_LABEL(sys_execve):
1006 mov %o7, %l5
1007 call C_LABEL(sparc_execve)
1008 add %sp, REGWIN_SZ, %o0 ! pt_regs *regs arg
1009
1010 jmp %l5 + 0x8
1011 nop
1012
1013 .align 4
1014 .globl C_LABEL(sys_pipe)
1015 C_LABEL(sys_pipe):
1016 mov %o7, %l5
1017
1018 call C_LABEL(sparc_pipe)
1019 add %sp, REGWIN_SZ, %o0 ! pt_regs *regs arg
1020
1021 jmp %l5 + 0x8
1022 nop
1023
1024 .align 4
1025 .globl C_LABEL(sys_sigpause)
1026 C_LABEL(sys_sigpause):
1027 ld [%sp + REGWIN_SZ + PT_I0], %o0
1028 call C_LABEL(do_sigpause)
1029 add %sp, REGWIN_SZ, %o1
1030
1031
1032 RESTORE_ALL
1033
1034 .align 4
1035 .globl C_LABEL(sys_sigsuspend)
1036 C_LABEL(sys_sigsuspend):
1037 call C_LABEL(do_sigsuspend)
1038 add %sp, REGWIN_SZ, %o0
1039
1040
1041 RESTORE_ALL
1042
1043 .align 4
1044 .globl C_LABEL(sys_sigreturn)
1045 C_LABEL(sys_sigreturn):
1046 call C_LABEL(do_sigreturn)
1047 add %sp, REGWIN_SZ, %o0
1048
1049
1050
1051
1052 RESTORE_ALL
1053
1054
1055
1056
1057
1058 .align 4
1059 .globl C_LABEL(sys_fork), C_LABEL(sys_vfork)
1060 C_LABEL(sys_vfork):
1061 C_LABEL(sys_fork):
1062 mov %o7, %l5
1063
1064
1065 FLUSH_ALL_KERNEL_WINDOWS;
1066 STORE_WINDOW(sp)
1067 LOAD_CURRENT(g6, g5)
1068 rd %psr, %g4
1069 rd %wim, %g5
1070 std %g4, [%g6 + THREAD_FORK_KPSR]
1071
1072 mov SIGCHLD, %o0 ! arg0: clone flags
1073 ld [%sp + REGWIN_SZ + PT_FP], %o1 ! arg1: usp
1074 call C_LABEL(do_fork)
1075 add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr
1076
1077 jmp %l5 + 0x8
1078 nop
1079
1080
1081 .globl C_LABEL(sys_clone)
1082 C_LABEL(sys_clone):
1083 mov %o7, %l5
1084
1085
1086 FLUSH_ALL_KERNEL_WINDOWS;
1087 STORE_WINDOW(sp)
1088 LOAD_CURRENT(g6, g5)
1089 rd %psr, %g4
1090 rd %wim, %g5
1091 std %g4, [%g6 + THREAD_FORK_KPSR]
1092
1093 ldd [%sp + REGWIN_SZ + PT_I0], %o0 ! arg0,1: flags,usp
1094 cmp %o1, 0x0 ! Is new_usp NULL?
1095 be,a 1f
1096 ld [%sp + REGWIN_SZ + PT_FP], %o1 ! yes, use current usp
1097 1:
1098 call C_LABEL(do_fork)
1099 add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr
1100
1101 jmp %l5 + 0x8
1102 nop
1103
1104
1105 .align 4
1106 .globl linux_sparc_syscall
1107 linux_sparc_syscall:
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125 cmp %g1, NR_SYSCALLS
1126 blu,a 1f
1127 sll %g1, 2, %l4
1128
1129 set C_LABEL(sys_ni_syscall), %l7
1130 b syscall_is_too_hard
1131 nop
1132
1133 1:
1134 ld [%l7 + %l4], %l7
1135
1136
1137
1138
1139
1140 andcc %l7, 0x1, %g0
1141 be syscall_is_too_hard
1142 andn %l7, 0x1, %l7
1143
1144 jmpl %l7, %g0
1145 nop
1146
1147 .globl syscall_is_too_hard
1148 syscall_is_too_hard:
1149 rd %wim, %l3
1150 SAVE_ALL
1151 ENTER_SYSCALL
1152
1153 wr %l0, PSR_ET, %psr
1154 WRITE_PAUSE
1155
1156 2:
1157 ldd [%sp + REGWIN_SZ + PT_I0], %o0
1158 st %o0, [%sp + REGWIN_SZ + PT_G0] ! for restarting syscalls
1159 ldd [%sp + REGWIN_SZ + PT_I2], %o2
1160 call %l7
1161 ldd [%sp + REGWIN_SZ + PT_I4], %o4
1162
1163 st %o0, [%sp + REGWIN_SZ + PT_I0]
1164
1165 .globl C_LABEL(ret_sys_call)
1166 C_LABEL(ret_sys_call):
1167 ld [%sp + REGWIN_SZ + PT_I0], %o0
1168 set PSR_C, %l6
1169 cmp %o0, -ENOIOCTLCMD
1170 bgeu 1f
1171 ld [%sp + REGWIN_SZ + PT_PSR], %l5
1172
1173
1174 andn %l5, %l6, %l5
1175 b 2f
1176 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1177
1178 1:
1179
1180
1181
1182 sub %g0, %o0, %o0
1183 st %o0, [%sp + REGWIN_SZ + PT_I0]
1184 or %l5, %l6, %l5
1185 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1186
1187
1188 2:
1189 ld [%sp + REGWIN_SZ + PT_NPC], %l1
1190 add %l1, 0x4, %l2
1191 st %l1, [%sp + REGWIN_SZ + PT_PC]
1192 st %l2, [%sp + REGWIN_SZ + PT_NPC]
1193
1194 RESTORE_ALL
1195
1196
1197 .align 4
1198 .globl solaris_syscall
1199 solaris_syscall:
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217 cmp %g1, NR_SYSCALLS
1218 blu,a 1f
1219 sll %g1, 2, %l4
1220
1221 set C_LABEL(sys_ni_syscall), %l7
1222 b solaris_is_too_hard
1223 nop
1224
1225 1:
1226 ld [%l7 + %l4], %l7
1227
1228
1229
1230
1231
1232 andcc %l7, 0x1, %g0
1233 be solaris_is_too_hard
1234 andn %l7, 0x1, %l7
1235
1236 jmpl %l7, %g0
1237 nop
1238
1239 .globl solaris_is_too_hard
1240 solaris_is_too_hard:
1241 rd %wim, %l3
1242 SAVE_ALL
1243 ENTER_SYSCALL
1244
1245 wr %l0, PSR_ET, %psr
1246 WRITE_PAUSE
1247
1248 2:
1249 ldd [%sp + REGWIN_SZ + PT_I0], %o0
1250 st %o0, [%sp + REGWIN_SZ + PT_G0] ! for restarting syscalls
1251 ldd [%sp + REGWIN_SZ + PT_I2], %o2
1252 call %l7
1253 ldd [%sp + REGWIN_SZ + PT_I4], %o4
1254
1255 st %o0, [%sp + REGWIN_SZ + PT_I0]
1256 set PSR_C, %l6
1257 cmp %o0, -ENOIOCTLCMD
1258 bgeu 1f
1259 ld [%sp + REGWIN_SZ + PT_PSR], %l5
1260
1261
1262 andn %l5, %l6, %l5
1263 b 2f
1264 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1265
1266 1:
1267
1268
1269
1270 sub %g0, %o0, %o0
1271 sethi %hi(C_LABEL(solaris_xlatb_rorl)), %o3
1272 or %o3, %lo(C_LABEL(solaris_xlatb_rorl)), %o3
1273 sll %o0, 2, %o0
1274 ld [%o3 + %o0], %o0
1275 st %o0, [%sp + REGWIN_SZ + PT_I0]
1276 or %l5, %l6, %l5
1277 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1278
1279
1280 2:
1281 ld [%sp + REGWIN_SZ + PT_NPC], %l1
1282 add %l1, 0x4, %l2
1283 st %l1, [%sp + REGWIN_SZ + PT_PC]
1284 st %l2, [%sp + REGWIN_SZ + PT_NPC]
1285
1286 RESTORE_ALL
1287
1288
1289 .align 4
1290 .globl bsd_syscall
1291 bsd_syscall:
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309 cmp %g1, NR_SYSCALLS
1310 blu,a 1f
1311 sll %g1, 2, %l4
1312
1313 set C_LABEL(sys_ni_syscall), %l7
1314 b bsd_is_too_hard
1315 nop
1316
1317 1:
1318 ld [%l7 + %l4], %l7
1319
1320
1321
1322
1323
1324 andcc %l7, 0x1, %g0
1325 be bsd_is_too_hard
1326 andn %l7, 0x1, %l7
1327
1328 jmpl %l7, %g0
1329 nop
1330
1331 .globl bsd_is_too_hard
1332 bsd_is_too_hard:
1333 rd %wim, %l3
1334 SAVE_ALL
1335 ENTER_SYSCALL
1336
1337 wr %l0, PSR_ET, %psr
1338 WRITE_PAUSE
1339
1340 2:
1341 ldd [%sp + REGWIN_SZ + PT_I0], %o0
1342 st %o0, [%sp + REGWIN_SZ + PT_G0] ! for restarting syscalls
1343 ldd [%sp + REGWIN_SZ + PT_I2], %o2
1344 call %l7
1345 ldd [%sp + REGWIN_SZ + PT_I4], %o4
1346
1347 st %o0, [%sp + REGWIN_SZ + PT_I0]
1348 set PSR_C, %l6
1349 cmp %o0, -ENOIOCTLCMD
1350 bgeu 1f
1351 ld [%sp + REGWIN_SZ + PT_PSR], %l5
1352
1353
1354 andn %l5, %l6, %l5
1355 b 2f
1356 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1357
1358 1:
1359
1360
1361
1362 sub %g0, %o0, %o0
1363 #if 0
1364 sethi %hi(C_LABEL(bsd_xlatb_rorl), %o3
1365 or %o3, %lo(C_LABEL(bsd_xlatb_rorl)), %o3
1366 sll %o0, 2, %o0
1367 ld [%o3 + %o0], %o0
1368 #endif
1369 st %o0, [%sp + REGWIN_SZ + PT_I0]
1370 or %l5, %l6, %l5
1371 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1372
1373
1374 2:
1375 ld [%sp + REGWIN_SZ + PT_NPC], %l1
1376 add %l1, 0x4, %l2
1377 st %l1, [%sp + REGWIN_SZ + PT_PC]
1378 st %l2, [%sp + REGWIN_SZ + PT_NPC]
1379
1380 RESTORE_ALL
1381
1382
1383
1384
1385
1386
1387
1388 .globl C_LABEL(fpsave)
1389 C_LABEL(fpsave):
1390 st %fsr, [%o1] ! this can trap on us if fpu is in bogon state
1391 ld [%o1], %g1
1392 set 0x2000, %g4
1393 andcc %g1, %g4, %g0
1394 be 2f
1395 mov 0, %g2
1396
1397
1398 1:
1399 std %fq, [%o2]
1400 fpsave_magic:
1401 st %fsr, [%o1]
1402 ld [%o1], %g3
1403 andcc %g3, %g4, %g0
1404 add %g2, 1, %g2
1405 bne 1b
1406 add %o2, 8, %o2
1407
1408 2:
1409 st %g2, [%o3]
1410
1411 std %f0, [%o0 + 0x00]
1412 std %f2, [%o0 + 0x08]
1413 std %f4, [%o0 + 0x10]
1414 std %f6, [%o0 + 0x18]
1415 std %f8, [%o0 + 0x20]
1416 std %f10, [%o0 + 0x28]
1417 std %f12, [%o0 + 0x30]
1418 std %f14, [%o0 + 0x38]
1419 std %f16, [%o0 + 0x40]
1420 std %f18, [%o0 + 0x48]
1421 std %f20, [%o0 + 0x50]
1422 std %f22, [%o0 + 0x58]
1423 std %f24, [%o0 + 0x60]
1424 std %f26, [%o0 + 0x68]
1425 std %f28, [%o0 + 0x70]
1426 retl
1427 std %f30, [%o0 + 0x78]
1428
1429
1430
1431
1432
1433
1434 fpsave_catch:
1435 b fpsave_magic + 4
1436 st %fsr, [%o1]
1437
1438 fpsave_catch2:
1439 b C_LABEL(fpsave) + 4
1440 st %fsr, [%o1]
1441
1442
1443
1444 .globl C_LABEL(fpload)
1445 C_LABEL(fpload):
1446 ldd [%o0 + 0x00], %f0
1447 ldd [%o0 + 0x08], %f2
1448 ldd [%o0 + 0x10], %f4
1449 ldd [%o0 + 0x18], %f6
1450 ldd [%o0 + 0x20], %f8
1451 ldd [%o0 + 0x28], %f10
1452 ldd [%o0 + 0x30], %f12
1453 ldd [%o0 + 0x38], %f14
1454 ldd [%o0 + 0x40], %f16
1455 ldd [%o0 + 0x48], %f18
1456 ldd [%o0 + 0x50], %f20
1457 ldd [%o0 + 0x58], %f22
1458 ldd [%o0 + 0x60], %f24
1459 ldd [%o0 + 0x68], %f26
1460 ldd [%o0 + 0x70], %f28
1461 ldd [%o0 + 0x78], %f30
1462 ld [%o1], %fsr
1463 retl
1464 nop
1465
1466 .globl C_LABEL(udelay)
1467 C_LABEL(udelay):
1468 save %sp, -REGWIN_SZ, %sp
1469 mov %i0, %o0
1470 sethi %hi(0x10c6), %o1
1471 call .umul
1472 or %o1, %lo(0x10c6), %o1
1473 #ifndef __SMP__
1474 sethi %hi(C_LABEL(loops_per_sec)), %o3
1475 call .umul
1476 ld [%o3 + %lo(C_LABEL(loops_per_sec))], %o1
1477 #else
1478 GET_PROCESSOR_OFFSET(o4)
1479 set C_LABEL(cpu_data), %o3
1480 call .umul
1481 ld [%o3 + %o4], %o1
1482 #endif
1483
1484 cmp %o1, 0x0
1485 1:
1486 bne 1b
1487 subcc %o1, 1, %o1
1488
1489 ret
1490 restore
1491
1492