分析system_call中断处理过程

本篇文章从上篇的 getpid() 说起。

我们在之前的 MenuOS 中加入 getpid() 功能。然后在 getpid 处打断点,然后看看这系统调用详细是怎么运作的。

 

一、实验步骤

首先修改 MenuOS 中 test.c 中的代码。在 test.c 中添加上 g_pid() 和 g_pid_asm() 两个方法。test.c是MenuOS的执行文件。

在 main 函数中添加两行命令:

修改后输入 make rootfs 编译运行。结果如下:

可以看到输入 getpid 时可以看到当前的 pid。

 

然后我们在 sys_getpid 上打上断点。


 

到最后我们发现我们无法继续跟踪调试汇编部分的代码,这里 system_call() 并不是一个普通的函数,gdb 并不能在此停下,所以剩下的还需要我们自己分析。

二、system_call()对应汇编代码工作过程

这一过程中,库函数触发了中断,并给出了系统调用号。然后系统通过中断描述符找到对应的中断处理函数。

然后我们发现了 ENTRY(system_call)。其位置是 /linux-3.18.6/include/linux/linkage.h

对应代码为:

  1 #ifndef _LINUX_LINKAGE_H
  2 #define _LINUX_LINKAGE_H
  3 
  4 #include <linux/compiler.h>
  5 #include <linux/stringify.h>
  6 #include <linux/export.h>
  7 #include <asm/linkage.h>
  8 
  9 /* Some toolchains use other characters (e.g. '`') to mark new line in macro */
 10 #ifndef ASM_NL
 11 #define ASM_NL         ;
 12 #endif
 13 
 14 #ifdef __cplusplus
 15 #define CPP_ASMLINKAGE extern "C"
 16 #else
 17 #define CPP_ASMLINKAGE
 18 #endif
 19 
 20 #ifndef asmlinkage
 21 #define asmlinkage CPP_ASMLINKAGE
 22 #endif
 23 
 24 #ifndef cond_syscall
 25 #define cond_syscall(x)    asm(                
 26     ".weak " VMLINUX_SYMBOL_STR(x) "
	"        
 27     ".set  " VMLINUX_SYMBOL_STR(x) ","        
 28          VMLINUX_SYMBOL_STR(sys_ni_syscall))
 29 #endif
 30 
 31 #ifndef SYSCALL_ALIAS
 32 #define SYSCALL_ALIAS(alias, name) asm(            
 33     ".globl " VMLINUX_SYMBOL_STR(alias) "
	"    
 34     ".set   " VMLINUX_SYMBOL_STR(alias) ","        
 35           VMLINUX_SYMBOL_STR(name))
 36 #endif
 37 
 38 #define __page_aligned_data    __section(.data..page_aligned) __aligned(PAGE_SIZE)
 39 #define __page_aligned_bss    __section(.bss..page_aligned) __aligned(PAGE_SIZE)
 40 
 41 /*
 42  * For assembly routines.
 43  *
 44  * Note when using these that you must specify the appropriate
 45  * alignment directives yourself
 46  */
 47 #define __PAGE_ALIGNED_DATA    .section ".data..page_aligned", "aw"
 48 #define __PAGE_ALIGNED_BSS    .section ".bss..page_aligned", "aw"
 49 
 50 /*
 51  * This is used by architectures to keep arguments on the stack
 52  * untouched by the compiler by keeping them live until the end.
 53  * The argument stack may be owned by the assembly-language
 54  * caller, not the callee, and gcc doesn't always understand
 55  * that.
 56  *
 57  * We have the return value, and a maximum of six arguments.
 58  *
 59  * This should always be followed by a "return ret" for the
 60  * protection to work (ie no more work that the compiler might
 61  * end up needing stack temporaries for).
 62  */
 63 /* Assembly files may be compiled with -traditional .. */
 64 #ifndef __ASSEMBLY__
 65 #ifndef asmlinkage_protect
 66 # define asmlinkage_protect(n, ret, args...)    do { } while (0)
 67 #endif
 68 #endif
 69 
 70 #ifndef __ALIGN
 71 #define __ALIGN        .align 4,0x90
 72 #define __ALIGN_STR    ".align 4,0x90"
 73 #endif
 74 
 75 #ifdef __ASSEMBLY__
 76 
 77 #ifndef LINKER_SCRIPT
 78 #define ALIGN __ALIGN
 79 #define ALIGN_STR __ALIGN_STR
 80 
 81 #ifndef ENTRY
 82 #define ENTRY(name) 
 83     .globl name ASM_NL 
 84     ALIGN ASM_NL 
 85     name:
 86 #endif
 87 #endif /* LINKER_SCRIPT */
 88 
 89 #ifndef WEAK
 90 #define WEAK(name)       
 91     .weak name ASM_NL   
 92     name:
 93 #endif
 94 
 95 #ifndef END
 96 #define END(name) 
 97     .size name, .-name
 98 #endif
 99 
100 /* If symbol 'name' is treated as a subroutine (gets called, and returns)
101  * then please use ENDPROC to mark 'name' as STT_FUNC for the benefit of
102  * static analysis tools such as stack depth analyzer.
103  */
104 #ifndef ENDPROC
105 #define ENDPROC(name) 
106     .type name, @function ASM_NL 
107     END(name)
108 #endif
109 
110 #endif
111 
112 #endif
View Code

