diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc index 885bf688e2..7f7b446c5f 100644 --- a/kernel/trunk/const.inc +++ b/kernel/trunk/const.inc @@ -143,6 +143,8 @@ SSE_FZ equ 0x8000 SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM) +IRQ_PIC equ 0 +IRQ_APIC equ 1 struc TSS { diff --git a/kernel/trunk/core/apic.inc b/kernel/trunk/core/apic.inc index 0e0c5ebdfc..012887447d 100644 --- a/kernel/trunk/core/apic.inc +++ b/kernel/trunk/core/apic.inc @@ -5,9 +5,232 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -align 4 -rerouteirqs: +iglobal +IRQ_COUNT dd 24 +endg + +uglobal +irq_mode rd 1 +IOAPIC_base rd 1 +LAPIC_BASE rd 1 +endg + +APIC_ID equ 0x20 +APIC_TPR equ 0x80 +APIC_EOI equ 0xb0 +APIC_LDR equ 0xd0 +APIC_DFR equ 0xe0 +APIC_SVR equ 0xf0 +APIC_ISR equ 0x100 +APIC_ESR equ 0x280 +APIC_ICRL equ 0x300 +APIC_ICRH equ 0x310 +APIC_LVT_LINT0 equ 0x350 +APIC_LVT_LINT1 equ 0x360 +APIC_LVT_err equ 0x370 + +; APIC timer +APIC_LVT_timer equ 0x320 +APIC_timer_div equ 0x3e0 +APIC_timer_init equ 0x380 +APIC_timer_cur equ 0x390 +; IOAPIC +IOAPIC_ID equ 0x0 +IOAPIC_VER equ 0x1 +IOAPIC_ARB equ 0x2 +IOAPIC_REDTBL equ 0x10 + +align 4 +APIC_init: + mov [irq_mode], IRQ_PIC + + cmp [acpi_ioapic_base], 0 + jz .no_apic + + cmp [acpi_lapic_base], 0 + jz .no_apic + + stdcall load_file, dev_data_path + test eax, eax + jz .no_apic + + 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_SW + mov [IOAPIC_base], eax + + mov eax, IOAPIC_VER + call IOAPIC_read + shr eax, 16 + inc al + movzx eax, al + cmp al, IRQ_RESERVED + jbe @f + + mov al, IRQ_RESERVED +@@: + mov [IRQ_COUNT], eax + + ; Reroute IOAPIC & mask all interrupts + xor ecx, ecx + mov eax, IOAPIC_REDTBL +@@: + mov ebx, eax + call IOAPIC_read + mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical + mov al, cl + add al, 0x20 ; vector + or eax, 0x10000 ; Mask Interrupt + cmp ecx, 16 + jb .set + + or eax, 0xa000 ;<<< level-triggered active-low for IRQ16+ +.set: + xchg eax, ebx + call IOAPIC_write + inc eax + mov ebx, eax + call IOAPIC_read + or eax, 0xff000000 ; Destination Field + xchg eax, ebx + call IOAPIC_write + inc eax + inc ecx + cmp ecx, [IRQ_COUNT] + jb @b + + call LAPIC_init + + mov [irq_mode], IRQ_APIC + + mov al, 0x70 + out 0x22, al + mov al, 1 + out 0x23, al + + call pci_irq_fixup +.no_apic: + + ret + +;=========================================================== +align 4 +LAPIC_init: + ; Check MSR support + ;.... + ; Get LAPIC base address +; mov ecx, 0x1b +; rdmsr ; it may be replaced to +; and ax, 0xf000 ; mov eax, 0xfee00000 + + stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW + mov [LAPIC_BASE], eax + mov esi, eax + + ; Program Destination Format Register for Flat mode. + mov eax, [esi + APIC_DFR] + or eax, 0xf0000000 + mov [esi + APIC_DFR], eax + + ; Program Logical Destination Register. + mov eax, [esi + APIC_LDR] + ;and eax, 0xff000000 + and eax, 0x00ffffff + or eax, 0x01000000 ;!!!!!!!!!!!! + mov [esi + APIC_LDR], eax + + ; Task Priority Register initialization. + mov eax, [esi + APIC_TPR] + and eax, 0xffffff00 + mov [esi + APIC_TPR], eax + + ; Flush the queue + mov edx, 0 +.nxt2: + mov ecx, 32 + mov eax, [esi + APIC_ISR + edx] +.nxt: + shr eax, 1 + jnc @f + mov dword [esi + APIC_EOI], 0 ; EOI +@@: + loop .nxt + + add edx, 0x10 + cmp edx, 0x170 + jbe .nxt2 + + ; Spurious-Interrupt Vector Register initialization. + mov eax, [esi + APIC_SVR] + or eax, 0x1ff + and eax, 0xfffffdff + mov [esi + APIC_SVR], eax + + ; Initialize LVT LINT0 register. (INTR) + mov eax, 0x00700 + ; mov eax, 0x10700 + mov [esi + APIC_LVT_LINT0], eax + + ; Initialize LVT LINT1 register. (NMI) + mov eax, 0x00400 + mov [esi + APIC_LVT_LINT1], eax + + ; Initialize LVT Error register. + mov eax, [esi + APIC_LVT_err] + or eax, 0x10000 ; bit 16 + mov [esi + APIC_LVT_err], eax + + ; LAPIC timer + ; pre init + mov dword[esi + APIC_timer_div], 1011b ; 1 + mov dword[esi + APIC_timer_init], 0xffffffff ; max val + push esi + mov esi, 640 ; wait 0.64 sec + call delay_ms + pop esi + mov eax, [esi + APIC_timer_cur] ; read current tick couner + xor eax, 0xffffffff ; eax = 0xffffffff - eax + shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec + + ; Start (every 0.01 sec) + mov dword[esi + APIC_LVT_timer], 0x30020 ; periodic int 0x20 + mov dword[esi + APIC_timer_init], eax + ret + +;=========================================================== +; IOAPIC implementation +align 4 +IOAPIC_read: +; in : EAX - IOAPIC register +; out: EAX - readed value + push esi + mov esi, [IOAPIC_base] + mov [esi], eax + mov eax, [esi + 0x10] + pop esi + ret + +align 4 +IOAPIC_write: +; in : EAX - IOAPIC register +; EBX - value +; out: none + push esi + mov esi, [IOAPIC_base] + mov [esi], eax + mov [esi + 0x10], ebx + pop esi + ret +;=========================================================== +; Remap all IRQ to 0x20+ Vectors +; IRQ0 to vector 0x20, IRQ1 to vector 0x21.... +align 4 +PIC_init: cli mov al,0x11 ; icw4, edge triggered out 0x20,al @@ -27,39 +250,168 @@ rerouteirqs: out 0x21,al out 0xA1,al - mov al,255 ; mask all irq's - out 0xA1,al - out 0x21,al - - mov al,255 ; mask all irq's - out 0xA1,al - out 0x21,al + call IRQ_mask_all + ; mov dword[irq_type_to_set], IRQ_TYPE_PIC ret - +; ----------------------------------------- +; TIMER SET TO 1/100 S align 4 -;proc enable_irq stdcall, irq_line:dword -enable_irq: ; FIXME make fastcall - mov ebx, [esp+4] ;irq_line +PIT_init: + mov al,0x34 ; set to 100Hz + out 0x43,al + mov al,0x9b ; lsb 1193180 / 1193 + out 0x40,al + mov al,0x2e ; msb + out 0x40,al + ret + +; ----------------------------------------- +align 4 +unmask_timer: + cmp [irq_mode], IRQ_APIC + je @f + + stdcall enable_irq, 0 + ret +@@: + ; use PIT + ; in some systems PIT no connected to IOAPIC + ; mov eax, 0x14 + ; call IOAPIC_read + ; mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical + ; mov al, 0x20 + ; or eax, 0x10000 ; Mask Interrupt + ; mov ebx, eax + ; mov eax, 0x14 + ; call IOAPIC_write + ; stdcall enable_irq, 2 + ; ret + + ; use LAPIC timer + mov esi, [LAPIC_BASE] + mov eax, [esi + APIC_LVT_timer] + and eax, 0xfffeffff + mov [esi + APIC_LVT_timer], eax + ret + +; ----------------------------------------- +; Disable all IRQ +align 4 +IRQ_mask_all: + cmp [irq_mode], IRQ_APIC + je .APIC + + mov al, 0xFF + out 0x21, al + out 0xA1, al + mov ecx,0x1000 + ret +.APIC: + mov ecx, [IRQ_COUNT] + mov eax, 0x10 +@@: + mov ebx, eax + call IOAPIC_read + or eax, 0x10000 ; bit 16 + xchg eax, ebx + call IOAPIC_write + inc eax + inc eax + loop @b + ret + +; ----------------------------------------- +; End Of Interrupt +; cl - IRQ number +align 4 +irq_eoi: ; __fastcall + cmp [irq_mode], IRQ_APIC + je .APIC + + cmp cl, 8 + mov al, 0x20 + jb @f + out 0xa0, al +@@: + out 0x20, al + ret + +.APIC: + mov eax, [LAPIC_BASE] + mov dword [eax + APIC_EOI], 0 ; EOI + ret + +; ----------------------------------------- +; from dll.inc +align 4 +proc enable_irq stdcall, irq_line:dword + mov ebx, [irq_line] + cmp [irq_mode], IRQ_APIC + je .APIC + mov edx, 0x21 cmp ebx, 8 jb @F + mov edx, 0xA1 sub ebx,8 @@: in al,dx btr eax, ebx out dx, al - ret 4 - + ret +.APIC: + shl ebx, 1 + add ebx, 0x10 + mov eax, ebx + call IOAPIC_read + and eax, 0xfffeffff ; bit 16 + xchg eax, ebx + call IOAPIC_write + ret +endp align 4 -;proc irq_eoi fastcall, irq_line:dword -irq_eoi: - cmp cl, 8 - mov al, 0x20 - jb @f - out 0xa0, al -@@: - out 0x20, al - ret +pci_irq_fixup: + + push ebp + + mov esi, [acpi_dev_data] + mov ebx, [acpi_dev_size] + + lea edi, [esi+ebx] + +.iterate: + + cmp esi, edi + jae .done + + mov eax, [esi] + + cmp eax, -1 + je .done + + movzx ebx, al + movzx ebp, ah + + stdcall pci_read32, ebp, ebx, 0 + + cmp eax, [esi+4] + jne .skip + + mov eax, [esi+8] + stdcall pci_write8, ebp, ebx, 0x3C, eax +.skip: + add esi, 16 + jmp .iterate + +.done: +.fail: + pop ebp + ret + + + + + diff --git a/kernel/trunk/core/irq.inc b/kernel/trunk/core/irq.inc index d281dc7e8b..076ff66cdc 100644 --- a/kernel/trunk/core/irq.inc +++ b/kernel/trunk/core/irq.inc @@ -5,7 +5,7 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -IRQ_RESERVED equ 16 +IRQ_RESERVED equ 24 IRQ_POOL_SIZE equ 48 diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index 210a37450f..5cc16ae918 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -45,7 +45,14 @@ iglobal 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 times 32 - IRQ_RESERVED dd unknown_interrupt ;int_0x40 gate trap (for directly copied) diff --git a/kernel/trunk/data32.inc b/kernel/trunk/data32.inc index cf4c866162..4a668ffe08 100644 --- a/kernel/trunk/data32.inc +++ b/kernel/trunk/data32.inc @@ -78,15 +78,12 @@ else boot_tss db 'Setting TSSs',0 boot_cpuid db 'Reading CPUIDs',0 boot_devices db 'Detecting devices',0 - boot_timer db 'Setting timer',0 - boot_irqs db 'Reprogramming IRQs',0 boot_setmouse db 'Setting mouse',0 boot_windefs db 'Setting window defaults',0 boot_bgr db 'Calculating background',0 boot_resirqports db 'Reserving IRQs & ports',0 - boot_setrports db 'Setting addresses for IRQs',0 boot_setostask db 'Setting OS task',0 - boot_allirqs db 'Unmasking all IRQs',0 + boot_allirqs db 'Unmasking IRQs',0 boot_tsc db 'Reading TSC',0 boot_cpufreq db 'CPU frequency is ',' ',' MHz',0 boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0 @@ -147,6 +144,7 @@ vmode db '/sys/drivers/VMODE.MDR',0 vrr_m db 'VRR_M',0 kernel_file db 'KERNEL MNT' +dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0 align 4 diff --git a/kernel/trunk/init.inc b/kernel/trunk/init.inc index 992e4adff3..80a070b2bc 100644 --- a/kernel/trunk/init.inc +++ b/kernel/trunk/init.inc @@ -437,6 +437,9 @@ acpi_rsdp rd 1 acpi_rsdt rd 1 acpi_madt rd 1 +acpi_dev_data rd 1 +acpi_dev_size rd 1 + acpi_rsdt_base rd 1 acpi_madt_base rd 1 acpi_lapic_base rd 1 diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index fe29ea838e..e94783fde3 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -226,7 +226,7 @@ B32: mov fs,ax mov gs,ax mov ss,ax - mov esp,0x5ec00 ; Set stack + mov esp,0x006CC00 ; Set stack ; CLEAR 0x280000 - HEAP_BASE @@ -236,13 +236,11 @@ B32: cld rep stosd - mov edi,0x40000 - mov ecx,(0x90000-0x40000)/4 - rep stosd - ; CLEAR KERNEL UNDEFINED GLOBALS mov edi, endofcode-OS_BASE - mov ecx, (uglobals_size/4)+4 + mov ecx, 0x90000 + sub ecx, edi + shr ecx, 2 rep stosd ; SAVE & CLEAR 0-0xffff @@ -605,28 +603,25 @@ high_code: ; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f call init_irqs - call rerouteirqs + call PIC_init ; Initialize system V86 machine call init_sys_v86 -; TIMER SET TO 1/100 S +; Initialize system timer (IRQ0) + call PIT_init - mov al,0x34 ; set to 100Hz - out 0x43,al - mov al,0x9b ; lsb 1193180 / 1193 - out 0x40,al - mov al,0x2e ; msb - out 0x40,al +; Try to Initialize APIC + call APIC_init ; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15) ; they are used: when partitions are scanned, hd_read relies on timer -; Also enable IRQ2, because in some configurations -; IRQs from slave controller are not delivered until IRQ2 on master is enabled - mov al, 0xFA - out 0x21, al - mov al, 0x3F - out 0xA1, al + call unmask_timer + stdcall enable_irq, 2 ; @#$%! PIC + stdcall enable_irq, 6 ; FDD + stdcall enable_irq, 13 ; co-processor + stdcall enable_irq, 14 + stdcall enable_irq, 15 ; Enable interrupts in IDE controller mov al, 0 @@ -679,6 +674,13 @@ end if mov esi,boot_fonts call boot_log +; Display APIC status + mov esi, boot_APIC_found + cmp [irq_mode], IRQ_APIC + je @f + mov esi, boot_APIC_nfound +@@: + ; PRINT AMOUNT OF MEMORY mov esi, boot_memdetect call boot_log @@ -822,17 +824,6 @@ end if call set_variables -; SET MOUSE - - ;call detect_devices - stdcall load_driver, szPS2MDriver -; stdcall load_driver, szCOM_MDriver - - mov esi,boot_setmouse - call boot_log - call setmouse - - ; STACK AND FDC call stack_init @@ -939,7 +930,16 @@ first_app_found: ;// mike.dld [ call set_lights ;// mike.dld ] + stdcall attach_int_handler, 1, irq1, 0 +; SET MOUSE + + stdcall load_driver, szPS2MDriver +; stdcall load_driver, szCOM_MDriver + + mov esi,boot_setmouse + call boot_log + call setmouse ; Setup serial output console (if enabled) @@ -993,10 +993,6 @@ if preboot_blogesc jne .bll1 end if - - stdcall attach_int_handler, 1, irq1, 0 - -; mov [dma_hdd],1 cmp [IDEContrRegsBaseAddr], 0 setnz [dma_hdd] mov [timer_ticks_enable],1 ; for cd driver @@ -4865,9 +4861,7 @@ end if call restorefatchain - mov al, 0xFF - out 0x21, al - out 0xA1, al + call IRQ_mask_all if 0 mov word [OS_BASE+0x467+0],pr_mode_exit diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index c6cc0b5d89..cfb30f70e1 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -220,8 +220,8 @@ include "core/peload.inc" ; include "core/exports.inc" include "core/string.inc" include "core/v86.inc" ; virtual-8086 manager -include "core/apic.inc" ; Interrupt Controller functions include "core/irq.inc" ; irq handling functions +include "core/apic.inc" ; Interrupt Controller functions include "core/timers.inc" ; GUI stuff