📄 entry.s
字号:
old_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 @(OFF_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 syscall_ret__INV_IMASK: .long 0xffffff0f ! ~(IMASK) .align 2reschedule: mova SYMBOL_NAME(ret_from_syscall), r0 mov.l 1f, r1 jmp @r1 lds r0, pr .align 21: .long SYMBOL_NAME(schedule)ret_from_irq:ret_from_exception: mov #OFF_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 ! bra ret_from_syscall nop .align 2#ifdef COMPAT_OLD_SYSCALL_ABIold_abi_syscall_ret: add r8, r15 ! pop off the arguments /* fall through */#endifsyscall_ret: mov.l r0, @(OFF_R0,r15) ! save the return value /* fall through */ENTRY(ret_from_syscall) /* CLI */ stc sr, r0 or #0xf0, r0 ldc r0, sr ! stc k_current, r1 mov.l @(need_resched,r1), r0 tst r0, r0 bf reschedule mov.l @(sigpending,r1), r0 tst r0, 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) .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 ret_from_exception1: .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 ret_from_irq4: .long 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 mov.l r11, @-r15 mov.l r10, @-r15 mov.l r9, @-r15 mov.l r8, @-r15 ! stc sr, r8 ! Back to normal register bank, and or k1, r8 ! Block all interrupts, may release FPU mov.l 5f, k1 and k1, r8 ! ... ldc r8, sr ! ...changed here. ! mov.l r7, @-r15 mov.l r6, @-r15 mov.l r5, @-r15 mov.l r4, @-r15 mov.l r3, @-r15 mov.l r2, @-r15 mov.l r1, @-r15 mov.l r0, @-r15 ! Then, dispatch to the handler, according to the exception code. stc k_ex_code, r8 shlr2 r8 shlr r8 mov.l 1f, r9 add r8, r9 mov.l @r9, r9 jmp @r9 nop .align 21: .long SYMBOL_NAME(exception_handling_table)2: .long 0x00008000 ! FD=13: .long 0x000000f0 ! FD=0, IMASK=154: .long 0x000080f0 ! FD=1, IMASK=155: .long 0xcfffffff ! RB=0, BL=06: .long 0x00080000 ! SZ=0, PR=1none: rts nop.dataENTRY(exception_handling_table) .long error .long error .long tlb_miss_load .long tlb_miss_store .long initial_page_write .long tlb_protection_violation_load .long tlb_protection_violation_store .long address_error_load .long address_error_store#if defined(__SH4__) .long SYMBOL_NAME(do_fpu_error)#else .long error ! fpu_exception#endif .long error .long system_call ! Unconditional Trap .long error ! reserved_instruction (filled by trap_init) .long error ! illegal_slot_instruction (filled by trap_init)ENTRY(nmi_slot) .long none ! Not implemented yetENTRY(user_break_point_trap) .long break_point_trapENTRY(interrupt_table) ! external hardware .long SYMBOL_NAME(do_IRQ) ! 0000 .long SYMBOL_NAME(do_IRQ) ! 0001 .long SYMBOL_NAME(do_IRQ) ! 0010 .long SYMBOL_NAME(do_IRQ) ! 0011 .long SYMBOL_NAME(do_IRQ) ! 0100 .long SYMBOL_NAME(do_IRQ) ! 0101 .long SYMBOL_NAME(do_IRQ) ! 0110
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -