Subversion Repositories Kolibri OS

Rev

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

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