Subversion Repositories Kolibri OS

Rev

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