Subversion Repositories Kolibri OS

Rev

Rev 2219 | Rev 2434 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1638 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2209 Serge 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
1638 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
 
9
iglobal
2219 Serge 10
IRQ_COUNT    dd 24
1638 serge 11
endg
12
 
13
uglobal
2219 Serge 14
irq_mode     rd  1
2212 Serge 15
IOAPIC_base  rd  1
16
LAPIC_BASE   rd  1
1638 serge 17
endg
18
 
2217 Serge 19
APIC_ID         equ 0x20
20
APIC_TPR        equ 0x80
21
APIC_EOI        equ 0xb0
22
APIC_LDR        equ 0xd0
23
APIC_DFR        equ 0xe0
24
APIC_SVR        equ 0xf0
25
APIC_ISR        equ 0x100
26
APIC_ESR        equ 0x280
27
APIC_ICRL       equ 0x300
28
APIC_ICRH       equ 0x310
1638 serge 29
APIC_LVT_LINT0	equ	0x350
30
APIC_LVT_LINT1	equ	0x360
2217 Serge 31
APIC_LVT_err    equ 0x370
1638 serge 32
 
33
; APIC timer
34
APIC_LVT_timer	equ	0x320
35
APIC_timer_div	equ	0x3e0
36
APIC_timer_init	equ	0x380
37
APIC_timer_cur	equ	0x390
38
; IOAPIC
2217 Serge 39
IOAPIC_ID       equ 0x0
40
IOAPIC_VER      equ 0x1
41
IOAPIC_ARB      equ 0x2
42
IOAPIC_REDTBL   equ 0x10
1638 serge 43
 
2217 Serge 44
align 4
1638 serge 45
APIC_init:
2219 Serge 46
        mov [irq_mode], IRQ_PIC
2010 serge 47
 
2219 Serge 48
        cmp [acpi_ioapic_base], 0
49
        jz .no_apic
50
 
51
        cmp [acpi_lapic_base], 0
52
        jz .no_apic
53
 
54
        stdcall load_file, dev_data_path
2217 Serge 55
        test eax, eax
56
        jz .no_apic
2212 Serge 57
 
2229 Serge 58
        mov [acpi_dev_data], eax
59
        mov [acpi_dev_size], ebx
60
 
2217 Serge 61
        call  IRQ_mask_all
2010 serge 62
 
2219 Serge 63
; IOAPIC init
2217 Serge 64
        stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW
65
        mov [IOAPIC_base], eax
2010 serge 66
 
2217 Serge 67
        mov eax, IOAPIC_VER
68
        call  IOAPIC_read
69
        shr eax, 16
70
        inc al
71
        movzx eax, al
72
        cmp al, IRQ_RESERVED
73
        jbe @f
74
 
75
        mov al, IRQ_RESERVED
2130 serge 76
@@:
2217 Serge 77
        mov [IRQ_COUNT], eax
1638 serge 78
 
79
	; Reroute IOAPIC & mask all interrupts
2217 Serge 80
        xor ecx, ecx
81
        mov eax, IOAPIC_REDTBL
82
@@:
83
        mov ebx, eax
84
        call  IOAPIC_read
85
        mov ah, 0x09    ; Delivery Mode: Lowest Priority, Destination Mode: Logical
86
        mov al, cl
87
        add al, 0x20    ; vector
88
        or  eax, 0x10000    ; Mask Interrupt
89
        cmp ecx, 16
90
        jb  .set
91
 
92
        or  eax, 0xa000   ;<<< level-triggered active-low for IRQ16+
1638 serge 93
.set:
2217 Serge 94
        xchg  eax, ebx
95
        call  IOAPIC_write
96
        inc eax
97
        mov ebx, eax
98
        call  IOAPIC_read
99
        or  eax, 0xff000000   ; Destination Field
100
        xchg  eax, ebx
101
        call  IOAPIC_write
102
        inc eax
103
        inc ecx
104
        cmp ecx, [IRQ_COUNT]
105
        jb  @b
1638 serge 106
 
2217 Serge 107
        call  LAPIC_init
2010 serge 108
 
2219 Serge 109
        mov [irq_mode], IRQ_APIC
2010 serge 110
 
2217 Serge 111
        mov al, 0x70
112
        out 0x22, al
113
        mov al, 1
114
        out 0x23, al
2010 serge 115
 
2229 Serge 116
        call pci_irq_fixup
2217 Serge 117
.no_apic:
118
 
119
        ret
2010 serge 120
 
1638 serge 121
;===========================================================
122
align 4
123
LAPIC_init:
124
	; Check MSR support
125
	;....
126
	; Get LAPIC base address
2212 Serge 127
; mov ecx, 0x1b
128
; rdmsr       ; it may be replaced to
129
; and ax, 0xf000    ; mov eax, 0xfee00000
2010 serge 130
 
2217 Serge 131
        stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW
132
        mov [LAPIC_BASE], eax
133
        mov esi, eax
2010 serge 134
 
1638 serge 135
	; Program Destination Format Register for Flat mode.
2217 Serge 136
        mov eax, [esi + APIC_DFR]
137
        or  eax, 0xf0000000
