Subversion Repositories Kolibri OS

Compare Revisions

Ignore whitespace Rev 2436 → Rev 2437

/kernel/branches/Kolibri-acpi/core/apic.inc
36,84 → 36,92
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
IOAPIC_ID equ 0x0
IOAPIC_VER equ 0x1
IOAPIC_ARB equ 0x2
IOAPIC_REDTBL equ 0x10
 
IPI_INIT equ (0x6 shl 8)
IPI_LEVEL_ASSERT equ (0x1 shl 14)
SHORTHAND_ALL_EXCL equ (0x3 shl 18)
 
CMD_IPI_INIT equ (IPI_INIT+SHORTHAND_ALL_EXCL)
 
 
 
align 4
APIC_init:
mov [irq_mode], IRQ_PIC
mov [irq_mode], IRQ_PIC
 
cmp [acpi_ioapic_base], 0
jz .no_apic
cmp [acpi_ioapic_base], 0
jz .no_apic
 
cmp [acpi_lapic_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
test eax, eax
jz .no_apic
 
mov [acpi_dev_data], eax
mov [acpi_dev_size], ebx
mov [acpi_dev_data], eax
mov [acpi_dev_size], ebx
 
call IRQ_mask_all
call IRQ_mask_all
 
; IOAPIC init
stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW
mov [IOAPIC_base], eax
mov [IOAPIC_base], eax
 
mov eax, IOAPIC_VER
call IOAPIC_read
shr eax, 16
inc al
call IOAPIC_read
shr eax, 16
inc al
movzx eax, al
cmp al, IRQ_RESERVED
jbe @f
cmp al, IRQ_RESERVED
jbe @f
 
mov al, IRQ_RESERVED
mov al, IRQ_RESERVED
@@:
mov [IRQ_COUNT], eax
mov [IRQ_COUNT], eax
 
; Reroute IOAPIC & mask all interrupts
xor ecx, ecx
mov eax, IOAPIC_REDTBL
xor ecx, ecx
mov eax, IOAPIC_REDTBL
@@:
mov ebx, eax
call IOAPIC_read
mov ebx, eax
call IOAPIC_read
mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical
mov al, cl
mov al, cl
add al, 0x20; vector
or eax, 0x10000; Mask Interrupt
cmp ecx, 16
jb .set
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
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
xchg eax, ebx
call IOAPIC_write
inc eax
inc ecx
cmp ecx, [IRQ_COUNT]
jb @b
 
call LAPIC_init
call LAPIC_init
 
mov [irq_mode], IRQ_APIC
mov [irq_mode], IRQ_APIC
 
mov al, 0x70
out 0x22, al
mov al, 1
out 0x23, al
mov al, 0x70
out 0x22, al
mov al, 1
out 0x23, al
 
call pci_irq_fixup
call pci_irq_fixup
.no_apic:
 
ret
124,82 → 132,111
; Check MSR support
;....
; Get LAPIC base address
; mov ecx, 0x1b
; rdmsr ; it may be replaced to
; and ax, 0xf000 ; mov eax, 0xfee00000
;mov ecx, 0x1b
;rdmsr ; it may be replaced to
;and ax, 0xf000 ; mov eax, 0xfee00000
 
mov [acpi_lapic_base], 0xfee00000
; xchg bx, bx
 
stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW
mov [LAPIC_BASE], eax
mov esi, eax
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
mov eax, [esi + APIC_DFR]
or eax, 0xf0000000
mov [esi + APIC_DFR], eax
 
; Program Logical Destination Register.
mov eax, [esi + APIC_LDR]
mov eax, [esi + APIC_LDR]
;and eax, 0xff000000
and eax, 0x00ffffff
and eax, 0x00ffffff
or eax, 0x01000000;!!!!!!!!!!!!
mov [esi + APIC_LDR], eax
mov [esi + APIC_LDR], eax
 
; Task Priority Register initialization.
mov eax, [esi + APIC_TPR]
and eax, 0xffffff00
mov [esi + APIC_TPR], eax
mov eax, [esi + APIC_TPR]
and eax, 0xffffff00
mov [esi + APIC_TPR], eax
 
; Flush the queue
mov edx, 0
mov edx, 0
.nxt2:
mov ecx, 32
mov eax, [esi + APIC_ISR + edx]
mov ecx, 32
mov eax, [esi + APIC_ISR + edx]
.nxt:
shr eax, 1
jnc @f
shr eax, 1
jnc @f
mov dword [esi + APIC_EOI], 0; EOI
@@:
loop .nxt
loop .nxt
 
add edx, 0x10
cmp edx, 0x170
jbe .nxt2
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
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, 0x00700
; mov eax, 0x10700
mov [esi + APIC_LVT_LINT0], eax
mov [esi + APIC_LVT_LINT0], eax
 
; Initialize LVT LINT1 register. (NMI)
mov eax, 0x00400
mov [esi + APIC_LVT_LINT1], eax
mov eax, 0x00400
mov [esi + APIC_LVT_LINT1], eax
 
; Initialize LVT Error register.
mov eax, [esi + APIC_LVT_err]
mov eax, [esi + APIC_LVT_err]
or eax, 0x10000; bit 16
mov [esi + APIC_LVT_err], eax
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
; 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
; mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
; mov dword[esi + APIC_timer_init], eax
xchg bx, bx
 
; mov al, 0x0F
; out 0x70, al
; mov al, 0x0A
; out 0x71, al
 
; mov [OS_BASE+0x469], word (__ap_start_16) shr 4
; mov [OS_BASE+0x469], word 0
 
mov [esi+APIC_ICRH], dword 0
mov [esi+APIC_ICRL], dword 0xc4500
 
mov ecx, 1000
@@:
loop @B
 
mov [esi+APIC_ICRH], dword 0
mov [esi+APIC_ICRL], dword 0xC4600+((0x10000+__ap_start_16) shr 12)
; mov [esi+APIC_ICRL], dword 0xC4612
 
; mov [esi+APIC_ICRH], dword 0
; mov [esi+APIC_ICRL], dword CMD_IPI_INIT+IPI_LEVEL_ASSERT+16
 
 
 
ret
 
;===========================================================
/kernel/branches/Kolibri-acpi/kernel.asm
161,6 → 161,8
 
; CR0 Flags - Protected mode and Paging
 
align 16
 
mov ecx, CR0_PE
 
; Enabling 32 bit protected mode
198,6 → 200,20
mov cr0, eax
jmp pword os_code:B32 ; jmp to enable 32 bit mode
 
include "boot/shutdown.inc" ; shutdown or restart
 
include "data16.inc"
 
align 4096
__ap_start_16:
cli
lgdt [cs:(tmp_gdt-__ap_start_16)] ; Load GDT
mov eax, cr0 ; protected mode
or eax, CR0_PE
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled
mov cr0, eax
jmp pword os_code:__ap_start_32 ; jmp to enable 32 bit mode
 
align 8
tmp_gdt:
 
217,11 → 233,37
dw 11011111b *256 +10010010b
db 0x00
 
include "data16.inc"
 
use32
org $+0x10000
 
align 16
__ap_start_32:
mov ax, os_stack ; Selector for os
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
 
bt [cpu_caps-OS_BASE], CAPS_PSE
jnc .no_PSE
 
mov ebx, cr4
or ebx, CR4_PSE
mov eax, PG_LARGE+PG_SW
mov cr4, ebx
.no_PSE:
mov eax, sys_pgdir-OS_BASE
mov cr3, eax
 
mov eax, cr0
or eax, CR0_PG+CR0_WP
mov cr0, eax
 
lgdt [gdts]
jmp pword os_code:ap_entry
 
align 4
B32:
mov ax, os_stack ; Selector for os
269,6 → 311,8
 
; ENABLE PAGING
 
xchg bx, bx
 
mov eax, sys_pgdir-OS_BASE
mov cr3, eax
 
283,11 → 327,6
bios32_entry dd ?
tmp_page_tabs dd ?
 
use16
org $-0x10000
include "boot/shutdown.inc" ; shutdown or restart
org $+0x10000
use32
 
__DEBUG__ fix 1
__DEBUG_LEVEL__ fix 1
295,6 → 334,31
 
org OS_BASE+$
 
ap_entry:
bt [cpu_caps], CAPS_PGE
jnc @F
 
mov ebx, cr4
or ebx, CR4_PGE
mov cr4, ebx
@@:
.1:
mov ebx, LFB_BASE
mov edx, 128
.2:
mov ecx, 128
mov edi, ebx
mov eax, [_display.width]
lea ebx, [ebx+eax*4]
mov eax, 0xFF808080
rep stosd
dec edx
jnz .2
jmp .1
 
hlt
jmp ap_entry
 
align 4
high_code:
mov ax, os_stack
317,12 → 381,12
or ebx, CR4_PGE
mov cr4, ebx
@@:
xor eax, eax
mov dword [sys_pgdir], eax
mov dword [sys_pgdir+4], eax
; xor eax, eax
; mov dword [sys_pgdir], eax
; mov dword [sys_pgdir+4], eax
 
mov eax, cr3
mov cr3, eax ; flush TLB
; mov eax, cr3
; mov cr3, eax ; flush TLB
 
mov ecx, pg_data.mutex
call mutex_init
619,6 → 683,8
; Try to Initialize APIC
call APIC_init
 
call LAPIC_init
 
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15)
; they are used: when partitions are scanned, hd_read relies on timer
call unmask_timer
/kernel/branches/Kolibri-acpi/struct.inc
0,0 → 1,240
 
