📄 entry.s
字号:
#ifdef COMPAT_OLD_SYSCALL_ABI! Handle old ABI system call.! Note that ptrace(SYSCALL) is not supported for the old ABI.! At this point:! $r0, $r4-7 as per ABI! $r8 = value of TRA register (= num_args<<2)! $r14 = points to SYSCALL_NR in stack frameold_abi_system_call: mov $r0, $r9 ! Save system call number in $r9 ! ! arrange for return which pops stack mov.l __old_abi_syscall_ret, $r10 lds $r10, $pr ! Build the stack frame if TRA > 0 mov $r8, $r10 cmp/pl $r10 bf 0f mov.l @(SP,$r15), $r0 ! get original user stack7: add #-4, $r104: mov.l @($r0,$r10), $r1 ! May cause address error exception.. mov.l $r1, @-$r15 cmp/pl $r10 bt 7b0: mov.l $r9, @$r14 ! set syscall_nr STI() ! Call the system call handler through the table. ! First check for bad syscall number mov.l __n_sys, $r10 cmp/hs $r10, $r9 bf 2f ! Bad syscall number rts ! return to old_abi_syscall_ret mov #-ENOSYS, $r0 ! Good syscall number2: shll2 $r9 ! x4 mov.l __sct, $r11 add $r11, $r9 mov.l @$r9, $r11 jmp @$r11 ! call specific syscall handler, nop .align 2__old_abi_syscall_ret: .long old_abi_syscall_ret ! This code gets called on address error exception when copying ! syscall arguments from user stack to kernel stack. It is ! supposed to return -EINVAL through old_abi_syscall_ret, but it ! appears to have been broken for a long time in that the $r0 ! return value will be saved into the kernel stack relative to $r15 ! but the value of $r15 is not correct partway through the loop. ! So the user prog is returned its old $r0 value, not -EINVAL. ! Greg Banks 28 Aug 2000. .section .fixup,"ax"fixup_syscall_argerr: ! First get $r15 back to rts mov #-EINVAL, $r0 .previous .section __ex_table, "a" .align 2 .long 4b,fixup_syscall_argerr .previous#endif .align 2__TRA: .long TRA__syscall_trace: .long SYMBOL_NAME(syscall_trace)__n_sys:.long NR_syscalls__sct: .long SYMBOL_NAME(sys_call_table)__syscall_ret_trace: .long syscall_ret_trace__syscall_ret: .long SYMBOL_NAME(syscall_ret) .align 2reschedule: mova SYMBOL_NAME(ret_from_syscall), $r0 mov.l 1f, $r1 jmp @$r1 lds $r0, $pr .align 21: .long SYMBOL_NAME(schedule)ENTRY(ret_from_irq) mov #SR, $r0 mov.l @($r0,$r15), $r0 ! get status register shll $r0 shll $r0 ! kernel space? bt restore_all ! Yes, it's from kernel, go back soon ! STI() bra ret_with_reschedule nopENTRY(ret_from_exception) mov #SR, $r0 mov.l @($r0,$r15), $r0 ! get status register shll $r0 shll $r0 ! kernel space? bt restore_all ! Yes, it's from kernel, go back soon ! STI() bra ret_from_syscall nop .align 2__INV_IMASK: .long 0xffffff0f ! ~(IMASK) .align 2#ifdef COMPAT_OLD_SYSCALL_ABIold_abi_syscall_ret: add $r8, $r15 ! pop off the arguments /* fall through */#endifsyscall_ret: mov.l $r0, @(R0,$r15) ! save the return value /* fall through */ENTRY(ret_from_syscall) mov.l __irq_stat, $r0 ! softirq_active mov.l @$r0, $r1 mov.l @(4,$r0), $r2 ! softirq_mask tst $r2, $r1 bt ret_with_reschedulehandle_softirq: mov.l __do_softirq, $r0 jsr @$r0 nopret_with_reschedule: stc $k_current, $r1 mov.l @(need_resched,$r1), $r0 tst #0xff, $r0 bf reschedule mov.l @(sigpending,$r1), $r0 tst #0xff, $r0 bt restore_allsignal_return: mov $r15, $r4 mov #0, $r5 mov.l __do_signal, $r1 mova restore_all, $r0 jmp @$r1 lds $r0, $pr .align 2__do_signal: .long SYMBOL_NAME(do_signal)__irq_stat: .long SYMBOL_NAME(irq_stat)__do_softirq: .long SYMBOL_NAME(do_softirq) .align 2restore_all:#if defined(__SH4__) mov.l __fpu_prepare_fd, $r0 jsr @$r0 stc $sr, $r4#endif ! mov.l @$r15+, $r0 mov.l @$r15+, $r1 mov.l @$r15+, $r2 mov.l @$r15+, $r3 mov.l @$r15+, $r4 mov.l @$r15+, $r5 mov.l @$r15+, $r6 mov.l @$r15+, $r7 ! stc $sr, $r8 mov.l __blrb_flags, $r9 ! BL =1, RB=1 or $r9, $r8 ldc $r8, $sr ! here, change the register bank ! mov.l @$r15+, $r8 mov.l @$r15+, $r9 mov.l @$r15+, $r10 mov.l @$r15+, $r11 mov.l @$r15+, $r12 mov.l @$r15+, $r13 mov.l @$r15+, $r14 mov.l @$r15+, $k4 ! original stack pointer ldc.l @$r15+, $spc lds.l @$r15+, $pr mov.l @$r15+, $k3 ! original SR ldc.l @$r15+, $gbr lds.l @$r15+, $mach lds.l @$r15+, $macl add #4, $r15 ! Skip syscall number ! ! Calculate new SR value mov $k3, $k2 ! original SR value mov.l 1f, $k1 stc $sr, $k0 and $k1, $k0 ! Get current FD-bit mov.l 2f, $k1 and $k1, $k2 ! Mask orignal SR value or $k0, $k2 ! Inherit current FD-bit ! mov $k3, $k0 ! Calculate IMASK-bits shlr2 $k0 and #0x3c, $k0 cmp/eq #0x3c, $k0 bt/s 7f shll2 $k0 mov $g_imask, $k0 !7: or $k0, $k2 ! Set the IMASK-bits ldc $k2, $ssr !#if defined(__SH4__) shll $k2 shll $k2 bf 9f ! user mode /* Kernel to kernel transition */ mov.l 1f, $k1 tst $k1, $k3 bf 9f ! it hadn't FPU ! Kernel to kernel and FPU was used ! There's the case we don't get FPU now stc $sr, $k2 tst $k1, $k2 bt 8f ! We need to grab FPU here xor $k1, $k2 ldc $k2, $sr ! Grab FPU mov.l __init_task_flags, $k1 mov.l @$k1, $k2 mov.l __PF_USEDFPU, $k0 or $k0, $k2 mov.l $k2, @$k1 ! Set init_task.flags |= PF_USEDFPU ! ! Restoring FPU... !8: mov.l 3f, $k1 lds $k1, $fpscr fmov.s @$r15+, $fr0 fmov.s @$r15+, $fr1 fmov.s @$r15+, $fr2 fmov.s @$r15+, $fr3 fmov.s @$r15+, $fr4 fmov.s @$r15+, $fr5 fmov.s @$r15+, $fr6 fmov.s @$r15+, $fr7 fmov.s @$r15+, $fr8 fmov.s @$r15+, $fr9 fmov.s @$r15+, $fr10 fmov.s @$r15+, $fr11 fmov.s @$r15+, $fr12 fmov.s @$r15+, $fr13 fmov.s @$r15+, $fr14 fmov.s @$r15+, $fr15 lds.l @$r15+, $fpscr lds.l @$r15+, $fpul9:#endif mov $k4, $r15 rte nop .align 2__blrb_flags: .long 0x30000000#if defined(__SH4__)__fpu_prepare_fd: .long SYMBOL_NAME(fpu_prepare_fd)__init_task_flags: .long SYMBOL_NAME(init_task_union)+4__PF_USEDFPU: .long PF_USEDFPU#endif1: .long 0x00008000 ! FD2: .long 0xffff7f0f ! ~(IMASK+FD)3: .long 0x00080000 ! SZ=0, PR=1! Exception Vector Base!! Should be aligned page boundary.! .balign 4096,0,4096ENTRY(vbr_base) .long 0! .balign 256,0,256general_exception: mov.l 1f, $k2 mov.l 2f, $k3 bra handle_exception mov.l @$k2, $k2 .align 22: .long SYMBOL_NAME(ret_from_exception)1: .long EXPEVT!! .balign 1024,0,1024tlb_miss: mov.l 1f, $k2 mov.l 4f, $k3 bra handle_exception mov.l @$k2, $k2! .balign 512,0,512interrupt: mov.l 2f, $k2 mov.l 3f, $k3 bra handle_exception mov.l @$k2, $k2 .align 21: .long EXPEVT2: .long INTEVT3: .long SYMBOL_NAME(ret_from_irq)4: .long SYMBOL_NAME(ret_from_exception)!!handle_exception: ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), ! save all registers onto stack. ! stc $ssr, $k0 ! from kernel space? shll $k0 ! Check MD bit (bit30) by shifting it into the T bit shll $k0#if defined(__SH4__) bf/s 8f ! it's from user to kernel transition mov $r15, $k0 ! save original stack to k0 /* It's a kernel to kernel transition. */ /* Is the FPU disabled? */ mov.l 2f, $k1 stc $ssr, $k0 tst $k1, $k0 mov.l 4f, $k1 bf/s 9f ! FPU is not enabled, no need to save it mov $r15, $k0 ! save original stack to k0 ! FPU is enabled, save it ! /* XXX: Need to save another bank of FPU if all FPU feature is used */ ! /* Currently it's not the case for GCC (only udivsi3_i4, divsi3_i4) */ sts.l $fpul, @-$r15 sts.l $fpscr, @-$r15 mov.l 6f, $k1 lds $k1, $fpscr mov.l 3f, $k1 fmov.s $fr15, @-$r15 fmov.s $fr14, @-$r15 fmov.s $fr13, @-$r15 fmov.s $fr12, @-$r15 fmov.s $fr11, @-$r15 fmov.s $fr10, @-$r15 fmov.s $fr9, @-$r15 fmov.s $fr8, @-$r15 fmov.s $fr7, @-$r15 fmov.s $fr6, @-$r15 fmov.s $fr5, @-$r15 fmov.s $fr4, @-$r15 fmov.s $fr3, @-$r15 fmov.s $fr2, @-$r15 fmov.s $fr1, @-$r15 bra 9f fmov.s $fr0, @-$r15#else mov.l 3f, $k1 bt/s 9f ! it's a kernel to kernel transition, and skip the FPU save. mov $r15, $k0 ! save original stack to k0 anyway#endif8: /* User space to kernel */ mov #0x20, $k1 shll8 $k1 ! $k1 <= 8192 == THREAD_SIZE add $current, $k1 mov $k1, $r15 ! change to kernel stack ! mov.l 4f, $k1 ! let kernel release FPU9: ! Save the user registers on the stack. ! At this point, k1 should have been set to the new SR value mov #-1, $k4 mov.l $k4, @-$r15 ! syscall_nr (default: -1) ! sts.l $macl, @-$r15 sts.l $mach, @-$r15 stc.l $gbr, @-$r15 stc.l $ssr, @-$r15 sts.l $pr, @-$r15 stc.l $spc, @-$r15 ! lds $k3, $pr ! Set the return address to pr ! mov.l $k0, @-$r15 ! save orignal stack mov.l $r14, @-$r15 mov.l $r13, @-$r15 mov.l $r12, @-$r15
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -