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