1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <linux/sys.h>
15 #include <asm/segment.h>
16 #include <asm/mipsregs.h>
17 #include <asm/mipsconfig.h>
18 #include <asm/mm.h>
19 #include <asm/stackframe.h>
20 #include <asm/regdef.h>
21 #include <asm/processor.h>
22
23
24
25
26 state = 0
27 counter = 4
28 priority = 8
29 signal = 12
30 blocked = 16
31 flags = 20
32 errno = 24 #
33 exec_domain = 60 #
34
35 ENOSYS = 38
36
37 .globl ret_from_sys_call
38 .globl _sys_call_table
39
40 .text
41 .set noreorder
42 .align 4
43 handle_bottom_half:
44
45
46
47
48 lui s0,%hi(_intr_count)
49 lw s1,%lo(_intr_count)(s0)
50 mfc0 s3,CP0_STATUS # Enable IRQs
51 addiu s2,s1,1
52 sw s2,%lo(_intr_count)(s0)
53 ori t0,s3,0x1f
54 xori t0,t0,0x1e
55 jal _do_bottom_half
56 mtc0 t0,CP0_STATUS # delay slot
57 mtc0 s3,CP0_STATUS # Restore old IRQ state
58 j 9f
59 sw s1,%lo(_intr_count)(s0) # delay slot
60
61 .set reorder
62 reschedule:
63 la ra,ret_from_sys_call
64 j _schedule
65 nop
66
67 .align 5
68 .globl _handle_sys
69 _handle_sys:
70 .set noreorder
71 .set noat
72 SAVE_ALL
73 .set at
74 STI
75
76
77
78
79
80 lw t3,FR_EPC(sp)
81 lw s1,FR_REG2(sp)
82 li t0,-ENOSYS
83 addiu t3,t3,4
84 sw t3,FR_EPC(sp)
85 li t2,NR_syscalls
86 bge s1,t2,ret_from_sys_call
87 sw t0,FR_REG2(sp) # delay slot
88 sll s1,s1,2
89 lw s1,_sys_call_table(s1)
90 lw s0,_current
91
92 beqz s1,ret_from_sys_call
93 lw t0,flags(s0)
94 sll t0,t0,2 # PF_TRACESYS
95 bltz t0,1f
96 sw zero,errno(s0) # delay slot
97
98 lw a0,FR_REG4(sp)
99 lw a1,FR_REG5(sp)
100 lw a2,FR_REG6(sp)
101 lw a3,FR_REG7(sp)
102 lw t0,FR_REG3(sp)
103 jalr s1 # do the real work
104 sw t0,16(sp) # delay slot
105
106 lw t0,errno(s0)
107 sw v0,FR_REG2(sp) # save the return value
108 subu t0,zero,t0 # t0 = -t0
109 beqz t0,ret_from_sys_call
110 nop
111
112
113
114 j ret_from_sys_call
115 sw t0,FR_REG2(sp) # delay slot
116
117 .align 4
118 1: jal _syscall_trace
119 nop # delay slot
120
121 lw a0,FR_REG4(sp)
122 lw a1,FR_REG5(sp)
123 lw a2,FR_REG6(sp)
124 lw a3,FR_REG7(sp)
125 lw t0,FR_REG3(sp)
126 jalr s1 # do the real work
127 sw t0,16(sp) # delay slot
128
129 lw t0,errno(s0)
130 sw v0,FR_REG2(sp) # save the return value
131 subu t0,zero,t0
132 beqz t0,1f
133 nop # delay slot
134 sw t1,FR_REG2(sp)
135
136
137
138 1: jal _syscall_trace
139 nop
140
141 .align 4
142 ret_from_sys_call:
143 lw t0,_intr_count # bottom half
144 bnez t0,2f
145 9:
146 lw t0,_bh_mask # delay slot
147 lw t1,_bh_active # unused delay slot
148 and t0,t1
149 bnez t0,handle_bottom_half
150
151 lw t0,FR_STATUS(sp) # returning to supervisor ?
152 andi t1,t0,0x10
153 beqz t1,2f
154
155 mfc0 t0,CP0_STATUS # delay slot
156 lw t1,_need_resched
157 ori t0,0x1f # enable irqs
158 xori t0,0x1e
159 bnez t1,reschedule
160 mtc0 t0,CP0_STATUS # delay slot
161
162 lw s0,_current
163 lw t0,_task
164 lw t1,state(s0) # state
165 beq s0,t0,2f # task[0] cannot have signals
166 lw t0,counter(s0) # counter
167 bnez t1,reschedule # state == 0 ?
168 lw a0,blocked(s0)
169
170
171 beqz t0,reschedule # counter == 0 ?
172 lw t0,signal(s0)
173 nor t1,zero,a0
174 and t1,t0,t1
175 beqz t1,skip_signal_return
176 nop
177
178 jal _do_signal
179 move a1,sp # delay slot
180
181 skip_signal_return:
182 .set noreorder
183 .set noat
184 2:
185 return: RESTORE_ALL
186 .set at
187
188
189
190
191
192 .text
193 .set noreorder
194 .set noat
195 .globl _handle_int
196 .align 5
197 _handle_int: SAVE_ALL
198 .set at
199 CLI
200 lui s0,%hi(PORT_BASE)
201 li t1,0x0f
202 sb t1,%lo(PORT_BASE+0x20)(s0) # poll command
203 lb t1,%lo(PORT_BASE+0x20)(s0) # read result
204 li s1,1
205 bgtz t1,poll_second
206 andi t1,t1,7
207
208
209
210 lb t2,%lo(PORT_BASE+0x21)(s0)
211 lui s4,%hi(_cache_21)
212 lb t0,%lo(_cache_21)(s4)
213 sllv s1,s1,t1
214 or t0,t0,s1
215 sb t0,%lo(_cache_21)(s4)
216 sb t0,%lo(PORT_BASE+0x21)(s0)
217 lui s3,%hi(_intr_count)
218 lw t0,%lo(_intr_count)(s3)
219 li t2,0x20
220 sb t2,%lo(PORT_BASE+0x20)(s0)
221
222
223
224 la t3,_IRQ_vectors
225 sll t2,t1,2
226 addu t3,t3,t2
227 lw t3,(t3)
228 addiu t0,t0,1
229 jalr t3
230 sw t0,%lo(_intr_count)(s3) # delay slot
231 lw t0,%lo(_intr_count)(s3)
232
233
234
235 lbu t1,%lo(PORT_BASE+0x21)(s0)
236 lb t1,%lo(_cache_21)(s4)
237 subu t0,t0,1
238 sw t0,%lo(_intr_count)(s3)
239 nor s1,zero,s1
240 and t1,t1,s1
241 sb t1,%lo(_cache_21)(s4)
242 jr v0
243 sb t1,%lo(PORT_BASE+0x21)(s0) # delay slot
244
245 .align 5
246 poll_second: li t1,0x0f
247 sb t1,%lo(PORT_BASE+0xa0)(s0) # poll command
248 lb t1,%lo(PORT_BASE+0xa0)(s0) # read result
249 lui s4,%hi(_cache_A1)
250 bgtz t1,spurious_interrupt
251 andi t1,t1,7
252
253
254
255 lbu t2,%lo(PORT_BASE+0xa1)(s0)
256 lb t3,%lo(_cache_A1)(s4)
257 sllv s1,s1,t1
258 or t3,t3,s1
259 sb t3,%lo(_cache_A1)(s4)
260 sb t3,%lo(PORT_BASE+0xa1)(s0)
261 li t3,0x20
262 sb t3,%lo(PORT_BASE+0xa0)(s0)
263 lui s3,%hi(_intr_count)
264 lw t0,%lo(_intr_count)(s3)
265 sb t3,%lo(PORT_BASE+0x20)(s0)
266
267
268
269 la t0,_IRQ_vectors
270 sll t2,t1,2
271 addu t0,t0,t2
272 lw t0,32(t0)
273 addiu t0,t0,1
274 jalr t0
275 sw t0,%lo(_intr_count)(s3) # delay slot
276 lw t0,%lo(_intr_count)(s3)
277
278
279
280 lb t1,%lo(PORT_BASE+0xa1)(s0)
281 lb t1,%lo(_cache_A1)(s4)
282 subu t0,t0,1
283 lw t0,%lo(_intr_count)(s3)
284 nor s1,zero,s1
285 and t1,t1,s1
286 sb t1,%lo(_cache_A1)(s4)
287 jr v0
288 sb t1,%lo(PORT_BASE+0xa1)(s0) # delay slot
289
290 .align 5
291 spurious_interrupt:
292
293
294
295 lui t1,%hi(_spurious_count)
296 lw t0,%lo(_spurious_count)(t1)
297 la v0,return
298 addiu t0,t0,1
299 jr ra
300 sw t0,%lo(_spurious_count)(t1)
301
302 .globl _interrupt
303 .align 5
304 _interrupt: move s2,ra
305 mfc0 t0,CP0_STATUS
306 ori t0,t0,0x1f
307 xori t0,t0,0x1e
308 mtc0 t0,CP0_STATUS
309 move a0,t1
310 jal _do_IRQ
311 move a1,sp # delay slot
312 mfc0 t0,CP0_STATUS
313 ori t0,t0,1
314 xori t0,t0,1
315 la v0,ret_from_sys_call
316 jr s2
317 mtc0 t0,CP0_STATUS # delay slot
318
319 .globl _fast_interrupt
320 .align 5
321 _fast_interrupt:
322 move s2,ra
323 move a0,t1
324 jal _do_fast_IRQ
325 move a1,sp # delay slot
326 la v0,return
327 jr s2
328 nop # delay slot
329
330 .globl _bad_interrupt
331 _bad_interrupt:
332
333
334
335 j return
336 nop
337
338 .globl _handle_tlbl
339 .align 5
340 _handle_tlbl:
341 .set noreorder
342 .set noat
343
344
345
346
347
348
349
350
351 mfc0 k0,CP0_BADVADDR
352 mfc0 k1,CP0_ENTRYHI
353 ori k0,k0,0x1fff
354 xori k0,k0,0x1fff
355 andi k1,k1,0xff
356 or k0,k0,k1
357 mfc0 k1,CP0_ENTRYHI
358 mtc0 k0,CP0_ENTRYHI
359 nop # for R4[04]00 pipeline
360 nop
361 nop
362 tlbp
363 nop # for R4[04]00 pipeline
364 nop
365 mfc0 k0,CP0_INDEX
366 srl k0,k0,31
367 beqz k0,invalid_tlbl
368 mtc0 k1,CP0_ENTRYHI # delay slot
369
370
371
372
373
374 dmfc0 k1,CP0_CONTEXT
375 dsra k1,k1,1
376 lwu k0,(k1) # Never causes another exception
377 lwu k1,4(k1)
378 dsrl k0,k0,6 # Convert to EntryLo format
379 dsrl k1,k1,6 # Convert to EntryLo format
380 dmtc0 k0,CP0_ENTRYLO0
381 dmtc0 k1,CP0_ENTRYLO1
382 nop # for R4[04]00 pipeline
383 tlbwr
384 eret
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399 invalid_tlbl:
400
401
402
403 mfc0 k0,CP0_INDEX
404 lui k1,0x0008
405 or k0,k0,k1
406 dsll k0,k0,13
407 dmtc0 k0,CP0_ENTRYHI
408 dmtc0 zero,CP0_ENTRYLO0
409 dmtc0 zero,CP0_ENTRYLO1
410
411
412
413 dmfc0 k0,CP0_BADVADDR
414 tlbwi # delayed, for R4[04]00 pipeline
415 srl k0,k0,10
416 lui k1,%HI(TLBMAP)
417 addu k0,k0,k1
418 ori k0,k0,3
419 xori k0,k0,3
420 lw k1,(k0)
421 andi k1,k1,PAGE_PRESENT
422 beqz k1,nopage_tlbl
423
424
425
426 lw k1,(k0) # delay slot
427 ori k1,k1,PAGE_ACCESSED
428 sw k1,(k0)
429 eret
430
431
432
433
434
435
436 nopage_tlbl:
437 SAVE_ALL
438 .set at
439 STI
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455 lw a1,FR_STATUS(sp)
456 move a0,sp
457 srl a1,a1,4
458 andi a1,a1,1
459 jal _do_page_fault
460 xori a1,a1,1 # delay slot
461 j ret_from_sys_call
462 nop # delay slot
463
464 .text
465 .globl _handle_tlbs
466 .align 5
467 _handle_tlbs:
468 .set noreorder
469 .set noat
470
471
472
473
474
475
476
477
478
479 dmfc0 k0,CP0_BADVADDR
480 srl k0,k0,10
481 lui k1,%HI(TLBMAP)
482 addu k0,k0,k1
483 ori k0,k0,3
484 xori k0,k0,3
485 lw k1,(k0)
486 andi k1,k1,(PAGE_PRESENT|PAGE_RW)
487 beqz k1,nopage_tlbs
488
489
490
491 lw k1,(k0) # delay slot
492 ori k1,k1,PAGE_ACCESSED|PAGE_DIRTY
493 sw k1,(k0)
494
495
496
497 ori k0,k0,0x1000
498 xori k0,k0,0x1000
499 lw k1,4(k0)
500 lw k0,(k0)
501 srl k0,k0,6
502 srl k1,k1,6
503 dmtc0 k0,CP0_ENTRYLO0
504 dmtc0 k1,CP0_ENTRYLO1
505 tlbwi
506 eret
507
508
509
510
511
512
513 nopage_tlbs:
514 nowrite_mod:
515
516
517
518 mfc0 k0,CP0_INDEX
519 lui k1,0x0008
520 or k0,k0,k1
521 dsll k0,k0,13
522 dmtc0 k0,CP0_ENTRYHI
523 dmtc0 zero,CP0_ENTRYLO0
524 dmtc0 zero,CP0_ENTRYLO1
525 tlbwi
526 SAVE_ALL
527 .set at
528 STI
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544 lw a1,FR_STATUS(sp)
545 move a0,sp
546 srl a1,a1,4
547 andi a1,a1,1
548 jal _do_page_fault
549 xori a1,a1,3 # branch delay slot
550 j ret_from_sys_call
551 nop # branch delay slot
552
553 .globl _handle_mod
554 .align 5
555 _handle_mod:
556 .set noreorder
557 .set noat
558
559
560
561
562
563 dmfc0 k0,CP0_BADVADDR
564 srl k0,k0,10
565 lui k1,%HI(TLBMAP)
566 addu k0,k0,k1
567 ori k0,k0,3
568 xori k0,k0,3
569 lw k1,(k0)
570 andi k1,k1,PAGE_RW
571 beqz k1,nopage_tlbs
572
573
574
575 lw k1,(k0) # delay slot
576 ori k1,k1,(PAGE_ACCESSED|PAGE_DIRTY)
577 sw k1,(k0)
578
579
580
581 ori k0,k0,0x1000
582 xori k0,k0,0x1000
583 lw k1,4(k0)
584 lw k0,(k0)
585 srl k0,k0,6
586 srl k1,k1,6
587 dmtc0 k0,CP0_ENTRYLO0
588 dmtc0 k1,CP0_ENTRYLO1
589 tlbwi
590 eret
591
592 .globl _handle_adel
593 .align 5
594 _handle_adel:
595 .set noreorder
596 .set noat
597 SAVE_ALL
598 STI
599 li t0,-1
600 sw t0,FR_ORIG_REG2(sp)
601 jal _do_adel
602 move a0,sp # delay slot
603 j ret_from_sys_call
604 nop # delay slot
605
606 .globl _handle_ades
607 .align 5
608 _handle_ades:
609 .set noreorder
610 .set noat
611 SAVE_ALL
612 STI
613 li t0,-1
614 sw t0,FR_ORIG_REG2(sp)
615 jal _do_ades
616 move a0,sp # delay slot
617 j ret_from_sys_call
618 nop # delay slot
619
620 .globl _handle_ibe
621 .align 5
622 _handle_ibe:
623 .set noreorder
624 .set noat
625 SAVE_ALL
626 STI
627 li t0,-1
628 sw t0,FR_ORIG_REG2(sp)
629 jal _do_ibe
630 move a0,sp # delay slot
631 j ret_from_sys_call
632 nop # delay slot
633
634 .globl _handle_dbe
635 .align 5
636 _handle_dbe:
637 .set noreorder
638 .set noat
639 SAVE_ALL
640 STI
641 li t0,-1
642 sw t0,FR_ORIG_REG2(sp)
643 jal _do_dbe
644 move a0,sp # delay slot
645 j ret_from_sys_call
646 nop # delay slot
647
648 .globl _handle_ov
649 .align 5
650 _handle_ov:
651 .set noreorder
652 .set noat
653 SAVE_ALL
654 STI
655 li t0,-1
656 sw t0,FR_ORIG_REG2(sp)
657 jal _do_ov
658 move a0,sp # delay slot
659 j ret_from_sys_call
660 nop # delay slot
661
662 .globl _handle_fpe
663 .align 5
664 _handle_fpe:
665 .set noreorder
666 .set noat
667 SAVE_ALL
668 STI
669 li t0,-1
670 sw t0,FR_ORIG_REG2(sp)
671 jal _do_fpe
672 move a0,sp # delay slot
673 j ret_from_sys_call
674 nop # delay slot
675
676 .globl _handle_bp
677 .align 5
678 _handle_bp:
679 .set noreorder
680 .set noat
681 SAVE_ALL
682 STI
683 li t0,-1
684 sw t0,FR_ORIG_REG2(sp)
685 jal _do_bp
686 move a0,sp # delay slot
687 j ret_from_sys_call
688 nop # delay slot
689
690 .globl _handle_tr
691 .align 5
692 _handle_tr:
693 .set noreorder
694 .set noat
695 SAVE_ALL
696 STI
697 li t0,-1
698 sw t0,FR_ORIG_REG2(sp)
699 jal _do_tr
700 move a0,sp # delay slot
701 j ret_from_sys_call
702 nop # delay slot
703
704 .globl _handle_ri
705 .align 5
706 _handle_ri:
707 .set noreorder
708 .set noat
709 SAVE_ALL
710 STI
711 li t0,-1
712 sw t0,FR_ORIG_REG2(sp)
713 jal _do_ri
714 move a0,sp # delay slot
715 j ret_from_sys_call
716 nop # delay slot
717
718 .globl _handle_cpu
719 .align 5
720 _handle_cpu:
721 .set noreorder
722 .set noat
723 SAVE_ALL
724 STI
725 li t0,-1
726 sw t0,FR_ORIG_REG2(sp)
727 jal _do_cpu
728 move a0,sp # delay slot
729 j ret_from_sys_call
730 nop # delay slot
731
732 .globl _handle_vcei
733 .align 5
734 _handle_vcei:
735 .set noreorder
736 .set noat
737 SAVE_ALL
738 STI
739 li t0,-1
740 sw t0,FR_ORIG_REG2(sp)
741 jal _do_vcei
742 move a0,sp # delay slot
743 j ret_from_sys_call
744 nop # delay slot
745
746 .globl _handle_vced
747 .align 5
748 _handle_vced:
749 .set noreorder
750 .set noat
751 SAVE_ALL
752 STI
753 li t0,-1
754 sw t0,FR_ORIG_REG2(sp)
755 jal _do_vced
756 move a0,sp # delay slot
757 j ret_from_sys_call
758 nop # delay slot
759
760 .globl _handle_watch
761 .align 5
762 _handle_watch:
763 .set noreorder
764 .set noat
765 SAVE_ALL
766 STI
767 li t0,-1
768 sw t0,FR_ORIG_REG2(sp)
769 jal _do_watch
770 move a0,sp # delay slot
771 j ret_from_sys_call
772 nop # delay slot
773
774 .globl _handle_reserved
775 .align 5
776 _handle_reserved:
777 .set noreorder
778 .set noat
779 SAVE_ALL
780 STI
781 li t0,-1
782 sw t0,FR_ORIG_REG2(sp)
783 jal _do_reserved
784 move a0,sp # delay slot
785 j ret_from_sys_call
786 nop # delay slot
787
788
789
790
791
792 .bss
793 .globl _exception_handlers
794 .align 2
795 _exception_handlers:
796 .fill 32,4,0
797
798
799
800
801 .data
802 _sys_call_table:
803 .word _sys_setup
804 .word _sys_exit
805 .word _sys_fork
806 .word _sys_read
807 .word _sys_write
808 .word _sys_open
809 .word _sys_close
810 .word _sys_waitpid
811 .word _sys_creat
812 .word _sys_link
813 .word _sys_unlink
814 .word _sys_execve
815 .word _sys_chdir
816 .word _sys_time
817 .word _sys_mknod
818 .word _sys_chmod
819 .word _sys_chown
820 .word _sys_break
821 .word _sys_stat
822 .word _sys_lseek
823 .word _sys_getpid
824 .word _sys_mount
825 .word _sys_umount
826 .word _sys_setuid
827 .word _sys_getuid
828 .word _sys_stime
829 .word _sys_ptrace
830 .word _sys_alarm
831 .word _sys_fstat
832 .word _sys_pause
833 .word _sys_utime
834 .word _sys_stty
835 .word _sys_gtty
836 .word _sys_access
837 .word _sys_nice
838 .word _sys_ftime
839 .word _sys_sync
840 .word _sys_kill
841 .word _sys_rename
842 .word _sys_mkdir
843 .word _sys_rmdir
844 .word _sys_dup
845 .word _sys_pipe
846 .word _sys_times
847 .word _sys_prof
848 .word _sys_brk
849 .word _sys_setgid
850 .word _sys_getgid
851 .word _sys_signal
852 .word _sys_geteuid
853 .word _sys_getegid
854 .word _sys_acct
855 .word _sys_phys
856 .word _sys_lock
857 .word _sys_ioctl
858 .word _sys_fcntl
859 .word _sys_mpx
860 .word _sys_setpgid
861 .word _sys_ulimit
862 .word _sys_olduname
863 .word _sys_umask
864 .word _sys_chroot
865 .word _sys_ustat
866 .word _sys_dup2
867 .word _sys_getppid
868 .word _sys_getpgrp
869 .word _sys_setsid
870 .word _sys_sigaction
871 .word _sys_sgetmask
872 .word _sys_ssetmask
873 .word _sys_setreuid
874 .word _sys_setregid
875 .word _sys_sigsuspend
876 .word _sys_sigpending
877 .word _sys_sethostname
878 .word _sys_setrlimit
879 .word _sys_getrlimit
880 .word _sys_getrusage
881 .word _sys_gettimeofday
882 .word _sys_settimeofday
883 .word _sys_getgroups
884 .word _sys_setgroups
885 .word _sys_select
886 .word _sys_symlink
887 .word _sys_lstat
888 .word _sys_readlink
889 .word _sys_uselib
890 .word _sys_swapon
891 .word _sys_reboot
892 .word _sys_readdir
893 .word _sys_mmap
894 .word _sys_munmap
895 .word _sys_truncate
896 .word _sys_ftruncate
897 .word _sys_fchmod
898 .word _sys_fchown
899 .word _sys_getpriority
900 .word _sys_setpriority
901 .word _sys_profil
902 .word _sys_statfs
903 .word _sys_fstatfs
904 .word _sys_ioperm
905 .word _sys_socketcall
906 .word _sys_syslog
907 .word _sys_setitimer
908 .word _sys_getitimer
909 .word _sys_newstat
910 .word _sys_newlstat
911 .word _sys_newfstat
912 .word _sys_uname
913 .word _sys_iopl
914 .word _sys_vhangup
915 .word _sys_idle
916 .word 0 #_sys_vm86
917 .word _sys_wait4
918 .word _sys_swapoff
919 .word _sys_sysinfo
920 .word _sys_ipc
921 .word _sys_fsync
922 .word _sys_sigreturn
923 .word _sys_clone
924 .word _sys_setdomainname
925 .word _sys_newuname
926 .word 0 #_sys_modify_ldt
927 .word _sys_adjtimex
928 .word _sys_mprotect
929 .word _sys_sigprocmask
930 .word _sys_create_module
931 .word _sys_init_module
932 .word _sys_delete_module
933 .word _sys_get_kernel_syms
934 .word _sys_quotactl
935 .word _sys_getpgid
936 .word _sys_fchdir
937 .word _sys_bdflush
938 .word _sys_sysfs
939 .word _sys_personality
940 .word 0
941 .word _sys_setfsuid
942 .word _sys_setfsgid
943 .word _sys_llseek
944 .space (NR_syscalls-140)*4
945
946 .bss
947 .globl _IRQ_vectors
948 _IRQ_vectors: .fill 16,4,0
949