Subversion Repositories Kolibri OS

Rev

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

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