Subversion Repositories Kolibri OS

Rev

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

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