3 * linux/arch/sh/entry.S
5 * Copyright (C) 1999 Niibe Yutaka
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
13 #include <linux/sys.h>
14 #include <linux/linkage.h>
17 ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
18 ! to be jumped is too far, but it causes illegal slot exception.
21 * entry.S contains the system-call and fault low-level handling routines.
22 * This also contains the timer-interrupt handler, as well as all interrupts
23 * and faults that can result in a task-switch.
25 * NOTE: This code handles signal-recognition, which happens every time
26 * after a timer-interrupt and after each system call.
28 * Stack layout in 'ret_from_syscall':
29 * ptrace needs to have all regs on the stack.
30 * if the order here is changed, it needs to be
31 * updated in process.c:copy_thread, signal.c:do_signal,
32 * ptrace.c and ptrace.h
48 * these are offsets into the task-struct.
64 /* Offsets to the stack */
74 #define kernel_sp r4 /* r4_bank1 */
75 #define ksp r4_bank /* r4_bank1 */
76 #define k_ex_code r2_bank /* r2_bank1 */
78 /* Kernel mode register usage:
81 k2 scratch (Exception code)
82 k3 scratch (Return address)
83 k4 Stack base = current+8192
90 ! TLB Miss / Initial Page write exception handling
92 ! TLB hits, but the access violate the protection.
93 ! It can be valid access, such as stack grow and/or C-O-W.
96 ! Find the pmd/pte entry and loadtlb
97 ! If it's not found, cause address error (SEGV)
99 ! Although this could be written in assembly language (and it'd be faster),
100 ! this first version depends *much* on C implementation.
102 MMU_TEA = 0xfffffffc ! TLB Exception Address Register
104 #define DO_FAULT(write) \
119 tlb_protection_violation_load:
122 mov.l r0,@r15 ! syscall nr = -1
126 tlb_protection_violation_store:
130 mov.l r0,@r15 ! syscall nr = -1
134 2: .long SYMBOL_NAME(do_page_fault)
135 3: .long 0xefffffff ! BL=0
146 mov.l r0,@r15 ! syscall nr = -1
151 1: .long SYMBOL_NAME(do_exception_error)
154 mova SYMBOL_NAME(ret_from_syscall),r0
159 1: .long SYMBOL_NAME(schedule)
161 badsys: mov #-ENOSYS,r0
162 bra SYMBOL_NAME(ret_from_syscall)
166 ! We can reach here from an interrupt handler,
167 ! so, we need to unblock interrupt.
180 1: .long 0xefffffff ! BL=0
181 2: .long SYMBOL_NAME(do_signal)
187 bra SYMBOL_NAME(ret_from_syscall)
188 add #4,r15 ! pop down bogus r0
191 ! The immediate value of "trapa" indicates the number of arguments
192 ! placed on the stack.
208 mov.l __tsk_flags,r0 !
210 mov.l @r1,r0 ! Is it trace?
225 ! Build the stack frame if TRA > 0
230 mov.l @(r0,r15),r0 ! get original stack
237 9: mov.l @(SYSCALL_NR,r15),r0
245 4: mov.l r0,@(R0,r15) ! save the return value
247 mova SYMBOL_NAME(ret_from_syscall),r0
251 3: .long SYMBOL_NAME(syscall_trace)
252 2: .long 0xefffffff ! BL=0
253 1: mov.l r0,@(R0,r15) ! save the return value
256 ENTRY(ret_from_syscall)
263 bt ret_with_reschedule
272 mov.l @(need_resched,r1),r0
275 mov.l @(sigpending,r1),r0
281 add #4,r15 ! skip syscall number
291 mov.l __blrb_flags,r9 ! BL =1, RB=1
293 ldc r14,sr ! here, change the register bank
313 __n_sys: .long NR_syscalls
314 __sct: .long SYMBOL_NAME(sys_call_table)
315 __bh_mask: .long SYMBOL_NAME(bh_mask)
316 __bh_active: .long SYMBOL_NAME(bh_active)
317 __dbh: .long SYMBOL_NAME(do_bottom_half)
318 __blrb_flags: .long 0x30000000
319 __minus8192: .long -8192 ! offset from stackbase to tsk
320 __tsk_flags: .long flags-8192 ! offset from stackbase to tsk->flags
323 ! Exception Vector Base
325 ! Should be aligned page boundary.
338 2: .long SYMBOL_NAME(ret_from_syscall)
356 3: .long SYMBOL_NAME(ret_from_syscall)
357 4: .long SYMBOL_NAME(ret_from_irq)
362 ! Using k0, k1 for scratch registers (r0_bank1, and r1_bank1),
363 ! save all registers onto stack.
366 stc ssr,k0 ! from kernel space?
367 shll k0 ! Check MD bit (bit30)
369 bt/s 1f ! it's from kernel to kernel transition
370 mov r15,k0 ! save original stack to k0 anyway
371 mov kernel_sp,r15 ! change to kernel stack
372 1: stc.l spc,@-r15 ! save control registers
376 lds k3,pr ! Set the return address to pr
381 mov.l k0,@-r15 ! save orignal stack, and general registers
384 stc sr,r14 ! back to normal register bank, and
386 ldc r14,sr ! ...changed here.
402 mov.l r0,@-r15 ! push r0 again (for syscall number)
403 ! Then, dispatch to the handler, according to the excepiton code.
411 mov.l @r15,r0 ! recovering r0..
413 1: .long SYMBOL_NAME(exception_handling_table)
414 2: .long 0xdfffffff ! RB=0, BL=1
417 ENTRY(exception_handling_table)
422 .long initial_page_write
423 .long tlb_protection_violation_load
424 .long tlb_protection_violation_store
425 .long error ! address_error_load (filled by trap_init)
426 .long error ! address_error_store (filled by trap_init)
429 .long system_call ! Unconditional Trap
430 .long error ! reserved_instruction (filled by trap_init)
431 .long error ! illegal_slot_instruction (filled by trap_init)
433 .long error ! Not implemented yet
434 ENTRY(user_break_point_trap)
435 .long error ! Not implemented yet
436 ENTRY(interrupt_table)
438 .long SYMBOL_NAME(do_IRQ) ! 0000
439 .long SYMBOL_NAME(do_IRQ) ! 0001
440 .long SYMBOL_NAME(do_IRQ) ! 0010
441 .long SYMBOL_NAME(do_IRQ) ! 0011
442 .long SYMBOL_NAME(do_IRQ) ! 0100
443 .long SYMBOL_NAME(do_IRQ) ! 0101
444 .long SYMBOL_NAME(do_IRQ) ! 0110
445 .long SYMBOL_NAME(do_IRQ) ! 0111
446 .long SYMBOL_NAME(do_IRQ) ! 1000
447 .long SYMBOL_NAME(do_IRQ) ! 1001
448 .long SYMBOL_NAME(do_IRQ) ! 1010
449 .long SYMBOL_NAME(do_IRQ) ! 1011
450 .long SYMBOL_NAME(do_IRQ) ! 1100
451 .long SYMBOL_NAME(do_IRQ) ! 1101
452 .long SYMBOL_NAME(do_IRQ) ! 1110
455 .long SYMBOL_NAME(do_IRQ) ! TMU0 tuni0
456 .long SYMBOL_NAME(do_IRQ) ! TMU1 tuni1
457 .long SYMBOL_NAME(do_IRQ) ! TMU2 tuni2
458 .long SYMBOL_NAME(do_IRQ) ! ticpi2
459 .long SYMBOL_NAME(do_IRQ) ! RTC ati
460 .long SYMBOL_NAME(do_IRQ) ! pri
461 .long SYMBOL_NAME(do_IRQ) ! cui
462 .long SYMBOL_NAME(do_IRQ) ! SCI eri
463 .long SYMBOL_NAME(do_IRQ) ! rxi
464 .long SYMBOL_NAME(do_IRQ) ! txi
465 .long SYMBOL_NAME(do_IRQ) ! tei
466 .long SYMBOL_NAME(do_IRQ) ! WDT iti
467 .long SYMBOL_NAME(do_IRQ) ! REF rcmi
468 .long SYMBOL_NAME(do_IRQ) ! rovi
469 .long SYMBOL_NAME(do_IRQ)
470 .long SYMBOL_NAME(do_IRQ)
471 .long SYMBOL_NAME(do_IRQ)
472 .long SYMBOL_NAME(do_IRQ)
473 .long SYMBOL_NAME(do_IRQ)
474 .long SYMBOL_NAME(do_IRQ)
475 .long SYMBOL_NAME(do_IRQ)
476 .long SYMBOL_NAME(do_IRQ)
477 .long SYMBOL_NAME(do_IRQ)
478 .long SYMBOL_NAME(do_IRQ)
480 ENTRY(sys_call_table)
481 .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/
482 .long SYMBOL_NAME(sys_exit)
483 .long SYMBOL_NAME(sys_fork)
484 .long SYMBOL_NAME(sys_read)
485 .long SYMBOL_NAME(sys_write)
486 .long SYMBOL_NAME(sys_open) /* 5 */
487 .long SYMBOL_NAME(sys_close)
488 .long SYMBOL_NAME(sys_waitpid)
489 .long SYMBOL_NAME(sys_creat)
490 .long SYMBOL_NAME(sys_link)
491 .long SYMBOL_NAME(sys_unlink) /* 10 */
492 .long SYMBOL_NAME(sys_execve)
493 .long SYMBOL_NAME(sys_chdir)
494 .long SYMBOL_NAME(sys_time)
495 .long SYMBOL_NAME(sys_mknod)
496 .long SYMBOL_NAME(sys_chmod) /* 15 */
497 .long SYMBOL_NAME(sys_lchown)
498 .long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
499 .long SYMBOL_NAME(sys_stat)
500 .long SYMBOL_NAME(sys_lseek)
501 .long SYMBOL_NAME(sys_getpid) /* 20 */
502 .long SYMBOL_NAME(sys_mount)
503 .long SYMBOL_NAME(sys_oldumount)
504 .long SYMBOL_NAME(sys_setuid)
505 .long SYMBOL_NAME(sys_getuid)
506 .long SYMBOL_NAME(sys_stime) /* 25 */
507 .long SYMBOL_NAME(sys_ptrace)
508 .long SYMBOL_NAME(sys_alarm)
509 .long SYMBOL_NAME(sys_fstat)
510 .long SYMBOL_NAME(sys_pause)
511 .long SYMBOL_NAME(sys_utime) /* 30 */
512 .long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */
513 .long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */
514 .long SYMBOL_NAME(sys_access)
515 .long SYMBOL_NAME(sys_nice)
516 .long SYMBOL_NAME(sys_ni_syscall) /* 35 */ /* old ftime syscall holder */
517 .long SYMBOL_NAME(sys_sync)
518 .long SYMBOL_NAME(sys_kill)
519 .long SYMBOL_NAME(sys_rename)
520 .long SYMBOL_NAME(sys_mkdir)
521 .long SYMBOL_NAME(sys_rmdir) /* 40 */
522 .long SYMBOL_NAME(sys_dup)
523 .long SYMBOL_NAME(sys_pipe)
524 .long SYMBOL_NAME(sys_times)
525 .long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
526 .long SYMBOL_NAME(sys_brk) /* 45 */
527 .long SYMBOL_NAME(sys_setgid)
528 .long SYMBOL_NAME(sys_getgid)
529 .long SYMBOL_NAME(sys_signal)
530 .long SYMBOL_NAME(sys_geteuid)
531 .long SYMBOL_NAME(sys_getegid) /* 50 */
532 .long SYMBOL_NAME(sys_acct)
533 .long SYMBOL_NAME(sys_umount) /* recycled never used phys() */
534 .long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
535 .long SYMBOL_NAME(sys_ioctl)
536 .long SYMBOL_NAME(sys_fcntl) /* 55 */
537 .long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */
538 .long SYMBOL_NAME(sys_setpgid)
539 .long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */
540 .long SYMBOL_NAME(sys_ni_syscall) /* sys_olduname */
541 .long SYMBOL_NAME(sys_umask) /* 60 */
542 .long SYMBOL_NAME(sys_chroot)
543 .long SYMBOL_NAME(sys_ustat)
544 .long SYMBOL_NAME(sys_dup2)
545 .long SYMBOL_NAME(sys_getppid)
546 .long SYMBOL_NAME(sys_getpgrp) /* 65 */
547 .long SYMBOL_NAME(sys_setsid)
548 .long SYMBOL_NAME(sys_sigaction)
549 .long SYMBOL_NAME(sys_sgetmask)
550 .long SYMBOL_NAME(sys_ssetmask)
551 .long SYMBOL_NAME(sys_setreuid) /* 70 */
552 .long SYMBOL_NAME(sys_setregid)
553 .long SYMBOL_NAME(sys_sigsuspend)
554 .long SYMBOL_NAME(sys_sigpending)
555 .long SYMBOL_NAME(sys_sethostname)
556 .long SYMBOL_NAME(sys_setrlimit) /* 75 */
557 .long SYMBOL_NAME(sys_getrlimit)
558 .long SYMBOL_NAME(sys_getrusage)
559 .long SYMBOL_NAME(sys_gettimeofday)
560 .long SYMBOL_NAME(sys_settimeofday)
561 .long SYMBOL_NAME(sys_getgroups) /* 80 */
562 .long SYMBOL_NAME(sys_setgroups)
563 .long SYMBOL_NAME(sys_ni_syscall) /* old_select */
564 .long SYMBOL_NAME(sys_symlink)
565 .long SYMBOL_NAME(sys_lstat)
566 .long SYMBOL_NAME(sys_readlink) /* 85 */
567 .long SYMBOL_NAME(sys_uselib)
568 .long SYMBOL_NAME(sys_swapon)
569 .long SYMBOL_NAME(sys_reboot)
570 .long SYMBOL_NAME(old_readdir)
571 .long SYMBOL_NAME(sys_ni_syscall) /* old_mmap */ /* 90 */
572 .long SYMBOL_NAME(sys_munmap)
573 .long SYMBOL_NAME(sys_truncate)
574 .long SYMBOL_NAME(sys_ftruncate)
575 .long SYMBOL_NAME(sys_fchmod)
576 .long SYMBOL_NAME(sys_fchown) /* 95 */
577 .long SYMBOL_NAME(sys_getpriority)
578 .long SYMBOL_NAME(sys_setpriority)
579 .long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */
580 .long SYMBOL_NAME(sys_statfs)
581 .long SYMBOL_NAME(sys_fstatfs) /* 100 */
582 .long SYMBOL_NAME(sys_ni_syscall) /* ioperm */
583 .long SYMBOL_NAME(sys_socketcall)
584 .long SYMBOL_NAME(sys_syslog)
585 .long SYMBOL_NAME(sys_setitimer)
586 .long SYMBOL_NAME(sys_getitimer) /* 105 */
587 .long SYMBOL_NAME(sys_newstat)
588 .long SYMBOL_NAME(sys_newlstat)
589 .long SYMBOL_NAME(sys_newfstat)
590 .long SYMBOL_NAME(sys_uname)
591 .long SYMBOL_NAME(sys_ni_syscall) /* 110 */ /* iopl */
592 .long SYMBOL_NAME(sys_vhangup)
593 .long SYMBOL_NAME(sys_ni_syscall) /* idle */
594 .long SYMBOL_NAME(sys_ni_syscall) /* vm86old */
595 .long SYMBOL_NAME(sys_wait4)
596 .long SYMBOL_NAME(sys_swapoff) /* 115 */
597 .long SYMBOL_NAME(sys_sysinfo)
598 .long SYMBOL_NAME(sys_ipc)
599 .long SYMBOL_NAME(sys_fsync)
600 .long SYMBOL_NAME(sys_sigreturn)
601 .long SYMBOL_NAME(sys_clone) /* 120 */
602 .long SYMBOL_NAME(sys_setdomainname)
603 .long SYMBOL_NAME(sys_newuname)
604 .long SYMBOL_NAME(sys_ni_syscall) /* sys_modify_ldt */
605 .long SYMBOL_NAME(sys_adjtimex)
606 .long SYMBOL_NAME(sys_mprotect) /* 125 */
607 .long SYMBOL_NAME(sys_sigprocmask)
608 .long SYMBOL_NAME(sys_create_module)
609 .long SYMBOL_NAME(sys_init_module)
610 .long SYMBOL_NAME(sys_delete_module)
611 .long SYMBOL_NAME(sys_get_kernel_syms) /* 130 */
612 .long SYMBOL_NAME(sys_quotactl)
613 .long SYMBOL_NAME(sys_getpgid)
614 .long SYMBOL_NAME(sys_fchdir)
615 .long SYMBOL_NAME(sys_bdflush)
616 .long SYMBOL_NAME(sys_sysfs) /* 135 */
617 .long SYMBOL_NAME(sys_personality)
618 .long SYMBOL_NAME(sys_ni_syscall) /* for afs_syscall */
619 .long SYMBOL_NAME(sys_setfsuid)
620 .long SYMBOL_NAME(sys_setfsgid)
621 .long SYMBOL_NAME(sys_llseek) /* 140 */
622 .long SYMBOL_NAME(sys_getdents)
623 .long SYMBOL_NAME(sys_select)
624 .long SYMBOL_NAME(sys_flock)
625 .long SYMBOL_NAME(sys_msync)
626 .long SYMBOL_NAME(sys_readv) /* 145 */
627 .long SYMBOL_NAME(sys_writev)
628 .long SYMBOL_NAME(sys_getsid)
629 .long SYMBOL_NAME(sys_fdatasync)
630 .long SYMBOL_NAME(sys_sysctl)
631 .long SYMBOL_NAME(sys_mlock) /* 150 */
632 .long SYMBOL_NAME(sys_munlock)
633 .long SYMBOL_NAME(sys_mlockall)
634 .long SYMBOL_NAME(sys_munlockall)
635 .long SYMBOL_NAME(sys_sched_setparam)
636 .long SYMBOL_NAME(sys_sched_getparam) /* 155 */
637 .long SYMBOL_NAME(sys_sched_setscheduler)
638 .long SYMBOL_NAME(sys_sched_getscheduler)
639 .long SYMBOL_NAME(sys_sched_yield)
640 .long SYMBOL_NAME(sys_sched_get_priority_max)
641 .long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */
642 .long SYMBOL_NAME(sys_sched_rr_get_interval)
643 .long SYMBOL_NAME(sys_nanosleep)
644 .long SYMBOL_NAME(sys_mremap)
645 .long SYMBOL_NAME(sys_setresuid)
646 .long SYMBOL_NAME(sys_getresuid) /* 165 */
647 .long SYMBOL_NAME(sys_ni_syscall) /* vm86 */
648 .long SYMBOL_NAME(sys_query_module)
649 .long SYMBOL_NAME(sys_poll)
650 .long SYMBOL_NAME(sys_nfsservctl)
651 .long SYMBOL_NAME(sys_setresgid) /* 170 */
652 .long SYMBOL_NAME(sys_getresgid)
653 .long SYMBOL_NAME(sys_prctl)
654 .long SYMBOL_NAME(sys_rt_sigreturn)
655 .long SYMBOL_NAME(sys_rt_sigaction)
656 .long SYMBOL_NAME(sys_rt_sigprocmask) /* 175 */
657 .long SYMBOL_NAME(sys_rt_sigpending)
658 .long SYMBOL_NAME(sys_rt_sigtimedwait)
659 .long SYMBOL_NAME(sys_rt_sigqueueinfo)
660 .long SYMBOL_NAME(sys_rt_sigsuspend)
661 .long SYMBOL_NAME(sys_pread) /* 180 */
662 .long SYMBOL_NAME(sys_pwrite)
663 .long SYMBOL_NAME(sys_chown)
664 .long SYMBOL_NAME(sys_getcwd)
665 .long SYMBOL_NAME(sys_capget)
666 .long SYMBOL_NAME(sys_capset) /* 185 */
667 .long SYMBOL_NAME(sys_sigaltstack)
668 .long SYMBOL_NAME(sys_sendfile)
669 .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
670 .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
671 .long SYMBOL_NAME(sys_vfork) /* 190 */
674 * NOTE!! This doesn't have to be exact - we just have
675 * to make sure we have _enough_ of the "sys_ni_syscall"
676 * entries. Don't panic if you notice that this hasn't
677 * been shrunk every time we add a new system call.
679 .rept NR_syscalls-190
680 .long SYMBOL_NAME(sys_ni_syscall)