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 /* Call the handler with exception number as
090 * argument */
091 pushl $\id
092 leal sos_exception_handler_array,%edi
093 call *\id*4(%edi)
094 addl $4, %esp
095
096 /* Restore the context */
097 popw %gs
098 popw %fs
099 popw %es
100 popw %ds
101 popw %ss
102 addl $2,%esp
103 popl %eax
104 popl %ebx
105 popl %ecx
106 popl %edx
107 popl %esi
108 popl %edi
109
110 popl %ebp
111 /* Remove fake error code */
112 addl $4, %esp
113 iret
114 .endr
115
116 /* These wrappers are for exceptions with error code */
117 .irp id, \
118 SOS_EXCEPT_INVALID_TSS, \
119 SOS_EXCEPT_SEGMENT_NOT_PRESENT, \
120 SOS_EXCEPT_STACK_SEGMENT_FAULT, \
121 SOS_EXCEPT_GENERAL_PROTECTION, \
122 SOS_EXCEPT_PAGE_FAULT, \
123 SOS_EXCEPT_ALIGNEMENT_CHECK
124
125 .p2align 2, 0x90
126 sos_exception_wrapper_\id:
127 .type sos_exception_wrapper_\id,@function
128
129 /* ret eflags */
130 /* ret cs */
131 /* ret eip */
132 /* Error code */
133
134 /* Backup the context */
135 pushl %ebp
136 movl %esp, %ebp
137
138 pushl %edi
139 pushl %esi
140 pushl %edx
141 pushl %ecx
142 pushl %ebx
143 pushl %eax
144 subl $2,%esp
145 pushw %ss
146 pushw %ds
147 pushw %es
148 pushw %fs
149 pushw %gs
150
151 /* Call the handler with exception number as
152 * argument */
153 pushl $\id
154 leal sos_exception_handler_array,%edi
155 call *\id*4(%edi)
156 addl $4, %esp
157
158 /* Restore the context */
159 popw %gs
160 popw %fs
161 popw %es
162 popw %ds
163 popw %ss
164 addl $2,%esp
165 popl %eax
166 popl %ebx
167 popl %ecx
168 popl %edx
169 popl %esi
170 popl %edi
171 popl %ebp
172
173 /* Error code isn't compatible with iretd */
174 addl $4, %esp
175
176 iret
177 .endr
178
179
180 /* Double fault handler not supported. We must define it since we
181 define an entry for it in the sos_exception_wrapper_array. */
182 .irp id, SOS_EXCEPT_DOUBLE_FAULT
183 .p2align 2, 0x90
184 sos_exception_wrapper_\id:
185 .type sos_exception_wrapper_\id,@function
186 1: hlt
187 jmp 1b /* Machine halting */
188 .endr
189
190 /* Build the sos_irq_wrapper_array, shared with interrupt.c */
191 .section ".rodata"
192 .p2align 5, 0x0
193 sos_exception_wrapper_array:
194 .irp id, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, \
195 16,17,18,19,20,21,22,23,24,25,26,27,29,30,31
196 .long (sos_exception_wrapper_\id)
197 .endr