1
2
3
4
5
6
7 #include <linux/config.h>
8
9 #include <asm/head.h>
10 #include <asm/asi.h>
11 #include <asm/kgdb.h>
12 #include <asm/contregs.h>
13 #include <asm/ptrace.h>
14 #include <asm/psr.h>
15 #include <asm/cprefix.h>
16 #include <asm/vaddrs.h>
17 #include <asm/memreg.h>
18 #include <asm/page.h>
19 #include <asm/winmacro.h>
20 #include <asm/signal.h>
21 #include <asm/errno.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 + STACKFRAME_SZ + PT_Y], %l4
76 ld [%sp + STACKFRAME_SZ + PT_WIM], %l3
77 ld [%sp + STACKFRAME_SZ + PT_PSR], %l0
78 ld [%sp + STACKFRAME_SZ + PT_PC], %l1
79 ld [%sp + STACKFRAME_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, STACKFRAME_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 ld [%sp + STACKFRAME_SZ + KGDB_WIM], %l6
105 wr %l0, 0x0, %y
106
107 sethi %hi(in_trap_handler), %l4
108 ld [%lo(in_trap_handler) + %l4], %l5
109 dec %l5
110 st %l5, [%lo(in_trap_handler) + %l4]
111
112 add %sp,(16+1+6+1+72)*4,%sp ! Undo the kgdb trap frame.
113
114
115
116
117 STORE_PT_INS(sp)
118 STORE_PT_GLOBALS(sp)
119 STORE_PT_YREG(sp, g2)
120 STORE_PT_PRIV(sp, l1, l2, l3, l6)
121
122
123 RESTORE_ALL
124
125
126 #ifdef CONFIG_BLK_DEV_FD
127 #ifdef TRACE_FLOPPY_HARDINT
128
129 .data
130 .align 4
131 .globl C_LABEL(floppy_hardint_trace)
132 C_LABEL(floppy_hardint_trace):
133 .skip 32
134 .globl C_LABEL(floppy_hardint_index)
135 C_LABEL(floppy_hardint_index):
136 .word 0
137 #endif
138
139 .text
140 .align 4
141 .globl C_LABEL(floppy_hardint)
142 C_LABEL(floppy_hardint):
143
144
145
146
147
148
149
150
151 #ifdef TRACE_FLOPPY_HARDINT
152 sethi %hi(C_LABEL(floppy_hardint_trace)), %l5
153 or %l5, %lo(C_LABEL(floppy_hardint_trace)), %l5
154 ld [%l5 + 32], %l7
155 add %l7, 1, %l7
156 and %l7, 31, %l7
157 st %l7, [%l5 + 32]
158 sub %l7, 1, %l7
159 and %l7, 31, %l7
160 add %l7, %l5, %l5
161 or %g0, 0xf, %l7
162 stb %l7, [%l5]
163 #endif
164
165
166 sethi %hi(C_LABEL(doing_pdma)), %l4
167 ld [%l4 + %lo(C_LABEL(doing_pdma))], %l4
168 cmp %l4, 0
169 be floppy_dosoftint
170 nop
171
172
173 sethi %hi(C_LABEL(fdc_status)), %l3
174 ld [%l3 + %lo(C_LABEL(fdc_status))], %l3
175
176
177 sethi %hi(C_LABEL(pdma_vaddr)), %l5 ! transfer buffer
178 ld [%l5 + %lo(C_LABEL(pdma_vaddr))], %l4
179 sethi %hi(C_LABEL(pdma_size)), %l5 ! bytes to go
180 ld [%l5 + %lo(C_LABEL(pdma_size))], %l6
181 next_byte:
182 #ifdef TRACE_FLOPPY_HARDINT
183 sethi %hi(C_LABEL(floppy_hardint_trace)), %l5
184 or %l5, %lo(C_LABEL(floppy_hardint_trace)), %l5
185 ld [%l5 + 32], %l7
186 add %l7, 1, %l7
187 and %l7, 31, %l7
188 st %l7, [%l5 + 32]
189 sub %l7, 1, %l7
190 and %l7, 31, %l7
191 add %l7, %l5, %l5
192 ldub [%l3], %l7
193 stb %l7, [%l5]
194 #else
195 ldub [%l3], %l7
196 #endif
197
198 andcc %l7, 0x80, %g0 ! Does fifo still have data
199 bz floppy_fifo_emptied ! fifo has been emptied...
200 andcc %l7, 0x20, %g0 ! in non-dma mode still?
201 bz floppy_overrun ! nope, overrun
202 andcc %l7, 0x40, %g0 ! 0=write 1=read
203 bz floppy_write
204 sub %l6, 0x1, %l6
205
206
207 ldub [%l3 + 1], %l7
208 orcc %g0, %l6, %g0
209 stb %l7, [%l4]
210 bne next_byte
211 add %l4, 0x1, %l4
212
213 b floppy_tdone
214 nop
215
216 floppy_write:
217
218 ldub [%l4], %l7
219 orcc %g0, %l6, %g0
220 stb %l7, [%l3 + 1]
221 bne next_byte
222 add %l4, 0x1, %l4
223
224
225 floppy_tdone:
226 sethi %hi(C_LABEL(pdma_vaddr)), %l5
227 st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
228 sethi %hi(C_LABEL(pdma_size)), %l5
229 st %l6, [%l5 + %lo(C_LABEL(pdma_size))]
230
231 sethi %hi(AUXIO_VADDR), %l4
232 ldub [%l4 + %lo(AUXIO_VADDR) + 0x3], %l5
233 or %l5, 0xf4, %l5
234 stb %l5, [%l4 + %lo(AUXIO_VADDR) + 0x3]
235
236
237 WRITE_PAUSE
238 WRITE_PAUSE
239
240 ldub [%l4 + %lo(AUXIO_VADDR) + 0x3], %l5
241 andn %l5, 0x04, %l5
242 or %l5, 0xf0, %l5
243 stb %l5, [%l4 + %lo(AUXIO_VADDR) + 0x3]
244
245
246 sethi %hi(C_LABEL(doing_pdma)), %l4
247 b floppy_dosoftint
248 st %g0, [%l4 + %lo(C_LABEL(doing_pdma))]
249
250
251
252
253
254
255 floppy_fifo_emptied:
256 sethi %hi(C_LABEL(pdma_vaddr)), %l5
257 st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
258 sethi %hi(C_LABEL(pdma_size)), %l7
259 st %l6, [%l7 + %lo(C_LABEL(pdma_size))]
260
261
262 wr %l0, 0x0, %psr
263 WRITE_PAUSE
264
265 jmp %l1
266 rett %l2
267
268 floppy_overrun:
269 sethi %hi(C_LABEL(pdma_vaddr)), %l5
270 st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
271 sethi %hi(C_LABEL(pdma_size)), %l5
272 st %l6, [%l5 + %lo(C_LABEL(pdma_size))]
273
274 sethi %hi(C_LABEL(doing_pdma)), %l4
275 st %g0, [%l4 + %lo(C_LABEL(doing_pdma))]
276
277
278 floppy_dosoftint:
279 rd %wim, %l3
280 SAVE_ALL
281
282
283 or %l0, PSR_PIL, %l4
284 wr %l4, 0x0, %psr
285 wr %l4, PSR_ET, %psr
286 WRITE_PAUSE
287
288 mov 11, %o0 ! floppy irq level
289 call C_LABEL(floppy_interrupt)
290 add %sp, STACKFRAME_SZ, %o1 ! struct pt_regs *regs
291
292 RESTORE_ALL
293
294 #endif
295
296
297 .globl bad_trap_handler
298 bad_trap_handler:
299 SAVE_ALL
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 RESTORE_ALL
308
309
310
311
312
313
314 .align 4
315 .globl real_irq_entry
316 real_irq_entry:
317 SAVE_ALL
318
319
320 sethi %hi(C_LABEL(intr_count)), %l4
321 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
322 add %l5, 0x1, %l5
323 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
324
325
326
327
328
329 or %l0, PSR_PIL, %l4
330 wr %l4, 0x0, %psr
331 wr %l4, PSR_ET, %psr
332 WRITE_PAUSE
333
334 mov %l7, %o0 ! irq level
335 call C_LABEL(handler_irq)
336 add %sp, STACKFRAME_SZ, %o1 ! pt_regs ptr
337
338 rie_checkbh:
339 sethi %hi(C_LABEL(intr_count)), %l4
340 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
341 subcc %l5, 0x1, %l5
342 bne 2f
343 nop
344 sethi %hi(C_LABEL(bh_active)), %l3
345 ld [%l3 + %lo(C_LABEL(bh_active))], %g2
346 sethi %hi(C_LABEL(bh_mask)), %l3
347 ld [%l3 + %lo(C_LABEL(bh_mask))], %g3
348 andcc %g2, %g3, %g0
349 be 2f
350 nop
351 call C_LABEL(do_bottom_half)
352 nop
353
354 b rie_checkbh
355 nop
356
357 2:
358 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
359 RESTORE_ALL
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377 .align 4
378 .globl soft_irq_entry
379 soft_irq_entry:
380 SAVE_ALL
381
382
383
384
385 sethi %hi(INTREG_VADDR), %l5
386 ldsb [%l5 + %lo(INTREG_VADDR)], %l6
387 andn %l6, %l4, %l6
388 stb %l6, [%l5 + %lo(INTREG_VADDR)]
389
390
391 sethi %hi(C_LABEL(intr_count)), %l4
392 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
393 add %l5, 0x1, %l5
394 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
395
396 or %l0, PSR_PIL, %l4
397 wr %l4, 0x0, %psr ! grrr!
398 wr %l4, PSR_ET, %psr ! double grrr!
399
400 mov %l7, %o0
401 add %sp, STACKFRAME_SZ, %o1
402 call C_LABEL(handler_irq)
403 nop
404
405 sethi %hi(C_LABEL(intr_count)), %l4
406 ld [%l4 + %lo(C_LABEL(intr_count))], %l5
407 subcc %l5, 0x1, %l5
408 st %l5, [%l4 + %lo(C_LABEL(intr_count))]
409
410 RESTORE_ALL
411
412
413
414
415 .align 4
416 .globl bad_instruction
417 bad_instruction:
418 SAVE_ALL
419 wr %l0, PSR_ET, %psr ! re-enable traps
420 WRITE_PAUSE
421
422 add %sp, STACKFRAME_SZ, %o0
423 mov %l1, %o1
424 mov %l2, %o2
425 call C_LABEL(do_illegal_instruction)
426 mov %l0, %o3
427 RESTORE_ALL
428
429 .align 4
430 .globl priv_instruction
431 priv_instruction:
432 SAVE_ALL
433 wr %l0, PSR_ET, %psr
434 WRITE_PAUSE
435
436 add %sp, STACKFRAME_SZ, %o0
437 mov %l1, %o1
438 mov %l2, %o2
439 call C_LABEL(do_priv_instruction)
440 mov %l0, %o3
441 RESTORE_ALL
442
443
444
445 .align 4
446 .globl mna_handler
447 mna_handler:
448 SAVE_ALL
449 wr %l0, PSR_ET, %psr ! re-enable traps
450 WRITE_PAUSE
451
452 add %sp, STACKFRAME_SZ, %o0
453 mov %l1, %o1
454 mov %l2, %o2
455 call C_LABEL(do_memaccess_unaligned)
456 mov %l0, %o3
457 RESTORE_ALL
458
459
460 .align 4
461 .globl fpd_trap_handler
462 fpd_trap_handler:
463 SAVE_ALL
464 wr %l0, PSR_ET, %psr ! re-enable traps
465 WRITE_PAUSE
466
467 add %sp, STACKFRAME_SZ, %o0
468 mov %l1, %o1
469 mov %l2, %o2
470 call C_LABEL(do_fpd_trap)
471 mov %l0, %o3
472 RESTORE_ALL
473
474
475 .align 4
476 .globl fpe_trap_handler
477 fpe_trap_handler:
478 SAVE_ALL
479 wr %l0, PSR_ET, %psr ! re-enable traps
480 WRITE_PAUSE
481
482 add %sp, STACKFRAME_SZ, %o0
483 mov %l1, %o1
484 mov %l2, %o2
485 call C_LABEL(do_fpe_trap)
486 mov %l0, %o3
487 RESTORE_ALL
488
489
490 .align 4
491 .globl do_tag_overflow
492 do_tag_overflow:
493 SAVE_ALL
494 wr %l0, PSR_ET, %psr ! re-enable traps
495 WRITE_PAUSE
496
497 add %sp, STACKFRAME_SZ, %o0
498 mov %l1, %o1
499 mov %l2, %o2
500 call C_LABEL(handle_tag_overflow)
501 mov %l0, %o3
502 RESTORE_ALL
503
504
505 .align 4
506 .globl do_watchpoint
507 do_watchpoint:
508 SAVE_ALL
509 wr %l0, PSR_ET, %psr ! re-enable traps
510 WRITE_PAUSE
511
512 add %sp, STACKFRAME_SZ, %o0
513 mov %l1, %o1
514 mov %l2, %o2
515 call C_LABEL(handle_watchpoint)
516 mov %l0, %o3
517 RESTORE_ALL
518
519
520 .align 4
521 .globl do_reg_access
522 do_reg_access:
523 SAVE_ALL
524 wr %l0, PSR_ET, %psr ! re-enable traps
525 WRITE_PAUSE
526
527 add %sp, STACKFRAME_SZ, %o0
528 mov %l1, %o1
529 mov %l2, %o2
530 call C_LABEL(handle_reg_access)
531 mov %l0, %o3
532 RESTORE_ALL
533
534
535 .align 4
536 .globl do_cp_disabled
537 do_cp_disabled:
538 SAVE_ALL
539 wr %l0, PSR_ET, %psr ! re-enable traps
540 WRITE_PAUSE
541
542 add %sp, STACKFRAME_SZ, %o0
543 mov %l1, %o1
544 mov %l2, %o2
545 call C_LABEL(handle_cp_disabled)
546 mov %l0, %o3
547 RESTORE_ALL
548
549
550 .align 4
551 .globl do_bad_flush
552 do_bad_flush:
553 SAVE_ALL
554 wr %l0, PSR_ET, %psr ! re-enable traps
555 WRITE_PAUSE
556
557 add %sp, STACKFRAME_SZ, %o0
558 mov %l1, %o1
559 mov %l2, %o2
560 call C_LABEL(handle_bad_flush)
561 mov %l0, %o3
562 RESTORE_ALL
563
564
565 .align 4
566 .globl do_cp_exception
567 do_cp_exception:
568 SAVE_ALL
569 wr %l0, PSR_ET, %psr ! re-enable traps
570 WRITE_PAUSE
571
572 add %sp, STACKFRAME_SZ, %o0
573 mov %l1, %o1
574 mov %l2, %o2
575 call C_LABEL(handle_cp_exception)
576 mov %l0, %o3
577 RESTORE_ALL
578
579
580 .align 4
581 .globl do_hw_divzero
582 do_hw_divzero:
583 SAVE_ALL
584 wr %l0, PSR_ET, %psr ! re-enable traps
585 WRITE_PAUSE
586
587 add %sp, STACKFRAME_SZ, %o0
588 mov %l1, %o1
589 mov %l2, %o2
590 call C_LABEL(handle_hw_divzero)
591 mov %l0, %o3
592 RESTORE_ALL
593
594 .align 4
595 .globl do_flush_windows
596 do_flush_windows:
597 SAVE_ALL
598
599 wr %l0, PSR_ET, %psr
600 WRITE_PAUSE
601
602 call C_LABEL(flush_user_windows)
603 nop
604
605
606 ld [%sp + STACKFRAME_SZ + PT_NPC], %l1
607 add %l1, 0x4, %l2
608 st %l1, [%sp + STACKFRAME_SZ + PT_PC]
609 st %l2, [%sp + STACKFRAME_SZ + PT_NPC]
610
611 RESTORE_ALL
612
613
614
615
616
617 .align 4
618 .globl getcc_trap_handler
619 getcc_trap_handler:
620 srl %l0, 20, %g1 ! give user
621 and %g1, 0xf, %g1 ! only ICC bits in %psr
622 jmp %l2 ! advance over trap instruction
623 rett %l2 + 0x4 ! like this...
624
625
626
627
628
629
630 .align 4
631 .globl setcc_trap_handler
632 setcc_trap_handler:
633 sll %g1, 0x14, %l4
634 set PSR_ICC, %l5
635 andn %l0, %l5, %l0 ! clear ICC bits in current %psr
636 and %l4, %l5, %l4 ! clear non-ICC bits in user value
637 or %l4, %l0, %l4 ! or them in... mix mix mix
638 wr %l4, 0x0, %psr ! set new %psr
639 WRITE_PAUSE ! TI scumbags...
640
641 jmp %l2 ! advance over trap instruction
642 rett %l2 + 0x4 ! like this...
643
644 .align 4
645 .globl linux_trap_nmi
646 linux_trap_nmi:
647 SAVE_ALL
648
649
650
651 sethi %hi(C_LABEL(interrupt_enable)), %l5
652 ld [%l5 + %lo(C_LABEL(interrupt_enable))], %l5
653 ldub [%l5], %l6
654 andn %l6, INTS_ENAB, %l6
655 stb %l6, [%l5]
656
657
658 or %l0, PSR_PIL, %l0
659 wr %l0, PSR_ET, %psr
660 WRITE_PAUSE
661
662
663
664
665
666 sethi %hi(AC_SYNC_ERR), %o0
667 add %o0, 0x4, %o0
668 lda [%o0] ASI_CONTROL, %o2 ! sync vaddr
669 sub %o0, 0x4, %o0
670 lda [%o0] ASI_CONTROL, %o1 ! sync error
671 add %o0, 0xc, %o0
672 lda [%o0] ASI_CONTROL, %o4 ! async vaddr
673 sub %o0, 0x4, %o0
674 lda [%o0] ASI_CONTROL, %o3 ! async error
675 call C_LABEL(sparc_lvl15_nmi)
676 add %sp, STACKFRAME_SZ, %o0
677
678 RESTORE_ALL
679
680 .align 4
681 .globl sparc_fault
682 sparc_fault:
683 SAVE_ALL
684 rd %tbr, %o1
685 wr %l0, PSR_ET, %psr
686 WRITE_PAUSE
687
688 call C_LABEL(do_sparc_fault)
689 add %sp, STACKFRAME_SZ, %o0
690 RESTORE_ALL
691
692
693
694
695
696 .globl C_LABEL(sunos_indir)
697 C_LABEL(sunos_indir):
698 ld [%sp + STACKFRAME_SZ + PT_I0], %g1
699 cmp %g1, NR_SYSCALLS
700 bleu,a 1f
701 sll %g1, 0x2, %g1
702
703 set C_LABEL(sunos_nosys), %l6
704 b 2f
705 nop
706
707 1:
708 set C_LABEL(sunos_sys_table), %l7
709 ld [%l7 + %g1], %l6
710
711 2:
712 ld [%sp + STACKFRAME_SZ + PT_I1], %o0
713 ld [%sp + STACKFRAME_SZ + PT_I2], %o1
714 ld [%sp + STACKFRAME_SZ + PT_I3], %o2
715 ld [%sp + STACKFRAME_SZ + PT_I4], %o3
716 call %l6
717 ld [%sp + STACKFRAME_SZ + PT_I5], %o4
718
719 b scall_store_args
720 nop
721
722 .align 4
723 .globl C_LABEL(sys_execve)
724 C_LABEL(sys_execve):
725 call C_LABEL(sparc_execve)
726 add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg
727
728 b scall_store_args
729 nop
730
731 .align 4
732 .globl C_LABEL(sys_pipe)
733 C_LABEL(sys_pipe):
734 call C_LABEL(sparc_pipe)
735 add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg
736
737 b C_LABEL(ret_sys_call)
738 nop
739
740 .align 4
741 .globl C_LABEL(sys_sigreturn)
742 C_LABEL(sys_sigreturn):
743 call C_LABEL(do_sigreturn)
744 add %sp, STACKFRAME_SZ, %o0
745
746
747
748
749 RESTORE_ALL
750
751
752
753
754
755 .align 4
756 .globl C_LABEL(sys_fork), C_LABEL(sys_vfork)
757 C_LABEL(sys_vfork):
758 C_LABEL(sys_fork):
759
760 FLUSH_ALL_KERNEL_WINDOWS;
761 STORE_WINDOW(sp)
762 LOAD_CURRENT(g6)
763 rd %psr, %g4
764 rd %wim, %g5
765 std %g4, [%g6 + THREAD_KPSR]
766 std %sp, [%g6 + THREAD_KSP]
767
768 mov SIGCHLD, %o0 ! arg0: clone flags
769 mov %fp, %o1 ! arg1: usp
770 call C_LABEL(do_fork)
771 add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr
772
773 b scall_store_args
774 nop
775
776
777 .globl C_LABEL(sys_clone)
778 C_LABEL(sys_clone):
779
780 FLUSH_ALL_KERNEL_WINDOWS;
781 STORE_WINDOW(sp)
782 LOAD_CURRENT(g6)
783 rd %psr, %g4
784 rd %wim, %g5
785 std %g4, [%g6 + THREAD_KPSR]
786 std %sp, [%g6 + THREAD_KSP]
787
788 ldd [%sp + STACKFRAME_SZ + PT_I0], %o0 ! arg0,1: flags,usp
789 cmp %o1, 0x0 ! Is new_usp NULL?
790 be,a 1f
791 mov %fp, %o1 ! yes, use current usp
792 1:
793 call C_LABEL(do_fork)
794 add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr
795
796 b scall_store_args
797 nop
798
799 #if 0
800
801 .globl C_LABEL(sys_vfork)
802 C_LABEL(sys_vfork):
803
804 FLUSH_ALL_KERNEL_WINDOWS;
805 STORE_WINDOW(sp)
806 LOAD_CURRENT(g6)
807 rd %psr, %g4
808 rd %wim, %g5
809 std %g4, [%g6 + THREAD_KPSR]
810 std %sp, [%g6 + THREAD_KSP]
811
812 set (0x2100 | SIGCHLD), %o0 ! CLONE_VFORK,CLONE_VM,SIGCHLD
813 mov %fp, %o1 ! use current usp
814 1:
815 call C_LABEL(do_fork)
816 add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr
817
818 b scall_store_args
819 nop
820 #endif
821
822
823 .align 4
824 .globl linux_sparc_syscall
825 linux_sparc_syscall:
826
827
828
829
830 rd %wim, %l3
831 SAVE_ALL
832
833 wr %l0, PSR_ET, %psr
834 WRITE_PAUSE
835
836 #if 0
837 add %sp, STACKFRAME_SZ, %o0
838 call C_LABEL(syscall_trace_entry)
839 nop
840 #endif
841
842
843 ld [%sp + STACKFRAME_SZ + PT_G1], %g1
844 cmp %g1, NR_SYSCALLS
845 bleu,a 1f
846 sll %g1, 0x2, %g1
847
848 set C_LABEL(sys_ni_syscall), %l6
849 b 2f
850 nop
851
852 1:
853
854 ld [%l7 + %g1], %l6 ! load up ptr to syscall handler
855
856
857 2:
858 ldd [%sp + STACKFRAME_SZ + PT_I0], %o0
859 ldd [%sp + STACKFRAME_SZ + PT_I2], %o2
860 ldd [%sp + STACKFRAME_SZ + PT_I4], %o4
861 call %l6
862 nop
863
864 scall_store_args:
865 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
866
867 .globl C_LABEL(ret_sys_call)
868 C_LABEL(ret_sys_call):
869 ld [%sp + STACKFRAME_SZ + PT_I0], %o0
870 set PSR_C, %l6
871 cmp %o0, -ELIBSCN
872 bgeu 1f
873 ld [%sp + STACKFRAME_SZ + PT_PSR], %l5
874
875
876 andn %l5, %l6, %l5
877 b 2f
878 st %l5, [%sp + STACKFRAME_SZ + PT_PSR]
879
880 1:
881
882
883
884 sub %g0, %o0, %o0
885 st %o0, [%sp + STACKFRAME_SZ + PT_I0]
886 or %l5, %l6, %l5
887 st %l5, [%sp + STACKFRAME_SZ + PT_PSR]
888
889
890
891
892
893 2:
894 ld [%sp + STACKFRAME_SZ + PT_NPC], %l1
895 add %l1, 0x4, %l2
896 st %l1, [%sp + STACKFRAME_SZ + PT_PC]
897 st %l2, [%sp + STACKFRAME_SZ + PT_NPC]
898
899 #if 0
900 add %sp, STACKFRAME_SZ, %o0
901 call C_LABEL(syscall_trace_exit)
902 nop
903 #endif
904
905 RESTORE_ALL
906
907 .globl C_LABEL(flush_user_windows)
908 C_LABEL(flush_user_windows):
909 LOAD_CURRENT(g2)
910 ld [%g2 + THREAD_UMASK], %g1
911 orcc %g0, %g1, %g0
912 be 3f
913 clr %g3
914 1:
915 _SV
916 LOAD_CURRENT(g2)
917 ld [%g2 + THREAD_UMASK], %g1
918 orcc %g0, %g1, %g0
919 bne 1b
920 add %g3, 1, %g3
921 2:
922 subcc %g3, 1, %g3
923 bne 2b
924 _RS
925 3:
926 jmp %o7 + 0x8
927 nop
928
929