SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

001 /* Copyright (C) 2004  The KOS Team
002 
003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any later version.
007    
008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details.
012    
013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA. 
017 */
018 
019 #include "segment.h"
020          
021 .file "irq_wrappers.S"
022 
023 .text
024 
025 /** The address of the table of handlers (defined in irq.c) */
026 .extern sos_irq_handler_array
027 
028 /** The address of the table of wrappers (defined below, and shared
029    with irq.c */
030 .globl sos_irq_wrapper_array
031 
032 /** The variable holding the nested level of the IRQ handlers */
033 .extern sos_irq_nested_level_counter
034 
035 /** Update the interrupted current thread's CPU context
036     Its prototype is:
037       sos_thread_prepare_irq_servicing(struct sos_cpu_state *);
038 */
039 .extern sos_thread_prepare_irq_servicing
040 
041 /** Update the kernel TSS in case we are switching to a thread in user
042         mode in order to come back into the correct kernel stack */
043 .extern sos_cpu_context_update_kernel_tss
044 
045 /** Select a thread to set on CPU (this enables user-threads
046     preemption) and configure the MMU to match that of the destination
047     thread.
048     Its prototype is:
049       struct sos_cpu_state * // Selected CPU context
050       sos_thread_prepare_irq_switch_back();
051 */
052 .extern sos_thread_prepare_irq_switch_back
053 
054 /* These pre-handlers are for IRQ (Master PIC) */
055 .irp id, 0,1,2,3,4,5,6,7
056 
057         .p2align 2, 0x90
058 
059         sos_irq_wrapper_\id:
060         .type sos_irq_wrapper_\id,@function
061 
062                 /*
063                  * Backup the CPU context
064                  */
065 
066                 /* Fake error code */
067                 pushl $0
068 
069                 /* Backup the actual context */
070                 pushl %ebp
071                 movl %esp, %ebp
072 
073                 pushl %edi
074                 pushl %esi
075                 pushl %edx
076                 pushl %ecx
077                 pushl %ebx
078                 pushl %eax
079                 subl  $2,%esp
080                 pushw %ss
081                 pushw %ds
082                 pushw %es
083                 pushw %fs
084                 pushw %gs
085 
086                 /* Set correct kernel segment descriptors' value */
087                 movw $SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA), %di
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_counter
097                 /* Outermost IRQ only: store the interrupted context
098                    of the current thread */
099                 cmpl $1, sos_irq_nested_level_counter
100                 jne 1f
101                 pushl %esp
102                 call sos_thread_prepare_irq_servicing
103                 addl $4, %esp
104 
105         1:
106 
107                 /* Send EOI to PIC. See Intel 8259 datasheet
108                    available on Kos website */  
109                 movb  $0x20, %al
110                 outb  %al, $0x20
111         
112                 /*
113                  * Call the handler with IRQ number as argument
114                  */
115                 pushl $\id
116                 leal  sos_irq_handler_array,%edi
117                 call  *\id*4(%edi)
118                 addl  $4, %esp
119         
120                 /*
121                  * Decrement IRQ nested level
122                  */
123                 cli  /* Just in case we messed up everything in the handler */
124                 subl $1, sos_irq_nested_level_counter
125 
126                 /* sos_irq_nested_level_counter went below 0 ?! */
127                 jnc 2f
128         
129         1:      /* Yes: Print fatal error message */
130                 pushl $msg_nested_level_overflow
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 handler ? */
138                 jnz 3f
139 
140                 /* Yes: reschedule */
141                 call sos_thread_prepare_irq_switch_back
142                 /* Establish new context: context switch ! */
143                 movl %eax, %esp
144 
145                 /* Prepare kernel TSS in case we are switching to a
146                    user thread: we make sure that we will come back
147                    into the kernel at a correct stack location */
148                 pushl %esp /* Pass the location of the context we are
149                               restoring to the function */
150                 call sos_cpu_context_update_kernel_tss
151                 addl $4, %esp
152         3:
153                 /* Restore the context */
154                 popw  %gs
155                 popw  %fs
156                 popw  %es
157                 popw  %ds
158                 popw  %ss
159                 addl  $2,%esp
160                 popl  %eax
161                 popl  %ebx
162                 popl  %ecx
163                 popl  %edx
164                 popl  %esi
165                 popl  %edi
166                 popl  %ebp
167 
168                 /* Remove fake error code */
169                 addl  $4, %esp
170 
171                 iret
172         .endr
173 
174 
175 /* These pre-handlers are for IRQ (Slave PIC) */
176 .irp id, 8,9,10,11,12,13,14,15
177 
178         .p2align 2, 0x90
179 
180         sos_irq_wrapper_\id:
181         .type sos_irq_wrapper_\id,@function
182 
183                 /*
184                  * Backup the CPU context
185                  */
186 
187                 /* Fake error code */
188                 pushl $0
189 
190                 /* Backup the actual context */
191                 pushl %ebp
192                 movl %esp, %ebp
193 
194                 pushl %edi
195                 pushl %esi
196                 pushl %edx
197                 pushl %ecx
198                 pushl %ebx
199                 pushl %eax
200                 subl  $2,%esp
201                 pushw %ss
202                 pushw %ds
203                 pushw %es
204                 pushw %fs
205                 pushw %gs
206 
207                 /* Set correct kernel segment descriptors' value */
208                 movw $SOS_BUILD_SEGMENT_REG_VALUE(0, 0, SOS_SEG_KDATA), %di
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_counter
218                 /* Outermost IRQ only: store the interrupted context
219                    of the current thread */
220                 cmpl $1, sos_irq_nested_level_counter
221                 jne 1f
222                 pushl %esp
223                 call sos_thread_prepare_irq_servicing
224                 addl $4, %esp
225 
226         1:
227 
228                 /* Send EOI to PIC. See Intel 8259 datasheet
229                    available on Kos website */  
230                 movb  $0x20, %al
231                 outb  %al, $0xa0
232                 outb  %al, $0x20
233 
234                 /*
235                  * Call the handler with IRQ number as argument
236                  */
237                 pushl $\id
238                 leal  sos_irq_handler_array,%edi
239                 call  *\id*4(%edi)
240                 addl  $4, %esp
241 
242                 /*
243                  * Decrement IRQ nested level
244                  */
245                 cli  /* Just in case we messed up everything in the handler */
246                 subl $1, sos_irq_nested_level_counter
247 
248                 /* sos_irq_nested_level_counter went below 0 ?! */
249                 jnc 2f
250                 
251         1:      /* Yes: Print fatal error message */
252                 pushl $msg_nested_level_overflow
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 handler ? */
260                 jnz 3f
261 
262                 /* Yes: reschedule */
263                 call sos_thread_prepare_irq_switch_back
264                 /* Establish new context: context switch ! */
265                 movl %eax, %esp
266 
267                 /* Prepare kernel TSS in case we are switching to a
268                    user thread: we make sure that we will come back
269                    into the kernel at a correct stack location */
270                 pushl %esp /* Pass the location of the context we are
271                               restoring to the function */
272                 call sos_cpu_context_update_kernel_tss
273                 addl $4, %esp
274         3:
275                 /* Restore the context */
276                 popw  %gs
277                 popw  %fs
278                 popw  %es
279                 popw  %ds
280                 popw  %ss
281                 addl  $2,%esp
282                 popl  %eax
283                 popl  %ebx
284                 popl  %ecx
285                 popl  %edx
286                 popl  %esi
287                 popl  %edi
288                 popl  %ebp
289 
290                 /* Remove fake error code */
291                 addl  $4, %esp
292 
293                 iret
294         .endr
295 
296 .section ".rodata"
297 msg_nested_level_overflow:
298         .string "irq_wrappers.S: IRQ Nested level overflow ! System halted."
299 
300 /* Build the sos_irq_wrapper_array, shared with irq.c */
301 .p2align 5, 0x0
302 sos_irq_wrapper_array:
303         .irp id, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
304                 .long (sos_irq_wrapper_\id)
305         .endr

source navigation ] diff markup ] identifier search ] general search ]