diff --git a/kernel/trunk/core/apic.inc b/kernel/trunk/core/apic.inc index bb462b0c23..cc011134ed 100644 --- a/kernel/trunk/core/apic.inc +++ b/kernel/trunk/core/apic.inc @@ -1,20 +1,21 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $Revision$ - -iglobal -IRQ_COUNT dd 24 -endg +MAX_IOAPICS = 2 uglobal -irq_mode rd 1 -IOAPIC_base rd 1 +IRQ_COUNT rd MAX_IOAPICS +irq_mode rd 1 ; PIC/(IO)APIC +IOAPIC_base rd MAX_IOAPICS +ioapic_gsi_base rd MAX_IOAPICS ; zero-based, i.e. not vector +ioapic_cnt dd ? ; from MADT aka APIC table +ioapic_cur dd ? LAPIC_BASE rd 1 endg @@ -45,6 +46,7 @@ IOAPIC_REDTBL = 0x10 align 4 APIC_init: + push ebx mov [irq_mode], IRQ_PIC cmp [acpi_ioapic_base], 0 @@ -60,39 +62,51 @@ APIC_init: mov [acpi_dev_data], eax mov [acpi_dev_size], ebx - call IRQ_mask_all - ; IOAPIC init - stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_GLOBAL+PG_NOCACHE+PG_SWR - mov [IOAPIC_base], eax + xor ebx, ebx +@@: + stdcall map_io_mem, [acpi_ioapic_base+ebx*4], 0x20, PG_GLOBAL+PG_NOCACHE+PG_SWR + mov [IOAPIC_base+ebx*4], eax + inc ebx + cmp ebx, [ioapic_cnt] + jnz @b + call IRQ_mask_all + mov [ioapic_cur], 0 +.next_ioapic: + mov edx, [ioapic_cur] mov eax, IOAPIC_VER call IOAPIC_read shr eax, 16 inc al movzx eax, al - cmp al, IRQ_RESERVED + mov ecx, [ioapic_gsi_base+edx*4] + cmp ecx, IRQ_RESERVED + jae .lapic_init + add ecx, eax + sub ecx, IRQ_RESERVED jbe @f - - mov al, IRQ_RESERVED + sub eax, ecx @@: - mov [IRQ_COUNT], eax + mov [IRQ_COUNT+edx*4], eax ; Reroute IOAPIC & mask all interrupts xor ecx, ecx mov eax, IOAPIC_REDTBL -@@: +.next_irq: mov ebx, eax call IOAPIC_read mov ah, 0x08; Delivery Mode: Fixed, Destination Mode: Logical mov al, cl add al, 0x20; vector - or eax, 0x10000; Mask Interrupt + add eax, [ioapic_gsi_base+edx*4] + or eax, 0x1a000; Mask Interrupt, level-triggered active-low + cmp [ioapic_cur], 0 + jnz @f cmp ecx, 16 - jb .set - - or eax, 0xa000;<<< level-triggered active-low for IRQ16+ -.set: + jae @f + and eax, NOT 0xa000 ; edge-triggered active-high for IRQ0-15 +@@: xchg eax, ebx call IOAPIC_write inc eax @@ -103,9 +117,15 @@ APIC_init: call IOAPIC_write inc eax inc ecx - cmp ecx, [IRQ_COUNT] - jb @b + cmp ecx, [IRQ_COUNT+edx*4] + jb .next_irq + inc [ioapic_cur] + inc edx + cmp edx, [ioapic_cnt] + jnz .next_ioapic + +.lapic_init: call LAPIC_init mov [irq_mode], IRQ_APIC @@ -117,7 +137,7 @@ APIC_init: call pci_irq_fixup .no_apic: - + pop ebx ret ;=========================================================== @@ -210,7 +230,8 @@ IOAPIC_read: ; in : EAX - IOAPIC register ; out: EAX - readed value push esi - mov esi, [IOAPIC_base] + mov esi, [ioapic_cur] + mov esi, [IOAPIC_base+esi*4] mov [esi], eax mov eax, [esi + 0x10] pop esi @@ -222,7 +243,8 @@ IOAPIC_write: ; EBX - value ; out: none push esi - mov esi, [IOAPIC_base] + mov esi, [ioapic_cur] + mov esi, [IOAPIC_base+esi*4] mov [esi], eax mov [esi + 0x10], ebx pop esi @@ -232,6 +254,7 @@ IOAPIC_write: ; IRQ0 to vector 0x20, IRQ1 to vector 0x21.... align 4 PIC_init: + mov [IRQ_COUNT], 16 cli mov al, 0x11 ; icw4, edge triggered out 0x20, al @@ -252,7 +275,6 @@ PIC_init: out 0xA1, al call IRQ_mask_all - ; mov dword[irq_type_to_set], IRQ_TYPE_PIC ret ; ----------------------------------------- @@ -309,7 +331,12 @@ IRQ_mask_all: mov ecx, 0x1000 ret .APIC: - mov ecx, [IRQ_COUNT] + cmp [IOAPIC_base], 0 + jz .done + mov [ioapic_cur], 0 +.next_ioapic: + mov edx, [ioapic_cur] + mov ecx, [IRQ_COUNT+edx*4] mov eax, 0x10 @@: mov ebx, eax @@ -320,6 +347,12 @@ IRQ_mask_all: inc eax inc eax loop @b + + inc [ioapic_cur] + inc edx + cmp edx, [ioapic_cnt] + jnz .next_ioapic +.done: ret ; ----------------------------------------- @@ -363,6 +396,20 @@ proc enable_irq stdcall, irq_line:dword out dx, al ret .APIC: + push [ioapic_cur] + xor eax, eax +.next_ioapic: + mov ecx, [ioapic_gsi_base+eax*4] + add ecx, [IRQ_COUNT+eax*4] + cmp ebx, ecx + jb .found + inc eax + cmp eax, [ioapic_cnt] + jnz .next_ioapic + jmp .done +.found: + mov [ioapic_cur], eax + sub ebx, [ioapic_gsi_base+eax*4] shl ebx, 1 add ebx, 0x10 mov eax, ebx @@ -370,6 +417,8 @@ proc enable_irq stdcall, irq_line:dword and eax, 0xfffeffff; bit 16 xchg eax, ebx call IOAPIC_write +.done: + pop [ioapic_cur] ret endp @@ -390,6 +439,20 @@ proc disable_irq stdcall, irq_line:dword out dx, al ret .APIC: + push [ioapic_cur] + xor eax, eax +.next_ioapic: + mov ecx, [ioapic_gsi_base+eax*4] + add ecx, [IRQ_COUNT+eax*4] + cmp ebx, ecx + jae .found + inc eax + cmp eax, [ioapic_cnt] + jnz .next_ioapic + jmp .done +.found: + mov [ioapic_cur], eax + sub ebx, [ioapic_gsi_base+eax*4] shl ebx, 1 add ebx, 0x10 mov eax, ebx @@ -397,6 +460,8 @@ proc disable_irq stdcall, irq_line:dword or eax, 0x10000; bit 16 xchg eax, ebx call IOAPIC_write +.done: + pop [ioapic_cur] ret endp diff --git a/kernel/trunk/core/irq.inc b/kernel/trunk/core/irq.inc index 351040fd1b..deac174d5a 100644 --- a/kernel/trunk/core/irq.inc +++ b/kernel/trunk/core/irq.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -8,7 +8,7 @@ $Revision$ -IRQ_RESERVED = 24 +IRQ_RESERVED = 56 IRQ_POOL_SIZE = 48 @@ -20,11 +20,27 @@ irqh_tab rd sizeof.LHEAD * IRQ_RESERVED / 4 irqh_pool rd sizeof.IRQH * IRQ_POOL_SIZE /4 next_irqh rd 1 -irq_active_set rd 1 +irq_active_set rd (IRQ_RESERVED+31)/32 irq_failed rd IRQ_RESERVED endg +set_irq_active: + mov eax, ebp + mov ecx, ebp + shr ecx, 5 + and eax, 31 + bts [irq_active_set+ecx*4], eax + ret + +reset_irq_active: + mov eax, ebp + mov ecx, ebp + shr ecx, 5 + and eax, 31 + btr [irq_active_set+ecx*4], eax + ret + align 4 init_irqs: @@ -137,20 +153,15 @@ align 4 align 16 irq_serv: -; .irq_1: -; push 1 -; jmp .main -; etc... - -irq_serv_h 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15 -irq_serv_h 16, 17, 18, 19, 20, 21, 22, 23 +rept 12 irqn:1 {irq_serv_h irqn} ; 1--12 +rept 18 irqn:14 {irq_serv_h irqn} ; 14--31 (irq32 is vector 0x40) +rept 23 irqn:33 {irq_serv_h irqn} ; 33--55 purge irq_serv_h align 16 .main: save_ring3_context - mov ebp, [esp + 32] mov bx, app_data;os_data mov ds, bx @@ -159,7 +170,7 @@ align 16 cmp [v86_irqhooks+ebp*8], 0 jnz v86_irq - bts [irq_active_set], ebp + call set_irq_active lea esi, [irqh_tab+ebp*8] ; esi= list head mov ebx, esi @@ -184,11 +195,11 @@ align 16 jz .next inc [ebx+IRQH.num_ints] - btr [irq_active_set], ebp + call reset_irq_active jmp .next .done: - btr [irq_active_set], ebp + call reset_irq_active jnc .exit ; There is at least one configuration with one device which generates IRQ diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index 1ffcafb20e..d382857bcf 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License. ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -20,6 +20,13 @@ build_interrupt_table: loop @b movsd ;copy low dword of trap gate for int 0x40 movsd ;copy high dword of trap gate for int 0x40 + mov ecx, 23 + mov eax, (10001110b shl 24) + os_code + @@: + movsw ;low word of code-entry + stosd ;interrupt gate type : os_code selector + movsw ;high word of code-entry + loop @b lidt [esi] ret @@ -33,29 +40,21 @@ iglobal times 12 dd unknown_interrupt ;int_20..int_31 ;interrupt handlers addresses (for interrupt gate construction) - ; 0x20 .. 0x2F - IRQ handlers - dd irq0, irq_serv.irq_1, irq_serv.irq_2 - dd irq_serv.irq_3, irq_serv.irq_4 - dd irq_serv.irq_5, irq_serv.irq_6, irq_serv.irq_7 - dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 - dd irq_serv.irq_11, irq_serv.irq_12, irqD, irq_serv.irq_14, irq_serv.irq_15 - dd irq_serv.irq_16 - dd irq_serv.irq_17 - dd irq_serv.irq_18 - dd irq_serv.irq_19 - dd irq_serv.irq_20 - dd irq_serv.irq_21 - dd irq_serv.irq_22 - dd irq_serv.irq_23 + ; 0x20+ are IRQ handlers + dd irq0 + rept 12 irqn:1 \{dd irq_serv.irq_\#irqn\} + dd irqD + rept 18 irqn:14 \{dd irq_serv.irq_\#irqn\} - times 32 - IRQ_RESERVED dd unknown_interrupt - ;int_0x40 gate trap (for directly copied) - dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 + ; int_0x40 gate trap (for directly copied) + dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16 + + rept 23 irqn:33 \{dd irq_serv.irq_\#irqn\} idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data) dw 2*($-sys_int-4)-1 dd idts ;0x8000B100 - dw 0 ;просто выравнивание + dw 0 ;alignment msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b dd msg_exc_c,msg_exc_d,msg_exc_e,msg_exc_u diff --git a/kernel/trunk/init.inc b/kernel/trunk/init.inc index 36d8e7f9e4..6cb6111701 100644 --- a/kernel/trunk/init.inc +++ b/kernel/trunk/init.inc @@ -1,6 +1,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; +;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -429,7 +429,7 @@ acpi_fadt_base rd 1 acpi_dsdt_base rd 1 acpi_dsdt_size rd 1 acpi_madt_base rd 1 -acpi_ioapic_base rd 1 +acpi_ioapic_base rd MAX_IOAPICS acpi_hpet_base rd 1 hpet_base rd 1 hpet_period rd 1 @@ -581,14 +581,18 @@ check_acpi: inc [cpu_count-OS_BASE] add edi, 4 + mov [ioapic_cnt-OS_BASE], 0 lea edx, [eax+44] mov ecx, [eax+4] add ecx, eax .check: mov eax, [edx] cmp al, 0 - jne .io_apic - + je .lapic + cmp al, 1 + je .io_apic + jmp .next +.lapic: shr eax, 24 ; get APIC ID cmp eax, ebx ; skip self je .next @@ -611,11 +615,12 @@ check_acpi: ret .io_apic: - cmp al, 1 - jne .next - - mov eax, [edx+4] - mov [acpi_ioapic_base-OS_BASE], eax + mov eax, [ioapic_cnt-OS_BASE] + push dword[edx+4] + pop [acpi_ioapic_base-OS_BASE+eax*4] + push dword[edx+8] + pop [ioapic_gsi_base-OS_BASE+eax*4] + inc [ioapic_cnt-OS_BASE] jmp .next HPET_PERIOD = 0x0004 diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 55df527717..94ff221e0b 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -715,7 +715,11 @@ endg ; Enable timer IRQ (IRQ0) and co-processor IRQ (IRQ13) ; they are used: when partitions are scanned, hd_read relies on timer call unmask_timer + ; Prevent duplicate timer IRQs in APIC mode + cmp [irq_mode], IRQ_APIC + jz @f stdcall enable_irq, 2 ; @#$%! PIC +@@: stdcall enable_irq, 13 ; co-processor ; Setup serial output console (if enabled)