⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entry.s

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 S
📖 第 1 页 / 共 3 页
字号:
/* *  arch/s390/kernel/entry.S *    S390 low-level entry points. * *  S390 version *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), *               Hartmut Penner (hp@de.ibm.com), *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), */#include <linux/sys.h>#include <linux/linkage.h>#include <linux/config.h>#include <asm/lowcore.h>#include <asm/errno.h>#define ASSEMBLY#include <asm/smp.h>#include <asm/s390-regs-common.h>/* * stack layout for the system_call stack entry * Martin please don't modify these back to hard coded values  * You know how bad I'm at mental arithmetic DJB & it gives  * me grief when I modify the pt_regs */SP_PTREGS    =  STACK_FRAME_OVERHEAD SP_PSW       =  SP_PTREGSSP_R0        =  (SP_PSW+PSW_MASK_SIZE+PSW_ADDR_SIZE)SP_R1        =  (SP_R0+GPR_SIZE)SP_R2        =  (SP_R1+GPR_SIZE)SP_R3        =  (SP_R2+GPR_SIZE)SP_R4        =  (SP_R3+GPR_SIZE)SP_R5        =  (SP_R4+GPR_SIZE)SP_R6        =  (SP_R5+GPR_SIZE)SP_R7        =  (SP_R6+GPR_SIZE)SP_R8        =  (SP_R7+GPR_SIZE)SP_R9        =  (SP_R8+GPR_SIZE)SP_RA        =  (SP_R9+GPR_SIZE)SP_RB        =  (SP_RA+GPR_SIZE)SP_RC        =  (SP_RB+GPR_SIZE)SP_RD        =  (SP_RC+GPR_SIZE)SP_RE        =  (SP_RD+GPR_SIZE)SP_RF        =  (SP_RE+GPR_SIZE)SP_AREGS     =  (SP_RF+GPR_SIZE)SP_ORIG_R2   =  (SP_AREGS+(NUM_ACRS*ACR_SIZE))SP_TRAP      =  (SP_ORIG_R2+GPR_SIZE)#if CONFIG_REMOTE_DEBUGSP_CRREGS    =  (SP_TRAP+4)/* fpu registers are saved & restored by the gdb stub itself */SP_FPC       =  (SP_CRREGS+(NUM_CRS*CR_SIZE))SP_FPRS      =  (SP_FPC+FPC_SIZE+FPC_PAD_SIZE)/* SP_PGM_OLD_ILC etc are not part of pt_regs & they are not  defined in ptrace.h but space is needed for this too */SP_PGM_OLD_ILC= (SP_FPRS+(NUM_FPRS*FPR_SIZE))#elseSP_PGM_OLD_ILC= (SP_TRAP+4)#endifSP_SVC_STEP   = (SP_PGM_OLD_ILC+4) SP_SIZE      =  (SP_SVC_STEP+4)/* * these defines are offsets into the thread_struct */_TSS_PTREGS  = 0_TSS_FPRS    = (_TSS_PTREGS+8)_TSS_AR2     = (_TSS_FPRS+136)_TSS_AR4     = (_TSS_AR2+4)_TSS_KSP     = (_TSS_AR4+4)_TSS_USERSEG = (_TSS_KSP+4)_TSS_ERROR   = (_TSS_USERSEG+4)_TSS_PROT    = (_TSS_ERROR+4)_TSS_TRAP    = (_TSS_PROT+4)_TSS_MM      = (_TSS_TRAP+4)_TSS_PER     = (_TSS_MM+8)/* * these are offsets into the task-struct. */state        =  0flags        =  4sigpending   =  8need_resched = 24processor    = 60/* PSW related defines */disable      = 0xFCenable       = 0x03daton        = 0x04#if 0/* some code left lying around in case we need a *	printk for debugging purposes */  sysc_printk:        .long  printk  sysc_msg:	      .string "<2>r15 %X\n"	.align 4		#	basr    %r13,0	l       %r0,SP_PSW+4(%r15)	sll     %r0,1	chi     %r0,0	jnz     sysc_dn	l       %r9,sysc_printk-sysc_lit(%r13)	la      %r2,sysc_msg-sysc_lit(%r13)	lr      %r3,%r15	basr    %r14,%r9sysc_dn:#endif/* * Register usage in interrupt handlers: *    R9  - pointer to current task structure *    R13 - pointer to literal pool *    R14 - return register for function calls *    R15 - kernel stack pointer */#define SAVE_ALL(psworg) \	st      %r15,__LC_SAVE_AREA   ; \        tm      psworg+1,0x01         ; /* test problem state bit */ \	jz	0f		      ; /* skip stack setup save */ \	l	%r15,__LC_KERNEL_STACK ; /* problem state -> load ksp */ \0:	ahi     %r15,-SP_SIZE         ; /* make room for registers & psw */ \        srl     %r15,3                ; \        sll     %r15,3                ; /* align stack pointer to 8 */ \        stm     %r0,%r14,SP_R0(%r15)  ; /* store gprs 0-14 to kernel stack */ \        st      %r2,SP_ORIG_R2(%r15)  ; /* store original content of gpr 2 */ \        mvc     SP_RF(4,%r15),__LC_SAVE_AREA   ; /* move R15 to stack */ \        stam    %a0,%a15,SP_AREGS(%r15) ; /* store access registers to kst. */ \        mvc     SP_PSW(8,%r15),psworg ; /* move user PSW to stack */ \        lhi     %r0,psworg            ; /* store trap indication */ \        st      %r0,SP_TRAP(%r15)     ; \        xc      0(4,%r15),0(%r15)     ; /* clear back chain */ \        tm      psworg+1,0x01         ; /* kmod.c .wishes the set_fs & gs */ \        jz      1f                    ; /* to work across syscalls */ \        slr     %r0,%r0               ; \        sar     %a2,%r0               ; /* set ac.reg. 2 to primary space */ \        lhi     %r0,1                 ; \        sar     %a4,%r0               ; /* set access reg. 4 to home space */ \1:#define RESTORE_ALL \        mvc     __LC_RETURN_PSW(8,0),SP_PSW(%r15) ; /* move user PSW to lowcore */ \        lam     %a0,%a15,SP_AREGS(%r15)   ; /* load the access registers */ \        lm      %r0,%r15,SP_R0(%r15)      ; /* load gprs 0-15 of user */ \        ni      __LC_RETURN_PSW+1(0),0xfd ; /* clear wait state bit */ \        lpsw    __LC_RETURN_PSW             /* back to caller */#define GET_CURRENT /* load pointer to task_struct to R9 */ \        lhi     %r9,-8192             ; \        nr      %r9,15/* * Scheduler resume function, called by switch_to *  grp2 = (thread_struct *) prev->tss *  grp3 = (thread_struct *) next->tss * Returns: *  gpr2 = prev */        .globl  resumeresume:        l       %r4,_TSS_PTREGS(%r3)        tm      SP_PSW-SP_PTREGS(%r4),0x40 # is the new process using per ?        jz      RES_DN1                 # if not we're fine        stctl   %r9,%r11,24(%r15)       # We are using per stuff        clc     _TSS_PER(12,%r3),24(%r15)        je      RES_DN1                 # we got away without bashing TLB's        lctl    %c9,%c11,_TSS_PER(%r3)  # Nope we didn'tRES_DN1:        stm     %r6,%r15,24(%r15)       # store resume registers of prev task        st      %r15,_TSS_KSP(%r2) # store kernel stack ptr to prev->tss.ksp        lhi     %r0,-8192        nr      %r0,%r15        l       %r15,_TSS_KSP(%r3) # load kernel stack ptr from next->tss.ksp        lhi     %r1,8191        or      %r1,%r15        ahi     %r1,1        st      %r1,__LC_KERNEL_STACK   # __LC_KERNEL_STACK = new kernel stack        stam    %a2,%a2,_TSS_AR2(%r2)   # store kernel access reg. 2        stam    %a4,%a4,_TSS_AR4(%r2)   # store kernel access reg. 4        lam     %a2,%a2,_TSS_AR2(%r3)   # load kernel access reg. 2        lam     %a4,%a4,_TSS_AR4(%r3)   # load kernel access reg. 4        lr      %r2,%r0                 # return task_struct of last task        lm      %r6,%r15,24(%r15)       # load resume registers of next task        br      %r14/* * SVC interrupt handler routine. System calls are synchronous events and * are executed with interrupts enabled. */sysc_lit:  sysc_do_signal:     .long  do_signal  sysc_do_softirq:    .long  do_softirq  sysc_schedule:      .long  schedule  sysc_trace:         .long  syscall_trace#ifdef CONFIG_SMP  sysc_schedtail:     .long  schedule_tail#endif  sysc_clone:         .long  sys_clone  sysc_fork:          .long  sys_fork  sysc_vfork:         .long  sys_vfork  sysc_sigreturn:     .long  sys_sigreturn  sysc_rt_sigreturn:  .long  sys_rt_sigreturn  sysc_execve:        .long  sys_execve  sysc_sigsuspend:    .long  sys_sigsuspend  sysc_rt_sigsuspend: .long  sys_rt_sigsuspend	.globl  system_callsystem_call:        SAVE_ALL(0x20)	XC      SP_SVC_STEP(4,%r15),SP_SVC_STEP(%r15)pgm_system_call:	        basr    %r13,0        ahi     %r13,sysc_lit-.   # setup base pointer R13 to sysc_lit        slr     %r8,%r8           # gpr 8 is call save (-> tracesys)        ic      %r8,0x8B          # get svc number from lowcore        stosm   24(%r15),0x03     # reenable interrupts        GET_CURRENT               # load pointer to task_struct to R9        sll     %r8,2        l       %r8,sys_call_table-sysc_lit(8,%r13) # get address of system call        tm      flags+3(%r9),0x20 # PF_TRACESYS        jnz     sysc_tracesys        basr    %r14,%r8          # call sys_xxxx        st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)                                  # ATTENTION: check sys_execve_glue before                                  # changing anything here !!sysc_return:        GET_CURRENT               # load pointer to task_struct to R9        tm      SP_PSW+1(%r15),0x01 # returning to user ?        jno     sysc_leave        # no-> skip bottom half, resched & signal## check, if bottom-half has to be done#        l       %r0,__LC_IRQ_STAT     # get softirq_active        n       %r0,__LC_IRQ_STAT+4   # and it with softirq_mask        jnz     sysc_handle_bottom_half## check, if reschedule is needed#sysc_return_bh:	        icm     %r0,15,need_resched(%r9) # get need_resched from task_struct        jnz     sysc_reschedule        icm     %r0,15,sigpending(%r9)   # get sigpending from task_struct        jnz     sysc_signal_returnsysc_leave:	icm     %r0,15,SP_SVC_STEP(%r15)   # get sigpending from task_struct        jnz     pgm_svcret	stnsm   24(%r15),disable  # disable I/O and ext. interrupts        RESTORE_ALL## call do_signal before return#sysc_signal_return:             la      %r2,SP_PTREGS(%r15) # load pt_regs        sr      %r3,%r3           # clear *oldset        l       %r1,sysc_do_signal-sysc_lit(%r13)	la      %r14,sysc_leave-sysc_lit(%r13)        br      %r1               # return point is sysc_leave## call trace before and after sys_call#sysc_tracesys:        l       %r1,sysc_trace-sysc_lit(%r13)	lhi     %r2,-ENOSYS	st      %r2,SP_R2(%r15)   # give sysc_trace an -ENOSYS retval        basr    %r14,%r1	lm      %r3,%r6,SP_R3(%r15)	l       %r2,SP_ORIG_R2(%r15)        basr    %r14,%r8          # call sys_xxx        st      %r2,SP_R2(%r15)   # store return value        l       %r1,sysc_trace-sysc_lit(%r13)	la      %r14,sysc_return-sysc_lit(%r13)        br      %r1               # return point is sysc_return## call do_softirq and return from syscall, if interrupt-level# is zero#sysc_handle_bottom_half:                l       %r1,sysc_do_softirq-sysc_lit(%r13)	la      %r14,sysc_return_bh-sysc_lit(%r13)        br      %r1               # call do_softirq## call schedule with sysc_return as return-address#sysc_reschedule:                l       %r1,sysc_schedule-sysc_lit(%r13)	la      %r14,sysc_return-sysc_lit(%r13)        br      %r1               # call scheduler, return to sysc_return#

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -