📄 entry.s
字号:
/* * arch/alpha/kernel/entry.S * * Kernel entry-points. */#include <linux/config.h>#include <asm/asm-offsets.h>#include <asm/thread_info.h>#include <asm/pal.h>#include <asm/errno.h>#include <asm/unistd.h> .text .set noat/* Stack offsets. */#define SP_OFF 184#define SWITCH_STACK_SIZE 320/* * This defines the normal kernel pt-regs layout. * * regs 9-15 preserved by C code * regs 16-18 saved by PAL-code * regs 29-30 saved and set up by PAL-code * JRP - Save regs 16-18 in a special area of the stack, so that * the palcode-provided values are available to the signal handler. */#define SAVE_ALL \ subq $sp, SP_OFF, $sp; \ stq $0, 0($sp); \ stq $1, 8($sp); \ stq $2, 16($sp); \ stq $3, 24($sp); \ stq $4, 32($sp); \ stq $28, 144($sp); \ lda $2, alpha_mv; \ stq $5, 40($sp); \ stq $6, 48($sp); \ stq $7, 56($sp); \ stq $8, 64($sp); \ stq $19, 72($sp); \ stq $20, 80($sp); \ stq $21, 88($sp); \ ldq $2, HAE_CACHE($2); \ stq $22, 96($sp); \ stq $23, 104($sp); \ stq $24, 112($sp); \ stq $25, 120($sp); \ stq $26, 128($sp); \ stq $27, 136($sp); \ stq $2, 152($sp); \ stq $16, 160($sp); \ stq $17, 168($sp); \ stq $18, 176($sp)#define RESTORE_ALL \ lda $19, alpha_mv; \ ldq $0, 0($sp); \ ldq $1, 8($sp); \ ldq $2, 16($sp); \ ldq $3, 24($sp); \ ldq $21, 152($sp); \ ldq $20, HAE_CACHE($19); \ ldq $4, 32($sp); \ ldq $5, 40($sp); \ ldq $6, 48($sp); \ ldq $7, 56($sp); \ subq $20, $21, $20; \ ldq $8, 64($sp); \ beq $20, 99f; \ ldq $20, HAE_REG($19); \ stq $21, HAE_CACHE($19); \ stq $21, 0($20); \ ldq $0, 0($sp); \ ldq $1, 8($sp); \99:; \ ldq $19, 72($sp); \ ldq $20, 80($sp); \ ldq $21, 88($sp); \ ldq $22, 96($sp); \ ldq $23, 104($sp); \ ldq $24, 112($sp); \ ldq $25, 120($sp); \ ldq $26, 128($sp); \ ldq $27, 136($sp); \ ldq $28, 144($sp); \ addq $sp, SP_OFF, $sp/* * Non-syscall kernel entry points. */ .align 4 .globl entInt .ent entIntentInt: SAVE_ALL lda $8, 0x3fff lda $26, ret_from_sys_call bic $sp, $8, $8 mov $sp, $19 jsr $31, do_entInt.end entInt .align 4 .globl entArith .ent entArithentArith: SAVE_ALL lda $8, 0x3fff lda $26, ret_from_sys_call bic $sp, $8, $8 mov $sp, $18 jsr $31, do_entArith.end entArith .align 4 .globl entMM .ent entMMentMM: SAVE_ALL/* save $9 - $15 so the inline exception code can manipulate them. */ subq $sp, 56, $sp stq $9, 0($sp) stq $10, 8($sp) stq $11, 16($sp) stq $12, 24($sp) stq $13, 32($sp) stq $14, 40($sp) stq $15, 48($sp) addq $sp, 56, $19/* handle the fault */ lda $8, 0x3fff bic $sp, $8, $8 jsr $26, do_page_fault/* reload the registers after the exception code played. */ ldq $9, 0($sp) ldq $10, 8($sp) ldq $11, 16($sp) ldq $12, 24($sp) ldq $13, 32($sp) ldq $14, 40($sp) ldq $15, 48($sp) addq $sp, 56, $sp/* finish up the syscall as normal. */ br ret_from_sys_call.end entMM .align 4 .globl entIF .ent entIFentIF: SAVE_ALL lda $8, 0x3fff lda $26, ret_from_sys_call bic $sp, $8, $8 mov $sp, $17 jsr $31, do_entIF.end entIF .align 4 .globl entUna .ent entUnaentUna: lda $sp, -256($sp) stq $0, 0($sp) ldq $0, 256($sp) /* get PS */ stq $1, 8($sp) stq $2, 16($sp) stq $3, 24($sp) and $0, 8, $0 /* user mode? */ stq $4, 32($sp) bne $0, entUnaUser /* yup -> do user-level unaligned fault */ stq $5, 40($sp) stq $6, 48($sp) stq $7, 56($sp) stq $8, 64($sp) stq $9, 72($sp) stq $10, 80($sp) stq $11, 88($sp) stq $12, 96($sp) stq $13, 104($sp) stq $14, 112($sp) stq $15, 120($sp) /* 16-18 PAL-saved */ stq $19, 152($sp) stq $20, 160($sp) stq $21, 168($sp) stq $22, 176($sp) stq $23, 184($sp) stq $24, 192($sp) stq $25, 200($sp) stq $26, 208($sp) stq $27, 216($sp) stq $28, 224($sp) mov $sp, $19 stq $gp, 232($sp) lda $8, 0x3fff stq $31, 248($sp) bic $sp, $8, $8 jsr $26, do_entUna ldq $0, 0($sp) ldq $1, 8($sp) ldq $2, 16($sp) ldq $3, 24($sp) ldq $4, 32($sp) ldq $5, 40($sp) ldq $6, 48($sp) ldq $7, 56($sp) ldq $8, 64($sp) ldq $9, 72($sp) ldq $10, 80($sp) ldq $11, 88($sp) ldq $12, 96($sp) ldq $13, 104($sp) ldq $14, 112($sp) ldq $15, 120($sp) /* 16-18 PAL-saved */ ldq $19, 152($sp) ldq $20, 160($sp) ldq $21, 168($sp) ldq $22, 176($sp) ldq $23, 184($sp) ldq $24, 192($sp) ldq $25, 200($sp) ldq $26, 208($sp) ldq $27, 216($sp) ldq $28, 224($sp) ldq $gp, 232($sp) lda $sp, 256($sp) call_pal PAL_rti.end entUna .align 4 .ent entUnaUserentUnaUser: ldq $0, 0($sp) /* restore original $0 */ lda $sp, 256($sp) /* pop entUna's stack frame */ SAVE_ALL /* setup normal kernel stack */ lda $sp, -56($sp) stq $9, 0($sp) stq $10, 8($sp) stq $11, 16($sp) stq $12, 24($sp) stq $13, 32($sp) stq $14, 40($sp) stq $15, 48($sp) lda $8, 0x3fff addq $sp, 56, $19 bic $sp, $8, $8 jsr $26, do_entUnaUser ldq $9, 0($sp) ldq $10, 8($sp) ldq $11, 16($sp) ldq $12, 24($sp) ldq $13, 32($sp) ldq $14, 40($sp) ldq $15, 48($sp) lda $sp, 56($sp) br ret_from_sys_call.end entUnaUser .align 4 .globl entDbg .ent entDbgentDbg: SAVE_ALL lda $8, 0x3fff lda $26, ret_from_sys_call bic $sp, $8, $8 mov $sp, $16 jsr $31, do_entDbg.end entDbg/* * The system call entry point is special. Most importantly, it looks * like a function call to userspace as far as clobbered registers. We * do preserve the argument registers (for syscall restarts) and $26 * (for leaf syscall functions). * * So much for theory. We don't take advantage of this yet. * * Note that a0-a2 are not saved by PALcode as with the other entry points. */ .align 4 .globl entSys .globl ret_from_sys_call .ent entSysentSys: SAVE_ALL lda $8, 0x3fff bic $sp, $8, $8 lda $4, NR_SYSCALLS($31) stq $16, SP_OFF+24($sp) lda $5, sys_call_table lda $27, sys_ni_syscall cmpult $0, $4, $4 ldl $3, TI_FLAGS($8) stq $17, SP_OFF+32($sp) s8addq $0, $5, $5 stq $18, SP_OFF+40($sp) blbs $3, strace beq $4, 1f ldq $27, 0($5)1: jsr $26, ($27), alpha_ni_syscall ldgp $gp, 0($26) blt $0, $syscall_error /* the call failed */ stq $0, 0($sp) stq $31, 72($sp) /* a3=0 => no error */ .align 4ret_from_sys_call: cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ ldq $0, SP_OFF($sp) and $0, 8, $0 beq $0, restore_allret_from_reschedule: /* Make sure need_resched and sigpending don't change between sampling and the rti. */ lda $16, 7 call_pal PAL_swpipl ldl $5, TI_FLAGS($8) and $5, _TIF_WORK_MASK, $2 bne $5, work_pendingrestore_all: RESTORE_ALL call_pal PAL_rti .align 3$syscall_error: /* * Some system calls (e.g., ptrace) can return arbitrary * values which might normally be mistaken as error numbers. * Those functions must zero $0 (v0) directly in the stack * frame to indicate that a negative return value wasn't an * error number.. */ ldq $19, 0($sp) /* old syscall nr (zero if success) */ beq $19, $ret_success ldq $20, 72($sp) /* .. and this a3 */ subq $31, $0, $0 /* with error in v0 */ addq $31, 1, $1 /* set a3 for errno return */ stq $0, 0($sp) mov $31, $26 /* tell "ret_from_sys_call" we can restart */ stq $1, 72($sp) /* a3 for return */ br ret_from_sys_call$ret_success: stq $0, 0($sp) stq $31, 72($sp) /* a3=0 => no error */ br ret_from_sys_call.end entSys/* * Do all cleanup when returning from all interrupts and system calls. * * Arguments: * $5: TI_FLAGS. * $8: current. * $19: The old syscall number, or zero if this is not a return * from a syscall that errored and is possibly restartable. * $20: Error indication. */ .align 4 .ent work_pendingwork_pending: and $5, _TIF_NEED_RESCHED, $2 beq $2, $work_notifysig$work_resched: subq $sp, 16, $sp stq $19, 0($sp) /* save syscall nr */ stq $20, 8($sp) /* and error indication (a3) */ jsr $26, schedule ldq $19, 0($sp) ldq $20, 8($sp) addq $sp, 16, $sp /* Make sure need_resched and sigpending don't change between sampling and the rti. */ lda $16, 7 call_pal PAL_swpipl ldl $5, TI_FLAGS($8) and $5, _TIF_WORK_MASK, $2 beq $2, restore_all and $5, _TIF_NEED_RESCHED, $2 bne $2, $work_resched$work_notifysig: mov $sp, $17 br $1, do_switch_stack mov $5, $21 mov $sp, $18 mov $31, $16 jsr $26, do_notify_resume bsr $1, undo_switch_stack br restore_all.end work_pending/* * PTRACE syscall handler */ .align 4 .ent stracestrace: /* set up signal stack, call syscall_trace */ bsr $1, do_switch_stack jsr $26, syscall_trace bsr $1, undo_switch_stack /* get the system call number and the arguments back.. */ ldq $0, 0($sp) ldq $16, SP_OFF+24($sp) ldq $17, SP_OFF+32($sp) ldq $18, SP_OFF+40($sp) ldq $19, 72($sp) ldq $20, 80($sp) ldq $21, 88($sp) /* get the system call pointer.. */ lda $1, NR_SYSCALLS($31) lda $2, sys_call_table lda $27, alpha_ni_syscall cmpult $0, $1, $1 s8addq $0, $2, $2 beq $1, 1f ldq $27, 0($2)1: jsr $26, ($27), sys_gettimeofday ldgp $gp, 0($26) /* check return.. */ blt $0, $strace_error /* the call failed */ stq $31, 72($sp) /* a3=0 => no error */$strace_success: stq $0, 0($sp) /* save return value */ bsr $1, do_switch_stack jsr $26, syscall_trace bsr $1, undo_switch_stack br $31, ret_from_sys_call .align 3$strace_error: ldq $19, 0($sp) /* old syscall nr (zero if success) */ beq $19, $strace_success ldq $20, 72($sp) /* .. and this a3 */ subq $31, $0, $0 /* with error in v0 */ addq $31, 1, $1 /* set a3 for errno return */ stq $0, 0($sp) stq $1, 72($sp) /* a3 for return */ bsr $1, do_switch_stack mov $19, $9 /* save old syscall number */ mov $20, $10 /* save old a3 */ jsr $26, syscall_trace mov $9, $19 mov $10, $20 bsr $1, undo_switch_stack mov $31, $26 /* tell "ret_from_sys_call" we can restart */ br ret_from_sys_call.end strace/* * Save and restore the switch stack -- aka the balance of the user context. */ .align 4 .ent do_switch_stackdo_switch_stack: lda $sp, -SWITCH_STACK_SIZE($sp) stq $9, 0($sp) stq $10, 8($sp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -