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
994
995
996
997 .align 4
998 .globl C_LABEL(sys_ptrace)
999 C_LABEL(sys_ptrace):
1000 call C_LABEL(do_ptrace)
1001 add %sp, REGWIN_SZ, %o0
1002
1003 LOAD_CURRENT(l4, l5)
1004 ld [%l4 + 0x14], %l5
1005 andcc %l5, 0x20, %g0
1006 be 1f
1007 nop
1008
1009 call C_LABEL(syscall_trace)
1010 nop
1011
1012 1:
1013 RESTORE_ALL
1014
1015 .align 4
1016 .globl C_LABEL(sys_execve)
1017 C_LABEL(sys_execve):
1018 mov %o7, %l5
1019 call C_LABEL(sparc_execve)
1020 add %sp, REGWIN_SZ, %o0 ! pt_regs *regs arg
1021
1022 jmp %l5 + 0x8
1023 nop
1024
1025 .align 4
1026 .globl C_LABEL(sys_pipe)
1027 C_LABEL(sys_pipe):
1028 mov %o7, %l5
1029
1030 call C_LABEL(sparc_pipe)
1031 add %sp, REGWIN_SZ, %o0 ! pt_regs *regs arg
1032
1033 jmp %l5 + 0x8
1034 nop
1035
1036 .align 4
1037 .globl C_LABEL(sys_sigpause)
1038 C_LABEL(sys_sigpause):
1039 ld [%sp + REGWIN_SZ + PT_I0], %o0
1040 call C_LABEL(do_sigpause)
1041 add %sp, REGWIN_SZ, %o1
1042
1043 LOAD_CURRENT(l4, l5)
1044 ld [%l4 + 0x14], %l5
1045 andcc %l5, 0x20, %g0
1046 be 1f
1047 nop
1048
1049 call C_LABEL(syscall_trace)
1050 nop
1051
1052 1:
1053
1054 RESTORE_ALL
1055
1056 .align 4
1057 .globl C_LABEL(sys_sigsuspend)
1058 C_LABEL(sys_sigsuspend):
1059 call C_LABEL(do_sigsuspend)
1060 add %sp, REGWIN_SZ, %o0
1061
1062 LOAD_CURRENT(l4, l5)
1063 ld [%l4 + 0x14], %l5
1064 andcc %l5, 0x20, %g0
1065 be 1f
1066 nop
1067
1068 call C_LABEL(syscall_trace)
1069 nop
1070
1071 1:
1072
1073 RESTORE_ALL
1074
1075 .align 4
1076 .globl C_LABEL(sys_sigreturn)
1077 C_LABEL(sys_sigreturn):
1078 call C_LABEL(do_sigreturn)
1079 add %sp, REGWIN_SZ, %o0
1080
1081 LOAD_CURRENT(l4, l5)
1082 ld [%l4 + 0x14], %l5
1083 andcc %l5, 0x20, %g0
1084 be 1f
1085 nop
1086
1087 call C_LABEL(syscall_trace)
1088 nop
1089
1090 1:
1091
1092
1093
1094 RESTORE_ALL
1095
1096
1097
1098
1099
1100 .align 4
1101 .globl C_LABEL(sys_fork), C_LABEL(sys_vfork)
1102 C_LABEL(sys_vfork):
1103 C_LABEL(sys_fork):
1104 mov %o7, %l5
1105
1106
1107 FLUSH_ALL_KERNEL_WINDOWS;
1108 STORE_WINDOW(sp)
1109 LOAD_CURRENT(g6, g5)
1110 rd %psr, %g4
1111 rd %wim, %g5
1112 std %g4, [%g6 + THREAD_FORK_KPSR]
1113
1114 mov SIGCHLD, %o0 ! arg0: clone flags
1115 ld [%sp + REGWIN_SZ + PT_FP], %o1 ! arg1: usp
1116 call C_LABEL(do_fork)
1117 add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr
1118
1119 jmp %l5 + 0x8
1120 nop
1121
1122
1123 .globl C_LABEL(sys_clone)
1124 C_LABEL(sys_clone):
1125 mov %o7, %l5
1126
1127
1128 FLUSH_ALL_KERNEL_WINDOWS;
1129 STORE_WINDOW(sp)
1130 LOAD_CURRENT(g6, g5)
1131 rd %psr, %g4
1132 rd %wim, %g5
1133 std %g4, [%g6 + THREAD_FORK_KPSR]
1134
1135 ldd [%sp + REGWIN_SZ + PT_I0], %o0 ! arg0,1: flags,usp
1136 cmp %o1, 0x0 ! Is new_usp NULL?
1137 be,a 1f
1138 ld [%sp + REGWIN_SZ + PT_FP], %o1 ! yes, use current usp
1139 1:
1140 call C_LABEL(do_fork)
1141 add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr
1142
1143 jmp %l5 + 0x8
1144 nop
1145
1146
1147 .align 4
1148 .globl linux_sparc_syscall
1149 linux_sparc_syscall:
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167 cmp %g1, NR_SYSCALLS
1168 blu,a 1f
1169 sll %g1, 2, %l4
1170
1171 set C_LABEL(sys_ni_syscall), %l7
1172 b syscall_is_too_hard
1173 nop
1174
1175 1:
1176 ld [%l7 + %l4], %l7
1177
1178
1179
1180
1181
1182 andcc %l7, 0x1, %g0
1183 be syscall_is_too_hard
1184 andn %l7, 0x1, %l7
1185
1186 jmpl %l7, %g0
1187 nop
1188
1189 .globl syscall_is_too_hard
1190 syscall_is_too_hard:
1191 rd %wim, %l3
1192 SAVE_ALL
1193 ENTER_SYSCALL
1194
1195 wr %l0, PSR_ET, %psr
1196 WRITE_PAUSE
1197
1198 LOAD_CURRENT(l4, l5)
1199 ld [%l4 + 0x14], %l5
1200 andcc %l5, 0x20, %g0
1201 be 2f
1202 nop
1203
1204 call C_LABEL(syscall_trace)
1205 nop
1206
1207 2:
1208 ldd [%sp + REGWIN_SZ + PT_I0], %o0
1209 st %o0, [%sp + REGWIN_SZ + PT_G0] ! for restarting syscalls
1210 ldd [%sp + REGWIN_SZ + PT_I2], %o2
1211 call %l7
1212 ldd [%sp + REGWIN_SZ + PT_I4], %o4
1213
1214 st %o0, [%sp + REGWIN_SZ + PT_I0]
1215
1216 .globl C_LABEL(ret_sys_call)
1217 C_LABEL(ret_sys_call):
1218 ld [%sp + REGWIN_SZ + PT_I0], %o0
1219 set PSR_C, %l6
1220 cmp %o0, -ENOIOCTLCMD
1221 bgeu 1f
1222 ld [%sp + REGWIN_SZ + PT_PSR], %l5
1223
1224
1225 andn %l5, %l6, %l5
1226 b 2f
1227 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1228
1229 1:
1230
1231
1232
1233 sub %g0, %o0, %o0
1234 st %o0, [%sp + REGWIN_SZ + PT_I0]
1235 or %l5, %l6, %l5
1236 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1237
1238 2:
1239 LOAD_CURRENT(l4, l5)
1240 ld [%l4 + 0x14], %l5
1241 andcc %l5, 0x20, %g0
1242 be 3f
1243 nop
1244
1245 call C_LABEL(syscall_trace)
1246 nop
1247
1248
1249 3:
1250 ld [%sp + REGWIN_SZ + PT_NPC], %l1
1251 add %l1, 0x4, %l2
1252 st %l1, [%sp + REGWIN_SZ + PT_PC]
1253 st %l2, [%sp + REGWIN_SZ + PT_NPC]
1254
1255 RESTORE_ALL
1256
1257
1258 .align 4
1259 .globl solaris_syscall
1260 solaris_syscall:
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278 cmp %g1, NR_SYSCALLS
1279 blu,a 1f
1280 sll %g1, 2, %l4
1281
1282 set C_LABEL(sys_ni_syscall), %l7
1283 b solaris_is_too_hard
1284 nop
1285
1286 1:
1287 ld [%l7 + %l4], %l7
1288
1289
1290
1291
1292
1293 andcc %l7, 0x1, %g0
1294 be solaris_is_too_hard
1295 andn %l7, 0x1, %l7
1296
1297 jmpl %l7, %g0
1298 nop
1299
1300 .globl solaris_is_too_hard
1301 solaris_is_too_hard:
1302 rd %wim, %l3
1303 SAVE_ALL
1304 ENTER_SYSCALL
1305
1306 wr %l0, PSR_ET, %psr
1307 WRITE_PAUSE
1308
1309 2:
1310 ldd [%sp + REGWIN_SZ + PT_I0], %o0
1311 st %o0, [%sp + REGWIN_SZ + PT_G0] ! for restarting syscalls
1312 ldd [%sp + REGWIN_SZ + PT_I2], %o2
1313 call %l7
1314 ldd [%sp + REGWIN_SZ + PT_I4], %o4
1315
1316 st %o0, [%sp + REGWIN_SZ + PT_I0]
1317 set PSR_C, %l6
1318 cmp %o0, -ENOIOCTLCMD
1319 bgeu 1f
1320 ld [%sp + REGWIN_SZ + PT_PSR], %l5
1321
1322
1323 andn %l5, %l6, %l5
1324 b 2f
1325 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1326
1327 1:
1328
1329
1330
1331 sub %g0, %o0, %o0
1332 sethi %hi(C_LABEL(solaris_xlatb_rorl)), %o3
1333 or %o3, %lo(C_LABEL(solaris_xlatb_rorl)), %o3
1334 sll %o0, 2, %o0
1335 ld [%o3 + %o0], %o0
1336 st %o0, [%sp + REGWIN_SZ + PT_I0]
1337 or %l5, %l6, %l5
1338 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1339
1340
1341 2:
1342 ld [%sp + REGWIN_SZ + PT_NPC], %l1
1343 add %l1, 0x4, %l2
1344 st %l1, [%sp + REGWIN_SZ + PT_PC]
1345 st %l2, [%sp + REGWIN_SZ + PT_NPC]
1346
1347 RESTORE_ALL
1348
1349
1350 .align 4
1351 .globl bsd_syscall
1352 bsd_syscall:
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370 cmp %g1, NR_SYSCALLS
1371 blu,a 1f
1372 sll %g1, 2, %l4
1373
1374 set C_LABEL(sys_ni_syscall), %l7
1375 b bsd_is_too_hard
1376 nop
1377
1378 1:
1379 ld [%l7 + %l4], %l7
1380
1381
1382
1383
1384
1385 andcc %l7, 0x1, %g0
1386 be bsd_is_too_hard
1387 andn %l7, 0x1, %l7
1388
1389 jmpl %l7, %g0
1390 nop
1391
1392 .globl bsd_is_too_hard
1393 bsd_is_too_hard:
1394 rd %wim, %l3
1395 SAVE_ALL
1396 ENTER_SYSCALL
1397
1398 wr %l0, PSR_ET, %psr
1399 WRITE_PAUSE
1400
1401 2:
1402 ldd [%sp + REGWIN_SZ + PT_I0], %o0
1403 st %o0, [%sp + REGWIN_SZ + PT_G0] ! for restarting syscalls
1404 ldd [%sp + REGWIN_SZ + PT_I2], %o2
1405 call %l7
1406 ldd [%sp + REGWIN_SZ + PT_I4], %o4
1407
1408 st %o0, [%sp + REGWIN_SZ + PT_I0]
1409 set PSR_C, %l6
1410 cmp %o0, -ENOIOCTLCMD
1411 bgeu 1f
1412 ld [%sp + REGWIN_SZ + PT_PSR], %l5
1413
1414
1415 andn %l5, %l6, %l5
1416 b 2f
1417 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1418
1419 1:
1420
1421
1422
1423 sub %g0, %o0, %o0
1424 #if 0
1425 sethi %hi(C_LABEL(bsd_xlatb_rorl), %o3
1426 or %o3, %lo(C_LABEL(bsd_xlatb_rorl)), %o3
1427 sll %o0, 2, %o0
1428 ld [%o3 + %o0], %o0
1429 #endif
1430 st %o0, [%sp + REGWIN_SZ + PT_I0]
1431 or %l5, %l6, %l5
1432 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1433
1434
1435 2:
1436 ld [%sp + REGWIN_SZ + PT_NPC], %l1
1437 add %l1, 0x4, %l2
1438 st %l1, [%sp + REGWIN_SZ + PT_PC]
1439 st %l2, [%sp + REGWIN_SZ + PT_NPC]
1440
1441 RESTORE_ALL
1442
1443
1444
1445
1446
1447
1448
1449 .globl C_LABEL(fpsave)
1450 C_LABEL(fpsave):
1451 st %fsr, [%o1] ! this can trap on us if fpu is in bogon state
1452 ld [%o1], %g1
1453 set 0x2000, %g4
1454 andcc %g1, %g4, %g0
1455 be 2f
1456 mov 0, %g2
1457
1458
1459 1:
1460 std %fq, [%o2]
1461 fpsave_magic:
1462 st %fsr, [%o1]
1463 ld [%o1], %g3
1464 andcc %g3, %g4, %g0
1465 add %g2, 1, %g2
1466 bne 1b
1467 add %o2, 8, %o2
1468
1469 2:
1470 st %g2, [%o3]
1471
1472 std %f0, [%o0 + 0x00]
1473 std %f2, [%o0 + 0x08]
1474 std %f4, [%o0 + 0x10]
1475 std %f6, [%o0 + 0x18]
1476 std %f8, [%o0 + 0x20]
1477 std %f10, [%o0 + 0x28]
1478 std %f12, [%o0 + 0x30]
1479 std %f14, [%o0 + 0x38]
1480 std %f16, [%o0 + 0x40]
1481 std %f18, [%o0 + 0x48]
1482 std %f20, [%o0 + 0x50]
1483 std %f22, [%o0 + 0x58]
1484 std %f24, [%o0 + 0x60]
1485 std %f26, [%o0 + 0x68]
1486 std %f28, [%o0 + 0x70]
1487 retl
1488 std %f30, [%o0 + 0x78]
1489
1490
1491
1492
1493
1494
1495 fpsave_catch:
1496 b fpsave_magic + 4
1497 st %fsr, [%o1]
1498
1499 fpsave_catch2:
1500 b C_LABEL(fpsave) + 4
1501 st %fsr, [%o1]
1502
1503
1504
1505 .globl C_LABEL(fpload)
1506 C_LABEL(fpload):
1507 ldd [%o0 + 0x00], %f0
1508 ldd [%o0 + 0x08], %f2
1509 ldd [%o0 + 0x10], %f4
1510 ldd [%o0 + 0x18], %f6
1511 ldd [%o0 + 0x20], %f8
1512 ldd [%o0 + 0x28], %f10
1513 ldd [%o0 + 0x30], %f12
1514 ldd [%o0 + 0x38], %f14
1515 ldd [%o0 + 0x40], %f16
1516 ldd [%o0 + 0x48], %f18
1517 ldd [%o0 + 0x50], %f20
1518 ldd [%o0 + 0x58], %f22
1519 ldd [%o0 + 0x60], %f24
1520 ldd [%o0 + 0x68], %f26
1521 ldd [%o0 + 0x70], %f28
1522 ldd [%o0 + 0x78], %f30
1523 ld [%o1], %fsr
1524 retl
1525 nop
1526
1527 .globl C_LABEL(udelay)
1528 C_LABEL(udelay):
1529 save %sp, -REGWIN_SZ, %sp
1530 mov %i0, %o0
1531 sethi %hi(0x10c6), %o1
1532 call .umul
1533 or %o1, %lo(0x10c6), %o1
1534 #ifndef __SMP__
1535 sethi %hi(C_LABEL(loops_per_sec)), %o3
1536 call .umul
1537 ld [%o3 + %lo(C_LABEL(loops_per_sec))], %o1
1538 #else
1539 GET_PROCESSOR_OFFSET(o4)
1540 set C_LABEL(cpu_data), %o3
1541 call .umul
1542 ld [%o3 + %o4], %o1
1543 #endif
1544
1545 cmp %o1, 0x0
1546 1:
1547 bne 1b
1548 subcc %o1, 1, %o1
1549
1550 ret
1551 restore
1552
1553