Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1637 → Rev 1638

/kernel/branches/Kolibri-acpi/core/apic.inc
0,0 → 1,487
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2007-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
IRQ_RESERVE = 24 ; 16 or 24
 
iglobal
IRQ_COUNT dd 16
endg
 
uglobal
APIC: dd 0
LAPIC_BASE: dd 0
IOAPIC_base: dd 0
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
 
APIC_init:
mov dword[APIC], 0
; jmp .no_apic ; NO APIC
bt [cpu_caps], CAPS_APIC
jnc .no_apic
; Check for MP table
;.....
call IRQ_mask_all
; IOAPIC init
; 0xfec00000 - may be relocated, see chip reference... & MP table
stdcall map_io_mem, 0xfec00000, 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_RESERVE
jbe @f
mov al, IRQ_RESERVE
@@: 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 dword[APIC], 0xffffffff
; mov dword[irq_type_to_set], IRQ_TYPE_APIC
.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, eax, 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....
PIC_init:
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
out 0x43,al
mov al,0x9b ; lsb 1193180 / 1193
out 0x40,al
mov al,0x2e ; msb
out 0x40,al
ret
 
; -----------------------------------------
unmask_timer:
test dword[APIC], 0xffffffff
jnz @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
IRQ_mask_all:
test dword[APIC], 0xffffffff
jnz .APIC
mov al, 0xFF
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
call IOAPIC_read
or eax, 0x10000 ; bit 16
xchg eax, ebx
call IOAPIC_write
inc eax
inc eax
loop @b
ret
; -----------------------------------------
; End Of Interrupt
; al - IRQ number
align 16
IRQ_EOI:
test dword[APIC], 0xffffffff
jnz .APIC
cmp al, 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]
test dword[APIC], 0xffffffff
jnz .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
.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
 
 
 
; IRQ_TYPE_DISABLE equ 0
; IRQ_TYPE_PIC equ 1
; IRQ_TYPE_APIC equ 2
 
; uglobal
; irq_type_to_set rd 1
; irq_types rd IRQ_RESERVE
; endg
 
; -----------------------------------------
; End Of Interrupt
; al - IRQ number
; align 16
; IRQ_EOI:
; movzx eax, al
; cmp dword[irq_types + eax * 4], IRQ_TYPE_APIC
; jne @f
; mov eax, [LAPIC_BASE]
; mov dword [eax + APIC_EOI], 0 ; EOI
; ret
; @@:
; cmp al, 8
; mov al, 0x20
; jb @f
; out 0xa0, al
; @@: out 0x20, al
; ret
 
; align 4
; proc enable_irq stdcall, irq_line:dword
; cmp dword[irq_type_to_set], IRQ_TYPE_APIC
; jne @f
; stdcall APIC_enable_irq, [irq_line]
; ret
; @@: stdcall PIC_enable_irq, [irq_line]
; ret
; endp
 
; align 4
; proc disable_irq stdcall, irq_line:dword
; push eax
; mov eax, [irq_line]
; cmp dword[irq_types + eax * 4], IRQ_TYPE_APIC
; jne @f
; stdcall APIC_disable_irq, eax
; pop eax
; ret
; @@: stdcall PIC_disable_irq, eax
; pop eax
; ret
; endp
 
; align 4
; proc PIC_enable_irq stdcall, irq_line:dword
; pusha
; mov ebx, [irq_line]
; mov eax, [irq_types + ebx * 4]
; cmp eax, IRQ_TYPE_DISABLE
; je @f
; cmp eax, IRQ_TYPE_PIC
; je @f
; stdcall disable_irq, ebx
; @@: mov dword[irq_types + ebx * 4], IRQ_TYPE_PIC
; mov edx, 0x21
; cmp ebx, 8
; jb @F
; mov edx, 0xA1
; sub ebx,8
; @@: in al,dx
; btr eax, ebx
; out dx, al
; popa
; ret
; endp
 
; align 4
; proc PIC_disable_irq stdcall, irq_line:dword
; pusha
; mov ebx, [irq_line]
; mov dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE
; mov edx, 0x21
; cmp ebx, 8
; jb @F
; mov edx, 0xA1
; sub ebx,8
; @@: in al,dx
; bts eax, ebx
; out dx, al
; popa
; ret
; endp
 
