📄 entry.s
字号:
/* -*- mode: asm -*- * * linux/arch/m68k/kernel/entry.S * * Copyright (C) 1991, 1992 Linus Torvalds * * This file is subject to the terms and conditions of the GNU General Public * License. See the file README.legal in the main directory of this archive * for more details. * * Linux/m68k support by Hamish Macdonald * * 68060 fixes by Jesper Skov * *//* * entry.S contains the system-call and fault low-level handling routines. * This also contains the timer-interrupt handler, as well as all interrupts * and faults that can result in a task-switch. * * NOTE: This code handles signal-recognition, which happens every time * after a timer-interrupt and after each system call. * *//* * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so * all pointers that used to be 'current' are now entry * number 0 in the 'current_set' list. * * 6/05/00 RZ: addedd writeback completion after return from sighandler * for 68040 */#include <linux/sys.h>#include <linux/config.h>#include <linux/linkage.h>#include <asm/entry.h>#include <asm/errno.h>#include <asm/setup.h>#include <asm/segment.h>#include <asm/traps.h>#include "m68k_defs.h".globl SYMBOL_NAME(system_call), SYMBOL_NAME(buserr), SYMBOL_NAME(trap).globl SYMBOL_NAME(resume), SYMBOL_NAME(ret_from_exception).globl SYMBOL_NAME(ret_from_signal).globl SYMBOL_NAME(inthandler), SYMBOL_NAME(sys_call_table).globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone), SYMBOL_NAME(sys_vfork).globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt).textENTRY(buserr) SAVE_ALL_INT GET_CURRENT(%d0) movel %sp,%sp@- | stack frame pointer argument bsrl SYMBOL_NAME(buserr_c) addql #4,%sp jra SYMBOL_NAME(ret_from_exception)ENTRY(trap) SAVE_ALL_INT GET_CURRENT(%d0) movel %sp,%sp@- | stack frame pointer argument bsrl SYMBOL_NAME(trap_c) addql #4,%sp jra SYMBOL_NAME(ret_from_exception)ENTRY(reschedule) | save top of frame movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) pea SYMBOL_NAME(ret_from_exception) jmp SYMBOL_NAME(schedule) | After a fork we jump here directly from resume, | so that %d1 contains the previous task | Theoretically only needed on SMP, but let's watch | what happens in schedule_tail() in future...ENTRY(ret_from_fork) movel %d1,%sp@- jsr SYMBOL_NAME(schedule_tail) addql #4,%sp jra SYMBOL_NAME(ret_from_exception)badsys: movel #-ENOSYS,%sp@(PT_D0) jra SYMBOL_NAME(ret_from_exception)do_trace: movel #-ENOSYS,%sp@(PT_D0) | needed for strace subql #4,%sp SAVE_SWITCH_STACK jbsr SYMBOL_NAME(syscall_trace) RESTORE_SWITCH_STACK addql #4,%sp movel %sp@(PT_ORIG_D0),%d1 movel #-ENOSYS,%d0 cmpl #NR_syscalls,%d1 jcc 1f jbsr @(SYMBOL_NAME(sys_call_table),%d1:l:4)@(0)1: movel %d0,%sp@(PT_D0) | save the return value subql #4,%sp | dummy return address SAVE_SWITCH_STACK jbsr SYMBOL_NAME(syscall_trace)SYMBOL_NAME_LABEL(ret_from_signal) RESTORE_SWITCH_STACK addql #4,%sp/* on 68040 complete pending writebacks if any */ #ifdef CONFIG_M68040 bfextu %sp@(PT_VECTOR){#0,#4},%d0 subql #7,%d0 | bus error frame ? jbne 1f movel %sp,%sp@- jbsr SYMBOL_NAME(berr_040cleanup) addql #4,%sp1: #endif jra SYMBOL_NAME(ret_from_exception)ENTRY(system_call) SAVE_ALL_SYS GET_CURRENT(%d1) | save top of frame movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) btst #PT_TRACESYS_BIT,%curptr@(TASK_PTRACE+PT_TRACESYS_OFF) jne do_trace cmpl #NR_syscalls,%d0 jcc badsys jbsr @(SYMBOL_NAME(sys_call_table),%d0:l:4)@(0) movel %d0,%sp@(PT_D0) | save the return valueSYMBOL_NAME_LABEL(ret_from_exception) btst #5,%sp@(PT_SR) | check if returning to kernel bnes 2f | if so, skip resched, signals | only allow interrupts when we are really the last one on the | kernel stack, otherwise stack overflow can occur during | heavy interupt load andw #ALLOWINT,%sr tstl %curptr@(TASK_NEEDRESCHED) jne SYMBOL_NAME(reschedule)#if 0 cmpl #SYMBOL_NAME(task),%curptr | task[0] cannot have signals jeq 2f#endif | check for delayed trace bclr #PT_DTRACE_BIT,%curptr@(TASK_PTRACE+PT_DTRACE_OFF) jne do_delayed_trace5: tstl %curptr@(TASK_STATE) | state jne SYMBOL_NAME(reschedule) tstl %curptr@(TASK_SIGPENDING) jne Lsignal_return2: RESTORE_ALLLsignal_return: subql #4,%sp | dummy return address SAVE_SWITCH_STACK pea %sp@(SWITCH_STACK_SIZE) clrl %sp@- bsrl SYMBOL_NAME(do_signal) addql #8,%sp RESTORE_SWITCH_STACK addql #4,%sp RESTORE_ALLdo_delayed_trace: bclr #7,%sp@(PT_SR) | clear trace bit in SR pea 1 | send SIGTRAP movel %curptr,%sp@- pea LSIGTRAP jbsr SYMBOL_NAME(send_sig) addql #8,%sp addql #4,%sp jra 5b#if 0#if CONFIG_AMIGASYMBOL_NAME_LABEL(ami_inthandler) addql #1,SYMBOL_NAME(irq_stat)+8 | local_irq_count SAVE_ALL_INT GET_CURRENT(%d0) bfextu %sp@(PT_VECTOR){#4,#12},%d0 movel %d0,%a0 addql #1,%a0@(SYMBOL_NAME(kstat)+STAT_IRQ-VECOFF(VEC_SPUR)) movel %a0@(SYMBOL_NAME(autoirq_list)-VECOFF(VEC_SPUR)),%a0| amiga vector int handler get the req mask instead of irq vector lea CUSTOMBASE,%a1 movew %a1@(C_INTREQR),%d0 andw %a1@(C_INTENAR),%d0| prepare stack (push frame pointer, dev_id & req mask) pea %sp@ movel %a0@(IRQ_DEVID),%sp@- movel %d0,%sp@- pea %pc@(SYMBOL_NAME(ret_from_interrupt):w) jbra @(IRQ_HANDLER,%a0)@(0)ENTRY(nmi_handler) rte#endif#endif/*** This is the main interrupt handler, responsible for calling process_int()*/SYMBOL_NAME_LABEL(inthandler) SAVE_ALL_INT GET_CURRENT(%d0) addql #1,SYMBOL_NAME(irq_stat)+8 | local_irq_count | put exception # in d0 bfextu %sp@(PT_VECTOR){#4,#10},%d0 movel %sp,%sp@- movel %d0,%sp@- | put vector # on stack#if defined(MACH_Q40_ONLY) && defined(CONFIG_BLK_DEV_FD) btstb #4,0xff000000 | Q40 floppy needs very special treatment ... jbeq 1f btstb #3,0xff000004 jbeq 1f jbsr SYMBOL_NAME(floppy_hardint) jbra 3f1:#endif jbsr SYMBOL_NAME(process_int)| process the IRQ3: addql #8,%sp | pop parameters off stackSYMBOL_NAME_LABEL(ret_from_interrupt) subql #1,SYMBOL_NAME(irq_stat)+8 | local_irq_count jeq 1f2: RESTORE_ALL1:#if 1 bfextu %sp@(PT_SR){#5,#3},%d0 | Check for nested interrupt.#if MAX_NOINT_IPL > 0 cmpiw #MAX_NOINT_IPL,%d0#endif jhi 2b#endif /* check if we need to do software interrupts */ movel SYMBOL_NAME(irq_stat),%d0 | softirq_active andl SYMBOL_NAME(irq_stat)+4,%d0 | softirq_mask jeq SYMBOL_NAME(ret_from_exception) pea SYMBOL_NAME(ret_from_exception) jra SYMBOL_NAME(do_softirq)/* Handler for uninitialized and spurious interrupts */SYMBOL_NAME_LABEL(bad_interrupt) addql #1,SYMBOL_NAME(num_spurious) rteENTRY(sys_fork) SAVE_SWITCH_STACK pea %sp@(SWITCH_STACK_SIZE) jbsr SYMBOL_NAME(m68k_fork) addql #4,%sp RESTORE_SWITCH_STACK rtsENTRY(sys_clone) SAVE_SWITCH_STACK pea %sp@(SWITCH_STACK_SIZE) jbsr SYMBOL_NAME(m68k_clone) addql #4,%sp RESTORE_SWITCH_STACK rtsENTRY(sys_vfork) SAVE_SWITCH_STACK pea %sp@(SWITCH_STACK_SIZE) jbsr SYMBOL_NAME(m68k_vfork) addql #4,%sp RESTORE_SWITCH_STACK rtsENTRY(sys_sigsuspend) SAVE_SWITCH_STACK pea %sp@(SWITCH_STACK_SIZE) jbsr SYMBOL_NAME(do_sigsuspend) addql #4,%sp RESTORE_SWITCH_STACK rtsENTRY(sys_rt_sigsuspend) SAVE_SWITCH_STACK pea %sp@(SWITCH_STACK_SIZE) jbsr SYMBOL_NAME(do_rt_sigsuspend) addql #4,%sp RESTORE_SWITCH_STACK rtsENTRY(sys_sigreturn) SAVE_SWITCH_STACK jbsr SYMBOL_NAME(do_sigreturn) RESTORE_SWITCH_STACK rtsENTRY(sys_rt_sigreturn) SAVE_SWITCH_STACK jbsr SYMBOL_NAME(do_rt_sigreturn) RESTORE_SWITCH_STACK rtsSYMBOL_NAME_LABEL(resume) /* * Beware - when entering resume, prev (the current task) is * in a0, next (the new task) is in a1,so don't change these * registers until their contents are no longer needed. */ /* save sr */ movew %sr,%a0@(TASK_THREAD+THREAD_SR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -