Can we start AP, please ?

git-svn-id: svn://kolibrios.org@2437 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2012-03-08 15:49:27 +00:00
parent aede9dbee9
commit 1fca7a07cb
3 changed files with 445 additions and 102 deletions

View File

@ -36,84 +36,92 @@ APIC_timer_div equ 0x3e0
APIC_timer_init equ 0x380 APIC_timer_init equ 0x380
APIC_timer_cur equ 0x390 APIC_timer_cur equ 0x390
; IOAPIC ; IOAPIC
IOAPIC_ID equ 0x0 IOAPIC_ID equ 0x0
IOAPIC_VER equ 0x1 IOAPIC_VER equ 0x1
IOAPIC_ARB equ 0x2 IOAPIC_ARB equ 0x2
IOAPIC_REDTBL equ 0x10 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 align 4
APIC_init: APIC_init:
mov [irq_mode], IRQ_PIC mov [irq_mode], IRQ_PIC
cmp [acpi_ioapic_base], 0 cmp [acpi_ioapic_base], 0
jz .no_apic jz .no_apic
cmp [acpi_lapic_base], 0 cmp [acpi_lapic_base], 0
jz .no_apic jz .no_apic
stdcall load_file, dev_data_path stdcall load_file, dev_data_path
test eax, eax test eax, eax
jz .no_apic jz .no_apic
mov [acpi_dev_data], eax mov [acpi_dev_data], eax
mov [acpi_dev_size], ebx mov [acpi_dev_size], ebx
call IRQ_mask_all call IRQ_mask_all
; IOAPIC init ; IOAPIC init
stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW
mov [IOAPIC_base], eax mov [IOAPIC_base], eax
mov eax, IOAPIC_VER mov eax, IOAPIC_VER
call IOAPIC_read call IOAPIC_read
shr eax, 16 shr eax, 16
inc al inc al
movzx eax, al movzx eax, al
cmp al, IRQ_RESERVED cmp al, IRQ_RESERVED
jbe @f jbe @f
mov al, IRQ_RESERVED mov al, IRQ_RESERVED
@@: @@:
mov [IRQ_COUNT], eax mov [IRQ_COUNT], eax
; Reroute IOAPIC & mask all interrupts ; Reroute IOAPIC & mask all interrupts
xor ecx, ecx xor ecx, ecx
mov eax, IOAPIC_REDTBL mov eax, IOAPIC_REDTBL
@@: @@:
mov ebx, eax mov ebx, eax
call IOAPIC_read call IOAPIC_read
mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical
mov al, cl mov al, cl
add al, 0x20; vector add al, 0x20; vector
or eax, 0x10000; Mask Interrupt or eax, 0x10000; Mask Interrupt
cmp ecx, 16 cmp ecx, 16
jb .set jb .set
or eax, 0xa000;<<< level-triggered active-low for IRQ16+ or eax, 0xa000;<<< level-triggered active-low for IRQ16+
.set: .set:
xchg eax, ebx xchg eax, ebx
call IOAPIC_write call IOAPIC_write
inc eax inc eax
mov ebx, eax mov ebx, eax
call IOAPIC_read call IOAPIC_read
or eax, 0xff000000; Destination Field or eax, 0xff000000; Destination Field
xchg eax, ebx xchg eax, ebx
call IOAPIC_write call IOAPIC_write
inc eax inc eax
inc ecx inc ecx
cmp ecx, [IRQ_COUNT] cmp ecx, [IRQ_COUNT]
jb @b jb @b
call LAPIC_init call LAPIC_init
mov [irq_mode], IRQ_APIC mov [irq_mode], IRQ_APIC
mov al, 0x70 mov al, 0x70
out 0x22, al out 0x22, al
mov al, 1 mov al, 1
out 0x23, al out 0x23, al
call pci_irq_fixup call pci_irq_fixup
.no_apic: .no_apic:
ret ret
@ -124,82 +132,111 @@ LAPIC_init:
; Check MSR support ; Check MSR support
;.... ;....
; Get LAPIC base address ; Get LAPIC base address
; mov ecx, 0x1b ;mov ecx, 0x1b
; rdmsr ; it may be replaced to ;rdmsr ; it may be replaced to
; and ax, 0xf000 ; mov eax, 0xfee00000 ;and ax, 0xf000 ; mov eax, 0xfee00000
mov [acpi_lapic_base], 0xfee00000
; xchg bx, bx
stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW
mov [LAPIC_BASE], eax mov [LAPIC_BASE], eax
mov esi, eax mov esi, eax
; Program Destination Format Register for Flat mode. ; Program Destination Format Register for Flat mode.
mov eax, [esi + APIC_DFR] mov eax, [esi + APIC_DFR]
or eax, 0xf0000000 or eax, 0xf0000000
mov [esi + APIC_DFR], eax mov [esi + APIC_DFR], eax
; Program Logical Destination Register. ; Program Logical Destination Register.
mov eax, [esi + APIC_LDR] mov eax, [esi + APIC_LDR]
;and eax, 0xff000000 ;and eax, 0xff000000
and eax, 0x00ffffff and eax, 0x00ffffff
or eax, 0x01000000;!!!!!!!!!!!! or eax, 0x01000000;!!!!!!!!!!!!
mov [esi + APIC_LDR], eax mov [esi + APIC_LDR], eax
; Task Priority Register initialization. ; Task Priority Register initialization.
mov eax, [esi + APIC_TPR] mov eax, [esi + APIC_TPR]
and eax, 0xffffff00 and eax, 0xffffff00
mov [esi + APIC_TPR], eax mov [esi + APIC_TPR], eax
; Flush the queue ; Flush the queue
mov edx, 0 mov edx, 0
.nxt2: .nxt2:
mov ecx, 32 mov ecx, 32
mov eax, [esi + APIC_ISR + edx] mov eax, [esi + APIC_ISR + edx]
.nxt: .nxt:
shr eax, 1 shr eax, 1
jnc @f jnc @f
mov dword [esi + APIC_EOI], 0; EOI mov dword [esi + APIC_EOI], 0; EOI
@@: @@:
loop .nxt loop .nxt
add edx, 0x10 add edx, 0x10
cmp edx, 0x170 cmp edx, 0x170
jbe .nxt2 jbe .nxt2
; Spurious-Interrupt Vector Register initialization. ; Spurious-Interrupt Vector Register initialization.
mov eax, [esi + APIC_SVR] mov eax, [esi + APIC_SVR]
or eax, 0x1ff or eax, 0x1ff
and eax, 0xfffffdff and eax, 0xfffffdff
mov [esi + APIC_SVR], eax mov [esi + APIC_SVR], eax
; Initialize LVT LINT0 register. (INTR) ; Initialize LVT LINT0 register. (INTR)
mov eax, 0x00700 mov eax, 0x00700
; mov eax, 0x10700 ; mov eax, 0x10700
mov [esi + APIC_LVT_LINT0], eax mov [esi + APIC_LVT_LINT0], eax
; Initialize LVT LINT1 register. (NMI) ; Initialize LVT LINT1 register. (NMI)
mov eax, 0x00400 mov eax, 0x00400
mov [esi + APIC_LVT_LINT1], eax mov [esi + APIC_LVT_LINT1], eax
; Initialize LVT Error register. ; Initialize LVT Error register.
mov eax, [esi + APIC_LVT_err] mov eax, [esi + APIC_LVT_err]
or eax, 0x10000; bit 16 or eax, 0x10000; bit 16
mov [esi + APIC_LVT_err], eax mov [esi + APIC_LVT_err], eax
; LAPIC timer ; LAPIC timer
; pre init ; pre init
mov dword[esi + APIC_timer_div], 1011b; 1 ; mov dword[esi + APIC_timer_div], 1011b; 1
mov dword[esi + APIC_timer_init], 0xffffffff; max val ; mov dword[esi + APIC_timer_init], 0xffffffff; max val
push esi ; push esi
mov esi, 640 ; wait 0.64 sec ; mov esi, 640 ; wait 0.64 sec
call delay_ms ; call delay_ms
pop esi ; pop esi
mov eax, [esi + APIC_timer_cur]; read current tick couner ; mov eax, [esi + APIC_timer_cur]; read current tick couner
xor eax, 0xffffffff ; eax = 0xffffffff - eax ; xor eax, 0xffffffff ; eax = 0xffffffff - eax
shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec ; shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec
; Start (every 0.01 sec) ; Start (every 0.01 sec)
mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20 ; mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
mov dword[esi + APIC_timer_init], eax ; 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 ret
;=========================================================== ;===========================================================

