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

@ -41,6 +41,14 @@ 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
@ -124,9 +132,12 @@ LAPIC_init:
; 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
@ -187,19 +198,45 @@ LAPIC_init:
; 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
;===========================================================

View File

@ -161,6 +161,8 @@ include "detect/biosdisk.inc"
; CR0 Flags - Protected mode and Paging
align 16
mov ecx, CR0_PE
; Enabling 32 bit protected mode
@ -198,6 +200,20 @@ include "detect/biosdisk.inc"
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 @@ tmp_gdt:
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 @@ B32:
; ENABLE PAGING
xchg bx, bx
mov eax, sys_pgdir-OS_BASE
mov cr3, eax
@ -283,11 +327,6 @@ align 4
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 @@ include 'init.inc'
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 @@ high_code:
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 @@ no_mode_0x12:
; 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

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