下面是系统调用表 /linux-3.18.6/arch/frv/kernel/entry.S

   1 /* entry.S: FR-V entry
   2  *
   3  * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
   4  * Written by David Howells (dhowells@redhat.com)
   5  *
   6  * This program is free software; you can redistribute it and/or
   7  * modify it under the terms of the GNU General Public License
   8  * as published by the Free Software Foundation; either version
   9  * 2 of the License, or (at your option) any later version.
  10  *
  11  *
  12  * Entry to the kernel is "interesting":
  13  *  (1) There are no stack pointers, not even for the kernel
  14  *  (2) General Registers should not be clobbered
  15  *  (3) There are no kernel-only data registers
  16  *  (4) Since all addressing modes are wrt to a General Register, no global
  17  *      variables can be reached
  18  *
  19  * We deal with this by declaring that we shall kill GR28 on entering the
  20  * kernel from userspace
  21  *
  22  * However, since break interrupts can interrupt the CPU even when PSR.ET==0,
  23  * they can't rely on GR28 to be anything useful, and so need to clobber a
  24  * separate register (GR31). Break interrupts are managed in break.S
  25  *
  26  * GR29 _is_ saved, and holds the current task pointer globally
  27  *
  28  */
  29 
  30 #include <linux/linkage.h>
  31 #include <asm/thread_info.h>
  32 #include <asm/setup.h>
  33 #include <asm/segment.h>
  34 #include <asm/ptrace.h>
  35 #include <asm/errno.h>
  36 #include <asm/cache.h>
  37 #include <asm/spr-regs.h>
  38 
  39 #define nr_syscalls ((syscall_table_size)/4)
  40 
  41     .section    .text..entry
  42     .balign        4
  43 
  44 .macro LEDS val
  45 #    sethi.p        %hi(0xe1200004),gr30
  46 #    setlo        %lo(0xe1200004),gr30
  47 #    setlos        #~val,gr31
  48 #    st        gr31,@(gr30,gr0)
  49 #    sethi.p        %hi(0xffc00100),gr30
  50 #    setlo        %lo(0xffc00100),gr30
  51 #    sth        gr0,@(gr30,gr0)
  52 #    membar
  53 .endm
  54 
  55 .macro LEDS32
  56 #    not        gr31,gr31
  57 #    sethi.p        %hi(0xe1200004),gr30
  58 #    setlo        %lo(0xe1200004),gr30
  59 #    st.p        gr31,@(gr30,gr0)
  60 #    srli        gr31,#16,gr31
  61 #    sethi.p        %hi(0xffc00100),gr30
  62 #    setlo        %lo(0xffc00100),gr30
  63 #    sth        gr31,@(gr30,gr0)
  64 #    membar
  65 .endm
  66 
  67 ###############################################################################
  68 #
  69 # entry point for External interrupts received whilst executing userspace code
  70 #
  71 ###############################################################################
  72     .globl        __entry_uspace_external_interrupt
  73         .type        __entry_uspace_external_interrupt,@function
  74 __entry_uspace_external_interrupt:
  75     LEDS        0x6200
  76     sethi.p        %hi(__kernel_frame0_ptr),gr28
  77     setlo        %lo(__kernel_frame0_ptr),gr28
  78     ldi        @(gr28,#0),gr28
  79 
  80     # handle h/w single-step through exceptions
  81     sti        gr0,@(gr28,#REG__STATUS)
  82 
  83     .globl        __entry_uspace_external_interrupt_reentry
  84 __entry_uspace_external_interrupt_reentry:
  85     LEDS        0x6201
  86 
  87     setlos        #REG__END,gr30
  88     dcpl        gr28,gr30,#0
  89 
  90     # finish building the exception frame
  91     sti        sp,  @(gr28,#REG_SP)
  92     stdi        gr2, @(gr28,#REG_GR(2))
  93     stdi        gr4, @(gr28,#REG_GR(4))
  94     stdi        gr6, @(gr28,#REG_GR(6))
  95     stdi        gr8, @(gr28,#REG_GR(8))
  96     stdi        gr10,@(gr28,#REG_GR(10))
  97     stdi        gr12,@(gr28,#REG_GR(12))
  98     stdi        gr14,@(gr28,#REG_GR(14))
  99     stdi        gr16,@(gr28,#REG_GR(16))
 100     stdi        gr18,@(gr28,#REG_GR(18))
 101     stdi        gr20,@(gr28,#REG_GR(20))
 102     stdi        gr22,@(gr28,#REG_GR(22))
 103     stdi        gr24,@(gr28,#REG_GR(24))
 104     stdi        gr26,@(gr28,#REG_GR(26))
 105     sti        gr0, @(gr28,#REG_GR(28))
 106     sti        gr29,@(gr28,#REG_GR(29))
 107     stdi.p        gr30,@(gr28,#REG_GR(30))
 108 
 109     # set up the kernel stack pointer
 110     ori        gr28,0,sp
 111 
 112     movsg        tbr ,gr20
 113     movsg        psr ,gr22
 114     movsg        pcsr,gr21
 115     movsg        isr ,gr23
 116     movsg        ccr ,gr24
 117     movsg        cccr,gr25
 118     movsg        lr  ,gr26
 119     movsg        lcr ,gr27
 120 
 121     setlos.p    #-1,gr4
 122     andi        gr22,#PSR_PS,gr5        /* try to rebuild original PSR value */
 123     andi.p        gr22,#~(PSR_PS|PSR_S),gr6
 124     slli        gr5,#1,gr5
 125     or        gr6,gr5,gr5
 126     andi        gr5,#~PSR_ET,gr5
 127 
 128     sti        gr20,@(gr28,#REG_TBR)
 129     sti        gr21,@(gr28,#REG_PC)
 130     sti        gr5 ,@(gr28,#REG_PSR)
 131     sti        gr23,@(gr28,#REG_ISR)
 132     stdi        gr24,@(gr28,#REG_CCR)
 133     stdi        gr26,@(gr28,#REG_LR)
 134     sti        gr4 ,@(gr28,#REG_SYSCALLNO)
 135 
 136     movsg        iacc0h,gr4
 137     movsg        iacc0l,gr5
 138     stdi        gr4,@(gr28,#REG_IACC0)
 139 
 140     movsg        gner0,gr4
 141     movsg        gner1,gr5
 142     stdi.p        gr4,@(gr28,#REG_GNER0)
 143 
 144     # interrupts start off fully disabled in the interrupt handler
 145     subcc        gr0,gr0,gr0,icc2        /* set Z and clear C */
 146 
 147     # set up kernel global registers
 148     sethi.p        %hi(__kernel_current_task),gr5
 149     setlo        %lo(__kernel_current_task),gr5
 150     sethi.p        %hi(_gp),gr16
 151     setlo        %lo(_gp),gr16
 152     ldi        @(gr5,#0),gr29
 153     ldi.p        @(gr29,#4),gr15        ; __current_thread_info = current->thread_info
 154 
 155     # make sure we (the kernel) get div-zero and misalignment exceptions
 156     setlos        #ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
 157     movgs        gr5,isr
 158 
 159     # switch to the kernel trap table
 160     sethi.p        %hi(__entry_kerneltrap_table),gr6
 161     setlo        %lo(__entry_kerneltrap_table),gr6
 162     movgs        gr6,tbr
 163 
 164     # set the return address
 165     sethi.p        %hi(__entry_return_from_user_interrupt),gr4
 166     setlo        %lo(__entry_return_from_user_interrupt),gr4
 167     movgs        gr4,lr
 168 
 169     # raise the minimum interrupt priority to 15 (NMI only) and enable exceptions
 170     movsg        psr,gr4
 171 
 172     ori        gr4,#PSR_PIL_14,gr4
 173     movgs        gr4,psr
 174     ori        gr4,#PSR_PIL_14|PSR_ET,gr4
 175     movgs        gr4,psr
 176 
 177     LEDS        0x6202
 178     bra        do_IRQ
 179 
 180     .size        __entry_uspace_external_interrupt,.-__entry_uspace_external_interrupt
 181 
 182 ###############################################################################
 183 #
 184 # entry point for External interrupts received whilst executing kernel code
 185 # - on arriving here, the following registers should already be set up:
 186 #    GR15    - current thread_info struct pointer
 187 #    GR16    - kernel GP-REL pointer
 188 #    GR29    - current task struct pointer
 189 #    TBR    - kernel trap vector table
 190 #    ISR    - kernel's preferred integer controls
 191 #
 192 ###############################################################################
 193     .globl        __entry_kernel_external_interrupt
 194         .type        __entry_kernel_external_interrupt,@function
 195 __entry_kernel_external_interrupt:
 196     LEDS        0x6210
 197 //    sub        sp,gr15,gr31
 198 //    LEDS32
 199 
 200     # set up the stack pointer
 201     or.p        sp,gr0,gr30
 202     subi        sp,#REG__END,sp
 203     sti        gr30,@(sp,#REG_SP)
 204 
 205     # handle h/w single-step through exceptions
 206     sti        gr0,@(sp,#REG__STATUS)
 207 
 208     .globl        __entry_kernel_external_interrupt_reentry
 209 __entry_kernel_external_interrupt_reentry:
 210     LEDS        0x6211
 211 
 212     # set up the exception frame
 213     setlos        #REG__END,gr30
 214     dcpl        sp,gr30,#0
 215 
 216     sti.p        gr28,@(sp,#REG_GR(28))
 217     ori        sp,0,gr28
 218 
 219     # finish building the exception frame
 220     stdi        gr2,@(gr28,#REG_GR(2))
 221     stdi        gr4,@(gr28,#REG_GR(4))
 222     stdi        gr6,@(gr28,#REG_GR(6))
 223     stdi        gr8,@(gr28,#REG_GR(8))
 224     stdi        gr10,@(gr28,#REG_GR(10))
 225     stdi        gr12,@(gr28,#REG_GR(12))
 226     stdi        gr14,@(gr28,#REG_GR(14))
 227     stdi        gr16,@(gr28,#REG_GR(16))
 228     stdi        gr18,@(gr28,#REG_GR(18))
 229     stdi        gr20,@(gr28,#REG_GR(20))
 230     stdi        gr22,@(gr28,#REG_GR(22))
 231     stdi        gr24,@(gr28,#REG_GR(24))
 232     stdi        gr26,@(gr28,#REG_GR(26))
 233     sti        gr29,@(gr28,#REG_GR(29))
 234     stdi.p        gr30,@(gr28,#REG_GR(30))
 235 
 236     # note virtual interrupts will be fully enabled upon return
 237     subicc        gr0,#1,gr0,icc2            /* clear Z, set C */
 238 
 239     movsg        tbr ,gr20
 240     movsg        psr ,gr22
 241     movsg        pcsr,gr21
 242     movsg        isr ,gr23
 243     movsg        ccr ,gr24
 244     movsg        cccr,gr25
 245     movsg        lr  ,gr26
 246     movsg        lcr ,gr27
 247 
 248     setlos.p    #-1,gr4
 249     andi        gr22,#PSR_PS,gr5        /* try to rebuild original PSR value */
 250     andi.p        gr22,#~(PSR_PS|PSR_S),gr6
 251     slli        gr5,#1,gr5
 252     or        gr6,gr5,gr5
 253     andi.p        gr5,#~PSR_ET,gr5
 254 
 255     # set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel
 256     # - for an explanation of how it works, see: Documentation/frv/atomic-ops.txt
 257     andi        gr25,#~0xc0,gr25
 258 
 259     sti        gr20,@(gr28,#REG_TBR)
 260     sti        gr21,@(gr28,#REG_PC)
 261     sti        gr5 ,@(gr28,#REG_PSR)
 262     sti        gr23,@(gr28,#REG_ISR)
 263     stdi        gr24,@(gr28,#REG_CCR)
 264     stdi        gr26,@(gr28,#REG_LR)
 265     sti        gr4 ,@(gr28,#REG_SYSCALLNO)
 266 
 267     movsg        iacc0h,gr4
 268     movsg        iacc0l,gr5
 269     stdi        gr4,@(gr28,#REG_IACC0)
 270 
 271     movsg        gner0,gr4
 272     movsg        gner1,gr5
 273     stdi.p        gr4,@(gr28,#REG_GNER0)
 274 
 275     # interrupts start off fully disabled in the interrupt handler
 276     subcc        gr0,gr0,gr0,icc2            /* set Z and clear C */
 277 
 278     # set the return address
 279     sethi.p        %hi(__entry_return_from_kernel_interrupt),gr4
 280     setlo        %lo(__entry_return_from_kernel_interrupt),gr4
 281     movgs        gr4,lr
 282 
 283     # clear power-saving mode flags
 284     movsg        hsr0,gr4
 285     andi        gr4,#~HSR0_PDM,gr4
 286     movgs        gr4,hsr0
 287 
 288     # raise the minimum interrupt priority to 15 (NMI only) and enable exceptions
 289     movsg        psr,gr4
 290     ori        gr4,#PSR_PIL_14,gr4
 291     movgs        gr4,psr
 292     ori        gr4,#PSR_ET,gr4
 293     movgs        gr4,psr
 294 
 295     LEDS        0x6212
 296     bra        do_IRQ
 297 
 298     .size        __entry_kernel_external_interrupt,.-__entry_kernel_external_interrupt
 299 
 300 ###############################################################################
 301 #
 302 # deal with interrupts that were actually virtually disabled
 303 # - we need to really disable them, flag the fact and return immediately
 304 # - if you change this, you must alter break.S also
 305 #
 306 ###############################################################################
 307     .balign        L1_CACHE_BYTES
 308     .globl        __entry_kernel_external_interrupt_virtually_disabled
 309     .type        __entry_kernel_external_interrupt_virtually_disabled,@function
 310 __entry_kernel_external_interrupt_virtually_disabled:
 311     movsg        psr,gr30
 312     andi        gr30,#~PSR_PIL,gr30
 313     ori        gr30,#PSR_PIL_14,gr30        ; debugging interrupts only
 314     movgs        gr30,psr
 315     subcc        gr0,gr0,gr0,icc2        ; leave Z set, clear C
 316     rett        #0
 317 
 318     .size        __entry_kernel_external_interrupt_virtually_disabled,.-__entry_kernel_external_interrupt_virtually_disabled
 319 
 320 ###############################################################################
 321 #
 322 # deal with re-enablement of interrupts that were pending when virtually re-enabled
 323 # - set ICC2.C, re-enable the real interrupts and return
 324 # - we can clear ICC2.Z because we shouldn't be here if it's not 0 [due to TIHI]
 325 # - if you change this, you must alter break.S also
 326 #
 327 ###############################################################################
 328     .balign        L1_CACHE_BYTES
 329     .globl        __entry_kernel_external_interrupt_virtual_reenable
 330     .type        __entry_kernel_external_interrupt_virtual_reenable,@function
 331 __entry_kernel_external_interrupt_virtual_reenable:
 332     movsg        psr,gr30
 333     andi        gr30,#~PSR_PIL,gr30        ; re-enable interrupts
 334     movgs        gr30,psr
 335     subicc        gr0,#1,gr0,icc2            ; clear Z, set C
 336     rett        #0
 337 
 338     .size        __entry_kernel_external_interrupt_virtual_reenable,.-__entry_kernel_external_interrupt_virtual_reenable
 339 
 340 ###############################################################################
 341 #
 342 # entry point for Software and Progam interrupts generated whilst executing userspace code
 343 #
 344 ###############################################################################
 345     .globl        __entry_uspace_softprog_interrupt
 346         .type        __entry_uspace_softprog_interrupt,@function
 347     .globl        __entry_uspace_handle_mmu_fault
 348 __entry_uspace_softprog_interrupt:
 349     LEDS        0x6000
 350 #ifdef CONFIG_MMU
 351     movsg        ear0,gr28
 352 __entry_uspace_handle_mmu_fault:
 353     movgs        gr28,scr2
 354 #endif
 355     sethi.p        %hi(__kernel_frame0_ptr),gr28
 356     setlo        %lo(__kernel_frame0_ptr),gr28
 357     ldi        @(gr28,#0),gr28
 358 
 359     # handle h/w single-step through exceptions
 360     sti        gr0,@(gr28,#REG__STATUS)
 361 
 362     .globl        __entry_uspace_softprog_interrupt_reentry
 363 __entry_uspace_softprog_interrupt_reentry:
 364     LEDS        0x6001
 365 
 366     setlos        #REG__END,gr30
 367     dcpl        gr28,gr30,#0
 368 
 369     # set up the kernel stack pointer
 370     sti.p        sp,@(gr28,#REG_SP)
 371     ori        gr28,0,sp
 372     sti        gr0,@(gr28,#REG_GR(28))
 373 
 374     stdi        gr20,@(gr28,#REG_GR(20))
 375     stdi        gr22,@(gr28,#REG_GR(22))
 376 
 377     movsg        tbr,gr20
 378     movsg        pcsr,gr21
 379     movsg        psr,gr22
 380 
 381     sethi.p        %hi(__entry_return_from_user_exception),gr23
 382     setlo        %lo(__entry_return_from_user_exception),gr23
 383 
 384     bra        __entry_common
 385 
 386     .size        __entry_uspace_softprog_interrupt,.-__entry_uspace_softprog_interrupt
 387 
 388     # single-stepping was disabled on entry to a TLB handler that then faulted
 389 #ifdef CONFIG_MMU
 390     .globl        __entry_uspace_handle_mmu_fault_sstep
 391 __entry_uspace_handle_mmu_fault_sstep:
 392     movgs        gr28,scr2
 393     sethi.p        %hi(__kernel_frame0_ptr),gr28
 394     setlo        %lo(__kernel_frame0_ptr),gr28
 395     ldi        @(gr28,#0),gr28
 396 
 397     # flag single-step re-enablement
 398     sti        gr0,@(gr28,#REG__STATUS)
 399     bra        __entry_uspace_softprog_interrupt_reentry
 400 #endif
 401 
 402 
 403 ###############################################################################
 404 #
 405 # entry point for Software and Progam interrupts generated whilst executing kernel code
 406 #
 407 ###############################################################################
 408     .globl        __entry_kernel_softprog_interrupt
 409         .type        __entry_kernel_softprog_interrupt,@function
 410 __entry_kernel_softprog_interrupt:
 411     LEDS        0x6004
 412 
 413 #ifdef CONFIG_MMU
 414     movsg        ear0,gr30
 415     movgs        gr30,scr2
 416 #endif
 417 
 418     .globl        __entry_kernel_handle_mmu_fault
 419 __entry_kernel_handle_mmu_fault:
 420     # set up the stack pointer
 421     subi        sp,#REG__END,sp
 422     sti        sp,@(sp,#REG_SP)
 423     sti        sp,@(sp,#REG_SP-4)
 424     andi        sp,#~7,sp
 425 
 426     # handle h/w single-step through exceptions
 427     sti        gr0,@(sp,#REG__STATUS)
 428 
 429     .globl        __entry_kernel_softprog_interrupt_reentry
 430 __entry_kernel_softprog_interrupt_reentry:
 431     LEDS        0x6005
 432 
 433     setlos        #REG__END,gr30
 434     dcpl        sp,gr30,#0
 435 
 436     # set up the exception frame
 437     sti.p        gr28,@(sp,#REG_GR(28))
 438     ori        sp,0,gr28
 439 
 440     stdi        gr20,@(gr28,#REG_GR(20))
 441     stdi        gr22,@(gr28,#REG_GR(22))
 442 
 443     ldi        @(sp,#REG_SP),gr22        /* reconstruct the old SP */
 444     addi        gr22,#REG__END,gr22
 445     sti        gr22,@(sp,#REG_SP)
 446 
 447     # set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel
 448     # - for an explanation of how it works, see: Documentation/frv/atomic-ops.txt
 449     movsg        cccr,gr20
 450     andi        gr20,#~0xc0,gr20
 451     movgs        gr20,cccr
 452 
 453     movsg        tbr,gr20
 454     movsg        pcsr,gr21
 455     movsg        psr,gr22
 456 
 457     sethi.p        %hi(__entry_return_from_kernel_exception),gr23
 458     setlo        %lo(__entry_return_from_kernel_exception),gr23
 459     bra        __entry_common
 460 
 461     .size        __entry_kernel_softprog_interrupt,.-__entry_kernel_softprog_interrupt
 462 
 463     # single-stepping was disabled on entry to a TLB handler that then faulted
 464 #ifdef CONFIG_MMU
 465     .globl        __entry_kernel_handle_mmu_fault_sstep
 466 __entry_kernel_handle_mmu_fault_sstep:
 467     # set up the stack pointer
 468     subi        sp,#REG__END,sp
 469     sti        sp,@(sp,#REG_SP)
 470     sti        sp,@(sp,#REG_SP-4)
 471     andi        sp,#~7,sp
 472 
 473     # flag single-step re-enablement
 474     sethi        #REG__STATUS_STEP,gr30
 475     sti        gr30,@(sp,#REG__STATUS)
 476     bra        __entry_kernel_softprog_interrupt_reentry
 477 #endif
 478 
 479 
 480 ###############################################################################
 481 #
 482 # the rest of the kernel entry point code
 483 # - on arriving here, the following registers should be set up:
 484 #    GR1    - kernel stack pointer
 485 #    GR7    - syscall number (trap 0 only)
 486 #    GR8-13    - syscall args (trap 0 only)
 487 #    GR20    - saved TBR
 488 #    GR21    - saved PC
 489 #    GR22    - saved PSR
 490 #    GR23    - return handler address
 491 #    GR28    - exception frame on stack
 492 #    SCR2    - saved EAR0 where applicable (clobbered by ICI & ICEF insns on FR451)
 493 #    PSR    - PSR.S 1, PSR.ET 0
 494 #
 495 ###############################################################################
 496     .globl        __entry_common
 497         .type        __entry_common,@function
 498 __entry_common:
 499     LEDS        0x6008
 500 
 501     # finish building the exception frame
 502     stdi        gr2,@(gr28,#REG_GR(2))
 503     stdi        gr4,@(gr28,#REG_GR(4))
 504     stdi        gr6,@(gr28,#REG_GR(6))
 505     stdi        gr8,@(gr28,#REG_GR(8))
 506     stdi        gr10,@(gr28,#REG_GR(10))
 507     stdi        gr12,@(gr28,#REG_GR(12))
 508     stdi        gr14,@(gr28,#REG_GR(14))
 509     stdi        gr16,@(gr28,#REG_GR(16))
 510     stdi        gr18,@(gr28,#REG_GR(18))
 511     stdi        gr24,@(gr28,#REG_GR(24))
 512     stdi        gr26,@(gr28,#REG_GR(26))
 513     sti        gr29,@(gr28,#REG_GR(29))
 514     stdi        gr30,@(gr28,#REG_GR(30))
 515 
 516     movsg        lcr ,gr27
 517     movsg        lr  ,gr26
 518     movgs        gr23,lr
 519     movsg        cccr,gr25
 520     movsg        ccr ,gr24
 521     movsg        isr ,gr23
 522 
 523     setlos.p    #-1,gr4
 524     andi        gr22,#PSR_PS,gr5        /* try to rebuild original PSR value */
 525     andi.p        gr22,#~(PSR_PS|PSR_S),gr6
 526     slli        gr5,#1,gr5
 527     or        gr6,gr5,gr5
 528     andi        gr5,#~PSR_ET,gr5
 529 
 530     sti        gr20,@(gr28,#REG_TBR)
 531     sti        gr21,@(gr28,#REG_PC)
 532     sti        gr5 ,@(gr28,#REG_PSR)
 533     sti        gr23,@(gr28,#REG_ISR)
 534     stdi        gr24,@(gr28,#REG_CCR)
 535     stdi        gr26,@(gr28,#REG_LR)
 536     sti        gr4 ,@(gr28,#REG_SYSCALLNO)
 537 
 538     movsg        iacc0h,gr4
 539     movsg        iacc0l,gr5
 540     stdi        gr4,@(gr28,#REG_IACC0)
 541 
 542     movsg        gner0,gr4
 543     movsg        gner1,gr5
 544     stdi.p        gr4,@(gr28,#REG_GNER0)
 545 
 546     # set up virtual interrupt disablement
 547     subicc        gr0,#1,gr0,icc2            /* clear Z flag, set C flag */
 548 
 549     # set up kernel global registers
 550     sethi.p        %hi(__kernel_current_task),gr5
 551     setlo        %lo(__kernel_current_task),gr5
 552     sethi.p        %hi(_gp),gr16
 553     setlo        %lo(_gp),gr16
 554     ldi        @(gr5,#0),gr29
 555     ldi        @(gr29,#4),gr15        ; __current_thread_info = current->thread_info
 556 
 557     # switch to the kernel trap table
 558     sethi.p        %hi(__entry_kerneltrap_table),gr6
 559     setlo        %lo(__entry_kerneltrap_table),gr6
 560     movgs        gr6,tbr
 561 
 562     # make sure we (the kernel) get div-zero and misalignment exceptions
 563     setlos        #ISR_EDE|ISR_DTT_DIVBYZERO|ISR_EMAM_EXCEPTION,gr5
 564     movgs        gr5,isr
 565 
 566     # clear power-saving mode flags
 567     movsg        hsr0,gr4
 568     andi        gr4,#~HSR0_PDM,gr4
 569     movgs        gr4,hsr0
 570 
 571     # multiplex again using old TBR as a guide
 572     setlos.p    #TBR_TT,gr3
 573     sethi        %hi(__entry_vector_table),gr6
 574     and.p        gr20,gr3,gr5
 575     setlo        %lo(__entry_vector_table),gr6
 576     srli        gr5,#2,gr5
 577     ld        @(gr5,gr6),gr5
 578 
 579     LEDS        0x6009
 580     jmpl        @(gr5,gr0)
 581 
 582 
 583     .size        __entry_common,.-__entry_common
 584 
 585 ###############################################################################
 586 #
 587 # handle instruction MMU fault
 588 #
 589 ###############################################################################
 590 #ifdef CONFIG_MMU
 591     .globl        __entry_insn_mmu_fault
 592 __entry_insn_mmu_fault:
 593     LEDS        0x6010
 594     setlos        #0,gr8
 595     movsg        esr0,gr9
 596     movsg        scr2,gr10
 597 
 598     # now that we've accessed the exception regs, we can enable exceptions
 599     movsg        psr,gr4
 600     ori        gr4,#PSR_ET,gr4
 601     movgs        gr4,psr
 602 
 603     sethi.p        %hi(do_page_fault),gr5
 604     setlo        %lo(do_page_fault),gr5
 605     jmpl        @(gr5,gr0)    ; call do_page_fault(0,esr0,ear0)
 606 #endif
 607 
 608 
 609 ###############################################################################
 610 #
 611 # handle instruction access error
 612 #
 613 ###############################################################################
 614     .globl        __entry_insn_access_error
 615 __entry_insn_access_error:
 616     LEDS        0x6011
 617     sethi.p        %hi(insn_access_error),gr5
 618     setlo        %lo(insn_access_error),gr5
 619     movsg        esfr1,gr8
 620     movsg        epcr0,gr9
 621     movsg        esr0,gr10
 622 
 623     # now that we've accessed the exception regs, we can enable exceptions
 624     movsg        psr,gr4
 625     ori        gr4,#PSR_ET,gr4
 626     movgs        gr4,psr
 627     jmpl        @(gr5,gr0)    ; call insn_access_error(esfr1,epcr0,esr0)
 628 
 629 ###############################################################################
 630 #
 631 # handle various instructions of dubious legality
 632 #
 633 ###############################################################################
 634     .globl        __entry_unsupported_trap
 635     .globl        __entry_illegal_instruction
 636     .globl        __entry_privileged_instruction
 637     .globl        __entry_debug_exception
 638 __entry_unsupported_trap:
 639     subi        gr21,#4,gr21
 640     sti        gr21,@(gr28,#REG_PC)
 641 __entry_illegal_instruction:
 642 __entry_privileged_instruction:
 643 __entry_debug_exception:
 644     LEDS        0x6012
 645     sethi.p        %hi(illegal_instruction),gr5
 646     setlo        %lo(illegal_instruction),gr5
 647     movsg        esfr1,gr8
 648     movsg        epcr0,gr9
 649     movsg        esr0,gr10
 650 
 651     # now that we've accessed the exception regs, we can enable exceptions
 652     movsg        psr,gr4
 653     ori        gr4,#PSR_ET,gr4
 654     movgs        gr4,psr
 655     jmpl        @(gr5,gr0)    ; call ill_insn(esfr1,epcr0,esr0)
 656 
 657 ###############################################################################
 658 #
 659 # handle atomic operation emulation for userspace
 660 #
 661 ###############################################################################
 662     .globl        __entry_atomic_op
 663 __entry_atomic_op:
 664     LEDS        0x6012
 665     sethi.p        %hi(atomic_operation),gr5
 666     setlo        %lo(atomic_operation),gr5
 667     movsg        esfr1,gr8
 668     movsg        epcr0,gr9
 669     movsg        esr0,gr10
 670 
 671     # now that we've accessed the exception regs, we can enable exceptions
 672     movsg        psr,gr4
 673     ori        gr4,#PSR_ET,gr4
 674     movgs        gr4,psr
 675     jmpl        @(gr5,gr0)    ; call atomic_operation(esfr1,epcr0,esr0)
 676 
 677 ###############################################################################
 678 #
 679 # handle media exception
 680 #
 681 ###############################################################################
 682     .globl        __entry_media_exception
 683 __entry_media_exception:
 684     LEDS        0x6013
 685     sethi.p        %hi(media_exception),gr5
 686     setlo        %lo(media_exception),gr5
 687     movsg        msr0,gr8
 688     movsg        msr1,gr9
 689 
 690     # now that we've accessed the exception regs, we can enable exceptions
 691     movsg        psr,gr4
 692     ori        gr4,#PSR_ET,gr4
 693     movgs        gr4,psr
 694     jmpl        @(gr5,gr0)    ; call media_excep(msr0,msr1)
 695 
 696 ###############################################################################
 697 #
 698 # handle data MMU fault
 699 # handle data DAT fault (write-protect exception)
 700 #
 701 ###############################################################################
 702 #ifdef CONFIG_MMU
 703     .globl        __entry_data_mmu_fault
 704 __entry_data_mmu_fault:
 705     .globl        __entry_data_dat_fault
 706 __entry_data_dat_fault:
 707     LEDS        0x6014
 708     setlos        #1,gr8
 709     movsg        esr0,gr9
 710     movsg        scr2,gr10    ; saved EAR0
 711 
 712     # now that we've accessed the exception regs, we can enable exceptions
 713     movsg        psr,gr4
 714     ori        gr4,#PSR_ET,gr4
 715     movgs        gr4,psr
 716 
 717     sethi.p        %hi(do_page_fault),gr5
 718     setlo        %lo(do_page_fault),gr5
 719     jmpl        @(gr5,gr0)    ; call do_page_fault(1,esr0,ear0)
 720 #endif
 721 
 722 ###############################################################################
 723 #
 724 # handle data and instruction access exceptions
 725 #
 726 ###############################################################################
 727     .globl        __entry_insn_access_exception
 728     .globl        __entry_data_access_exception
 729 __entry_insn_access_exception:
 730 __entry_data_access_exception:
 731     LEDS        0x6016
 732     sethi.p        %hi(memory_access_exception),gr5
 733     setlo        %lo(memory_access_exception),gr5
 734     movsg        esr0,gr8
 735     movsg        scr2,gr9    ; saved EAR0
 736     movsg        epcr0,gr10
 737 
 738     # now that we've accessed the exception regs, we can enable exceptions
 739     movsg        psr,gr4
 740     ori        gr4,#PSR_ET,gr4
 741     movgs        gr4,psr
 742     jmpl        @(gr5,gr0)    ; call memory_access_error(esr0,ear0,epcr0)
 743 
 744 ###############################################################################
 745 #
 746 # handle data access error
 747 #
 748 ###############################################################################
 749     .globl        __entry_data_access_error
 750 __entry_data_access_error:
 751     LEDS        0x6016
 752     sethi.p        %hi(data_access_error),gr5
 753     setlo        %lo(data_access_error),gr5
 754     movsg        esfr1,gr8
 755     movsg        esr15,gr9
 756     movsg        ear15,gr10
 757 
 758     # now that we've accessed the exception regs, we can enable exceptions
 759     movsg        psr,gr4
 760     ori        gr4,#PSR_ET,gr4
 761     movgs        gr4,psr
 762     jmpl        @(gr5,gr0)    ; call data_access_error(esfr1,esr15,ear15)
 763 
 764 ###############################################################################
 765 #
 766 # handle data store error
 767 #
 768 ###############################################################################
 769     .globl        __entry_data_store_error
 770 __entry_data_store_error:
 771     LEDS        0x6017
 772     sethi.p        %hi(data_store_error),gr5
 773     setlo        %lo(data_store_error),gr5
 774     movsg        esfr1,gr8
 775     movsg        esr14,gr9
 776 
 777     # now that we've accessed the exception regs, we can enable exceptions
 778     movsg        psr,gr4
 779     ori        gr4,#PSR_ET,gr4
 780     movgs        gr4,psr
 781     jmpl        @(gr5,gr0)    ; call data_store_error(esfr1,esr14)
 782 
 783 ###############################################################################
 784 #
 785 # handle division exception
 786 #
 787 ###############################################################################
 788     .globl        __entry_division_exception
 789 __entry_division_exception:
 790     LEDS        0x6018
 791     sethi.p        %hi(division_exception),gr5
 792     setlo        %lo(division_exception),gr5
 793     movsg        esfr1,gr8
 794     movsg        esr0,gr9
 795     movsg        isr,gr10
 796 
 797     # now that we've accessed the exception regs, we can enable exceptions
 798     movsg        psr,gr4
 799     ori        gr4,#PSR_ET,gr4
 800     movgs        gr4,psr
 801     jmpl        @(gr5,gr0)    ; call div_excep(esfr1,esr0,isr)
 802 
 803 ###############################################################################
 804 #
 805 # handle compound exception
 806 #
 807 ###############################################################################
 808     .globl        __entry_compound_exception
 809 __entry_compound_exception:
 810     LEDS        0x6019
 811     sethi.p        %hi(compound_exception),gr5
 812     setlo        %lo(compound_exception),gr5
 813     movsg        esfr1,gr8
 814     movsg        esr0,gr9
 815     movsg        esr14,gr10
 816     movsg        esr15,gr11
 817     movsg        msr0,gr12
 818     movsg        msr1,gr13
 819 
 820     # now that we've accessed the exception regs, we can enable exceptions
 821     movsg        psr,gr4
 822     ori        gr4,#PSR_ET,gr4
 823     movgs        gr4,psr
 824     jmpl        @(gr5,gr0)    ; call comp_excep(esfr1,esr0,esr14,esr15,msr0,msr1)
 825 
 826 ###############################################################################
 827 #
 828 # handle interrupts and NMIs
 829 #
 830 ###############################################################################
 831     .globl        __entry_do_IRQ
 832 __entry_do_IRQ:
 833     LEDS        0x6020
 834 
 835     # we can enable exceptions
 836     movsg        psr,gr4
 837     ori        gr4,#PSR_ET,gr4
 838     movgs        gr4,psr
 839     bra        do_IRQ
 840 
 841     .globl        __entry_do_NMI
 842 __entry_do_NMI:
 843     LEDS        0x6021
 844 
 845     # we can enable exceptions
 846     movsg        psr,gr4
 847     ori        gr4,#PSR_ET,gr4
 848     movgs        gr4,psr
 849     bra        do_NMI
 850 
 851 ###############################################################################
 852 #
 853 # the return path for a newly forked child process
 854 # - __switch_to() saved the old current pointer in GR8 for us
 855 #
 856 ###############################################################################
 857     .globl        ret_from_fork
 858 ret_from_fork:
 859     LEDS        0x6100
 860     call        schedule_tail
 861 
 862     # fork & co. return 0 to child
 863     setlos.p    #0,gr8
 864     bra        __syscall_exit
 865 
 866     .globl        ret_from_kernel_thread
 867 ret_from_kernel_thread:
 868     lddi.p        @(gr28,#REG_GR(8)),gr20
 869     call        schedule_tail
 870     calll.p        @(gr21,gr0)
 871     or        gr20,gr20,gr8
 872     bra        __syscall_exit
 873 
 874 ###################################################################################################
 875 #
 876 # Return to user mode is not as complex as all this looks,
 877 # but we want the default path for a system call return to
 878 # go as quickly as possible which is why some of this is
 879 # less clear than it otherwise should be.
 880 #
 881 ###################################################################################################
 882     .balign        L1_CACHE_BYTES
 883     .globl        system_call
 884 system_call:
 885     LEDS        0x6101
 886     movsg        psr,gr4            ; enable exceptions
 887     ori        gr4,#PSR_ET,gr4
 888     movgs        gr4,psr
 889 
 890     sti        gr7,@(gr28,#REG_SYSCALLNO)
 891     sti.p        gr8,@(gr28,#REG_ORIG_GR8)
 892 
 893     subicc        gr7,#nr_syscalls,gr0,icc0
 894     bnc        icc0,#0,__syscall_badsys
 895 
 896     ldi        @(gr15,#TI_FLAGS),gr4
 897     andicc        gr4,#_TIF_SYSCALL_TRACE,gr0,icc0
 898     bne        icc0,#0,__syscall_trace_entry
 899 
 900 __syscall_call:
 901     slli.p        gr7,#2,gr7
 902     sethi        %hi(sys_call_table),gr5
 903     setlo        %lo(sys_call_table),gr5
 904     ld        @(gr5,gr7),gr4
 905     calll        @(gr4,gr0)
 906 
 907 
 908 ###############################################################################
 909 #
 910 # return to interrupted process
 911 #
 912 ###############################################################################
 913 __syscall_exit:
 914     LEDS        0x6300
 915 
 916     # keep current PSR in GR23
 917     movsg        psr,gr23
 918 
 919     ldi        @(gr28,#REG_PSR),gr22
 920 
 921     sti.p        gr8,@(gr28,#REG_GR(8))    ; save return value
 922 
 923     # rebuild saved psr - execve will change it for init/main.c
 924     srli        gr22,#1,gr5
 925     andi.p        gr22,#~PSR_PS,gr22
 926     andi        gr5,#PSR_PS,gr5
 927     or        gr5,gr22,gr22
 928     ori.p        gr22,#PSR_S,gr22
 929 
 930     # make sure we don't miss an interrupt setting need_resched or sigpending between
 931     # sampling and the RETT
 932     ori        gr23,#PSR_PIL_14,gr23
 933     movgs        gr23,psr
 934 
 935     ldi        @(gr15,#TI_FLAGS),gr4
 936     andicc        gr4,#_TIF_ALLWORK_MASK,gr0,icc0
 937     bne        icc0,#0,__syscall_exit_work
 938 
 939     # restore all registers and return
 940 __entry_return_direct:
 941     LEDS        0x6301
 942 
 943     andi        gr22,#~PSR_ET,gr22
 944     movgs        gr22,psr
 945 
 946     ldi        @(gr28,#REG_ISR),gr23
 947     lddi        @(gr28,#REG_CCR),gr24
 948     lddi        @(gr28,#REG_LR) ,gr26
 949     ldi        @(gr28,#REG_PC) ,gr21
 950     ldi        @(gr28,#REG_TBR),gr20
 951 
 952     movgs        gr20,tbr
 953     movgs        gr21,pcsr
 954     movgs        gr23,isr
 955     movgs        gr24,ccr
 956     movgs        gr25,cccr
 957     movgs        gr26,lr
 958     movgs        gr27,lcr
 959 
 960     lddi        @(gr28,#REG_GNER0),gr4
 961     movgs        gr4,gner0
 962     movgs        gr5,gner1
 963 
 964     lddi        @(gr28,#REG_IACC0),gr4
 965     movgs        gr4,iacc0h
 966     movgs        gr5,iacc0l
 967 
 968     lddi        @(gr28,#REG_GR(4)) ,gr4
 969     lddi        @(gr28,#REG_GR(6)) ,gr6
 970     lddi        @(gr28,#REG_GR(8)) ,gr8
 971     lddi        @(gr28,#REG_GR(10)),gr10
 972     lddi        @(gr28,#REG_GR(12)),gr12
 973     lddi        @(gr28,#REG_GR(14)),gr14
 974     lddi        @(gr28,#REG_GR(16)),gr16
 975     lddi        @(gr28,#REG_GR(18)),gr18
 976     lddi        @(gr28,#REG_GR(20)),gr20
 977     lddi        @(gr28,#REG_GR(22)),gr22
 978     lddi        @(gr28,#REG_GR(24)),gr24
 979     lddi        @(gr28,#REG_GR(26)),gr26
 980     ldi        @(gr28,#REG_GR(29)),gr29
 981     lddi        @(gr28,#REG_GR(30)),gr30
 982 
 983     # check to see if a debugging return is required
 984     LEDS        0x67f0
 985     movsg        ccr,gr2
 986     ldi        @(gr28,#REG__STATUS),gr3
 987     andicc        gr3,#REG__STATUS_STEP,gr0,icc0
 988     bne        icc0,#0,__entry_return_singlestep
 989     movgs        gr2,ccr
 990 
 991     ldi        @(gr28,#REG_SP)    ,sp
 992     lddi        @(gr28,#REG_GR(2)) ,gr2
 993     ldi        @(gr28,#REG_GR(28)),gr28
 994 
 995     LEDS        0x67fe
 996 //    movsg        pcsr,gr31
 997 //    LEDS32
 998 
 999 #if 0
1000     # store the current frame in the workram on the FR451
1001     movgs        gr28,scr2
1002     sethi.p        %hi(0xfe800000),gr28
1003     setlo        %lo(0xfe800000),gr28
1004 
1005     stdi        gr2,@(gr28,#REG_GR(2))
1006     stdi        gr4,@(gr28,#REG_GR(4))
1007     stdi        gr6,@(gr28,#REG_GR(6))
1008     stdi        gr8,@(gr28,#REG_GR(8))
1009     stdi        gr10,@(gr28,#REG_GR(10))
1010     stdi        gr12,@(gr28,#REG_GR(12))
1011     stdi        gr14,@(gr28,#REG_GR(14))
1012     stdi        gr16,@(gr28,#REG_GR(16))
1013     stdi        gr18,@(gr28,#REG_GR(18))
1014     stdi        gr24,@(gr28,#REG_GR(24))
1015     stdi        gr26,@(gr28,#REG_GR(26))
1016     sti        gr29,@(gr28,#REG_GR(29))
1017     stdi        gr30,@(gr28,#REG_GR(30))
1018 
1019     movsg        tbr ,gr30
1020     sti        gr30,@(gr28,#REG_TBR)
1021     movsg        pcsr,gr30
1022     sti        gr30,@(gr28,#REG_PC)
1023     movsg        psr ,gr30
1024     sti        gr30,@(gr28,#REG_PSR)
1025     movsg        isr ,gr30
1026     sti        gr30,@(gr28,#REG_ISR)
1027     movsg        ccr ,gr30
1028     movsg        cccr,gr31
1029     stdi        gr30,@(gr28,#REG_CCR)
1030     movsg        lr  ,gr30
1031     movsg        lcr ,gr31
1032     stdi        gr30,@(gr28,#REG_LR)
1033     sti        gr0 ,@(gr28,#REG_SYSCALLNO)
1034     movsg        scr2,gr28
1035 #endif
1036 
1037     rett        #0
1038 
1039     # return via break.S
1040 __entry_return_singlestep:
1041     movgs        gr2,ccr
1042     lddi        @(gr28,#REG_GR(2)) ,gr2
1043     ldi        @(gr28,#REG_SP)    ,sp
1044     ldi        @(gr28,#REG_GR(28)),gr28
1045     LEDS        0x67ff
1046     break
1047     .globl        __entry_return_singlestep_breaks_here
1048 __entry_return_singlestep_breaks_here:
1049     nop
1050 
1051 
1052 ###############################################################################
1053 #
1054 # return to a process interrupted in kernel space
1055 # - we need to consider preemption if that is enabled
1056 #
1057 ###############################################################################
1058     .balign        L1_CACHE_BYTES
1059 __entry_return_from_kernel_exception:
1060     LEDS        0x6302
1061     movsg        psr,gr23
1062     ori        gr23,#PSR_PIL_14,gr23
1063     movgs        gr23,psr
1064     bra        __entry_return_direct
1065 
1066     .balign        L1_CACHE_BYTES
1067 __entry_return_from_kernel_interrupt:
1068     LEDS        0x6303
1069     movsg        psr,gr23
1070     ori        gr23,#PSR_PIL_14,gr23
1071     movgs        gr23,psr
1072 
1073 #ifdef CONFIG_PREEMPT
1074     ldi        @(gr15,#TI_PRE_COUNT),gr5
1075     subicc        gr5,#0,gr0,icc0
1076     beq        icc0,#0,__entry_return_direct
1077 
1078     subcc        gr0,gr0,gr0,icc2        /* set Z and clear C */
1079     call        preempt_schedule_irq
1080 #endif
1081     bra        __entry_return_direct
1082 
1083 
1084 ###############################################################################
1085 #
1086 # perform work that needs to be done immediately before resumption
1087 #
1088 ###############################################################################
1089     .globl        __entry_return_from_user_exception
1090     .balign        L1_CACHE_BYTES
1091 __entry_return_from_user_exception:
1092     LEDS        0x6501
1093 
1094 __entry_resume_userspace:
1095     # make sure we don't miss an interrupt setting need_resched or sigpending between
1096     # sampling and the RETT
1097     movsg        psr,gr23
1098     ori        gr23,#PSR_PIL_14,gr23
1099     movgs        gr23,psr
1100 
1101 __entry_return_from_user_interrupt:
1102     LEDS        0x6402
1103     ldi        @(gr15,#TI_FLAGS),gr4
1104     andicc        gr4,#_TIF_WORK_MASK,gr0,icc0
1105     beq        icc0,#1,__entry_return_direct
1106 
1107 __entry_work_pending:
1108     LEDS        0x6404
1109     andicc        gr4,#_TIF_NEED_RESCHED,gr0,icc0
1110     beq        icc0,#1,__entry_work_notifysig
1111 
1112 __entry_work_resched:
1113     LEDS        0x6408
1114     movsg        psr,gr23
1115     andi        gr23,#~PSR_PIL,gr23
1116     movgs        gr23,psr
1117     call        schedule
1118     movsg        psr,gr23
1119     ori        gr23,#PSR_PIL_14,gr23
1120     movgs        gr23,psr
1121 
1122     LEDS        0x6401
1123     ldi        @(gr15,#TI_FLAGS),gr4
1124     andicc        gr4,#_TIF_WORK_MASK,gr0,icc0
1125     beq        icc0,#1,__entry_return_direct
1126     andicc        gr4,#_TIF_NEED_RESCHED,gr0,icc0
1127     bne        icc0,#1,__entry_work_resched
1128 
1129 __entry_work_notifysig:
1130     LEDS        0x6410
1131     ori.p        gr4,#0,gr8
1132     call        do_notify_resume
1133     bra        __entry_resume_userspace
1134 
1135     # perform syscall entry tracing
1136 __syscall_trace_entry:
1137     LEDS        0x6320
1138     call        syscall_trace_entry
1139 
1140     lddi.p        @(gr28,#REG_GR(8)) ,gr8
1141     ori        gr8,#0,gr7        ; syscall_trace_entry() returned new syscallno
1142     lddi        @(gr28,#REG_GR(10)),gr10
1143     lddi.p        @(gr28,#REG_GR(12)),gr12
1144 
1145     subicc        gr7,#nr_syscalls,gr0,icc0
1146     bnc        icc0,#0,__syscall_badsys
1147     bra        __syscall_call
1148 
1149     # perform syscall exit tracing
1150 __syscall_exit_work:
1151     LEDS        0x6340
1152     andicc        gr22,#PSR_PS,gr0,icc1    ; don't handle on return to kernel mode
1153     andicc.p    gr4,#_TIF_SYSCALL_TRACE,gr0,icc0
1154     bne        icc1,#0,__entry_return_direct
1155     beq        icc0,#1,__entry_work_pending
1156 
1157     movsg        psr,gr23
1158     andi        gr23,#~PSR_PIL,gr23    ; could let syscall_trace_exit() call schedule()
1159     movgs        gr23,psr
1160 
1161     call        syscall_trace_exit
1162     bra        __entry_resume_userspace
1163 
1164 __syscall_badsys:
1165     LEDS        0x6380
1166     setlos        #-ENOSYS,gr8
1167     sti        gr8,@(gr28,#REG_GR(8))    ; save return value
1168     bra        __entry_resume_userspace
1169 
1170 
1171 ###############################################################################
1172 #
1173 # syscall vector table
1174 #
1175 ###############################################################################
1176     .section .rodata
1177 ALIGN
1178     .globl        sys_call_table
1179 sys_call_table:
1180     .long sys_restart_syscall    /* 0 - old "setup()" system call, used for restarting */
1181     .long sys_exit
1182     .long sys_fork
1183     .long sys_read
1184     .long sys_write
1185     .long sys_open        /* 5 */
1186     .long sys_close
1187     .long sys_waitpid
1188     .long sys_creat
1189     .long sys_link
1190     .long sys_unlink        /* 10 */
1191     .long sys_execve
1192     .long sys_chdir
1193     .long sys_time
1194     .long sys_mknod
1195     .long sys_chmod        /* 15 */
1196     .long sys_lchown16
1197     .long sys_ni_syscall            /* old break syscall holder */
1198     .long sys_stat
1199     .long sys_lseek
1200     .long sys_getpid        /* 20 */
1201     .long sys_mount
1202     .long sys_oldumount
1203     .long sys_setuid16
1204     .long sys_getuid16
1205     .long sys_ni_syscall // sys_stime        /* 25 */
1206     .long sys_ptrace
1207     .long sys_alarm
1208     .long sys_fstat
1209     .long sys_pause
1210     .long sys_utime        /* 30 */
1211     .long sys_ni_syscall            /* old stty syscall holder */
1212     .long sys_ni_syscall            /* old gtty syscall holder */
1213     .long sys_access
1214     .long sys_nice
1215     .long sys_ni_syscall    /* 35 */    /* old ftime syscall holder */
1216     .long sys_sync
1217     .long sys_kill
1218     .long sys_rename
1219     .long sys_mkdir
1220     .long sys_rmdir        /* 40 */
1221     .long sys_dup
1222     .long sys_pipe
1223     .long sys_times
1224     .long sys_ni_syscall            /* old prof syscall holder */
1225     .long sys_brk        /* 45 */
1226     .long sys_setgid16
1227     .long sys_getgid16
1228     .long sys_ni_syscall // sys_signal
1229     .long sys_geteuid16
1230     .long sys_getegid16    /* 50 */
1231     .long sys_acct
1232     .long sys_umount                /* recycled never used phys( */
1233     .long sys_ni_syscall            /* old lock syscall holder */
1234     .long sys_ioctl
1235     .long sys_fcntl        /* 55 */
1236     .long sys_ni_syscall            /* old mpx syscall holder */
1237     .long sys_setpgid
1238     .long sys_ni_syscall            /* old ulimit syscall holder */
1239     .long sys_ni_syscall            /* old old uname syscall */
1240     .long sys_umask        /* 60 */
1241     .long sys_chroot
1242     .long sys_ustat
1243     .long sys_dup2
1244     .long sys_getppid
1245     .long sys_getpgrp    /* 65 */
1246     .long sys_setsid
1247     .long sys_sigaction
1248     .long sys_ni_syscall // sys_sgetmask
1249     .long sys_ni_syscall // sys_ssetmask
1250     .long sys_setreuid16    /* 70 */
1251     .long sys_setregid16
1252     .long sys_sigsuspend
1253     .long sys_ni_syscall // sys_sigpending
1254     .long sys_sethostname
1255     .long sys_setrlimit    /* 75 */
1256     .long sys_ni_syscall // sys_old_getrlimit
1257     .long sys_getrusage
1258     .long sys_gettimeofday
1259     .long sys_settimeofday
1260     .long sys_getgroups16    /* 80 */
1261     .long sys_setgroups16
1262     .long sys_ni_syscall            /* old_select slot */
1263     .long sys_symlink
1264     .long sys_lstat
1265     .long sys_readlink        /* 85 */
1266     .long sys_uselib
1267     .long sys_swapon
1268     .long sys_reboot
1269     .long sys_ni_syscall // old_readdir
1270     .long sys_ni_syscall    /* 90 */    /* old_mmap slot */
1271     .long sys_munmap
1272     .long sys_truncate
1273     .long sys_ftruncate
1274     .long sys_fchmod
1275     .long sys_fchown16        /* 95 */
1276     .long sys_getpriority
1277     .long sys_setpriority
1278     .long sys_ni_syscall            /* old profil syscall holder */
1279     .long sys_statfs
1280     .long sys_fstatfs        /* 100 */
1281     .long sys_ni_syscall            /* ioperm for i386 */
1282     .long sys_socketcall
1283     .long sys_syslog
1284     .long sys_setitimer
1285     .long sys_getitimer    /* 105 */
1286     .long sys_newstat
1287     .long sys_newlstat
1288     .long sys_newfstat
1289     .long sys_ni_syscall    /* obsolete olduname( syscall */
1290     .long sys_ni_syscall    /* iopl for i386 */ /* 110 */
1291     .long sys_vhangup
1292     .long sys_ni_syscall    /* obsolete idle( syscall */
1293     .long sys_ni_syscall    /* vm86old for i386 */
1294     .long sys_wait4
1295     .long sys_swapoff        /* 115 */
1296     .long sys_sysinfo
1297     .long sys_ipc
1298     .long sys_fsync
1299     .long sys_sigreturn
1300     .long sys_clone        /* 120 */
1301     .long sys_setdomainname
1302     .long sys_newuname
1303     .long sys_ni_syscall    /* old "cacheflush" */
1304     .long sys_adjtimex
1305     .long sys_mprotect    /* 125 */
1306     .long sys_sigprocmask
1307     .long sys_ni_syscall    /* old "create_module" */
1308     .long sys_init_module
1309     .long sys_delete_module
1310     .long sys_ni_syscall    /* old "get_kernel_syms" */
1311     .long sys_quotactl
1312     .long sys_getpgid
1313     .long sys_fchdir
1314     .long sys_bdflush
1315     .long sys_sysfs        /* 135 */
1316     .long sys_personality
1317     .long sys_ni_syscall    /* for afs_syscall */
1318     .long sys_setfsuid16
1319     .long sys_setfsgid16
1320     .long sys_llseek        /* 140 */
1321     .long sys_getdents
1322     .long sys_select
1323     .long sys_flock
1324     .long sys_msync
1325     .long sys_readv        /* 145 */
1326     .long sys_writev
1327     .long sys_getsid
1328     .long sys_fdatasync
1329     .long sys_sysctl
1330     .long sys_mlock        /* 150 */
1331     .long sys_munlock
1332     .long sys_mlockall
1333     .long sys_munlockall
1334     .long sys_sched_setparam
1335     .long sys_sched_getparam   /* 155 */
1336     .long sys_sched_setscheduler
1337     .long sys_sched_getscheduler
1338     .long sys_sched_yield
1339     .long sys_sched_get_priority_max
1340     .long sys_sched_get_priority_min  /* 160 */
1341     .long sys_sched_rr_get_interval
1342     .long sys_nanosleep
1343     .long sys_mremap
1344     .long sys_setresuid16
1345     .long sys_getresuid16    /* 165 */
1346     .long sys_ni_syscall    /* for vm86 */
1347     .long sys_ni_syscall    /* Old sys_query_module */
1348     .long sys_poll
1349     .long sys_ni_syscall    /* Old nfsservctl */
1350     .long sys_setresgid16    /* 170 */
1351     .long sys_getresgid16
1352     .long sys_prctl
1353     .long sys_rt_sigreturn
1354     .long sys_rt_sigaction
1355     .long sys_rt_sigprocmask    /* 175 */
1356     .long sys_rt_sigpending
1357     .long sys_rt_sigtimedwait
1358     .long sys_rt_sigqueueinfo
1359     .long sys_rt_sigsuspend
1360     .long sys_pread64        /* 180 */
1361     .long sys_pwrite64
1362     .long sys_chown16
1363     .long sys_getcwd
1364     .long sys_capget
1365     .long sys_capset           /* 185 */
1366     .long sys_sigaltstack
1367     .long sys_sendfile
1368     .long sys_ni_syscall        /* streams1 */
1369     .long sys_ni_syscall        /* streams2 */
1370     .long sys_vfork            /* 190 */
1371     .long sys_getrlimit
1372     .long sys_mmap2
1373     .long sys_truncate64
1374     .long sys_ftruncate64
1375     .long sys_stat64        /* 195 */
1376     .long sys_lstat64
1377     .long sys_fstat64
1378     .long sys_lchown
1379     .long sys_getuid
1380     .long sys_getgid        /* 200 */
1381     .long sys_geteuid
1382     .long sys_getegid
1383     .long sys_setreuid
1384     .long sys_setregid
1385     .long sys_getgroups    /* 205 */
1386     .long sys_setgroups
1387     .long sys_fchown
1388     .long sys_setresuid
1389     .long sys_getresuid
1390     .long sys_setresgid    /* 210 */
1391     .long sys_getresgid
1392     .long sys_chown
1393     .long sys_setuid
1394     .long sys_setgid
1395     .long sys_setfsuid        /* 215 */
1396     .long sys_setfsgid
1397     .long sys_pivot_root
1398     .long sys_mincore
1399     .long sys_madvise
1400     .long sys_getdents64    /* 220 */
1401     .long sys_fcntl64
1402     .long sys_ni_syscall    /* reserved for TUX */
1403     .long sys_ni_syscall    /* Reserved for Security */
1404     .long sys_gettid
1405     .long sys_readahead    /* 225 */
1406     .long sys_setxattr
1407     .long sys_lsetxattr
1408     .long sys_fsetxattr
1409     .long sys_getxattr
1410     .long sys_lgetxattr    /* 230 */
1411     .long sys_fgetxattr
1412     .long sys_listxattr
1413     .long sys_llistxattr
1414     .long sys_flistxattr
1415     .long sys_removexattr    /* 235 */
1416     .long sys_lremovexattr
1417     .long sys_fremovexattr
1418      .long sys_tkill
1419     .long sys_sendfile64
1420     .long sys_futex        /* 240 */
1421     .long sys_sched_setaffinity
1422     .long sys_sched_getaffinity
1423     .long sys_ni_syscall    //sys_set_thread_area
1424     .long sys_ni_syscall    //sys_get_thread_area
1425     .long sys_io_setup    /* 245 */
1426     .long sys_io_destroy
1427     .long sys_io_getevents
1428     .long sys_io_submit
1429     .long sys_io_cancel
1430     .long sys_fadvise64    /* 250 */
1431     .long sys_ni_syscall
1432     .long sys_exit_group
1433     .long sys_lookup_dcookie
1434     .long sys_epoll_create
1435     .long sys_epoll_ctl    /* 255 */
1436     .long sys_epoll_wait
1437      .long sys_remap_file_pages
1438      .long sys_set_tid_address
1439      .long sys_timer_create
1440      .long sys_timer_settime        /* 260 */
1441      .long sys_timer_gettime
1442      .long sys_timer_getoverrun
1443      .long sys_timer_delete
1444      .long sys_clock_settime
1445      .long sys_clock_gettime        /* 265 */
1446      .long sys_clock_getres
1447      .long sys_clock_nanosleep
1448     .long sys_statfs64
1449     .long sys_fstatfs64
1450     .long sys_tgkill    /* 270 */
1451     .long sys_utimes
1452      .long sys_fadvise64_64
1453     .long sys_ni_syscall    /* sys_vserver */
1454     .long sys_mbind
1455     .long sys_get_mempolicy
1456     .long sys_set_mempolicy
1457     .long sys_mq_open
1458     .long sys_mq_unlink
1459     .long sys_mq_timedsend
1460     .long sys_mq_timedreceive    /* 280 */
1461     .long sys_mq_notify
1462     .long sys_mq_getsetattr
1463     .long sys_ni_syscall        /* reserved for kexec */
1464     .long sys_waitid
1465     .long sys_ni_syscall        /* 285 */ /* available */
1466     .long sys_add_key
1467     .long sys_request_key
1468     .long sys_keyctl
1469     .long sys_ioprio_set
1470     .long sys_ioprio_get        /* 290 */
1471     .long sys_inotify_init
1472     .long sys_inotify_add_watch
1473     .long sys_inotify_rm_watch
1474     .long sys_migrate_pages
1475     .long sys_openat        /* 295 */
1476     .long sys_mkdirat
1477     .long sys_mknodat
1478     .long sys_fchownat
1479     .long sys_futimesat
1480     .long sys_fstatat64        /* 300 */
1481     .long sys_unlinkat
1482     .long sys_renameat
1483     .long sys_linkat
1484     .long sys_symlinkat
1485     .long sys_readlinkat        /* 305 */
1486     .long sys_fchmodat
1487     .long sys_faccessat
1488     .long sys_pselect6
1489     .long sys_ppoll
1490     .long sys_unshare        /* 310 */
1491     .long sys_set_robust_list
1492     .long sys_get_robust_list
1493     .long sys_splice
1494     .long sys_sync_file_range
1495     .long sys_tee            /* 315 */
1496     .long sys_vmsplice
1497     .long sys_move_pages
1498     .long sys_getcpu
1499     .long sys_epoll_pwait
1500     .long sys_utimensat        /* 320 */
1501     .long sys_signalfd
1502     .long sys_timerfd_create
1503     .long sys_eventfd
1504     .long sys_fallocate
1505     .long sys_timerfd_settime    /* 325 */
1506     .long sys_timerfd_gettime
1507     .long sys_signalfd4
1508     .long sys_eventfd2
1509     .long sys_epoll_create1
1510     .long sys_dup3            /* 330 */
1511     .long sys_pipe2
1512     .long sys_inotify_init1
1513     .long sys_preadv
1514     .long sys_pwritev
1515     .long sys_rt_tgsigqueueinfo    /* 335 */
1516     .long sys_perf_event_open
1517     .long sys_setns
1518 
1519 syscall_table_size = (. - sys_call_table)
View Code

三、总结

从整体过程来看,系统通过 int 0x80 从用户态进入内核态。在这个过程中系统先保存了中断环境,然后执行系统调用函数。system_call() 函数通过系统调用号查找系统调用表 sys_cal_table 来查找到具体的系统调用服务进程。在执行完系统调用后在执行 iret 之前,内核做了一系列检查,用于检查是否有新的中断产生。如果没有新的中断,则通过已保存的系统中断环境返回用户态。这样就完成了一个系统调用过程。

需要注意的是,系统调用通过 INT 0x80 进入内核,跳转到 system_call() 函数,然后执行相应服务进程。因为代表了用户进程,所以这个过程并不属于中断上下文,而是属于进程上下文。

 

李若森

原创作品转载请注明出处

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

原文地址:https://www.cnblogs.com/Hitman_47/p/4394244.html