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