View File

@ -161,6 +161,8 @@ include "detect/biosdisk.inc"
; CR0 Flags - Protected mode and Paging ; CR0 Flags - Protected mode and Paging
align 16
mov ecx, CR0_PE mov ecx, CR0_PE
; Enabling 32 bit protected mode ; Enabling 32 bit protected mode
@ -198,6 +200,20 @@ include "detect/biosdisk.inc"
mov cr0, eax mov cr0, eax
jmp pword os_code:B32 ; jmp to enable 32 bit mode 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 align 8
tmp_gdt: tmp_gdt:
@ -217,11 +233,37 @@ tmp_gdt:
dw 11011111b *256 +10010010b dw 11011111b *256 +10010010b
db 0x00 db 0x00
include "data16.inc"
use32 use32
org $+0x10000 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 align 4
B32: B32:
mov ax, os_stack ; Selector for os mov ax, os_stack ; Selector for os
@ -269,6 +311,8 @@ B32:
; ENABLE PAGING ; ENABLE PAGING
xchg bx, bx
mov eax, sys_pgdir-OS_BASE mov eax, sys_pgdir-OS_BASE
mov cr3, eax mov cr3, eax
@ -283,11 +327,6 @@ align 4
bios32_entry dd ? bios32_entry dd ?
tmp_page_tabs dd ? tmp_page_tabs dd ?
use16
org $-0x10000
include "boot/shutdown.inc" ; shutdown or restart
org $+0x10000
use32
__DEBUG__ fix 1 __DEBUG__ fix 1
__DEBUG_LEVEL__ fix 1 __DEBUG_LEVEL__ fix 1
@ -295,6 +334,31 @@ include 'init.inc'
org OS_BASE+$ 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 align 4
high_code: high_code:
mov ax, os_stack mov ax, os_stack
@ -317,12 +381,12 @@ high_code:
or ebx, CR4_PGE or ebx, CR4_PGE
mov cr4, ebx mov cr4, ebx
@@: @@:
xor eax, eax ; xor eax, eax
mov dword [sys_pgdir], eax ; mov dword [sys_pgdir], eax
mov dword [sys_pgdir+4], eax ; mov dword [sys_pgdir+4], eax
mov eax, cr3 ; mov eax, cr3
mov cr3, eax ; flush TLB ; mov cr3, eax ; flush TLB
mov ecx, pg_data.mutex mov ecx, pg_data.mutex
call mutex_init call mutex_init
@ -619,6 +683,8 @@ no_mode_0x12:
; Try to Initialize APIC ; Try to Initialize APIC
call APIC_init call APIC_init
call LAPIC_init
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15) ; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15)
; they are used: when partitions are scanned, hd_read relies on timer ; they are used: when partitions are scanned, hd_read relies on timer
call unmask_timer call unmask_timer

View File

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