Subversion Repositories Kolibri OS

Rev

Rev 3513 | Rev 3543 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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