; align 4
; proc APIC_enable_irq stdcall, irq_line:dword
; pusha
; mov ebx, [irq_line]
; mov eax, [irq_types + ebx * 4]
; cmp eax, IRQ_TYPE_DISABLE
; je @f
; cmp eax, IRQ_TYPE_APIC
; je @f
; stdcall disable_irq, ebx
; @@: mov dword[irq_types + ebx * 4], IRQ_TYPE_APIC
; shl ebx, 1
; add ebx, 0x10
; mov eax, ebx
; call IOAPIC_read
; and eax, 0xfffeffff ; bit 16
; xchg eax, ebx
; call IOAPIC_write
; popa
; ret
; endp
 
; align 4
; proc APIC_disable_irq stdcall, irq_line:dword
; pusha
; mov ebx, [irq_line]
; mov dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE
; shl ebx, 1
; add ebx, 0x10
; mov eax, ebx
; call IOAPIC_read
; or eax, 0x10000
; xchg eax, ebx
; call IOAPIC_write
; popa
; ret
; endp
/kernel/branches/Kolibri-acpi/core/dll.inc
22,8 → 22,9
mov ebx, [irq] ;irq num
test ebx, ebx
jz .err
cmp ebx, 15 ; hidnplayr says: we only have 16 IRQ's
ja .err
cmp ebx, [IRQ_COUNT] ; hidnplayr says: we only have 16 IRQ's
; Ghost says: we can have more...
jae .err
mov eax, [handler]
test eax, eax
jz .err
54,7 → 55,7
 
uglobal
 
irq_rights rd 16
irq_rights rd IRQ_RESERVE
 
endg
 
80,20 → 81,6
ret
endp
 
align 4
proc enable_irq stdcall, irq_line:dword
mov ebx, [irq_line]
mov edx, 0x21
cmp ebx, 8
jb @F
mov edx, 0xA1
sub ebx,8
@@:
in al,dx
btr eax, ebx
out dx, al
ret
endp
 
align 16
;; proc irq_serv
100,66 → 87,26
 
irq_serv:
 
.irq_1:
push 1
jmp .main
align 4
.irq_2:
push 2
jmp .main
align 4
.irq_3:
push 3
jmp .main
align 4
.irq_4:
push 4
jmp .main
align 4
.irq_5:
push 5
jmp .main
; align 4
; .irq_6:
; push 6
; .irq_1:
; push 1
; jmp .main
; etc...
macro irq_serv_h [num] {
forward
align 4
.irq_7:
push 7
.irq_#num :
push num
jmp .main
align 4
.irq_8:
push 8
jmp .main
align 4
.irq_9:
push 9
jmp .main
align 4
.irq_10:
push 10
jmp .main
align 4
.irq_11:
push 11
jmp .main
align 4
.irq_12:
push 12
jmp .main
; align 4
; .irq_13:
; push 13
; jmp .main
; align 4
; .irq_14:
; push 14
; jmp .main
; align 4
; .irq_15:
; push 15
; jmp .main
}
 
irq_serv_h 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12
 
; I don`t known how to use IRQ_RESERVE
if IRQ_RESERVE > 16
irq_serv_h 16, 17, 18, 19, 20, 21, 22, 23
end if
 
align 16
.main:
save_ring3_context
178,15 → 125,8
call ebx
mov [check_idle_semaphore],5
 
.exit:
 
cmp dword [esp + 32], 8
mov al, 0x20
jb @f
out 0xa0, al
@@:
out 0x20, al
 
.exit: mov eax, [esp + 32]
call IRQ_EOI
restore_ring3_context
add esp, 4
 
1620,70 → 1560,3
 
call free ;release object memory
ret
 
 
 
if 0
 
irq:
 
.irq0:
pusfd
pushad
push IRQ_0
jmp .master
.irq_1:
pusfd
pushad
push IRQ_1
jmp .master
 
.master:
mov ax, app_data
mov ds, eax
mov es, eax
mov ebx, [esp+4] ;IRQ_xx
mov eax, [irq_handlers+ebx+4]
call intr_handler
mov ecx, [esp+4]
cmp [irq_actids+ecx*4], 0
je @F
in al, 0x21
bts eax, ecx
out 0x21, al
mov al, 0x20
out 0x20, al
jmp .restart
 
.slave:
mov ax, app_data
mov ds, eax
mov es, eax
mov ebx, [esp+4] ;IRQ_xx
mov eax, [irq_handlers+ebx+4]
call intr_handler
mov ecx, [esp+4]
sub ecx, 8
cmp [irq_actids+ecx*4], 0
je @F
in al, 0xA1
bts eax, ecx
out 0xA1, al
mov al, 0x20
out 0xA0, al
out 0x20, al
.restart:
mov ebx, [next_slot]
test ebx, ebx
jz @F
mov [next_task],0
mov esi, [prev_slot]
call do_change_task
add esp, 4
iretd
 
end if
 
 
 
 
/kernel/branches/Kolibri-acpi/core/sched.inc
27,8 → 27,8
add [next_usage_update],100
call updatecputimes
.nocounter:
mov al,0x20 ; send End Of Interrupt signal
out 0x20,al
mov al, 0 ; send End Of Interrupt signal
call IRQ_EOI
btr dword[DONT_SWITCH], 0
jc .return
call find_next_task
/kernel/branches/Kolibri-acpi/core/sys32.inc
39,6 → 39,7
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
if USE_COM_IRQ
dd irq_serv.irq_3, irq_serv.irq_4
47,9 → 48,22
end if
dd irq_serv.irq_5, p_irq6, 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,p_irq14,p_irq15
times 16 dd unknown_interrupt ;int_0x30..int_0x3F
dd irq_serv.irq_11, irq_serv.irq_12
dd irq13
dd p_irq14,p_irq15
; I don`t known how to use IRQ_RESERVE
if IRQ_RESERVE > 16
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
end if
 
