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