Subversion Repositories Kolibri OS

Rev

Rev 6015 | Rev 7733 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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