/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 \} } |