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