001 /* Copyright (C) 2005 David Decotigny
002 Copyright (C) 2004 The KOS Team
003
004 This program is free software; you can redistribute it and/or
005 modify it under the terms of the GNU General Public License
006 as published by the Free Software Foundation; either version 2
007 of the License, or (at your option) any later version.
008
009 This program is distributed in the hope that it will be useful,
010 but WITHOUT ANY WARRANTY; without even the implied warranty of
011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012 GNU General Public License for more details.
013
014 You should have received a copy of the GNU General Public License
015 along with this program; if not, write to the Free Software
016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
017 USA.
018 */
019 #include "segment.h"
020
021
022 /**
023 * @file swintr_wrappers.S
024 *
025 * The SOS low-level handlers for the software interrupts. Currently
026 * only 1 wrapper: that for the SOS syscalls.
027 */
028 .file "swintr_wrappers.S"
029
030 .text
031
032 /* The address of the real "C" syscall function */
033 .extern sos_do_syscall
034
035 /** Update the kernel TSS in case we are switching to a thread in user
036 mode in order to come back into the correct kernel stack */
037 .extern sos_cpu_context_update_kernel_tss
038
039 /* The address of the function to call to set back the user thread's
040 MMU configuration upon return to user context */
041 .extern sos_thread_prepare_syscall_switch_back
042
043 .p2align 2, 0x90
044 .globl sos_syscall_wrapper
045 sos_syscall_wrapper:
046 .type sos_syscall_wrapper,@function
047
048 /* Fake error code */
049 pushl $0
050 /* Backup the context */
051 pushl %ebp
052 movl %esp, %ebp
053
054 pushl %edi
055 pushl %esi
056 pushl %edx
057 pushl %ecx
058 pushl %ebx
059 pushl %eax
060 subl $2,%esp
061 pushw %ss
062 pushw %ds
063 pushw %es
064 pushw %fs
065 pushw %gs
066
067 /* Set correct kernel segment descriptors' value */
068 movw $SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA), %di
069 pushw %di ; popw %ds
070 pushw %di ; popw %es
071 pushw %di ; popw %fs
072 pushw %di ; popw %gs
073
074 /* Prepare the call to do_syscall */
075 pushl %esp /* user_ctxt */
076 pushl %eax /* syscall ID */
077
078 call sos_do_syscall
079 /* Unallocate the stack used by the
080 do_syscall arguments */
081 addl $8, %esp
082
083 /* store the do_syscall return value into interrupted context */
084 movl %eax, 12(%esp)
085
086 /* Set the MMU configuration to that of the user thread's process */
087 pushl %esp /* user_ctxt */
088 call sos_thread_prepare_syscall_switch_back
089 addl $4, %esp /* Unallocate the stack */
090
091 /* Prepare kernel TSS because we are switching back to a user
092 thread: we make sure that we will come back into the kernel at a
093 correct stack location */
094 pushl %esp /* Pass the location of the context we are
095 restoring to the function */
096 call sos_cpu_context_update_kernel_tss
097 addl $4, %esp
098
099 /* Restore the user context */
100 popw %gs
101 popw %fs
102 popw %es
103 popw %ds
104 popw %ss
105 addl $2,%esp
106 popl %eax /* This is the return value of do_syscall (see above) */
107 popl %ebx
108 popl %ecx
109 popl %edx
110 popl %esi
111 popl %edi
112
113 popl %ebp
114 /* Remove fake error code */
115 addl $4, %esp
116 iret