; Macroinstructions for defining data structures
 
macro struct name
{ virtual at 0
fields@struct equ name
match child parent, name \{ fields@struct equ child,fields@\#parent \}
sub@struct equ
struc db [val] \{ \common define field@struct .,db,<val>
fields@struct equ fields@struct,field@struct \}
struc dw [val] \{ \common define field@struct .,dw,<val>
fields@struct equ fields@struct,field@struct \}
struc du [val] \{ \common define field@struct .,du,<val>
fields@struct equ fields@struct,field@struct \}
struc dd [val] \{ \common define field@struct .,dd,<val>
fields@struct equ fields@struct,field@struct \}
struc dp [val] \{ \common define field@struct .,dp,<val>
fields@struct equ fields@struct,field@struct \}
struc dq [val] \{ \common define field@struct .,dq,<val>
fields@struct equ fields@struct,field@struct \}
struc dt [val] \{ \common define field@struct .,dt,<val>
fields@struct equ fields@struct,field@struct \}
struc rb count \{ define field@struct .,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rw count \{ define field@struct .,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rd count \{ define field@struct .,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rp count \{ define field@struct .,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rq count \{ define field@struct .,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
struc rt count \{ define field@struct .,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro db [val] \{ \common \local anonymous
define field@struct anonymous,db,<val>
fields@struct equ fields@struct,field@struct \}
macro dw [val] \{ \common \local anonymous
define field@struct anonymous,dw,<val>
fields@struct equ fields@struct,field@struct \}
macro du [val] \{ \common \local anonymous
define field@struct anonymous,du,<val>
fields@struct equ fields@struct,field@struct \}
macro dd [val] \{ \common \local anonymous
define field@struct anonymous,dd,<val>
fields@struct equ fields@struct,field@struct \}
macro dp [val] \{ \common \local anonymous
define field@struct anonymous,dp,<val>
fields@struct equ fields@struct,field@struct \}
macro dq [val] \{ \common \local anonymous
define field@struct anonymous,dq,<val>
fields@struct equ fields@struct,field@struct \}
macro dt [val] \{ \common \local anonymous
define field@struct anonymous,dt,<val>
fields@struct equ fields@struct,field@struct \}
macro rb count \{ \local anonymous
define field@struct anonymous,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rw count \{ \local anonymous
define field@struct anonymous,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rd count \{ \local anonymous
define field@struct anonymous,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rp count \{ \local anonymous
define field@struct anonymous,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rq count \{ \local anonymous
define field@struct anonymous,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rt count \{ \local anonymous
define field@struct anonymous,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro union \{ fields@struct equ fields@struct,,union,<
sub@struct equ union \}
macro struct \{ fields@struct equ fields@struct,,substruct,<
sub@struct equ substruct \} }
 
macro ends
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
restruc rb,rw,rd,rp,rq,rt
purge db,dw,du,dd,dp,dq,dt
purge rb,rw,rd,rp,rq,rt
purge union,struct
match name tail,fields@struct, \\{ if $
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
err
end if \\}
match name=,fields,fields@struct \\{ fields@struct equ
make@struct name,fields
define fields@\\#name fields \\}
end virtual \}
match any, sub@struct \{ fields@struct equ fields@struct> \}
restore sub@struct }
 
macro make@struct name,[field,type,def]
{ common
local define
define equ name
forward
local sub
match , field \{ make@substruct type,name,sub def
define equ define,.,sub, \}
match any, field \{ define equ define,.#field,type,<def> \}
common
match fields, define \{ define@struct fields \} }
 
macro define@struct name,[field,type,def]
{ common
virtual
db `name
load initial@struct byte from 0
if initial@struct = '.'
display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
err
end if
end virtual
local list
list equ
forward
if ~ field eq .
name#field type def
sizeof.#name#field = $ - name#field
else
label name#.#type
rb sizeof.#type
end if
local value
match any, list \{ list equ list, \}
list equ list <value>
common
sizeof.#name = $
restruc name
match values, list \{
struc name value \\{ \\local \\..base
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\}
match , fields@struct \\\{ label \\..base
forward
match , value \\\\{ field type def \\\\}
match any, value \\\\{ field type value
if ~ field eq .
rb sizeof.#name#field - ($-field)
end if \\\\}
common label . at \\..base \\\}
\\}
macro name value \\{
match any, fields@struct \\\{ \\\local anonymous
fields@struct equ fields@struct,anonymous,name,<values> \\\}
match , fields@struct \\\{
forward
match , value \\\\{ type def \\\\}
match any, value \\\\{ \\\\local ..field
..field = $
type value
if ~ field eq .
rb sizeof.#name#field - ($-..field)
end if \\\\}
common \\\} \\} \} }
 
macro enable@substruct
{ macro make@substruct substruct,parent,name,[field,type,def]
\{ \common
\local define
define equ parent,name
\forward
\local sub
match , field \\{ match any, type \\\{ enable@substruct
make@substruct type,parent,sub def
purge make@substruct
define equ define,.,sub, \\\} \\}
match any, field \\{ define equ define,.\#field,type,<def> \\}
\common
match fields, define \\{ define@\#substruct fields \\} \} }
 
enable@substruct
 
macro define@union parent,name,[field,type,def]
{ common
virtual at parent#.#name
forward
if ~ field eq .
virtual at parent#.#name
parent#field type def
sizeof.#parent#field = $ - parent#field
end virtual
if sizeof.#parent#field > $ - parent#.#name
rb sizeof.#parent#field - ($ - parent#.#name)
end if
else
virtual at parent#.#name
label parent#.#type
type def
end virtual
label name#.#type at parent#.#name
if sizeof.#type > $ - parent#.#name
rb sizeof.#type - ($ - parent#.#name)
end if
end if
common
sizeof.#name = $ - parent#.#name
end virtual
struc name [value] \{ \common
label .\#name
last@union equ
forward
match any, last@union \\{ virtual at .\#name
field type def
end virtual \\}
match , last@union \\{ match , value \\\{ field type def \\\}
match any, value \\\{ field type value \\\} \\}
last@union equ field
common rb sizeof.#name - ($ - .\#name) \}
macro name [value] \{ \common \local ..anonymous
..anonymous name value \} }
 
macro define@substruct parent,name,[field,type,def]
{ common
virtual at parent#.#name
forward
if ~ field eq .
parent#field type def
sizeof.#parent#field = $ - parent#field
else
label parent#.#type
rb sizeof.#type
end if
common
sizeof.#name = $ - parent#.#name
end virtual
struc name value \{
label .\#name
forward
match , value \\{ field type def \\}
match any, value \\{ field type value
if ~ field eq .
rb sizeof.#parent#field - ($-field)
end if \\}
common \}
macro name value \{ \local ..anonymous
..anonymous name \} }