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 .file "exception_wrappers.S"
021
022 .text
023
024 /* The address of the table of handlers (defined in exception.c) */
025 .extern sos_exception_handler_array
026
027 /* The address of the table of wrappers (defined below, and shared
028 with exception.c */
029 .globl sos_exception_wrapper_array
030
031 /**
032 * For exceptions with/without error code, refer to Intel x86 doc vol 3,
033 * section 5.12
034 */
035
036 /* These wrappers are for exceptions without error code */
037 .irp id, \
038 SOS_EXCEPT_DIVIDE_ERROR, \
039 SOS_EXCEPT_DEBUG, \
040 SOS_EXCEPT_NMI_INTERRUPT, \
041 SOS_EXCEPT_BREAKPOINT, \
042 SOS_EXCEPT_OVERFLOW, \
043 SOS_EXCEPT_BOUND_RANGE_EXCEDEED, \
044 SOS_EXCEPT_INVALID_OPCODE, \
045 SOS_EXCEPT_DEVICE_NOT_AVAILABLE, \
046 SOS_EXCEPT_COPROCESSOR_SEGMENT_OVERRUN, \
047 SOS_EXCEPT_INTEL_RESERVED_1, \
048 SOS_EXCEPT_FLOATING_POINT_ERROR, \
049 SOS_EXCEPT_MACHINE_CHECK, \
050 SOS_EXCEPT_INTEL_RESERVED_2, \
051 SOS_EXCEPT_INTEL_RESERVED_3, \
052 SOS_EXCEPT_INTEL_RESERVED_4, \
053 SOS_EXCEPT_INTEL_RESERVED_5, \
054 SOS_EXCEPT_INTEL_RESERVED_6, \
055 SOS_EXCEPT_INTEL_RESERVED_7, \
056 SOS_EXCEPT_INTEL_RESERVED_8, \
057 SOS_EXCEPT_INTEL_RESERVED_9, \
058 SOS_EXCEPT_INTEL_RESERVED_10, \
059 SOS_EXCEPT_INTEL_RESERVED_11, \
060 SOS_EXCEPT_INTEL_RESERVED_12, \
061 SOS_EXCEPT_INTEL_RESERVED_13, \
062 SOS_EXCEPT_INTEL_RESERVED_14
063
064 .p2align 2, 0x90
065 sos_exception_wrapper_\id:
066 .type sos_exception_wrapper_\id,@function
067
068 /* Fake error code */
069 pushl $0
070 /* Backup the context */
071 pushl %ebp
072 movl %esp, %ebp
073
074 pushl %edi
075 pushl %esi
076 pushl %edx
077 pushl %ecx
078 pushl %ebx
079 pushl %eax
080 subl $2,%esp
081 pushw %ss
082 pushw %ds
083 pushw %es
084 pushw %fs
085 pushw %gs
086
087 /*
088 * Call the handler with the exception number and the
089 * address of the stored CPU context as arguments
090 */
091 pushl %esp
092 pushl $\id
093 leal sos_exception_handler_array,%edi
094 call *\id*4(%edi)
095 /* Unallocate the arguments passed to the handler */
096 addl $8, %esp
097
098 /* Restore the context */
099 popw %gs
100 popw %fs
101 popw %es
102 popw %ds
103 popw %ss
104 addl $2,%esp
105 popl %eax
106 popl %ebx
107 popl %ecx
108 popl %edx
109 popl %esi
110 popl %edi
111
112 popl %ebp
113 /* Remove fake error code */
114 addl $4, %esp
115 iret
116 .endr
117
118 /* These wrappers are for exceptions with error code */
119 .irp id, \
120 SOS_EXCEPT_INVALID_TSS, \
121 SOS_EXCEPT_SEGMENT_NOT_PRESENT, \
122 SOS_EXCEPT_STACK_SEGMENT_FAULT, \
123 SOS_EXCEPT_GENERAL_PROTECTION, \
124 SOS_EXCEPT_PAGE_FAULT, \
125 SOS_EXCEPT_ALIGNEMENT_CHECK
126
127 .p2align 2, 0x90
128 sos_exception_wrapper_\id:
129 .type sos_exception_wrapper_\id,@function
130
131 /* ret eflags */
132 /* ret cs */
133 /* ret eip */
134 /* Error code */
135
136 /* Backup the context */
137 pushl %ebp
138 movl %esp, %ebp
139
140 pushl %edi
141 pushl %esi
142 pushl %edx
143 pushl %ecx
144 pushl %ebx
145 pushl %eax
146 subl $2,%esp
147 pushw %ss
148 pushw %ds
149 pushw %es
150 pushw %fs
151 pushw %gs
152
153 /*
154 * Call the handler with the exception number and the
155 * address of the stored CPU context as arguments
156 */
157 pushl %esp
158 pushl $\id
159 leal sos_exception_handler_array,%edi
160 call *\id*4(%edi)
161 /* Unallocate the arguments passed to the handler */
162 addl $8, %esp
163
164 /* Restore the context */
165 popw %gs
166 popw %fs
167 popw %es
168 popw %ds
169 popw %ss
170 addl $2,%esp
171 popl %eax
172 popl %ebx
173 popl %ecx
174 popl %edx
175 popl %esi
176 popl %edi
177 popl %ebp
178
179 /* Error code isn't compatible with iretd */
180 addl $4, %esp
181
182 iret
183 .endr
184
185
186 /* Double fault handler not supported. We must define it since we
187 define an entry for it in the sos_exception_wrapper_array. It
188 simply uses an alternate stack to display a message and stop the
189 system. qemu won't handle it correctly (see comment in qemu's
190 sources). */
191 #define ALTERNATE_DOUBLE_FAULT_STACK_SIZE 512
192 .irp id, SOS_EXCEPT_DOUBLE_FAULT
193 .p2align 2, 0x90
194 sos_exception_wrapper_\id:
195 .type sos_exception_wrapper_\id,@function
196 1: cli /* Not necessary */
197 movl $double_fault_alternate_stack, %eax
198 addl $ALTERNATE_DOUBLE_FAULT_STACK_SIZE, %eax
199 movl %eax, %esp
200 pushl $msg_double_fault_not_supported
201 call sos_display_fatal_error ; jmp 1b /* Not necessary */
202 .endr
203
204 .section ".rodata"
205 msg_double_fault_not_supported:
206 .string "exception_wrappers.S: Double fault detected ! NOT SUPPORTED yet. System Halted."
207
208 /* Build the sos_irq_wrapper_array, shared with interrupt.c */
209 .p2align 5, 0x0
210 sos_exception_wrapper_array:
211 .irp id, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \
212 16,17,18,19,20,21,22,23,24,25,26,27,29,30,31
213 .long (sos_exception_wrapper_\id)
214 .endr
215
216 /* Alternate stack for double fault handler */
217 .bss
218 .p2align 2, 0x0
219 .size double_fault_alternate_stack, ALTERNATE_DOUBLE_FAULT_STACK_SIZE
220 double_fault_alternate_stack:
221 .fill ALTERNATE_DOUBLE_FAULT_STACK_SIZE, 1, 0x0