times 32 - IRQ_RESERVE dd unknown_interrupt
;int_0x40 gate trap (for directly copied)
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
 
122,8 → 136,9
reg_esi equ esp+0x04
reg_edi equ esp+0x00
 
Mov ds,ax,app_data ; çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ
mov es,ax ; â ñåãìåíòíûå ðåãèñòðû
mov ax, app_data ;èñêëþ÷åíèå
mov ds, ax ;çàãðóçèì ïðàâèëüíûå çíà÷åíè
mov es, ax ;â ðåãèñòðû
cld ; è ïðèâîäèì DF ê ñòàíäàðòó
movzx ebx,bl
; redirect to V86 manager? (EFLAGS & 0x20000) != 0?
186,10 → 201,12
stosd
mov [edi], ebx
restore_ring3_context
; simply return control to interrupted process
unknown_interrupt:
iretd
 
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; bl - error vector
show_error_parameters:
mov edx,[TASK_BASE] ;not scratched below
DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid]
228,6 → 245,8
restore reg_esi
restore reg_edi
 
; IRQ runtime
 
; irq1 -> hid/keyboard.inc
macro irqh [num] {
p_irq#num :
235,9 → 254,13
jmp irqhandler
}
 
irqh 2,3,4,5,7,8,9,10,11
; I don`t known how to use IRQ_RESERVE
if IRQ_RESERVE > 16
irqh 16, 17, 18, 19, 20, 21, 22, 23
end if
 
 
p_irq6:
p_irq6: ; FDC
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
246,12 → 269,28
cmp [v86_irqhooks+edi*8], 0
jnz v86_irq2
call fdc_irq
call ready_for_next_irq
mov [check_idle_semaphore], 5
mov al, 6
call IRQ_EOI
restore_ring3_context
iret
 
irq13: ; Math coprocessor
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
mov es, ax
 
p_irq14:
mov dx, 0xf0
mov al, 0
out dx, al
 
mov al, 13
call IRQ_EOI
restore_ring3_context
iret
 
p_irq14: ; HDD
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
261,10 → 300,13
jnz v86_irq2
; mov byte [BOOT_VAR + 0x48E], 0xFF
call [irq14_func]
call ready_for_next_irq_1
mov [check_idle_semaphore], 5
mov al, 14
call IRQ_EOI
restore_ring3_context
iret
p_irq15:
 
p_irq15: ; HDD2
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
274,7 → 316,9
jnz v86_irq2
; mov byte [BOOT_VAR + 0x48E], 0xFF
call [irq15_func]
call ready_for_next_irq_1
mov [check_idle_semaphore], 5
mov al, 15
call IRQ_EOI
restore_ring3_context
iret
 
307,7 → 351,7
iret
 
 
irqh 2,3,4,5,7,8,9,10,11
align 4
 
irqhandler:
 
/kernel/branches/Kolibri-acpi/core/v86.inc
328,7 → 328,7
cmp edx, -1
jz .noirqhook
uglobal
v86_irqhooks rd 16*2
v86_irqhooks rd IRQ_RESERVE * 2
endg
cmp [v86_irqhooks+edx*8], 0
jz @f
898,12 → 898,10
pop ecx
.cont:
loop .scan
mov al, 20h
out 20h, al
cmp edi, 8
jb @f
out 0A0h, al
@@:
mov eax, edi
call IRQ_EOI
 
popad
iretd
.found: