Subversion Repositories Kolibri OS

Rev

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

Rev 3786 Rev 4850
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