138
        mov [esi + APIC_DFR], eax
2010 serge 139
 
1638 serge 140
	; Program Logical Destination Register.
2217 Serge 141
        mov eax, [esi + APIC_LDR]
142
        ;and  eax, 0xff000000
143
        and eax, 0x00ffffff
144
        or  eax, 0x01000000 ;!!!!!!!!!!!!
145
        mov [esi + APIC_LDR], eax
2010 serge 146
 
1638 serge 147
	; Task Priority Register initialization.
2217 Serge 148
        mov eax, [esi + APIC_TPR]
149
        and eax, 0xffffff00
150
        mov [esi + APIC_TPR], eax
1638 serge 151
 
152
	; Flush the queue
2217 Serge 153
        mov edx, 0
154
.nxt2:
155
        mov ecx, 32
156
        mov eax, [esi + APIC_ISR + edx]
157
.nxt:
158
        shr eax, 1
159
        jnc @f
160
        mov dword [esi + APIC_EOI], 0 ; EOI
161
@@:
162
        loop  .nxt
1638 serge 163
 
2217 Serge 164
        add edx, 0x10
165
        cmp edx, 0x170
166
        jbe .nxt2
167
 
1638 serge 168
	; Spurious-Interrupt Vector Register initialization.
2217 Serge 169
        mov eax, [esi + APIC_SVR]
170
        or  eax, 0x1ff
171
        and eax, 0xfffffdff
172
        mov [esi + APIC_SVR], eax
1638 serge 173
 
174
	; Initialize LVT LINT0 register. (INTR)
2217 Serge 175
        mov eax, 0x00700
176
        ; mov eax, 0x10700
177
        mov [esi + APIC_LVT_LINT0], eax
1638 serge 178
 
179
	; Initialize LVT LINT1 register. (NMI)
2217 Serge 180
        mov eax, 0x00400
181
        mov [esi + APIC_LVT_LINT1], eax
1638 serge 182
 
183
	; Initialize LVT Error register.
2217 Serge 184
        mov eax, [esi + APIC_LVT_err]
185
        or  eax, 0x10000    ; bit 16
186
        mov [esi + APIC_LVT_err], eax
2010 serge 187
 
1638 serge 188
	; LAPIC timer
189
	; pre init
2217 Serge 190
        mov dword[esi + APIC_timer_div], 1011b  ; 1
191
        mov dword[esi + APIC_timer_init], 0xffffffff  ; max val
192
        push  esi
193
        mov esi, 640        ; wait 0.64 sec
194
        call  delay_ms
195
        pop esi
196
        mov eax, [esi + APIC_timer_cur]   ; read current tick couner
197
        xor eax, 0xffffffff       ; eax = 0xffffffff - eax
198
        shr eax, 6          ; eax /= 64; APIC ticks per 0.01 sec
2010 serge 199
 
1638 serge 200
	; Start (every 0.01 sec)
2217 Serge 201
        mov dword[esi + APIC_LVT_timer], 0x30020  ; periodic int 0x20
202
        mov dword[esi + APIC_timer_init], eax
203
        ret
2010 serge 204
 
1638 serge 205
;===========================================================
206
; IOAPIC implementation
207
align 4
208
IOAPIC_read:
209
; in : EAX - IOAPIC register
210
; out: EAX - readed value
2217 Serge 211
        push  esi
212
        mov esi, [IOAPIC_base]
213
        mov [esi], eax
214
        mov eax, [esi + 0x10]
215
        pop esi
216
        ret
217
 
1638 serge 218
align 4
219
IOAPIC_write:
220
; in :	EAX - IOAPIC register
221
;	EBX - value
222
; out:	none
2217 Serge 223
        push  esi
224
        mov esi, [IOAPIC_base]
225
        mov [esi], eax
226
        mov [esi + 0x10], ebx
227
        pop esi
228
        ret
1638 serge 229
;===========================================================
230
; Remap all IRQ to 0x20+ Vectors
231
; IRQ0 to vector 0x20, IRQ1 to vector 0x21....
2219 Serge 232
align 4
1638 serge 233
PIC_init:
2217 Serge 234
        cli
235
        mov al,0x11   ;  icw4, edge triggered
236
        out 0x20,al
237
        out 0xA0,al
1638 serge 238
 
2217 Serge 239
        mov al,0x20   ;  generate 0x20 +
240
        out 0x21,al
241
        mov al,0x28   ;  generate 0x28 +
242
        out 0xA1,al
1638 serge 243
 
2217 Serge 244
        mov al,0x04   ;  slave at irq2
245
        out 0x21,al
246
        mov al,0x02   ;  at irq9
247
        out 0xA1,al
1638 serge 248
 
2217 Serge 249
        mov al,0x01   ;  8086 mode
250
        out 0x21,al
251
        out 0xA1,al
1638 serge 252
 
2217 Serge 253
        call  IRQ_mask_all
1638 serge 254
	; mov	dword[irq_type_to_set], IRQ_TYPE_PIC
2217 Serge 255
        ret
1638 serge 256
 
257
; -----------------------------------------
258
; TIMER SET TO 1/100 S
2219 Serge 259
align 4
1638 serge 260
PIT_init:
2217 Serge 261
        mov   al,0x34      ; set to 100Hz
