From 1fca7a07cbad915701ecc71856d7974169981664 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Thu, 8 Mar 2012 15:49:27 +0000 Subject: [PATCH] Can we start AP, please ? git-svn-id: svn://kolibrios.org@2437 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/Kolibri-acpi/core/apic.inc | 219 +++++++++++-------- kernel/branches/Kolibri-acpi/kernel.asm | 88 +++++++- kernel/branches/Kolibri-acpi/struct.inc | 240 +++++++++++++++++++++ 3 files changed, 445 insertions(+), 102 deletions(-) create mode 100644 kernel/branches/Kolibri-acpi/struct.inc diff --git a/kernel/branches/Kolibri-acpi/core/apic.inc b/kernel/branches/Kolibri-acpi/core/apic.inc index 261a3550f4..5be484b923 100644 --- a/kernel/branches/Kolibri-acpi/core/apic.inc +++ b/kernel/branches/Kolibri-acpi/core/apic.inc @@ -36,84 +36,92 @@ 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 +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 @@ 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 - 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 ;=========================================================== diff --git a/kernel/branches/Kolibri-acpi/kernel.asm b/kernel/branches/Kolibri-acpi/kernel.asm index 81e12b98f8..9eb2c8750d 100644 --- a/kernel/branches/Kolibri-acpi/kernel.asm +++ b/kernel/branches/Kolibri-acpi/kernel.asm @@ -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 diff --git a/kernel/branches/Kolibri-acpi/struct.inc b/kernel/branches/Kolibri-acpi/struct.inc new file mode 100644 index 0000000000..37f0b65b72 --- /dev/null +++ b/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, + fields@struct equ fields@struct,field@struct \} + struc dw [val] \{ \common define field@struct .,dw, + fields@struct equ fields@struct,field@struct \} + struc du [val] \{ \common define field@struct .,du, + fields@struct equ fields@struct,field@struct \} + struc dd [val] \{ \common define field@struct .,dd, + fields@struct equ fields@struct,field@struct \} + struc dp [val] \{ \common define field@struct .,dp, + fields@struct equ fields@struct,field@struct \} + struc dq [val] \{ \common define field@struct .,dq, + fields@struct equ fields@struct,field@struct \} + struc dt [val] \{ \common define field@struct .,dt, + 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, + fields@struct equ fields@struct,field@struct \} + macro dw [val] \{ \common \local anonymous + define field@struct anonymous,dw, + fields@struct equ fields@struct,field@struct \} + macro du [val] \{ \common \local anonymous + define field@struct anonymous,du, + fields@struct equ fields@struct,field@struct \} + macro dd [val] \{ \common \local anonymous + define field@struct anonymous,dd, + fields@struct equ fields@struct,field@struct \} + macro dp [val] \{ \common \local anonymous + define field@struct anonymous,dp, + fields@struct equ fields@struct,field@struct \} + macro dq [val] \{ \common \local anonymous + define field@struct anonymous,dq, + fields@struct equ fields@struct,field@struct \} + macro dt [val] \{ \common \local anonymous + define field@struct anonymous,dt, + 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, \} + 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 + common + sizeof.#name = $ + restruc name + match values, list \{ + struc name value \\{ \\local \\..base + match any, fields@struct \\\{ fields@struct equ fields@struct,.,name, \\\} + 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, \\\} + 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, \\} + \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 \} }