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 |