262
        out   0x43,al
263
        mov   al,0x9b      ; lsb    1193180 / 1193
264
        out   0x40,al
265
        mov   al,0x2e      ; msb
266
        out   0x40,al
267
        ret
1638 serge 268
 
269
; -----------------------------------------
2219 Serge 270
align 4
1638 serge 271
unmask_timer:
2219 Serge 272
        cmp  [irq_mode], IRQ_APIC
273
        je @f
274
 
2217 Serge 275
        stdcall enable_irq, 0
276
        ret
2049 serge 277
@@:
1638 serge 278
	; use PIT
279
	; in some systems PIT no connected to IOAPIC
280
	; mov	eax, 0x14
281
	; call	IOAPIC_read
282
	; mov	ah, 0x09		; Delivery Mode: Lowest Priority, Destination Mode: Logical
283
	; mov	al, 0x20
284
	; or	eax, 0x10000		; Mask Interrupt
285
	; mov	ebx, eax
286
	; mov	eax, 0x14
287
	; call	IOAPIC_write
288
	; stdcall enable_irq, 2
289
	; ret
2049 serge 290
 
1638 serge 291
	; use LAPIC timer
2217 Serge 292
        mov esi, [LAPIC_BASE]
293
        mov eax, [esi + APIC_LVT_timer]
294
        and eax, 0xfffeffff
295
        mov [esi + APIC_LVT_timer], eax
296
        ret
1638 serge 297
 
298
; -----------------------------------------
299
; Disable all IRQ
2219 Serge 300
align 4
1638 serge 301
IRQ_mask_all:
2219 Serge 302
        cmp [irq_mode], IRQ_APIC
303
        je .APIC
304
 
2217 Serge 305
        mov al, 0xFF
306
        out 0x21, al
307
        out 0xA1, al
308
        mov ecx,0x1000
309
        ret
1638 serge 310
.APIC:
2217 Serge 311
        mov ecx, [IRQ_COUNT]
312
        mov eax, 0x10
313
@@:
314
        mov ebx, eax
315
        call  IOAPIC_read
316
        or  eax, 0x10000    ; bit 16
317
        xchg  eax, ebx
318
        call  IOAPIC_write
319
        inc eax
320
        inc eax
321
        loop  @b
322
        ret
323
 
1638 serge 324
; -----------------------------------------
325
; End Of Interrupt
2166 serge 326
; cl - IRQ number
2219 Serge 327
align 4
2166 serge 328
irq_eoi:         ; __fastcall
2219 Serge 329
        cmp [irq_mode], IRQ_APIC
330
        je .APIC
2217 Serge 331
 
332
        cmp cl, 8
333
        mov al, 0x20
334
        jb  @f
335
        out 0xa0, al
2166 serge 336
@@:
2217 Serge 337
        out 0x20, al
338
        ret
2166 serge 339
 
2049 serge 340
.APIC:
2217 Serge 341
        mov eax, [LAPIC_BASE]
342
        mov dword [eax + APIC_EOI], 0 ; EOI
343
        ret
2049 serge 344
 
1638 serge 345
; -----------------------------------------
346
; from dll.inc
347
align 4
348
proc enable_irq stdcall, irq_line:dword
2217 Serge 349
        mov ebx, [irq_line]
2219 Serge 350
        cmp [irq_mode], IRQ_APIC
351
        je .APIC
2217 Serge 352
 
353
        mov edx, 0x21
354
        cmp ebx, 8
355
        jb  @F
356
 
357
        mov edx, 0xA1
358
        sub ebx,8
1638 serge 359
@@:
2217 Serge 360
        in  al,dx
361
        btr eax, ebx
362
        out dx, al
363
        ret
1638 serge 364
.APIC:
2217 Serge 365
        shl ebx, 1
366
        add ebx, 0x10
367
        mov eax, ebx
368
        call  IOAPIC_read
369
        and eax, 0xfffeffff   ; bit 16
370
        xchg  eax, ebx
371
        call  IOAPIC_write
372
        ret
1638 serge 373
endp
374
 
2219 Serge 375
align 4
376
pci_irq_fixup:
1638 serge 377
 
2219 Serge 378
        push ebp
1638 serge 379
 
2219 Serge 380
        mov esi, [acpi_dev_data]
381
        mov ebx, [acpi_dev_size]
382
 
383
        lea edi, [esi+ebx]
384
 
385
.iterate:
386
 
387
        cmp esi, edi
388
        jae .done
389
 
390
        mov eax, [esi]
391
 
392
        cmp eax, -1
393
        je .done
394
 
395
        movzx ebx, al
396
        movzx ebp, ah
397
 
398
        stdcall pci_read32, ebp, ebx, 0
399
 
400
        cmp eax, [esi+4]
401
        jne .skip
402
 
403
        mov eax, [esi+8]
404
        stdcall pci_write8, ebp, ebx, 0x3C, eax
405
.skip:
406
        add esi, 16
407
        jmp .iterate
408
 
409
.done:
410
.fail:
411
        pop ebp
412
        ret
413