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 #define ASM_SOURCE 1
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 /* These pre-handlers are for IRQ (Master PIC) */
036 .irp id, 0,1,2,3,4,5,6,7
037
038 .p2align 2, 0x90
039
040 sos_irq_wrapper_\id:
041 .type sos_irq_wrapper_\id,@function
042
043 /*
044 * Backup the CPU context
045 */
046
047 /* Fake error code */
048 pushl $0
049
050 /* Backup the actual context */
051 pushl %ebp
052 movl %esp, %ebp
053
054 pushl %edi
055 pushl %esi
056 pushl %edx
057 pushl %ecx
058 pushl %ebx
059 pushl %eax
060 subl $2,%esp
061 pushw %ss
062 pushw %ds
063 pushw %es
064 pushw %fs
065 pushw %gs
066
067 /*
068 * Increment IRQ nested level
069 */
070 incl sos_irq_nested_level_counter
071
072 /* Send EOI to PIC. See Intel 8259 datasheet
073 available on Kos website */
074 movb $0x20, %al
075 outb %al, $0x20
076
077 /*
078 * Call the handler with the IRQ number and the
079 * address of the stored CPU context as arguments
080 */
081 pushl %esp
082 pushl $\id
083 leal sos_irq_handler_array,%edi
084 call *\id*4(%edi)
085 /* Unallocate the arguments passed to the handler */
086 addl $8, %esp
087
088 /*
089 * Decrement IRQ nested level
090 */
091 cli /* Just in case we messed up everything in the handler */
092 subl $1, sos_irq_nested_level_counter
093
094 /* sos_irq_nested_level_counter went below 0 ?! */
095 jnc 2f
096
097 1: /* Yes: Print fatal error message */
098 pushl $msg_nested_level_overflow
099 call sos_display_fatal_error
100 addl $4, %esp ; jmp 1b
101 /* Never returns */
102
103 2: /* No: all right ! */
104
105 /* Restore the context */
106 popw %gs
107 popw %fs
108 popw %es
109 popw %ds
110 popw %ss
111 addl $2,%esp
112 popl %eax
113 popl %ebx
114 popl %ecx
115 popl %edx
116 popl %esi
117 popl %edi
118 popl %ebp
119
120 /* Remove fake error code */
121 addl $4, %esp
122
123 iret
124 .endr
125
126
127 /* These pre-handlers are for IRQ (Slave PIC) */
128 .irp id, 8,9,10,11,12,13,14,15
129
130 .p2align 2, 0x90
131
132 sos_irq_wrapper_\id:
133 .type sos_irq_wrapper_\id,@function
134
135 /*
136 * Backup the CPU context
137 */
138
139 /* Fake error code */
140 pushl $0
141
142 /* Backup the actual context */
143 pushl %ebp
144 movl %esp, %ebp
145
146 pushl %edi
147 pushl %esi
148 pushl %edx
149 pushl %ecx
150 pushl %ebx
151 pushl %eax
152 subl $2,%esp
153 pushw %ss
154 pushw %ds
155 pushw %es
156 pushw %fs
157 pushw %gs
158
159 /*
160 * Increment IRQ nested level
161 */
162 incl sos_irq_nested_level_counter
163
164 /* Send EOI to PIC. See Intel 8259 datasheet
165 available on Kos website */
166 movb $0x20, %al
167 outb %al, $0xa0
168 outb %al, $0x20
169
170 /*
171 * Call the handler with the IRQ number and the
172 * address of the stored CPU context as arguments
173 */
174 pushl %esp
175 pushl $\id
176 leal sos_irq_handler_array,%edi
177 call *\id*4(%edi)
178 /* Unallocate the arguments passed to the handler */
179 addl $8, %esp
180
181 /*
182 * Decrement IRQ nested level
183 */
184 cli /* Just in case we messed up everything in the handler */
185 subl $1, sos_irq_nested_level_counter
186
187 /* sos_irq_nested_level_counter went below 0 ?! */
188 jnc 2f
189
190 1: /* Yes: Print fatal error message */
191 pushl $msg_nested_level_overflow
192 call sos_display_fatal_error
193 addl $4, %esp ; jmp 1b
194 /* Never returns */
195
196 2: /* No: all right ! */
197
198 /* Restore the context */
199 popw %gs
200 popw %fs
201 popw %es
202 popw %ds
203 popw %ss
204 addl $2,%esp
205 popl %eax
206 popl %ebx
207 popl %ecx
208 popl %edx
209 popl %esi
210 popl %edi
211 popl %ebp
212
213 /* Remove fake error code */
214 addl $4, %esp
215
216 iret
217 .endr
218
219 .section ".rodata"
220 msg_nested_level_overflow:
221 .string "irq_wrappers.S: IRQ Nested level overflow ! System halted."
222
223 /* Build the sos_irq_wrapper_array, shared with irq.c */
224 .p2align 5, 0x0
225 sos_irq_wrapper_array:
226 .irp id, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
227 .long (sos_irq_wrapper_\id)
228 .endr