home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / kernel / sys_call.S < prev    next >
Encoding:
Text File  |  1993-12-01  |  7.3 KB  |  391 lines

  1. /*
  2.  *  linux/kernel/sys_call.S
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. /*
  8.  * sys_call.S  contains the system-call and fault low-level handling routines.
  9.  * This also contains the timer-interrupt handler, as well as all interrupts
  10.  * and faults that can result in a task-switch.
  11.  *
  12.  * NOTE: This code handles signal-recognition, which happens every time
  13.  * after a timer-interrupt and after each system call.
  14.  *
  15.  * I changed all the .align's to 4 (16 byte alignment), as that's faster
  16.  * on a 486.
  17.  *
  18.  * Stack layout in 'ret_from_system_call':
  19.  *     ptrace needs to have all regs on the stack.
  20.  *    if the order here is changed, it needs to be 
  21.  *    updated in fork.c:copy_process, signal.c:do_signal,
  22.  *    ptrace.c and ptrace.h
  23.  *
  24.  *     0(%esp) - %ebx
  25.  *     4(%esp) - %ecx
  26.  *     8(%esp) - %edx
  27.  *       C(%esp) - %esi
  28.  *    10(%esp) - %edi
  29.  *    14(%esp) - %ebp
  30.  *    18(%esp) - %eax
  31.  *    1C(%esp) - %ds
  32.  *    20(%esp) - %es
  33.  *      24(%esp) - %fs
  34.  *    28(%esp) - %gs
  35.  *    2C(%esp) - orig_eax
  36.  *    30(%esp) - %eip
  37.  *    34(%esp) - %cs
  38.  *    38(%esp) - %eflags
  39.  *    3C(%esp) - %oldesp
  40.  *    40(%esp) - %oldss
  41.  */
  42.  
  43. #include <linux/segment.h>
  44.  
  45. EBX        = 0x00
  46. ECX        = 0x04
  47. EDX        = 0x08
  48. ESI        = 0x0C
  49. EDI        = 0x10
  50. EBP        = 0x14
  51. EAX        = 0x18
  52. DS        = 0x1C
  53. ES        = 0x20
  54. FS        = 0x24
  55. GS        = 0x28
  56. ORIG_EAX    = 0x2C
  57. EIP        = 0x30
  58. CS        = 0x34
  59. EFLAGS        = 0x38
  60. OLDESP        = 0x3C
  61. OLDSS        = 0x40
  62.  
  63. CF_MASK        = 0x00000001
  64. IF_MASK        = 0x00000200
  65. NT_MASK        = 0x00004000
  66. VM_MASK        = 0x00020000
  67.  
  68. /*
  69.  * these are offsets into the task-struct.
  70.  */
  71. state        =  0
  72. counter        =  4
  73. priority    =  8
  74. signal        = 12
  75. blocked        = 16
  76. flags        = 20
  77. errno        = 24
  78. dbgreg6        = 52
  79. dbgreg7        = 56
  80.  
  81. ENOSYS = 38
  82.  
  83. .globl _system_call,_lcall7
  84. .globl _device_not_available, _coprocessor_error
  85. .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
  86. .globl _double_fault,_coprocessor_segment_overrun
  87. .globl _invalid_TSS,_segment_not_present,_stack_segment
  88. .globl _general_protection,_reserved
  89. .globl _alignment_check,_page_fault
  90. .globl ret_from_sys_call
  91.  
  92. #define SAVE_ALL \
  93.     cld; \
  94.     push %gs; \
  95.     push %fs; \
  96.     push %es; \
  97.     push %ds; \
  98.     pushl %eax; \
  99.     pushl %ebp; \
  100.     pushl %edi; \
  101.     pushl %esi; \
  102.     pushl %edx; \
  103.     pushl %ecx; \
  104.     pushl %ebx; \
  105.     movl $(KERNEL_DS),%edx; \
  106.     mov %dx,%ds; \
  107.     mov %dx,%es; \
  108.     movl $(USER_DS),%edx; \
  109.     mov %dx,%fs;
  110.  
  111. #define RESTORE_ALL \
  112.     cmpw $(KERNEL_CS),CS(%esp); \
  113.     je 1f;   \
  114.     movl _current,%eax; \
  115.     movl dbgreg7(%eax),%ebx; \
  116.     movl %ebx,%db7;    \
  117. 1:    popl %ebx; \
  118.     popl %ecx; \
  119.     popl %edx; \
  120.     popl %esi; \
  121.     popl %edi; \
  122.     popl %ebp; \
  123.     popl %eax; \
  124.     pop %ds; \
  125.     pop %es; \
  126.     pop %fs; \
  127.     pop %gs; \
  128.     addl $4,%esp; \
  129.     iret
  130.  
  131. .align 4
  132. _lcall7:
  133.     pushfl            # We get a different stack layout with call gates,
  134.     pushl %eax        # which has to be cleaned up later..
  135.     SAVE_ALL
  136.     movl EIP(%esp),%eax    # due to call gates, this is eflags, not eip..
  137.     movl CS(%esp),%edx    # this is eip..
  138.     movl EFLAGS(%esp),%ecx    # and this is cs..
  139.     movl %eax,EFLAGS(%esp)    #
  140.     movl %edx,EIP(%esp)    # Now we move them to their "normal" places
  141.     movl %ecx,CS(%esp)    #
  142.     movl %esp,%eax
  143.     pushl %eax
  144.     call _iABI_emulate
  145.     popl %eax
  146.     jmp ret_from_sys_call
  147.  
  148. .align 4
  149. handle_bottom_half:
  150.     pushfl
  151.     incl _intr_count
  152.     sti
  153.     call _do_bottom_half
  154.     popfl
  155.     decl _intr_count
  156.     jmp 9f
  157. .align 4
  158. reschedule:
  159.     pushl $ret_from_sys_call
  160.     jmp _schedule
  161. .align 4
  162. _system_call:
  163.     pushl %eax            # save orig_eax
  164.     SAVE_ALL
  165.     movl $-ENOSYS,EAX(%esp)
  166.     cmpl _NR_syscalls,%eax
  167.     jae ret_from_sys_call
  168.     movl _current,%ebx
  169.     andl $~CF_MASK,EFLAGS(%esp)    # clear carry - assume no errors
  170.     movl $0,errno(%ebx)
  171.     movl %db6,%edx
  172.     movl %edx,dbgreg6(%ebx)  # save current hardware debugging status
  173.     testb $0x20,flags(%ebx)        # PF_TRACESYS
  174.     jne 1f
  175.     call _sys_call_table(,%eax,4)
  176.     movl %eax,EAX(%esp)        # save the return value
  177.     movl errno(%ebx),%edx
  178.     negl %edx
  179.     je ret_from_sys_call
  180.     movl %edx,EAX(%esp)
  181.     orl $(CF_MASK),EFLAGS(%esp)    # set carry to indicate error
  182.     jmp ret_from_sys_call
  183. .align 4
  184. 1:    call _syscall_trace
  185.     movl ORIG_EAX(%esp),%eax
  186.     call _sys_call_table(,%eax,4)
  187.     movl %eax,EAX(%esp)        # save the return value
  188.     movl _current,%eax
  189.     movl errno(%eax),%edx
  190.     negl %edx
  191.     je 1f
  192.     movl %edx,EAX(%esp)
  193.     orl $(CF_MASK),EFLAGS(%esp)    # set carry to indicate error
  194. 1:    call _syscall_trace
  195.  
  196.     .align 4,0x90
  197. ret_from_sys_call:
  198.     cmpl $0,_intr_count
  199.     jne 2f
  200.     movl _bh_mask,%eax
  201.     andl _bh_active,%eax
  202.     jne handle_bottom_half
  203. 9:    movl EFLAGS(%esp),%eax        # check VM86 flag: CS/SS are
  204.     testl $(VM_MASK),%eax        # different then
  205.     jne 1f
  206.     cmpw $(KERNEL_CS),CS(%esp)    # was old code segment supervisor ?
  207.     je 2f
  208. 1:    sti
  209.     orl $(IF_MASK),%eax        # these just try to make sure
  210.     andl $~NT_MASK,%eax        # the program doesn't do anything
  211.     movl %eax,EFLAGS(%esp)        # stupid
  212.     cmpl $0,_need_resched
  213.     jne reschedule
  214.     movl _current,%eax
  215.     cmpl _task,%eax            # task[0] cannot have signals
  216.     je 2f
  217.     cmpl $0,state(%eax)        # state
  218.     jne reschedule
  219.     cmpl $0,counter(%eax)        # counter
  220.     je reschedule
  221.     movl blocked(%eax),%ecx
  222.     movl %ecx,%ebx            # save blocked in %ebx for signal handling
  223.     notl %ecx
  224.     andl signal(%eax),%ecx
  225.     jne signal_return
  226. 2:    RESTORE_ALL
  227. .align 4
  228. signal_return:
  229.     movl %esp,%ecx
  230.     pushl %ecx
  231.     testl $(VM_MASK),EFLAGS(%ecx)
  232.     jne v86_signal_return
  233.     pushl %ebx
  234.     call _do_signal
  235.     popl %ebx
  236.     popl %ebx
  237.     RESTORE_ALL
  238. .align 4
  239. v86_signal_return:
  240.     call _save_v86_state
  241.     movl %eax,%esp
  242.     pushl %eax
  243.     pushl %ebx
  244.     call _do_signal
  245.     popl %ebx
  246.     popl %ebx
  247.     RESTORE_ALL
  248.  
  249. .align 4
  250. _divide_error:
  251.     pushl $0        # no error code
  252.     pushl $_do_divide_error
  253. .align 4,0x90
  254. error_code:
  255.     push %fs
  256.     push %es
  257.     push %ds
  258.     pushl %eax
  259.     pushl %ebp
  260.     pushl %edi
  261.     pushl %esi
  262.     pushl %edx
  263.     pushl %ecx
  264.     pushl %ebx
  265.     movl $0,%eax
  266.     movl %eax,%db7            # disable hardware debugging...
  267.     cld
  268.     movl $-1, %eax
  269.     xchgl %eax, ORIG_EAX(%esp)    # orig_eax (get the error code. )
  270.     xorl %ebx,%ebx            # zero ebx
  271.     mov %gs,%bx            # get the lower order bits of gs
  272.     xchgl %ebx, GS(%esp)        # get the address and save gs.
  273.     pushl %eax            # push the error code
  274.     lea 4(%esp),%edx
  275.     pushl %edx
  276.     movl $(KERNEL_DS),%edx
  277.     mov %dx,%ds
  278.     mov %dx,%es
  279.     movl $(USER_DS),%edx
  280.     mov %dx,%fs
  281.     pushl %eax
  282.     movl _current,%eax
  283.     movl %db6,%edx
  284.     movl %edx,dbgreg6(%eax)  # save current hardware debugging status
  285.     popl %eax
  286.     call *%ebx
  287.     addl $8,%esp
  288.     jmp ret_from_sys_call
  289.  
  290. .align 4
  291. _coprocessor_error:
  292.     pushl $0
  293.     pushl $_do_coprocessor_error
  294.     jmp error_code
  295.  
  296. .align 4
  297. _device_not_available:
  298.     pushl $-1        # mark this as an int
  299.     SAVE_ALL
  300.     pushl $ret_from_sys_call
  301.     movl %cr0,%eax
  302.     testl $0x4,%eax            # EM (math emulation bit)
  303.     je _math_state_restore
  304.     pushl $0        # temporary storage for ORIG_EIP
  305.     call _math_emulate
  306.     addl $4,%esp
  307.     ret
  308.  
  309. .align 4
  310. _debug:
  311.     pushl $0
  312.     pushl $_do_debug
  313.     jmp error_code
  314.  
  315. .align 4
  316. _nmi:
  317.     pushl $0
  318.     pushl $_do_nmi
  319.     jmp error_code
  320.  
  321. .align 4
  322. _int3:
  323.     pushl $0
  324.     pushl $_do_int3
  325.     jmp error_code
  326.  
  327. .align 4
  328. _overflow:
  329.     pushl $0
  330.     pushl $_do_overflow
  331.     jmp error_code
  332.  
  333. .align 4
  334. _bounds:
  335.     pushl $0
  336.     pushl $_do_bounds
  337.     jmp error_code
  338.  
  339. .align 4
  340. _invalid_op:
  341.     pushl $0
  342.     pushl $_do_invalid_op
  343.     jmp error_code
  344.  
  345. .align 4
  346. _coprocessor_segment_overrun:
  347.     pushl $0
  348.     pushl $_do_coprocessor_segment_overrun
  349.     jmp error_code
  350.  
  351. .align 4
  352. _reserved:
  353.     pushl $0
  354.     pushl $_do_reserved
  355.     jmp error_code
  356.  
  357. .align 4
  358. _double_fault:
  359.     pushl $_do_double_fault
  360.     jmp error_code
  361.  
  362. .align 4
  363. _invalid_TSS:
  364.     pushl $_do_invalid_TSS
  365.     jmp error_code
  366.  
  367. .align 4
  368. _segment_not_present:
  369.     pushl $_do_segment_not_present
  370.     jmp error_code
  371.  
  372. .align 4
  373. _stack_segment:
  374.     pushl $_do_stack_segment
  375.     jmp error_code
  376.  
  377. .align 4
  378. _general_protection:
  379.     pushl $_do_general_protection
  380.     jmp error_code
  381.  
  382. .align 4
  383. _alignment_check:
  384.     pushl $_do_alignment_check
  385.     jmp error_code
  386.  
  387. .align 4
  388. _page_fault:
  389.     pushl $_do_page_fault
  390.     jmp error_code
  391.