Subversion Repositories Kolibri OS

Rev

Rev 2229 | Rev 2437 | 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
2434 Serge 85
        mov     ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical
2217 Serge 86
        mov al, cl
2434 Serge 87
        add     al, 0x20; vector
88
        or      eax, 0x10000; Mask Interrupt
2217 Serge 89
        cmp ecx, 16
90
        jb  .set
91
 
2434 Serge 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
2434 Serge 99
        or      eax, 0xff000000; Destination Field
2217 Serge 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
2434 Serge 144
        or      eax, 0x01000000;!!!!!!!!!!!!
2217 Serge 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
2434 Serge 160
        mov     dword [esi + APIC_EOI], 0; EOI
2217 Serge 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]
2434 Serge 185
        or      eax, 0x10000; bit 16
2217 Serge 186
        mov [esi + APIC_LVT_err], eax
2010 serge 187
 
1638 serge 188
	; LAPIC timer
189
	; pre init
2434 Serge 190
        mov     dword[esi + APIC_timer_div], 1011b; 1
191
        mov     dword[esi + APIC_timer_init], 0xffffffff; max val
2217 Serge 192
        push  esi
193
        mov esi, 640        ; wait 0.64 sec
194
        call  delay_ms
195
        pop esi
2434 Serge 196
        mov     eax, [esi + APIC_timer_cur]; read current tick couner
2217 Serge 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)
2434 Serge 201
        mov     dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
2217 Serge 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
2434 Serge 235
        mov     al, 0x11        ;  icw4, edge triggered
236
        out     0x20, al
237
        out     0xA0, al
1638 serge 238
 
2434 Serge 239
        mov     al, 0x20        ;  generate 0x20 +
240
        out     0x21, al
241
        mov     al, 0x28        ;  generate 0x28 +
242
        out     0xA1, al
1638 serge 243
 
2434 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
 
2434 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:
2434 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
2217 Serge 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
2434 Serge 308
        mov     ecx, 0x1000
2217 Serge 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
2434 Serge 316
        or      eax, 0x10000; bit 16
2217 Serge 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]
2434 Serge 342
        mov     dword [eax + APIC_EOI], 0; EOI
2217 Serge 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
2434 Serge 358
        sub     ebx, 8
1638 serge 359
@@:
2434 Serge 360
        in      al, dx
2217 Serge 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
2434 Serge 369
        and     eax, 0xfffeffff; bit 16
2217 Serge 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