Rev 9715 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2288 | clevermous | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
10051 | ace_dent | 3 | ;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;; |
2288 | clevermous | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
7 | |||
4850 | mario79 | 8 | |
7733 | dunkaist | 9 | IRQ_RESERVED = 56 |
2288 | clevermous | 10 | |
7136 | dunkaist | 11 | IRQ_POOL_SIZE = 48 |
2288 | clevermous | 12 | |
13 | uglobal |
||
14 | |||
15 | align 16 |
||
2384 | hidnplayr | 16 | irqh_tab rd sizeof.LHEAD * IRQ_RESERVED / 4 |
2288 | clevermous | 17 | |
2384 | hidnplayr | 18 | irqh_pool rd sizeof.IRQH * IRQ_POOL_SIZE /4 |
2288 | clevermous | 19 | next_irqh rd 1 |
20 | |||
9715 | Doczom | 21 | irq_active_set rd (IRQ_RESERVED + 31)/32 |
2288 | clevermous | 22 | irq_failed rd IRQ_RESERVED |
23 | |||
24 | endg |
||
25 | |||
7733 | dunkaist | 26 | set_irq_active: |
27 | mov eax, ebp |
||
28 | mov ecx, ebp |
||
29 | shr ecx, 5 |
||
30 | and eax, 31 |
||
9715 | Doczom | 31 | bts [irq_active_set + ecx*4], eax |
7733 | dunkaist | 32 | ret |
33 | |||
34 | reset_irq_active: |
||
35 | mov eax, ebp |
||
36 | mov ecx, ebp |
||
37 | shr ecx, 5 |
||
38 | and eax, 31 |
||
9715 | Doczom | 39 | btr [irq_active_set + ecx*4], eax |
7733 | dunkaist | 40 | ret |
41 | |||
2288 | clevermous | 42 | align 4 |
43 | init_irqs: |
||
44 | |||
45 | mov ecx, IRQ_RESERVED |
||
46 | mov edi, irqh_tab |
||
47 | @@: |
||
48 | mov eax, edi |
||
49 | stosd |
||
50 | stosd |
||
51 | loop @B |
||
52 | |||
53 | mov ecx, IRQ_POOL_SIZE-1 |
||
9715 | Doczom | 54 | mov eax, irqh_pool + sizeof.IRQH |
2288 | clevermous | 55 | mov [next_irqh], irqh_pool |
56 | @@: |
||
9715 | Doczom | 57 | mov [eax - sizeof.IRQH], eax |
2384 | hidnplayr | 58 | add eax, sizeof.IRQH |
2288 | clevermous | 59 | loop @B |
60 | |||
9715 | Doczom | 61 | mov [eax - sizeof.IRQH], dword 0 |
2288 | clevermous | 62 | ret |
63 | |||
64 | |||
65 | align 4 |
||
66 | proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword |
||
67 | locals |
||
68 | .irqh dd ? |
||
69 | endl |
||
3786 | Serge | 70 | |
3774 | mario79 | 71 | DEBUGF 1, "K : Attach Interrupt %d Handler %x\n", [irq], [handler] |
2288 | clevermous | 72 | |
73 | and [.irqh], 0 |
||
74 | |||
75 | push ebx |
||
76 | |||
77 | mov ebx, [irq] ;irq num |
||
78 | test ebx, ebx |
||
79 | jz .err |
||
80 | |||
81 | cmp ebx, IRQ_RESERVED |
||
82 | jae .err |
||
83 | |||
84 | mov edx, [handler] |
||
85 | test edx, edx |
||
86 | jz .err |
||
87 | |||
3505 | clevermous | 88 | spin_lock_irqsave IrqsList |
2288 | clevermous | 89 | |
90 | ;allocate handler |
||
91 | |||
92 | mov ecx, [next_irqh] |
||
93 | test ecx, ecx |
||
94 | jz .fail |
||
95 | |||
96 | mov eax, [ecx] |
||
97 | mov [next_irqh], eax |
||
98 | mov [.irqh], ecx |
||
99 | |||
9715 | Doczom | 100 | mov [irq_failed + ebx*4], 0;clear counter |
2288 | clevermous | 101 | |
102 | mov eax, [user_data] |
||
9715 | Doczom | 103 | mov [ecx + IRQH.handler], edx |
104 | mov [ecx + IRQH.data], eax |
||
105 | and [ecx + IRQH.num_ints], 0 |
||
2288 | clevermous | 106 | |
9715 | Doczom | 107 | lea edx, [irqh_tab + ebx*8] |
3505 | clevermous | 108 | list_add_tail ecx, edx ;clobber eax |
2288 | clevermous | 109 | stdcall enable_irq, ebx |
110 | |||
111 | .fail: |
||
3505 | clevermous | 112 | spin_unlock_irqrestore IrqsList |
2288 | clevermous | 113 | .err: |
114 | pop ebx |
||
115 | mov eax, [.irqh] |
||
116 | ret |
||
117 | |||
118 | endp |
||
119 | |||
120 | if 0 |
||
121 | align 4 |
||
122 | proc get_int_handler stdcall, irq:dword |
||
123 | |||
124 | mov eax, [irq] |
||
125 | cmp eax, 15 |
||
126 | ja .fail |
||
127 | mov eax, [irq_tab + 4 * eax] |
||
128 | ret |
||
129 | .fail: |
||
130 | xor eax, eax |
||
131 | ret |
||
132 | endp |
||
133 | end if |
||
134 | |||
135 | |||
136 | align 4 |
||
137 | proc detach_int_handler |
||
138 | |||
139 | ret |
||
140 | endp |
||
141 | |||
142 | |||
143 | macro irq_serv_h [num] { |
||
144 | forward |
||
145 | align 4 |
||
146 | .irq_#num : |
||
147 | push num |
||
148 | jmp .main |
||
149 | } |
||
150 | |||
151 | align 16 |
||
152 | irq_serv: |
||
153 | |||
7733 | dunkaist | 154 | rept 12 irqn:1 {irq_serv_h irqn} ; 1--12 |
155 | rept 18 irqn:14 {irq_serv_h irqn} ; 14--31 (irq32 is vector 0x40) |
||
156 | rept 23 irqn:33 {irq_serv_h irqn} ; 33--55 |
||
2288 | clevermous | 157 | |
158 | purge irq_serv_h |
||
159 | |||
160 | align 16 |
||
161 | .main: |
||
3505 | clevermous | 162 | save_ring3_context |
2288 | clevermous | 163 | mov ebp, [esp + 32] |
164 | mov bx, app_data;os_data |
||
165 | mov ds, bx |
||
166 | mov es, bx |
||
167 | |||
9715 | Doczom | 168 | cmp [v86_irqhooks + ebp*8], 0 |
2288 | clevermous | 169 | jnz v86_irq |
170 | |||
7733 | dunkaist | 171 | call set_irq_active |
2288 | clevermous | 172 | |
9715 | Doczom | 173 | lea esi, [irqh_tab + ebp*8] ; esi= list head |
2288 | clevermous | 174 | mov ebx, esi |
175 | .next: |
||
9715 | Doczom | 176 | mov ebx, [ebx + IRQH.list.next]; ebx= irqh pointer |
2288 | clevermous | 177 | cmp ebx, esi |
178 | je .done |
||
179 | |||
180 | push ebx ; FIX THIS |
||
181 | push edi |
||
182 | push esi |
||
183 | |||
9715 | Doczom | 184 | push [ebx + IRQH.data] |
185 | call [ebx + IRQH.handler] |
||
3505 | clevermous | 186 | pop ecx |
2288 | clevermous | 187 | |
188 | pop esi |
||
189 | pop edi |
||
190 | pop ebx |
||
191 | |||
192 | test eax, eax |
||
193 | jz .next |
||
194 | |||
9715 | Doczom | 195 | inc [ebx + IRQH.num_ints] |
7733 | dunkaist | 196 | call reset_irq_active |
2288 | clevermous | 197 | jmp .next |
198 | |||
199 | .done: |
||
7733 | dunkaist | 200 | call reset_irq_active |
2288 | clevermous | 201 | jnc .exit |
202 | |||
3505 | clevermous | 203 | ; There is at least one configuration with one device which generates IRQ |
204 | ; that is not the same as it should be according to PCI config space. |
||
205 | ; For that device, the handler is registered at wrong IRQ. |
||
206 | ; As a workaround, when nobody acknowledges the generated IRQ, |
||
207 | ; try to ask all other registered handlers; if some handler acknowledges |
||
208 | ; the IRQ this time, relink it to the current IRQ list. |
||
209 | ; To make this more reliable, for every handler keep number of times |
||
210 | ; that it has acknowledged an IRQ, and assume that handlers with at least one |
||
211 | ; acknowledged IRQ are registered properly. |
||
212 | ; Note: this still isn't 100% correct, because two IRQs can fire simultaneously, |
||
213 | ; the better way would be to find the correct IRQ, but I don't know how to do |
||
214 | ; this in that case. |
||
6015 | clevermous | 215 | cmp ebp, 1 |
216 | jz .fail |
||
3505 | clevermous | 217 | push ebp |
218 | xor ebp, ebp |
||
219 | .try_other_irqs: |
||
220 | cmp ebp, [esp] |
||
221 | jz .try_next_irq |
||
3543 | clevermous | 222 | cmp ebp, 1 |
223 | jz .try_next_irq |
||
3771 | mario79 | 224 | cmp ebp, 6 |
225 | jz .try_next_irq |
||
3543 | clevermous | 226 | cmp ebp, 12 |
227 | jz .try_next_irq |
||
3762 | mario79 | 228 | cmp ebp, 14 |
229 | jz .try_next_irq |
||
230 | cmp ebp, 15 |
||
231 | jz .try_next_irq |
||
9715 | Doczom | 232 | lea esi, [irqh_tab + ebp*8] |
3505 | clevermous | 233 | mov ebx, esi |
234 | .try_next_handler: |
||
9715 | Doczom | 235 | mov ebx, [ebx + IRQH.list.next] |
3505 | clevermous | 236 | cmp ebx, esi |
237 | je .try_next_irq |
||
9715 | Doczom | 238 | cmp [ebx + IRQH.num_ints], 0 |
3512 | clevermous | 239 | jne .try_next_handler |
3509 | clevermous | 240 | ; keyboard handler acknowledges everything |
9715 | Doczom | 241 | push [ebx + IRQH.data] |
242 | call [ebx + IRQH.handler] |
||
3505 | clevermous | 243 | pop ecx |
244 | test eax, eax |
||
3511 | clevermous | 245 | jz .try_next_handler |
246 | |||
247 | .found_in_wrong_list: |
||
248 | DEBUGF 1,'K : warning: relinking handler from IRQ%d to IRQ%d\n',\ |
||
249 | ebp, [esp] |
||
3513 | clevermous | 250 | pop ebp |
3511 | clevermous | 251 | spin_lock_irqsave IrqsList |
252 | list_del ebx |
||
9715 | Doczom | 253 | lea edx, [irqh_tab + ebp*8] |
3511 | clevermous | 254 | list_add_tail ebx, edx |
255 | spin_unlock_irqrestore IrqsList |
||
256 | jmp .exit |
||
257 | |||
3505 | clevermous | 258 | .try_next_irq: |
259 | inc ebp |
||
260 | cmp ebp, 16 |
||
261 | jb .try_other_irqs |
||
262 | pop ebp |
||
263 | |||
3509 | clevermous | 264 | .fail: |
9715 | Doczom | 265 | inc [irq_failed + ebp*4] |
2288 | clevermous | 266 | .exit: |
267 | |||
268 | mov ecx, ebp |
||
269 | call irq_eoi |
||
270 | |||
3615 | clevermous | 271 | ; IRQ handler could make some kernel thread ready; reschedule |
272 | mov bl, SCHEDULE_HIGHER_PRIORITY |
||
273 | call find_next_task |
||
274 | jz .return ; if there is only one running process |
||
275 | call do_change_task |
||
276 | .return: |
||
3505 | clevermous | 277 | restore_ring3_context |
2288 | clevermous | 278 | add esp, 4 |
279 | iret |
||
280 | |||
281 | align 4 |
||
282 | irqD: |
||
283 | push eax |
||
284 | push ecx |
||
285 | xor eax, eax |
||
286 | out 0xf0, al |
||
287 | mov cl, 13 |
||
288 | call irq_eoi |
||
289 | pop ecx |
||
290 | pop eax |
||
291 | iret |
||
292 |