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