common.S和call.S的部分理解1(2)


  1: /*
    2:  *  linux/arch/arm/kernel/entry-common.S
    3:  *
    4:  *  Copyright (C) 2000 Russell King
    5:  *
    6:  * This program is free software; you can redistribute it and/or modify
    7:  * it under the terms of the GNU General Public License version 2 as
    8:  * published by the Free Software Foundation.
    9:  */
  10: 
  11: #include <asm/unistd.h>
  12: #include <asm/ftrace.h>
  13: #include <mach/entry-macro.S>
  14: #include <asm/unwind.h>
  15: 
  16: #include "entry-header.S"
  17: 
  18: 
  19:    .align    5
  20: /*
  21:  * This is the fast syscall return path.  We do as little as
  22:  * possible here, and this includes saving r0 back into the SVC
  23:  * stack.
  24:  */
  25: ret_fast_syscall:
  26:  UNWIND(.fnstart    )
  27:  UNWIND(.cantunwind    )
  28:    disable_irq                @ disable interrupts
  29:    ldr    r1, [tsk, #TI_FLAGS]
  30:    tst    r1, #_TIF_WORK_MASK
  31:    bne    fast_work_pending
  32: 
  33:    /* perform architecture specific actions before user return */
  34:    arch_ret_to_user r1, lr
  35: 
  36:    @ fast_restore_user_regs
  37:    ldr    r1, [sp, #S_OFF + S_PSR]    @ get calling cpsr
  38:    ldr    lr, [sp, #S_OFF + S_PC]!    @ get pc
  39:    msr    spsr_cxsf, r1            @ save in spsr_svc
  40:    ldmdb    sp, {r1 - lr}^            @ get calling r1 - lr
  41:    mov    r0, r0
  42:    add    sp, sp, #S_FRAME_SIZE - S_PC
  43:    movs    pc, lr                @ return & move spsr_svc into cpsr
  44:  UNWIND(.fnend        )
  45: 
  46: /*
  47:  * Ok, we need to do extra processing, enter the slow path.
  48:  */
  49: fast_work_pending:
  50:    str    r0, [sp, #S_R0+S_OFF]!        @ returned r0
  51: work_pending:
  52:    tst    r1, #_TIF_NEED_RESCHED
  53:    bne    work_resched
  54:    tst    r1, #_TIF_SIGPENDING
  55:    beq    no_work_pending
  56:    mov    r0, sp                @ 'regs'
  57:    mov    r2, why                @ 'syscall'
  58:    bl    do_notify_resume
  59:    b    ret_slow_syscall        @ Check work again
  60: 
  61: work_resched:
  62:    bl    schedule
  63: /*
  64:  * "slow" syscall return path.  "why" tells us if this was a real syscall.
  65:  */
  66: ENTRY(ret_to_user)
  67: ret_slow_syscall:
  68:    disable_irq                @ disable interrupts
  69:    ldr    r1, [tsk, #TI_FLAGS]
  70:    tst    r1, #_TIF_WORK_MASK
  71:    bne    work_pending
  72: no_work_pending:
  73:    /* perform architecture specific actions before user return */
  74:    arch_ret_to_user r1, lr
  75: 
  76:    @ slow_restore_user_regs
  77:    ldr    r1, [sp, #S_PSR]        @ get calling cpsr
  78:    ldr    lr, [sp, #S_PC]!        @ get pc
  79:    msr    spsr_cxsf, r1            @ save in spsr_svc
  80:    ldmdb    sp, {r0 - lr}^            @ get calling r0 - lr
  81:    mov    r0, r0
  82:    add    sp, sp, #S_FRAME_SIZE - S_PC
  83:    movs    pc, lr                @ return & move spsr_svc into cpsr
  84: ENDPROC(ret_to_user)
  85: 
  86: /*
  87:  * This is how we return from a fork.
  88:  */
  89: ENTRY(ret_from_fork)
  90:    bl    schedule_tail
  91:    get_thread_info tsk
  92:    ldr    r1, [tsk, #TI_FLAGS]        @ check for syscall tracing
  93:    mov    why, #1
  94:    tst    r1, #_TIF_SYSCALL_TRACE        @ are we tracing syscalls?
  95:    beq    ret_slow_syscall
  96:    mov    r1, sp
  97:    mov    r0, #1                @ trace exit [IP = 1]
  98:    bl    syscall_trace
  99:    b    ret_slow_syscall
  100: ENDPROC(ret_from_fork)
  101: 
  102:    .equ NR_syscalls,0
  103: #define CALL(x) .equ NR_syscalls,NR_syscalls+1
  104: #include "calls.S"
  105: #undef CALL
  106: #define CALL(x) .long x
  107: 
  108: #ifdef CONFIG_FUNCTION_TRACER
  109: #ifdef CONFIG_DYNAMIC_FTRACE
  110: ENTRY(mcount)
  111:    stmdb sp!, {r0-r3, lr}
  112:    mov r0, lr
  113:    sub r0, r0, #MCOUNT_INSN_SIZE
  114: 
  115:    .globl mcount_call
  116: mcount_call:
  117:    bl ftrace_stub
  118:    ldr lr, [fp, #-4]            @ restore lr
  119:    ldmia sp!, {r0-r3, pc}
  120: 
  121: ENTRY(ftrace_caller)
  122:    stmdb sp!, {r0-r3, lr}
  123:    ldr r1, [fp, #-4]
  124:    mov r0, lr
  125:    sub r0, r0, #MCOUNT_INSN_SIZE
  126: 
  127:    .globl ftrace_call
  128: ftrace_call:
  129:    bl ftrace_stub
  130:    ldr lr, [fp, #-4]            @ restore lr
  131:    ldmia sp!, {r0-r3, pc}
  132: 
  133: #else
  134: 
  135: ENTRY(mcount)
  136:    stmdb sp!, {r0-r3, lr}
  137:    ldr r0, =ftrace_trace_function
  138:    ldr r2, [r0]
  139:    adr r0, ftrace_stub
  140:    cmp r0, r2
  141:    bne trace
  142:    ldr lr, [fp, #-4]            @ restore lr
  143:    ldmia sp!, {r0-r3, pc}
  144: 
  145: trace:
  146:    ldr r1, [fp, #-4]            @ lr of instrumented routine
  147:    mov r0, lr
  148:    sub r0, r0, #MCOUNT_INSN_SIZE
  149:    mov lr, pc
  150:    mov pc, r2
  151:    mov lr, r1                @ restore lr
  152:    ldmia sp!, {r0-r3, pc}
  153: 
  154: #endif /* CONFIG_DYNAMIC_FTRACE */
  155: 
  156:    .globl ftrace_stub
  157: ftrace_stub:
  158:    mov pc, lr
  159: 
  160: #endif /* CONFIG_FUNCTION_TRACER */
  161: 
  162: /*=============================================================================
  163:  * SWI handler
  164:  *-----------------------------------------------------------------------------
  165:  */
  166: 
  167:    /* If we're optimising for StrongARM the resulting code won't
  168:        run on an ARM7 and we can save a couple of instructions. 
  169:                                --pb */
  170: #ifdef CONFIG_CPU_ARM710
  171: #define A710(code...) code
  172: .Larm710bug:
  173:    ldmia    sp, {r0 - lr}^            @ Get calling r0 - lr
  174:    mov    r0, r0
  175:    add    sp, sp, #S_FRAME_SIZE
  176:    subs    pc, lr, #4
  177: #else
  178: #define A710(code...)
  179: #endif
  180: 
  181:    .align    5
  182: ENTRY(vector_swi)
  183:    sub    sp, sp, #S_FRAME_SIZE
  184:    stmia    sp, {r0 - r12}            @ Calling r0 - r12
  185:    add    r8, sp, #S_PC
  186:    stmdb    r8, {sp, lr}^            @ Calling sp, lr
  187:    mrs    r8, spsr            @ called from non-FIQ mode, so ok.
  188:    str    lr, [sp, #S_PC]            @ Save calling PC
  189:    str    r8, [sp, #S_PSR]        @ Save CPSR
  190:    str    r0, [sp, #S_OLD_R0]        @ Save OLD_R0
  191:    zero_fp
  192: 
  193:    /*
  194:      * Get the system call number.
  195:      */
  196: 
  197: #if defined(CONFIG_OABI_COMPAT)
  198: 
  199:    /*
  200:      * If we have CONFIG_OABI_COMPAT then we need to look at the swi
  201:      * value to determine if it is an EABI or an old ABI call.
  202:      */
  203: #ifdef CONFIG_ARM_THUMB
  204:    tst    r8, #PSR_T_BIT
  205:    movne    r10, #0                @ no thumb OABI emulation
  206:    ldreq    r10, [lr, #-4]            @ get SWI instruction
  207: #else
  208:    ldr    r10, [lr, #-4]            @ get SWI instruction
  209:  A710(    and    ip, r10, #0x0f000000        @ check for SWI        )
  210:  A710(    teq    ip, #0x0f000000                        )
  211:  A710(    bne    .Larm710bug                        )
  212: #endif
  213: 
  214: #elif defined(CONFIG_AEABI)
  215: 
  216:    /*
  217:      * Pure EABI user space always put syscall number into scno (r7).
  218:      */
  219:  A710(    ldr    ip, [lr, #-4]            @ get SWI instruction    )
  220:  A710(    and    ip, ip, #0x0f000000        @ check for SWI        )
  221:  A710(    teq    ip, #0x0f000000                        )
  222:  A710(    bne    .Larm710bug                        )
  223: 
  224: #elif defined(CONFIG_ARM_THUMB)
  225: 
  226:    /* Legacy ABI only, possibly thumb mode. */
  227:    tst    r8, #PSR_T_BIT            @ this is SPSR from save_user_regs
  228:    addne    scno, r7, #__NR_SYSCALL_BASE    @ put OS number in
  229:    ldreq    scno, [lr, #-4]
  230: 
  231: #else
  232: 
  233:    /* Legacy ABI only. */
  234:    ldr    scno, [lr, #-4]            @ get SWI instruction
  235:  A710(    and    ip, scno, #0x0f000000        @ check for SWI        )
  236:  A710(    teq    ip, #0x0f000000                        )
  237:  A710(    bne    .Larm710bug                        )
  238: 
  239: #endif
  240: 
  241: #ifdef CONFIG_ALIGNMENT_TRAP
  242:    ldr    ip, __cr_alignment
  243:    ldr    ip, [ip]
  244:    mcr    p15, 0, ip, c1, c0        @ update control register
  245: #endif
  246:    enable_irq
  247: 
  248:    get_thread_info tsk
  249:    adr    tbl, sys_call_table        @ load syscall table pointer
  250:    ldr    ip, [tsk, #TI_FLAGS]        @ check for syscall tracing
  251: 
  252: #if defined(CONFIG_OABI_COMPAT)
  253:    /*
  254:      * If the swi argument is zero, this is an EABI call and we do nothing.
  255:      *
  256:      * If this is an old ABI call, get the syscall number into scno and
  257:      * get the old ABI syscall table address.
  258:      */
  259:    bics    r10, r10, #0xff000000
  260:    eorne    scno, r10, #__NR_OABI_SYSCALL_BASE
  261:    ldrne    tbl, =sys_oabi_call_table
  262: #elif !defined(CONFIG_AEABI)
  263:    bic    scno, scno, #0xff000000        @ mask off SWI op-code
  264:    eor    scno, scno, #__NR_SYSCALL_BASE    @ check OS number
  265: #endif
  266: 
  267:    stmdb    sp!, {r4, r5}            @ push fifth and sixth args
  268:    tst    ip, #_TIF_SYSCALL_TRACE        @ are we tracing syscalls?
  269:    bne    __sys_trace
  270: 
  271:    cmp    scno, #NR_syscalls        @ check upper syscall limit
  272:    adr    lr, ret_fast_syscall        @ return address
  273:    ldrcc    pc, [tbl, scno, lsl #2]        @ call sys_* routine
  274: 
  275:    add    r1, sp, #S_OFF
  276: 2:    mov    why, #0                @ no longer a real syscall
  277:    cmp    scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
  278:    eor    r0, scno, #__NR_SYSCALL_BASE    @ put OS number back
  279:    bcs    arm_syscall   
  280:    b    sys_ni_syscall            @ not private func
  281: ENDPROC(vector_swi)
  282: 
  283:    /*
  284:      * This is the really slow path.  We're going to be doing
  285:      * context switches, and waiting for our parent to respond.
  286:      */
  287: __sys_trace:
  288:    mov    r2, scno
  289:    add    r1, sp, #S_OFF
  290:    mov    r0, #0                @ trace entry [IP = 0]
  291:    bl    syscall_trace
  292: 
  293:    adr    lr, __sys_trace_return        @ return address
  294:    mov    scno, r0            @ syscall number (possibly new)
  295:    add    r1, sp, #S_R0 + S_OFF        @ pointer to regs
  296:    cmp    scno, #NR_syscalls        @ check upper syscall limit
  297:    ldmccia    r1, {r0 - r3}            @ have to reload r0 - r3
  298:    ldrcc    pc, [tbl, scno, lsl #2]        @ call sys_* routine
  299:    b    2b
  300: 
  301: __sys_trace_return:
  302:    str    r0, [sp, #S_R0 + S_OFF]!    @ save returned r0
  303:    mov    r2, scno
  304:    mov    r1, sp
  305:    mov    r0, #1                @ trace exit [IP = 1]
  306:    bl    syscall_trace
  307:    b    ret_slow_syscall
  308: 
  309:    .align    5
  310: #ifdef CONFIG_ALIGNMENT_TRAP
  311:    .type    __cr_alignment, #object
  312: __cr_alignment:
  313:    .word    cr_alignment
  314: #endif
  315:    .ltorg
  316: 
  317: /*
  318:  * This is the syscall table declaration for native ABI syscalls.
  319:  * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
  320:  */
  321: #define ABI(native, compat) native
  322: #ifdef CONFIG_AEABI
  323: #define OBSOLETE(syscall) sys_ni_syscall
  324: #else
  325: #define OBSOLETE(syscall) syscall
  326: #endif
  327: 
  328:    .type    sys_call_table, #object
  329: ENTRY(sys_call_table)
  330: #include "calls.S"
  331: #undef ABI
  332: #undef OBSOLETE
  333: 
  334: /*============================================================================
  335:  * Special system call wrappers
  336:  */
  337: @ r0 = syscall number
  338: @ r8 = syscall table
  339: sys_syscall:
  340:        bic    scno, r0, #__NR_OABI_SYSCALL_BASE
  341:        cmp    scno, #__NR_syscall - __NR_SYSCALL_BASE
  342:        cmpne    scno, #NR_syscalls    @ check range
  343:        stmloia    sp, {r5, r6}        @ shuffle args
  344:        movlo    r0, r1
  345:        movlo    r1, r2
  346:        movlo    r2, r3
  347:        movlo    r3, r4
  348:        ldrlo    pc, [tbl, scno, lsl #2]
  349:        b    sys_ni_syscall
  350: ENDPROC(sys_syscall)
  351: 
  352: sys_fork_wrapper:
  353:        add    r0, sp, #S_OFF
  354:        b    sys_fork
  355: ENDPROC(sys_fork_wrapper)
  356: 
  357: sys_vfork_wrapper:
  358:        add    r0, sp, #S_OFF
  359:        b    sys_vfork
  360: ENDPROC(sys_vfork_wrapper)
  361: 
  362: sys_execve_wrapper:
  363:        add    r3, sp, #S_OFF
  364:        b    sys_execve
  365: ENDPROC(sys_execve_wrapper)
  366: 
  367: sys_clone_wrapper:
  368:        add    ip, sp, #S_OFF
  369:        str    ip, [sp, #4]
  370:        b    sys_clone
  371: ENDPROC(sys_clone_wrapper)
  372: 
  373: sys_sigsuspend_wrapper:
  374:        add    r3, sp, #S_OFF
  375:        b    sys_sigsuspend
  376: ENDPROC(sys_sigsuspend_wrapper)
  377: 
  378: sys_rt_sigsuspend_wrapper:
  379:        add    r2, sp, #S_OFF
  380:        b    sys_rt_sigsuspend
  381: ENDPROC(sys_rt_sigsuspend_wrapper)
  382: 
  383: sys_sigreturn_wrapper:
  384:        add    r0, sp, #S_OFF
  385:        b    sys_sigreturn
  386: ENDPROC(sys_sigreturn_wrapper)
  387: 
  388: sys_rt_sigreturn_wrapper:
  389:        add    r0, sp, #S_OFF
  390:        b    sys_rt_sigreturn
  391: ENDPROC(sys_rt_sigreturn_wrapper)
  392: 
  393: sys_sigaltstack_wrapper:
  394:        ldr    r2, [sp, #S_OFF + S_SP]
  395:        b    do_sigaltstack
  396: ENDPROC(sys_sigaltstack_wrapper)
  397: 
  398: sys_statfs64_wrapper:
  399:        teq    r1, #88
  400:        moveq    r1, #84
  401:        b    sys_statfs64
  402: ENDPROC(sys_statfs64_wrapper)
  403: 
  404: sys_fstatfs64_wrapper:
  405:        teq    r1, #88
  406:        moveq    r1, #84
  407:        b    sys_fstatfs64
  408: ENDPROC(sys_fstatfs64_wrapper)
  409: 
  410: /*
  411:  * Note: off_4k (r5) is always units of 4K.  If we can't do the requested
  412:  * offset, we return EINVAL.
  413:  */
  414: sys_mmap2:
  415: #if PAGE_SHIFT > 12
  416:        tst    r5, #PGOFF_MASK
  417:        moveq    r5, r5, lsr #PAGE_SHIFT - 12
  418:        streq    r5, [sp, #4]
  419:        beq    do_mmap2
  420:        mov    r0, #-EINVAL
  421:        mov    pc, lr
  422: #else
  423:        str    r5, [sp, #4]
  424:        b    do_mmap2
  425: #endif
  426: ENDPROC(sys_mmap2)
  427: 
  428: ENTRY(pabort_ifar)
  429:        mrc    p15, 0, r0, cr6, cr0, 2
  430: ENTRY(pabort_noifar)
  431:        mov    pc, lr
  432: ENDPROC(pabort_ifar)
  433: ENDPROC(pabort_noifar)
  434: 
  435: #ifdef CONFIG_OABI_COMPAT
  436: 
  437: /*
  438:  * These are syscalls with argument register differences
  439:  */
  440: 
  441: sys_oabi_pread64:
  442:        stmia    sp, {r3, r4}
  443:        b    sys_pread64
  444: ENDPROC(sys_oabi_pread64)
  445: 
  446: sys_oabi_pwrite64:
  447:        stmia    sp, {r3, r4}
  448:        b    sys_pwrite64
  449: ENDPROC(sys_oabi_pwrite64)
  450: 
  451: sys_oabi_truncate64:
  452:        mov    r3, r2
  453:        mov    r2, r1
  454:        b    sys_truncate64
  455: ENDPROC(sys_oabi_truncate64)
  456: 
  457: sys_oabi_ftruncate64:
  458:        mov    r3, r2
  459:        mov    r2, r1
  460:        b    sys_ftruncate64
  461: ENDPROC(sys_oabi_ftruncate64)
  462: 
  463: sys_oabi_readahead:
  464:        str    r3, [sp]
  465:        mov    r3, r2
  466:        mov    r2, r1
  467:        b    sys_readahead
  468: ENDPROC(sys_oabi_readahead)
  469: 
  470: /*
  471:  * Let's declare a second syscall table for old ABI binaries
  472:  * using the compatibility syscall entries.
  473:  */
  474: #define ABI(native, compat) compat
  475: #define OBSOLETE(syscall) syscall
  476: 
  477:    .type    sys_oabi_call_table, #object
  478: ENTRY(sys_oabi_call_table)
  479: #include "calls.S"
  480: #undef ABI
  481: #undef OBSOLETE
  482: 
  483: #endif
  484: 

在entry-common.S中包含了上次calls.S,这里简单分析前两次:

第一次:

在entry-common.S中:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/55ed6c6fe9c780ca1b111aa019ccd733.html