SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

001 /* Copyright (C) 2004  The KOS Team
002 
003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any later version.
007    
008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details.
012    
013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA. 
017 */
018 #include "exception.h"
019 
020 #include "segment.h"
021          
022 .file "exception_wrappers.S"
023 
024 .text
025 
026 /* The address of the table of handlers (defined in exception.c) */
027 .extern sos_exception_handler_array
028 
029 /* The address of the table of wrappers (defined below, and shared
030    with exception.c */
031 .globl sos_exception_wrapper_array
032 
033 /** Update the kernel TSS in case we are switching to a thread in user
034         mode in order to come back into the correct kernel stack */
035 .extern sos_cpu_context_update_kernel_tss
036 
037 /* The address of the function to call to set back the user thread's
038    MMU configuration upon return to user context */
039 .extern sos_thread_prepare_exception_switch_back
040 
041 /**
042  * For exceptions with/without error code, refer to Intel x86 doc vol 3,
043  * section 5.12
044  */
045 
046 /* These wrappers are for exceptions without error code */
047 .irp id,                              \
048          SOS_EXCEPT_DIVIDE_ERROR,                \
049          SOS_EXCEPT_DEBUG,                       \
050          SOS_EXCEPT_NMI_INTERRUPT,               \
051          SOS_EXCEPT_BREAKPOINT,                  \
052          SOS_EXCEPT_OVERFLOW,                    \
053          SOS_EXCEPT_BOUND_RANGE_EXCEDEED,        \
054          SOS_EXCEPT_INVALID_OPCODE,              \
055          SOS_EXCEPT_DEVICE_NOT_AVAILABLE,        \
056          SOS_EXCEPT_COPROCESSOR_SEGMENT_OVERRUN, \
057          SOS_EXCEPT_INTEL_RESERVED_1,            \
058          SOS_EXCEPT_FLOATING_POINT_ERROR,        \
059          SOS_EXCEPT_MACHINE_CHECK,               \
060          SOS_EXCEPT_INTEL_RESERVED_2,            \
061          SOS_EXCEPT_INTEL_RESERVED_3,            \
062          SOS_EXCEPT_INTEL_RESERVED_4,            \
063          SOS_EXCEPT_INTEL_RESERVED_5,            \
064          SOS_EXCEPT_INTEL_RESERVED_6,            \
065          SOS_EXCEPT_INTEL_RESERVED_7,            \
066          SOS_EXCEPT_INTEL_RESERVED_8,            \
067          SOS_EXCEPT_INTEL_RESERVED_9,            \
068          SOS_EXCEPT_INTEL_RESERVED_10,           \
069          SOS_EXCEPT_INTEL_RESERVED_11,           \
070          SOS_EXCEPT_INTEL_RESERVED_12,           \
071          SOS_EXCEPT_INTEL_RESERVED_13,           \
072          SOS_EXCEPT_INTEL_RESERVED_14
073  
074         .p2align 2, 0x90
075         sos_exception_wrapper_\id:
076         .type sos_exception_wrapper_\id,@function
077  
078                 /* Fake error code */
079                 pushl $0
080                 /* Backup the context */
081                 pushl %ebp
082                 movl %esp, %ebp
083  
084                 pushl %edi
085                 pushl %esi
086                 pushl %edx
087                 pushl %ecx
088                 pushl %ebx
089                 pushl %eax
090                 subl  $2,%esp
091                 pushw %ss
092                 pushw %ds
093                 pushw %es
094                 pushw %fs
095                 pushw %gs
096  
097                 /* Set correct kernel segment descriptors' value */
098                 movw $SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA), %di
099                 pushw %di ; popw %ds
100                 pushw %di ; popw %es
101                 pushw %di ; popw %fs
102                 pushw %di ; popw %gs
103 
104                 /*
105                  * Call the handler with the exception number and the
106                  * address of the stored CPU context as arguments
107                  */
108                 pushl %esp
109                 pushl $\id
110                 leal  sos_exception_handler_array,%edi
111                 call  *\id*4(%edi)
112                 /* Unallocate the arguments passed to the handler */
113                 addl  $8, %esp
114 
115                 /* Reconfigure the MMU if needed */
116                 pushl %esp /* cpu_ctxt */
117                 call sos_thread_prepare_exception_switch_back
118                 addl  $4, %esp /* Unallocate the stack */
119 
120                 /* Prepare kernel TSS in case we are switching to a
121                    user thread: we make sure that we will come back
122                    into the kernel at a correct stack location */
123                 pushl %esp /* Pass the location of the context we are
124                               restoring to the function */
125                 call sos_cpu_context_update_kernel_tss
126                 addl $4, %esp
127 
128                 /* Restore the context */
129                 popw  %gs
130                 popw  %fs
131                 popw  %es
132                 popw  %ds
133                 popw  %ss
134                 addl  $2,%esp
135                 popl  %eax
136                 popl  %ebx
137                 popl  %ecx
138                 popl  %edx
139                 popl  %esi
140                 popl  %edi
141  
142                 popl  %ebp
143                 /* Remove fake error code */
144                 addl $4, %esp
145                 iret
146 .endr 
147  
148         /* These wrappers are for exceptions with error code */
149 .irp id,                              \
150         SOS_EXCEPT_INVALID_TSS,                  \
151         SOS_EXCEPT_SEGMENT_NOT_PRESENT,          \
152         SOS_EXCEPT_STACK_SEGMENT_FAULT,          \
153         SOS_EXCEPT_GENERAL_PROTECTION,           \
154         SOS_EXCEPT_PAGE_FAULT,                   \
155         SOS_EXCEPT_ALIGNEMENT_CHECK
156  
157         .p2align 2, 0x90
158         sos_exception_wrapper_\id:
159         .type sos_exception_wrapper_\id,@function
160  
161                 /* ret eflags */
162                 /* ret cs */
163                 /* ret eip */
164                 /* Error code */
165  
166                 /* Backup the context */
167                 pushl %ebp
168                 movl %esp, %ebp
169  
170                 pushl %edi
171                 pushl %esi
172                 pushl %edx
173                 pushl %ecx
174                 pushl %ebx
175                 pushl %eax
176                 subl  $2,%esp
177                 pushw %ss
178                 pushw %ds
179                 pushw %es
180                 pushw %fs
181                 pushw %gs
182 
183                 /* Set correct kernel segment descriptors' value */
184                 movw $SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA), %di
185                 pushw %di ; popw %ds
186                 pushw %di ; popw %es
187                 pushw %di ; popw %fs
188                 pushw %di ; popw %gs
189 
190                 /*
191                  * Call the handler with the exception number and the
192                  * address of the stored CPU context as arguments
193                  */
194                 pushl %esp
195                 pushl $\id
196                 leal  sos_exception_handler_array,%edi
197                 call  *\id*4(%edi)
198                 /* Unallocate the arguments passed to the handler */
199                 addl  $8, %esp
200 
201                 /* Reconfigure the MMU if needed */
202                 pushl %esp /* cpu_ctxt */
203                 call sos_thread_prepare_exception_switch_back
204                 addl  $4, %esp /* Unallocate the stack */
205 
206                 /* Prepare kernel TSS in case we are switching to a
207                    user thread: we make sure that we will come back
208                    into the kernel at a correct stack location */
209                 pushl %esp /* Pass the location of the context we are
210                               restoring to the function */
211                 call sos_cpu_context_update_kernel_tss
212                 addl $4, %esp
213 
214                 /* Restore the context */
215                 popw  %gs
216                 popw  %fs
217                 popw  %es
218                 popw  %ds
219                 popw  %ss
220                 addl  $2,%esp
221                 popl  %eax
222                 popl  %ebx
223                 popl  %ecx
224                 popl  %edx
225                 popl  %esi
226                 popl  %edi
227                 popl  %ebp
228  
229                 /* Error code isn't compatible with iretd */
230                 addl $4, %esp
231  
232                 iret
233 .endr
234 
235 
236 /* Double fault handler not supported. We must define it since we
237    define an entry for it in the sos_exception_wrapper_array. It
238    simply uses an alternate stack to display a message and stop the
239    system. qemu won't handle it correctly (see comment in qemu's
240    sources). */
241 #define ALTERNATE_DOUBLE_FAULT_STACK_SIZE 512
242 .irp id, SOS_EXCEPT_DOUBLE_FAULT
243 .p2align 2, 0x90
244 sos_exception_wrapper_\id:
245 .type sos_exception_wrapper_\id,@function
246 1:      cli /* Not necessary */
247         movl $double_fault_alternate_stack, %eax
248         addl $ALTERNATE_DOUBLE_FAULT_STACK_SIZE, %eax
249         movl %eax, %esp
250         pushl $msg_double_fault_not_supported
251         call sos_display_fatal_error ; jmp 1b /* Not necessary */
252 .endr
253 
254 .section ".rodata"
255 msg_double_fault_not_supported:
256         .string "exception_wrappers.S: Double fault detected ! NOT SUPPORTED yet. System Halted."
257 
258 /* Build the sos_irq_wrapper_array, shared with interrupt.c */
259 .p2align 5, 0x0
260 sos_exception_wrapper_array:
261         .irp id, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \
262                  16,17,18,19,20,21,22,23,24,25,26,27,29,30,31
263           .long (sos_exception_wrapper_\id)
264         .endr
265 
266 /* Alternate stack for double fault handler */
267 .bss
268 .p2align 2, 0x0
269 .size double_fault_alternate_stack, ALTERNATE_DOUBLE_FAULT_STACK_SIZE
270 double_fault_alternate_stack:
271         .fill ALTERNATE_DOUBLE_FAULT_STACK_SIZE, 1, 0x0

source navigation ] diff markup ] identifier search ] general search ]