42,6 → 42,7 |
IOAPIC_ARB equ 0x2 |
IOAPIC_REDTBL equ 0x10 |
|
align 4 |
APIC_init: |
mov dword[APIC], 0 |
|
62,6 → 63,7 |
movzx eax, al |
cmp al, IRQ_RESERVED |
jbe @f |
|
mov al, IRQ_RESERVED |
@@: |
mov [IRQ_COUNT], eax |
69,7 → 71,8 |
; Reroute IOAPIC & mask all interrupts |
xor ecx, ecx |
mov eax, IOAPIC_REDTBL |
@@: mov ebx, eax |
@@: |
mov ebx, eax |
call IOAPIC_read |
mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical |
mov al, cl |
77,6 → 80,7 |
or eax, 0x10000 ; Mask Interrupt |
cmp ecx, 16 |
jb .set |
|
or eax, 0xa000 ;<<< level-triggered active-low for IRQ16+ |
.set: |
xchg eax, ebx |
103,6 → 107,8 |
|
; mov dword[irq_type_to_set], IRQ_TYPE_APIC |
|
.no_apic: |
|
;init handlers table |
|
mov ecx, IRQ_RESERVED |
116,7 → 122,6 |
mov ecx, 47 |
mov eax, irqh_pool+IRQH.sizeof |
mov [next_irqh], irqh_pool |
|
@@: |
mov [eax-IRQH.sizeof], eax |
add eax, IRQH.sizeof |
124,7 → 129,6 |
|
mov [eax-IRQH.sizeof], dword 0 |
|
.no_apic: |
ret |
|
;=========================================================== |
146,7 → 150,6 |
or eax, 0xf0000000 |
mov [esi + APIC_DFR], eax |
|
|
; Program Logical Destination Register. |
mov eax, [esi + APIC_LDR] |
;and eax, 0xff000000 |
161,12 → 164,16 |
|
; Flush the queue |
mov edx, 0 |
.nxt2: mov ecx, 32 |
.nxt2: |
mov ecx, 32 |
mov eax, [esi + APIC_ISR + edx] |
.nxt: shr eax, 1 |
.nxt: |
shr eax, 1 |
jnc @f |
mov dword [esi + APIC_EOI], 0 ; EOI |
@@: loop .nxt |
@@: |
loop .nxt |
|
add edx, 0x10 |
cmp edx, 0x170 |
jbe .nxt2 |
206,8 → 213,8 |
; Start (every 0.01 sec) |
mov dword[esi + APIC_LVT_timer], 0x30020 ; periodic int 0x20 |
mov dword[esi + APIC_timer_init], eax |
ret |
|
ret |
;=========================================================== |
; IOAPIC implementation |
align 4 |
220,6 → 227,7 |
mov eax, [esi + 0x10] |
pop esi |
ret |
|
align 4 |
IOAPIC_write: |
; in : EAX - IOAPIC register |
238,41 → 246,27 |
cli |
mov al,0x11 ; icw4, edge triggered |
out 0x20,al |
call pic_delay |
out 0xA0,al |
call pic_delay |
|
mov al,0x20 ; generate 0x20 + |
out 0x21,al |
call pic_delay |
mov al,0x28 ; generate 0x28 + |
out 0xA1,al |
call pic_delay |
|
mov al,0x04 ; slave at irq2 |
out 0x21,al |
call pic_delay |
mov al,0x02 ; at irq9 |
out 0xA1,al |
call pic_delay |
|
mov al,0x01 ; 8086 mode |
out 0x21,al |
call pic_delay |
out 0xA1,al |
call pic_delay |
|
call IRQ_mask_all |
cli |
; mov dword[irq_type_to_set], IRQ_TYPE_PIC |
ret |
|
; ----------------------------------------- |
pic_delay: |
jmp pdl1 |
pdl1: ret |
|
; ----------------------------------------- |
; TIMER SET TO 1/100 S |
PIT_init: |
mov al,0x34 ; set to 100Hz |
319,14 → 313,12 |
out 0x21, al |
out 0xA1, al |
mov ecx,0x1000 |
cld |
@@: call pic_delay |
loop @b |
ret |
.APIC: |
mov ecx, [IRQ_COUNT] |
mov eax, 0x10 |
@@: mov ebx, eax |
@@: |
mov ebx, eax |
call IOAPIC_read |
or eax, 0x10000 ; bit 16 |
xchg eax, ebx |
335,6 → 327,7 |
inc eax |
loop @b |
ret |
|
; ----------------------------------------- |
; End Of Interrupt |
; cl - IRQ number |
342,6 → 335,7 |
irq_eoi: ; __fastcall |
test dword[APIC], 0xffffffff |
jnz .APIC |
|
cmp cl, 8 |
mov al, 0x20 |
jb @f |
362,9 → 356,11 |
mov ebx, [irq_line] |
test dword[APIC], 0xffffffff |
jnz .APIC |
|
mov edx, 0x21 |
cmp ebx, 8 |
jb @F |
|
mov edx, 0xA1 |
sub ebx,8 |
@@: |