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 !! 019 #define ASM_SOURCE 1
019 #include "segment.h" <<
020 020
021 .file "irq_wrappers.S" 021 .file "irq_wrappers.S"
022 022
023 .text 023 .text
024 024
025 /** The address of the table of handlers (defi !! 025 /* The address of the table of handlers (defined in irq.c) */
026 .extern sos_irq_handler_array 026 .extern sos_irq_handler_array
027 027
028 /** The address of the table of wrappers (defi !! 028 /* The address of the table of wrappers (defined below, and shared
029 with irq.c */ 029 with irq.c */
030 .globl sos_irq_wrapper_array 030 .globl sos_irq_wrapper_array
031 031
032 /** The variable holding the nested level of t <<
033 .extern sos_irq_nested_level_counter <<
034 <<
035 /** Update the interrupted current thread's CP <<
036 Its prototype is: <<
037 sos_thread_prepare_irq_servicing(struct <<
038 */ <<
039 .extern sos_thread_prepare_irq_servicing <<
040 <<
041 /** Update the kernel TSS in case we are switc <<
042 mode in order to come back into the co <<
043 .extern sos_cpu_context_update_kernel_tss <<
044 <<
045 /** Select a thread to set on CPU (this enable <<
046 preemption) and configure the MMU to match <<
047 thread. <<
048 Its prototype is: <<
049 struct sos_cpu_state * // Selected CPU c <<
050 sos_thread_prepare_irq_switch_back(); <<
051 */ <<
052 .extern sos_thread_prepare_irq_switch_back <<
053 032
054 /* These pre-handlers are for IRQ (Master PIC) 033 /* These pre-handlers are for IRQ (Master PIC) */
055 .irp id, 0,1,2,3,4,5,6,7 034 .irp id, 0,1,2,3,4,5,6,7
056 035
057 .p2align 2, 0x90 036 .p2align 2, 0x90
058 037
059 sos_irq_wrapper_\id: 038 sos_irq_wrapper_\id:
060 .type sos_irq_wrapper_\id,@function 039 .type sos_irq_wrapper_\id,@function
061 040
062 /* 041 /*
063 * Backup the CPU context 042 * Backup the CPU context
064 */ 043 */
065 044
066 /* Fake error code */ 045 /* Fake error code */
067 pushl $0 046 pushl $0
068 047
069 /* Backup the actual context * 048 /* Backup the actual context */
070 pushl %ebp 049 pushl %ebp
071 movl %esp, %ebp 050 movl %esp, %ebp
072 051
073 pushl %edi 052 pushl %edi
074 pushl %esi 053 pushl %esi
075 pushl %edx 054 pushl %edx
076 pushl %ecx 055 pushl %ecx
077 pushl %ebx 056 pushl %ebx
078 pushl %eax 057 pushl %eax
079 subl $2,%esp 058 subl $2,%esp
080 pushw %ss 059 pushw %ss
081 pushw %ds 060 pushw %ds
082 pushw %es 061 pushw %es
083 pushw %fs 062 pushw %fs
084 pushw %gs 063 pushw %gs
085 064
086 /* Set correct kernel segment <<
087 movw $SOS_BUILD_SEGMENT_REG_VA <<
088 pushw %di ; popw %ds <<
089 pushw %di ; popw %es <<
090 pushw %di ; popw %fs <<
091 pushw %di ; popw %gs <<
092 <<
093 /* <<
094 * Increment IRQ nested level <<
095 */ <<
096 incl sos_irq_nested_level_coun <<
097 /* Outermost IRQ only: store t <<
098 of the current thread */ <<
099 cmpl $1, sos_irq_nested_level_ <<
100 jne 1f <<
101 pushl %esp <<
102 call sos_thread_prepare_irq_se <<
103 addl $4, %esp <<
104 <<
105 1: <<
106 <<
107 /* Send EOI to PIC. See Intel 065 /* Send EOI to PIC. See Intel 8259 datasheet
108 available on Kos website */ 066 available on Kos website */
109 movb $0x20, %al 067 movb $0x20, %al
110 outb %al, $0x20 068 outb %al, $0x20
111 069
112 /* 070 /*
113 * Call the handler with IRQ n 071 * Call the handler with IRQ number as argument
114 */ 072 */
115 pushl $\id 073 pushl $\id
116 leal sos_irq_handler_array,%e 074 leal sos_irq_handler_array,%edi
117 call *\id*4(%edi) 075 call *\id*4(%edi)
118 addl $4, %esp 076 addl $4, %esp
119 <<
120 /* <<
121 * Decrement IRQ nested level <<
122 */ <<
123 cli /* Just in case we messed <<
124 subl $1, sos_irq_nested_level_ <<
125 077
126 /* sos_irq_nested_level_counte <<
127 jnc 2f <<
128 <<
129 1: /* Yes: Print fatal error mess <<
130 pushl $msg_nested_level_overfl <<
131 call sos_display_fatal_error <<
132 addl $4, %esp ; jmp 1b <<
133 /* Never returns */ <<
134 <<
135 2: /* No: all right ! */ <<
136 <<
137 /* Was this the outermost IRQ <<
138 jnz 3f <<
139 <<
140 /* Yes: reschedule */ <<
141 call sos_thread_prepare_irq_sw <<
142 /* Establish new context: cont <<
143 movl %eax, %esp <<
144 <<
145 /* Prepare kernel TSS in case <<
146 user thread: we make sure t <<
147 into the kernel at a correc <<
148 pushl %esp /* Pass the locatio <<
149 restoring to the <<
150 call sos_cpu_context_update_ke <<
151 addl $4, %esp <<
152 3: <<
153 /* Restore the context */ 078 /* Restore the context */
154 popw %gs 079 popw %gs
155 popw %fs 080 popw %fs
156 popw %es 081 popw %es
157 popw %ds 082 popw %ds
158 popw %ss 083 popw %ss
159 addl $2,%esp 084 addl $2,%esp
160 popl %eax 085 popl %eax
161 popl %ebx 086 popl %ebx
162 popl %ecx 087 popl %ecx
163 popl %edx 088 popl %edx
164 popl %esi 089 popl %esi
165 popl %edi 090 popl %edi
166 popl %ebp 091 popl %ebp
167 092
168 /* Remove fake error code */ 093 /* Remove fake error code */
169 addl $4, %esp 094 addl $4, %esp
170 095
171 iret 096 iret
172 .endr 097 .endr
173 098
174 099
175 /* These pre-handlers are for IRQ (Slave PIC) 100 /* These pre-handlers are for IRQ (Slave PIC) */
176 .irp id, 8,9,10,11,12,13,14,15 101 .irp id, 8,9,10,11,12,13,14,15
177 102
178 .p2align 2, 0x90 103 .p2align 2, 0x90
179 104
180 sos_irq_wrapper_\id: 105 sos_irq_wrapper_\id:
181 .type sos_irq_wrapper_\id,@function 106 .type sos_irq_wrapper_\id,@function
182 107
183 /* 108 /*
184 * Backup the CPU context 109 * Backup the CPU context
185 */ 110 */
186 111
187 /* Fake error code */ 112 /* Fake error code */
188 pushl $0 113 pushl $0
189 114
190 /* Backup the actual context * 115 /* Backup the actual context */
191 pushl %ebp 116 pushl %ebp
192 movl %esp, %ebp 117 movl %esp, %ebp
193 118
194 pushl %edi 119 pushl %edi
195 pushl %esi 120 pushl %esi
196 pushl %edx 121 pushl %edx
197 pushl %ecx 122 pushl %ecx
198 pushl %ebx 123 pushl %ebx
199 pushl %eax 124 pushl %eax
200 subl $2,%esp 125 subl $2,%esp
201 pushw %ss 126 pushw %ss
202 pushw %ds 127 pushw %ds
203 pushw %es 128 pushw %es
204 pushw %fs 129 pushw %fs
205 pushw %gs 130 pushw %gs
206 131
207 /* Set correct kernel segment <<
208 movw $SOS_BUILD_SEGMENT_REG_VA <<
209 pushw %di ; popw %ds <<
210 pushw %di ; popw %es <<
211 pushw %di ; popw %fs <<
212 pushw %di ; popw %gs <<
213 <<
214 /* <<
215 * Increment IRQ nested level <<
216 */ <<
217 incl sos_irq_nested_level_coun <<
218 /* Outermost IRQ only: store t <<
219 of the current thread */ <<
220 cmpl $1, sos_irq_nested_level_ <<
221 jne 1f <<
222 pushl %esp <<
223 call sos_thread_prepare_irq_se <<
224 addl $4, %esp <<
225 <<
226 1: <<
227 <<
228 /* Send EOI to PIC. See Intel 132 /* Send EOI to PIC. See Intel 8259 datasheet
229 available on Kos website */ 133 available on Kos website */
230 movb $0x20, %al 134 movb $0x20, %al
231 outb %al, $0xa0 135 outb %al, $0xa0
232 outb %al, $0x20 136 outb %al, $0x20
233 137
234 /* 138 /*
235 * Call the handler with IRQ n 139 * Call the handler with IRQ number as argument
236 */ 140 */
237 pushl $\id 141 pushl $\id
238 leal sos_irq_handler_array,%e 142 leal sos_irq_handler_array,%edi
239 call *\id*4(%edi) 143 call *\id*4(%edi)
240 addl $4, %esp 144 addl $4, %esp
241 145
242 /* <<
243 * Decrement IRQ nested level <<
244 */ <<
245 cli /* Just in case we messed <<
246 subl $1, sos_irq_nested_level_ <<
247 <<
248 /* sos_irq_nested_level_counte <<
249 jnc 2f <<
250 <<
251 1: /* Yes: Print fatal error mess <<
252 pushl $msg_nested_level_overfl <<
253 call sos_display_fatal_error <<
254 addl $4, %esp ; jmp 1b <<
255 /* Never returns */ <<
256 <<
257 2: /* No: all right ! */ <<
258 <<
259 /* Was this the outermost IRQ <<
260 jnz 3f <<
261 <<
262 /* Yes: reschedule */ <<
263 call sos_thread_prepare_irq_sw <<
264 /* Establish new context: cont <<
265 movl %eax, %esp <<
266 <<
267 /* Prepare kernel TSS in case <<
268 user thread: we make sure t <<
269 into the kernel at a correc <<
270 pushl %esp /* Pass the locatio <<
271 restoring to the <<
272 call sos_cpu_context_update_ke <<
273 addl $4, %esp <<
274 3: <<
275 /* Restore the context */ 146 /* Restore the context */
276 popw %gs 147 popw %gs
277 popw %fs 148 popw %fs
278 popw %es 149 popw %es
279 popw %ds 150 popw %ds
280 popw %ss 151 popw %ss
281 addl $2,%esp 152 addl $2,%esp
282 popl %eax 153 popl %eax
283 popl %ebx 154 popl %ebx
284 popl %ecx 155 popl %ecx
285 popl %edx 156 popl %edx
286 popl %esi 157 popl %esi
287 popl %edi 158 popl %edi
288 popl %ebp 159 popl %ebp
289 160
290 /* Remove fake error code */ 161 /* Remove fake error code */
291 addl $4, %esp 162 addl $4, %esp
292 163
293 iret 164 iret
294 .endr 165 .endr
295 166
296 .section ".rodata" <<
297 msg_nested_level_overflow: <<
298 .string "irq_wrappers.S: IRQ Nested le <<
299 <<
300 /* Build the sos_irq_wrapper_array, shared wit 167 /* Build the sos_irq_wrapper_array, shared with irq.c */
>> 168 .section ".rodata"
301 .p2align 5, 0x0 169 .p2align 5, 0x0
302 sos_irq_wrapper_array: 170 sos_irq_wrapper_array:
303 .irp id, 0,1,2,3,4,5,6,7,8,9,10,11,12, 171 .irp id, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
304 .long (sos_irq_wrapper_\id) 172 .long (sos_irq_wrapper_\id)
305 .endr 173 .endr