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/kgdb.h>
13 #include <asm/contregs.h>
14 #include <asm/ptrace.h>
15 #include <asm/psr.h>
16 #include <asm/cprefix.h>
17 #include <asm/vaddrs.h>
18 #include <asm/memreg.h>
19 #include <asm/page.h>
20 #include <asm/winmacro.h>
21 #include <asm/signal.h>
22
23 #define NR_SYSCALLS 255
24
25
26
27
28
29 #define SAVE_ALL \
30 sethi %hi(trap_setup), %l4; \
31 jmpl %l4 + %lo(trap_setup), %l6; \
32 nop;
33
34
35
36
37
38
39 #define RESTORE_ALL \
40 b ret_trap_entry; \
41 nop;
42
43
44
45
46
47
48 .data
49 .align 4
50
51 in_trap_handler:
52 .word 0
53
54 .text
55 .align 4
56
57 ! This function is called when any SPARC trap (except window overflow or
58 ! underflow) occurs. It makes sure that the invalid register window is still
59 ! available before jumping into C code. It will also restore the world if you
60 ! return from handle_exception.
61
62 .globl C_LABEL(trap_low)
63 C_LABEL(trap_low):
64 rd %wim, %l3
65 SAVE_ALL
66
67 sethi %hi(in_trap_handler), %l4
68 ld [%lo(in_trap_handler) + %l4], %l5
69 inc %l5
70 st %l5, [%lo(in_trap_handler) + %l4]
71
72
73 LOAD_PT_GLOBALS(sp)
74 LOAD_PT_INS(sp)
75 ld [%sp + REGWIN_SZ + PT_Y], %l4
76 ld [%sp + REGWIN_SZ + PT_WIM], %l3
77 ld [%sp + REGWIN_SZ + PT_PSR], %l0
78 ld [%sp + REGWIN_SZ + PT_PC], %l1
79 ld [%sp + REGWIN_SZ + PT_NPC], %l2
80 rd %tbr, %l5
81
82
83 sub %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals
84 ! + hidden arg + arg spill
85 ! + doubleword alignment
86 ! + registers[72] local var
87 SAVE_KGDB_GLOBALS(sp)
88 SAVE_KGDB_INS(sp)
89 SAVE_KGDB_SREGS(sp, l4, l0, l3, l5, l1, l2)
90
91
92 or %l0, PSR_PIL, %l0
93 wr %l0, 0, %psr
94 wr %l0, PSR_ET, %psr
95 WRITE_PAUSE
96
97 call C_LABEL(handle_exception)
98 add %sp, REGWIN_SZ, %o0 ! Pass address of registers
99
100
101 LOAD_KGDB_GLOBALS(sp)
102 LOAD_KGDB_INS(sp)
103 LOAD_KGDB_SREGS(sp, l0, l2)
104 wr %l0, 0x0, %y
105
106 sethi %hi(in_trap_handler), %l4
107 ld [%lo(in_trap_handler) + %l4], %l5
108 dec %l5
109 st %l5, [%lo(in_trap_handler) + %l4]
110
111 add %sp,(16+1+6+1+72)*4,%sp ! Undo the kgdb trap frame.
112
113
114
115
116 STORE_PT_INS(sp)
117 STORE_PT_GLOBALS(sp)
118 STORE_PT_YREG(sp, g2)
119 STORE_PT_PRIV(sp, l1, l2, l3)
120
121 RESTORE_ALL
122
123
124 #ifdef CONFIG_BLK_DEV_FD
125 #ifdef TRACE_FLOPPY_HARDINT
126
127 .data
128 .align 4
129 .globl C_LABEL(floppy_hardint_trace)
130 C_LABEL(floppy_hardint_trace):
131 .skip 32
132 .globl C_LABEL(floppy_hardint_index)
133 C_LABEL(floppy_hardint_index):
134 .word 0
135 #endif
136
137 .text
138 .align 4
139 .globl C_LABEL(floppy_hardint)
140 C_LABEL(floppy_hardint):
141
142
143
144
145
146
147
148
149 #ifdef TRACE_FLOPPY_HARDINT
150 sethi %hi(C_LABEL(floppy_hardint_trace)), %l5
151 or %l5, %lo(C_LABEL(floppy_hardint_trace)), %l5
152 ld [%l5 + 32], %l7
153 add %l7, 1, %l7
154 and %l7, 31, %l7
155 st %l7, [%l5 + 32]
156 sub %l7, 1, %l7
157 and %l7, 31, %l7
158 add %l7, %l5, %l5
159 or %g0, 0xf, %l7
160 stb %l7, [%l5]
161 #endif
162
163
164 sethi %hi(C_LABEL(doing_pdma)), %l4
165 ld [%l4 + %lo(C_LABEL(doing_pdma))], %l4
166 cmp %l4, 0
167 be floppy_dosoftint
168 nop
169
170
171 sethi %hi(C_LABEL(fdc_status)), %l3
172 ld [%l3 + %lo(C_LABEL(fdc_status))], %l3
173
174
175 sethi %hi(C_LABEL(pdma_vaddr)), %l5 ! transfer buffer
176 ld [%l5 + %lo(C_LABEL(pdma_vaddr))], %l4
177 sethi %hi(C_LABEL(pdma_size)), %l5 ! bytes to go
178 ld [%l5 + %lo(C_LABEL(pdma_size))], %l6
179 next_byte:
180 #ifdef TRACE_FLOPPY_HARDINT
181 sethi %hi(C_LABEL(floppy_hardint_trace)), %l5
182 or %l5, %lo(C_LABEL(floppy_hardint_trace)), %l5
183 ld [%l5 + 32], %l7
184 add %l7, 1, %l7
185 and %l7, 31, %l7
186 st %l7, [%l5 + 32]
187 sub %l7, 1, %l7
188 and %l7, 31, %l7
189 add %l7, %l5, %l5
190 ldub [%l3], %l7
191 stb %l7, [%l5]
192 #else
193 ldub [%l3], %l7
194 #endif
195
196 andcc %l7, 0x80, %g0 ! Does fifo still have data
197 bz floppy_fifo_emptied ! fifo has been emptied...
198 andcc %l7, 0x20, %g0 ! in non-dma mode still?
199 bz floppy_overrun ! nope, overrun
200 andcc %l7, 0x40, %g0 ! 0=write 1=read
201 bz floppy_write
202 sub %l6, 0x1, %l6
203
204
205 ldub [%l3 + 1], %l7
206 orcc %g0, %l6, %g0
207 stb %l7, [%l4]
208 bne next_byte
209 add %l4, 0x1, %l4
210
211 b floppy_tdone
212 nop
213
214 floppy_write:
215
216 ldub [%l4], %l7
217 orcc %g0, %l6, %g0
218 stb %l7, [%l3 + 1]
219 bne next_byte
220 add %l4, 0x1, %l4
221
222
223 floppy_tdone:
224 sethi %hi(C_LABEL(pdma_vaddr)), %l5
225 st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
226 sethi %hi(C_LABEL(pdma_size)), %l5
227 st %l6, [%l5 + %lo(C_LABEL(pdma_size))]
228
229 set C_LABEL(auxio_register), %l4
230 ld [%l4], %l4
231 ldub [%l4], %l5
232 or %l5, 0xf4, %l5
233 stb %l5, [%l4]
234
235
236 WRITE_PAUSE
237 WRITE_PAUSE
238
239 ldub [%l4], %l5
240 andn %l5, 0x04, %l5
241 or %l5, 0xf0, %l5
242 stb %l5, [%l4]
243
244
245 sethi %hi(C_LABEL(doing_pdma)), %l4
246 b floppy_dosoftint
247 st %g0, [%l4 + %lo(C_LABEL(doing_pdma))]
248
249
250
251
252
253
254 floppy_fifo_emptied:
255 sethi %hi(C_LABEL(pdma_vaddr)), %l5
256 st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
257 sethi %hi(C_LABEL(pdma_size)), %l7
258 st %l6, [%l7 + %lo(C_LABEL(pdma_size))]
259
260
261 wr %l0, 0x0, %psr
262 WRITE_PAUSE
263
264 jmp %l1
265 rett %l2
266
267 floppy_overrun:
268 sethi %hi(C_LABEL(pdma_vaddr)), %l5
269 st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
270 sethi %hi(C_LABEL(pdma_size)), %l5
271 st %l6, [%l5 + %lo(C_LABEL(pdma_size))]
272
273 sethi %hi(C_LABEL(doing_pdma)), %l4
274 st %g0, [%l4 + %lo(C_LABEL(doing_pdma))]
275
276
277 floppy_dosoftint:
278 rd %wim, %l3
279 SAVE_ALL
280
281
282 or %l0, PSR_PIL, %l4
283 wr %l4, 0x0, %psr
284 wr %l4, PSR_ET, %psr
285 WRITE_PAUSE
286
287 mov 11, %o0 ! floppy irq level
288 call C_LABEL(floppy_interrupt)
289 add %sp, REGWIN_SZ, %o1 ! struct pt_regs *regs
290
291 RESTORE_ALL
292
293 #endif
294
295
296 .globl bad_trap_handler
297 bad_trap_handler:
298 SAVE_ALL
299
300 wr %l0, PSR_ET, %psr
301 WRITE_PAUSE
302
303 mov %l7, %o0 ! trap number
304 mov %l0, %o1 ! psr
305 call C_LABEL(do_hw_interrupt)
306 mov %l1, %o2 ! pc
307
308 RESTORE_ALL
309
310
311
312
313
314
315 .align 4
316 .globl real_irq_entry
317 real_irq_entry:
318 SAVE_ALL
319
320
321 sethi %hi(C_LABEL(intr_count)), %l4
322 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
323 add %l5, 0x1, %l5
324 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
325
326
327
328
329
330 or %l0, PSR_PIL, %l4
331 wr %l4, 0x0, %psr
332 wr %l4, PSR_ET, %psr
333 WRITE_PAUSE
334
335 mov %l7, %o0 ! irq level
336 call C_LABEL(handler_irq)
337 add %sp, REGWIN_SZ, %o1 ! pt_regs ptr
338
339 rie_checkbh:
340 sethi %hi(C_LABEL(intr_count)), %l4
341 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
342 subcc %l5, 0x1, %l5
343 bne 2f
344 nop
345
346 sethi %hi(C_LABEL(bh_active)), %l3
347 ld [%l3 + %lo(C_LABEL(bh_active))], %g2
348 sethi %hi(C_LABEL(bh_mask)), %l3
349 ld [%l3 + %lo(C_LABEL(bh_mask))], %g3
350 andcc %g2, %g3, %g0
351 be 2f
352 nop
353
354
355
356
357 rd %psr, %g4
358 andn %g4, PSR_PIL, %g4
359 wr %g4, 0x0, %psr
360 WRITE_PAUSE
361 call C_LABEL(do_bottom_half)
362 nop
363
364
365 b rie_checkbh
366 nop
367
368 2:
369 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
370
371 RESTORE_ALL
372
373
374
375
376 .align 4
377 .globl bad_instruction
378 bad_instruction:
379 SAVE_ALL
380
381 wr %l0, PSR_ET, %psr ! re-enable traps
382 WRITE_PAUSE
383
384 add %sp, REGWIN_SZ, %o0
385 mov %l1, %o1
386 mov %l2, %o2
387 call C_LABEL(do_illegal_instruction)
388 mov %l0, %o3
389 RESTORE_ALL
390
391 .align 4
392 .globl priv_instruction
393 priv_instruction:
394 SAVE_ALL
395
396 wr %l0, PSR_ET, %psr
397 WRITE_PAUSE
398
399 add %sp, REGWIN_SZ, %o0
400 mov %l1, %o1
401 mov %l2, %o2
402 call C_LABEL(do_priv_instruction)
403 mov %l0, %o3
404
405 RESTORE_ALL
406
407
408
409 .align 4
410 .globl mna_handler
411 mna_handler:
412 SAVE_ALL
413
414 wr %l0, PSR_ET, %psr ! re-enable traps
415 WRITE_PAUSE
416
417 add %sp, REGWIN_SZ, %o0
418 mov %l1, %o1
419 mov %l2, %o2
420 call C_LABEL(do_memaccess_unaligned)
421 mov %l0, %o3
422
423 RESTORE_ALL
424
425
426 .align 4
427 .globl fpd_trap_handler
428 fpd_trap_handler:
429 SAVE_ALL
430
431 wr %l0, PSR_ET, %psr ! re-enable traps
432 WRITE_PAUSE
433
434 add %sp, REGWIN_SZ, %o0
435 mov %l1, %o1
436 mov %l2, %o2
437 call C_LABEL(do_fpd_trap)
438 mov %l0, %o3
439
440 RESTORE_ALL
441
442
443 .align 4
444 .globl fpe_trap_handler
445 fpe_trap_handler:
446 set fpsave_magic, %l5
447 cmp %l1, %l5
448 bne 1f
449 sethi %hi(fpsave_catch), %l5
450 or %l5, %lo(fpsave_catch), %l5
451 wr %l0, 0x0, %psr
452 WRITE_PAUSE
453 jmp %l5
454 rett %l5 + 4
455
456 1:
457 SAVE_ALL
458
459 wr %l0, PSR_ET, %psr ! re-enable traps
460 WRITE_PAUSE
461
462 add %sp, REGWIN_SZ, %o0
463 mov %l1, %o1
464 mov %l2, %o2
465 call C_LABEL(do_fpe_trap)
466 mov %l0, %o3
467
468 RESTORE_ALL
469
470
471 .align 4
472 .globl do_tag_overflow
473 do_tag_overflow:
474 SAVE_ALL
475
476 wr %l0, PSR_ET, %psr ! re-enable traps
477 WRITE_PAUSE
478
479 add %sp, REGWIN_SZ, %o0
480 mov %l1, %o1
481 mov %l2, %o2
482 call C_LABEL(handle_tag_overflow)
483 mov %l0, %o3
484
485 RESTORE_ALL
486
487
488 .align 4
489 .globl do_watchpoint
490 do_watchpoint:
491 SAVE_ALL
492
493 wr %l0, PSR_ET, %psr ! re-enable traps
494 WRITE_PAUSE
495
496 add %sp, REGWIN_SZ, %o0
497 mov %l1, %o1
498 mov %l2, %o2
499 call C_LABEL(handle_watchpoint)
500 mov %l0, %o3
501
502 RESTORE_ALL
503
504
505 .align 4
506 .globl do_reg_access
507 do_reg_access:
508 SAVE_ALL
509
510 wr %l0, PSR_ET, %psr ! re-enable traps
511 WRITE_PAUSE
512
513 add %sp, REGWIN_SZ, %o0
514 mov %l1, %o1
515 mov %l2, %o2
516 call C_LABEL(handle_reg_access)
517 mov %l0, %o3
518
519 RESTORE_ALL
520
521
522 .align 4
523 .globl do_cp_disabled
524 do_cp_disabled:
525 SAVE_ALL
526
527 wr %l0, PSR_ET, %psr ! re-enable traps
528 WRITE_PAUSE
529
530 add %sp, REGWIN_SZ, %o0
531 mov %l1, %o1
532 mov %l2, %o2
533 call C_LABEL(handle_cp_disabled)
534 mov %l0, %o3
535
536 RESTORE_ALL
537
538
539 .align 4
540 .globl do_bad_flush
541 do_bad_flush:
542 SAVE_ALL
543
544 wr %l0, PSR_ET, %psr ! re-enable traps
545 WRITE_PAUSE
546
547 add %sp, REGWIN_SZ, %o0
548 mov %l1, %o1
549 mov %l2, %o2
550 call C_LABEL(handle_bad_flush)
551 mov %l0, %o3
552
553 RESTORE_ALL
554
555
556 .align 4
557 .globl do_cp_exception
558 do_cp_exception:
559 SAVE_ALL
560
561 wr %l0, PSR_ET, %psr ! re-enable traps
562 WRITE_PAUSE
563
564 add %sp, REGWIN_SZ, %o0
565 mov %l1, %o1
566 mov %l2, %o2
567 call C_LABEL(handle_cp_exception)
568 mov %l0, %o3
569
570 RESTORE_ALL
571
572
573 .align 4
574 .globl do_hw_divzero
575 do_hw_divzero:
576 SAVE_ALL
577
578 wr %l0, PSR_ET, %psr ! re-enable traps
579 WRITE_PAUSE
580
581 add %sp, REGWIN_SZ, %o0
582 mov %l1, %o1
583 mov %l2, %o2
584 call C_LABEL(handle_hw_divzero)
585 mov %l0, %o3
586
587 RESTORE_ALL
588
589 .align 4
590 .globl do_flush_windows
591 do_flush_windows:
592 SAVE_ALL
593
594 wr %l0, PSR_ET, %psr
595 WRITE_PAUSE
596
597 andcc %l0, PSR_PS, %g0
598 bne dfw_kernel
599 nop
600
601 call C_LABEL(flush_user_windows)
602 nop
603
604
605 ld [%sp + REGWIN_SZ + PT_NPC], %l1
606 add %l1, 0x4, %l2
607 st %l1, [%sp + REGWIN_SZ + PT_PC]
608 st %l2, [%sp + REGWIN_SZ + PT_NPC]
609
610 RESTORE_ALL
611
612
613 dfw_kernel:
614 FLUSH_ALL_KERNEL_WINDOWS
615 RESTORE_ALL
616
617
618
619
620
621 .align 4
622 .globl getcc_trap_handler
623 getcc_trap_handler:
624 srl %l0, 20, %g1 ! give user
625 and %g1, 0xf, %g1 ! only ICC bits in %psr
626 jmp %l2 ! advance over trap instruction
627 rett %l2 + 0x4 ! like this...
628
629
630
631
632
633
634 .align 4
635 .globl setcc_trap_handler
636 setcc_trap_handler:
637 sll %g1, 0x14, %l4
638 set PSR_ICC, %l5
639 andn %l0, %l5, %l0 ! clear ICC bits in current %psr
640 and %l4, %l5, %l4 ! clear non-ICC bits in user value
641 or %l4, %l0, %l4 ! or them in... mix mix mix
642
643 wr %l4, 0x0, %psr ! set new %psr
644 WRITE_PAUSE ! TI scumbags...
645
646 jmp %l2 ! advance over trap instruction
647 rett %l2 + 0x4 ! like this...
648
649 .align 4
650 .globl linux_trap_nmi_sun4c
651 linux_trap_nmi_sun4c:
652 SAVE_ALL
653
654
655
656
657 sethi %hi(C_LABEL(interrupt_enable)), %l5
658 ld [%l5 + %lo(C_LABEL(interrupt_enable))], %l5
659 ldub [%l5], %l6
660 andn %l6, INTS_ENAB, %l6
661 stb %l6, [%l5]
662
663
664 or %l0, PSR_PIL, %l0
665 wr %l0, PSR_ET, %psr
666 WRITE_PAUSE
667
668
669
670
671
672 sethi %hi(AC_SYNC_ERR), %o0
673 add %o0, 0x4, %o0
674 lda [%o0] ASI_CONTROL, %o2 ! sync vaddr
675 sub %o0, 0x4, %o0
676 lda [%o0] ASI_CONTROL, %o1 ! sync error
677 add %o0, 0xc, %o0
678 lda [%o0] ASI_CONTROL, %o4 ! async vaddr
679 sub %o0, 0x4, %o0
680 lda [%o0] ASI_CONTROL, %o3 ! async error
681 call C_LABEL(sparc_lvl15_nmi)
682 add %sp, REGWIN_SZ, %o0
683
684 RESTORE_ALL
685
686 #if 0
687
688 .align 4
689 .globl sun4m_ipi
690 sun4m_ipi:
691 SAVE_ALL_IPI4M
692
693 set MAILBOX_ADDRESS, %l4
694 ldub [%l4], %l5
695 subcc %l5, MBOX_STOPCPU, %g0
696 bne,a 1f
697 subcc %l5, MBOX_STOPCPU2, %g0
698
699 call C_LABEL(prom_stopcpu)
700 mov 0, %o0
701 ba,a 2f
702
703 1:
704 bne,a 1f
705 subcc %l5, MBOX_IDLECPU, %g0
706
707 call C_LABEL(prom_stopcpu)
708 mov 0, %o0
709 ba,a 2f
710
711 1:
712 bne,a 1f
713 subcc %l5, MBOX_IDLECPU2, %g0
714
715 call C_LABEL(prom_idlecpu)
716 mov 0, %o0
717 ba,a 2f
718
719 1:
720 bne,a 2f
721 nop
722
723 call C_LABEL(prom_idlecpu)
724 mov 0, %o0
725 ba,a 2f
726
727 2:
728 call C_LABEL(smp_callin)
729
730 RESTORE_ALL_IPI4M
731 #endif
732
733 .align 4
734 .globl sun4c_fault
735 sun4c_fault:
736 SAVE_ALL
737
738
739 sethi %hi(AC_SYNC_ERR), %l4
740 add %l4, 0x4, %l5 ! AC_SYNC_VA in %l5
741 lda [%l5] ASI_CONTROL, %o3
742 lda [%l4] ASI_CONTROL, %l6
743 srl %l6, 15, %l6
744 and %l6, 1, %o2
745
746 wr %l0, PSR_ET, %psr
747 WRITE_PAUSE
748
749 mov %l7, %o1
750 call C_LABEL(do_sparc_fault)
751 add %sp, REGWIN_SZ, %o0
752
753 RESTORE_ALL
754
755 .align 4
756 .globl C_LABEL(srmmu_fault)
757 C_LABEL(srmmu_fault):
758
759 mov 0x400, %l5
760 mov 0x300, %l4
761
762
763 lda [%l5] ASI_M_MMUREGS, %l6 ! read sfar first
764 lda [%l4] ASI_M_MMUREGS, %l5 ! read sfsr last
765
766
767 andn %l6, 0xfff, %l6
768 srl %l5, 6, %l5 ! and encode all info into l7
769
770
771 and %l5, 2, %l5
772 or %l5, %l6, %l6
773
774
775 or %l6, %l7, %l7 ! l7 = [addr,write,txtfault]
776
777 SAVE_ALL
778
779 mov %l7, %o1
780 mov %l7, %o2
781 and %o1, 1, %o1 ! arg2 = text_faultp
782 mov %l7, %o3
783 and %o2, 2, %o2 ! arg3 = writep
784 andn %o3, 0xfff, %o3 ! arg4 = faulting address
785
786 wr %l0, PSR_ET, %psr
787 WRITE_PAUSE
788
789 call C_LABEL(do_sparc_fault)
790 add %sp, REGWIN_SZ, %o0 ! arg1 = pt_regs ptr
791
792 RESTORE_ALL
793
794
795
796
797
798 .globl C_LABEL(sunos_indir)
799 C_LABEL(sunos_indir):
800 ld [%sp + REGWIN_SZ + PT_I0], %g1
801 cmp %g1, NR_SYSCALLS
802 blu,a 1f
803 sll %g1, 0x2, %g1
804
805 set C_LABEL(sunos_nosys), %l6
806 b 2f
807 nop
808
809 1:
810 set C_LABEL(sunos_sys_table), %l7
811 ld [%l7 + %g1], %l6
812
813 2:
814 ld [%sp + REGWIN_SZ + PT_I1], %o0
815 ld [%sp + REGWIN_SZ + PT_I2], %o1
816 ld [%sp + REGWIN_SZ + PT_I3], %o2
817 ld [%sp + REGWIN_SZ + PT_I4], %o3
818 call %l6
819 ld [%sp + REGWIN_SZ + PT_I5], %o4
820
821 b scall_store_args
822 nop
823
824 #if 0
825 .align 4
826 .globl C_LABEL(sys_ptrace)
827 C_LABEL(sys_ptrace):
828 call C_LABEL(do_ptrace)
829 add %sp, REGWIN_SZ, %o0
830
831 RESTORE_ALL
832 #endif
833
834 .align 4
835 .globl C_LABEL(sys_execve)
836 C_LABEL(sys_execve):
837 call C_LABEL(sparc_execve)
838 add %sp, REGWIN_SZ, %o0 ! pt_regs *regs arg
839
840 b scall_store_args
841 nop
842
843 .align 4
844 .globl C_LABEL(sys_pipe)
845 C_LABEL(sys_pipe):
846 call C_LABEL(sparc_pipe)
847 add %sp, REGWIN_SZ, %o0 ! pt_regs *regs arg
848
849 b C_LABEL(ret_sys_call)
850 nop
851
852 .align 4
853 .globl C_LABEL(sys_sigpause)
854 C_LABEL(sys_sigpause):
855 ld [%sp + REGWIN_SZ + PT_I0], %o0
856 call C_LABEL(do_sigpause)
857 add %sp, REGWIN_SZ, %o1
858
859
860
861 RESTORE_ALL
862
863 .align 4
864 .globl C_LABEL(sys_sigsuspend)
865 C_LABEL(sys_sigsuspend):
866 ld [%sp + REGWIN_SZ + PT_I0], %o0
867 call C_LABEL(do_sigsuspend)
868 add %sp, REGWIN_SZ, %o1
869
870
871
872 RESTORE_ALL
873
874 .align 4
875 .globl C_LABEL(sys_sigreturn)
876 C_LABEL(sys_sigreturn):
877 call C_LABEL(do_sigreturn)
878 add %sp, REGWIN_SZ, %o0
879
880
881
882
883 RESTORE_ALL
884
885
886
887
888
889 .align 4
890 .globl C_LABEL(sys_fork), C_LABEL(sys_vfork)
891 C_LABEL(sys_vfork):
892 C_LABEL(sys_fork):
893
894 FLUSH_ALL_KERNEL_WINDOWS;
895 STORE_WINDOW(sp)
896 LOAD_CURRENT(g6, g5)
897 rd %psr, %g4
898 rd %wim, %g5
899 std %g4, [%g6 + THREAD_FORK_KPSR]
900
901 mov SIGCHLD, %o0 ! arg0: clone flags
902 ld [%sp + REGWIN_SZ + PT_FP], %o1 ! arg1: usp
903 call C_LABEL(do_fork)
904 add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr
905
906 b scall_store_args
907 nop
908
909
910 .globl C_LABEL(sys_clone)
911 C_LABEL(sys_clone):
912
913 FLUSH_ALL_KERNEL_WINDOWS;
914 STORE_WINDOW(sp)
915 LOAD_CURRENT(g6, g5)
916 rd %psr, %g4
917 rd %wim, %g5
918 std %g4, [%g6 + THREAD_FORK_KPSR]
919
920 ldd [%sp + REGWIN_SZ + PT_I0], %o0 ! arg0,1: flags,usp
921 cmp %o1, 0x0 ! Is new_usp NULL?
922 be,a 1f
923 ld [%sp + REGWIN_SZ + PT_FP], %o1 ! yes, use current usp
924 1:
925 call C_LABEL(do_fork)
926 add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr
927
928 b scall_store_args
929 nop
930
931
932 .align 4
933 .globl linux_sparc_syscall
934 linux_sparc_syscall:
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952 cmp %g1, NR_SYSCALLS
953 blu,a 1f
954 sll %g1, 2, %l4
955
956 b syscall_is_too_hard
957 set C_LABEL(sys_ni_syscall), %l7
958
959 1:
960 ld [%l7 + %l4], %l7
961
962
963
964
965
966 andcc %l7, 0x1, %g0
967 be syscall_is_too_hard
968 andn %l7, 0x1, %l7
969
970 jmpl %l7, %g0
971 nop
972
973 .globl syscall_is_too_hard
974 syscall_is_too_hard:
975 rd %wim, %l3
976 SAVE_ALL
977
978 wr %l0, PSR_ET, %psr
979 WRITE_PAUSE
980
981 2:
982 ldd [%sp + REGWIN_SZ + PT_I0], %o0
983 st %o0, [%sp + REGWIN_SZ + PT_G0] ! for restarting syscalls
984 ldd [%sp + REGWIN_SZ + PT_I2], %o2
985 call %l7
986 ldd [%sp + REGWIN_SZ + PT_I4], %o4
987
988 scall_store_args:
989 st %o0, [%sp + REGWIN_SZ + PT_I0]
990
991 .globl C_LABEL(ret_sys_call)
992 C_LABEL(ret_sys_call):
993 ld [%sp + REGWIN_SZ + PT_I0], %o0
994 set PSR_C, %l6
995 cmp %o0, -ENOIOCTLCMD
996 bgeu 1f
997 ld [%sp + REGWIN_SZ + PT_PSR], %l5
998
999
1000 andn %l5, %l6, %l5
1001 b 2f
1002 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1003
1004 1:
1005
1006
1007
1008 sub %g0, %o0, %o0
1009 st %o0, [%sp + REGWIN_SZ + PT_I0]
1010 or %l5, %l6, %l5
1011 st %l5, [%sp + REGWIN_SZ + PT_PSR]
1012
1013
1014 2:
1015 ld [%sp + REGWIN_SZ + PT_NPC], %l1
1016 add %l1, 0x4, %l2
1017 st %l1, [%sp + REGWIN_SZ + PT_PC]
1018 st %l2, [%sp + REGWIN_SZ + PT_NPC]
1019
1020 RESTORE_ALL
1021
1022
1023
1024
1025
1026
1027
1028 .globl C_LABEL(fpsave)
1029 C_LABEL(fpsave):
1030 st %fsr, [%o1]
1031 ld [%o1], %g1
1032 set 0x2000, %g4
1033 andcc %g1, %g4, %g0
1034 be 2f
1035 mov 0, %g2
1036
1037
1038 1:
1039 std %fq, [%o2]
1040 fpsave_magic:
1041 st %fsr, [%o1]
1042 ld [%o1], %g3
1043 andcc %g3, %g4, %g0
1044 add %g2, 1, %g2
1045 bne 1b
1046 add %o2, 8, %o2
1047
1048 2:
1049 st %g2, [%o3]
1050
1051 std %f0, [%o0 + 0x00]
1052 std %f2, [%o0 + 0x08]
1053 std %f4, [%o0 + 0x10]
1054 std %f6, [%o0 + 0x18]
1055 std %f8, [%o0 + 0x20]
1056 std %f10, [%o0 + 0x28]
1057 std %f12, [%o0 + 0x30]
1058 std %f14, [%o0 + 0x38]
1059 std %f16, [%o0 + 0x40]
1060 std %f18, [%o0 + 0x48]
1061 std %f20, [%o0 + 0x50]
1062 std %f22, [%o0 + 0x58]
1063 std %f24, [%o0 + 0x60]
1064 std %f26, [%o0 + 0x68]
1065 std %f28, [%o0 + 0x70]
1066 retl
1067 std %f30, [%o0 + 0x78]
1068
1069
1070
1071
1072
1073
1074 fpsave_catch:
1075 b fpsave_magic + 4
1076 st %fsr, [%o1]
1077
1078
1079
1080 .globl C_LABEL(fpload)
1081 C_LABEL(fpload):
1082 ldd [%o0 + 0x00], %f0
1083 ldd [%o0 + 0x08], %f2
1084 ldd [%o0 + 0x10], %f4
1085 ldd [%o0 + 0x18], %f6
1086 ldd [%o0 + 0x20], %f8
1087 ldd [%o0 + 0x28], %f10
1088 ldd [%o0 + 0x30], %f12
1089 ldd [%o0 + 0x38], %f14
1090 ldd [%o0 + 0x40], %f16
1091 ldd [%o0 + 0x48], %f18
1092 ldd [%o0 + 0x50], %f20
1093 ldd [%o0 + 0x58], %f22
1094 ldd [%o0 + 0x60], %f24
1095 ldd [%o0 + 0x68], %f26
1096 ldd [%o0 + 0x70], %f28
1097 ldd [%o0 + 0x78], %f30
1098 ld [%o1], %fsr
1099 retl
1100 nop
1101
1102 .globl C_LABEL(udelay)
1103 C_LABEL(udelay):
1104 save %sp, -REGWIN_SZ, %sp
1105 mov %i0, %o0
1106 sethi %hi(0x10c6), %o1
1107 call .umul
1108 or %o1, %lo(0x10c6), %o1
1109 sethi %hi(C_LABEL(loops_per_sec)), %o3
1110 call .umul
1111 ld [%o3 + %lo(C_LABEL(loops_per_sec))], %o1
1112
1113 cmp %o1, 0x0
1114 1:
1115 bne 1b
1116 subcc %o1, 1, %o1
1117
1118 ret
1119 restore
1120
1121