;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; include "../macros.inc" include "../proc32.inc" include "../const.inc" $Revision: 847 $ sel_tss equ 0x08 sel_os_code equ 0x10 sel_os_stack equ 0x18 sel_app_code equ 0x23 sel_app_data equ 0x2B sel_srv_code equ 0x31 sel_srv_stack equ 0x39 sel_code_16 equ 0x70 format MS COFF use32 public __os_stack public _pg_balloc public high_code public core_init public test_cpu public cpu_vendor public cpu_sign public cpu_info public cpu_caps extrn _parse_mbi extrn _16bit_start extrn _16bit_end extrn _enter_bootscreen extrn init_fpu extrn init_idt extrn _init_mm extrn _slab_cache_init extrn @init_heap@8 extrn init_malloc extrn _init_core_dll extrn _init_threads extrn init_mtrr extrn system_init extrn sysenter_entry extrn syscall_entry extrn @create_systhread@4 extrn _sys_pdbr extrn _current_thread extrn _k_reenter:dword extrn scr_mode:dword extrn LFBAddress:dword extrn LFBSize:dword section '.text' code readable align 16 high_code: mov ax, sel_os_stack mov dx, sel_app_data mov ss, ax mov esp, __os_stack mov ds, dx mov es, dx mov fs, dx mov gs, dx ; bt [cpu_caps], CAPS_PGE ; jnc @F ; or dword [sys_pgdir-OS_BASE+(OS_BASE shr 20)], PG_GLOBAL ; mov ebx, cr4 ; or ebx, CR4_PGE ; mov cr4, ebx @@: ; mov eax, cr3 ; mov cr3, eax ; flush TLB mov edx, 0x3fB mov eax, 3 out dx, al call test_cpu call _parse_mbi ; mov eax, [_pg_balloc] ; mov [_copy_pg_balloc], eax __core_restart: mov esi, _16bit_start mov ecx, _16bit_end shr ecx, 2 mov edi, _16BIT_BASE cld rep movsd jmp far sel_code_16:_enter_bootscreen; align 16 core_init: cld mov ax, sel_os_stack mov dx, sel_app_data mov ss, ax mov esp, __os_stack mov ds, dx mov es, dx mov fs, dx mov gs, dx mov [tss._ss0], sel_os_stack mov [tss._esp0], __os_stack mov [tss._esp], __os_stack mov [tss._cs], sel_os_code mov [tss._ss], sel_os_stack mov [tss._ds], sel_app_data mov [tss._es], sel_app_data mov [tss._fs], sel_app_data mov [tss._gs], sel_app_data mov [tss._io], 128 ;Add IO access table - bit array of permitted ports mov edi, tss._io_map_0 xor eax, eax ; not eax mov ecx, 8192/4 rep stosd ; access to 4096*8=65536 ports mov ax, sel_tss ltr ax ; -------- Fast System Call init ---------- ; Intel SYSENTER/SYSEXIT (AMD CPU support it too) bt [cpu_caps], CAPS_SEP jnc .SEnP ; SysEnter not Present xor edx, edx mov ecx, MSR_SYSENTER_CS mov eax, sel_os_code wrmsr mov ecx, MSR_SYSENTER_ESP ; mov eax, sysenter_stack ; Check it xor eax, eax wrmsr mov ecx, MSR_SYSENTER_EIP mov eax, sysenter_entry wrmsr .SEnP: ; AMD SYSCALL/SYSRET cmp byte[cpu_vendor], 'A' jne .noSYSCALL mov eax, 0x80000001 cpuid test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support jz .noSYSCALL mov ecx, MSR_AMD_EFER rdmsr or eax, 1 ; bit_0 - System Call Extension (SCE) wrmsr ; Bits of EDX : ; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register ; and the contents of this field, plus 8, are copied into the SS register. ; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register ; and the contents of this field, plus 8, are copied into the SS register. mov edx, ((sel_os_code + 16) shl 16) + sel_os_code mov eax, syscall_entry mov ecx, MSR_AMD_STAR wrmsr .noSYSCALL: call init_fpu call init_idt call _init_mm call init_malloc call _slab_cache_init mov ecx, 0x80000000 mov edx, 0x40000000 call @init_heap@8 call _init_core_dll ; call _init_threads ; SAVE & CLEAR 0-0xffff mov dword [_sys_pdbr], eax mov dword [_sys_pdbr+4], eax movzx eax,word [BOOT_VAR+0x9008] ; screen mode mov [scr_mode],eax mov eax,[BOOT_VAR+0x9018] call map_LFB mov eax, cr3 mov cr3, eax jmp system_init if 0 mov ecx, system_init call @create_systhread@4 mov [_current_thread], eax mov ebx, [eax+THR.pdir] mov ecx, cr3 cmp ebx, ecx je .skip mov cr3, ebx .skip: mov esp, [_current_thread] ; lea eax, [esp+THR.pl0_stack] ; mov [tss._esp0], eax restart1: dec [_k_reenter] popad add esp, 4 ; skip return adr iretd ; continue process end if align 4 map_LFB: cmp eax, -1 jne @f ret @@: test [scr_mode], 0100000000000000b jnz @f mov [BOOT_VAR+0x901c],byte 2 ret @@: mov [LFBAddress], eax mov [LFBSize], 0x800000 call init_mtrr mov eax, [LFBAddress] or eax, PG_LARGE+PG_UW mov [_sys_pdbr+(LFB_BASE shr 20)], eax add eax, 0x00400000 mov [_sys_pdbr+4+(LFB_BASE shr 20)], eax if SHADOWFB mov ecx, 1 shl 11 call @frame_alloc@4 or eax, PG_LARGE+PG_UW mov [_sys_pdbr+(SHADOWFB shr 20)], eax add eax, 0x00400000 mov [_sys_pdbr+4+(SHADOWFB shr 20)], eax end if bt [cpu_caps], CAPS_PGE jnc @F or dword [_sys_pdbr+(LFB_BASE shr 20)], PG_GLOBAL @@: mov dword [LFBAddress], LFB_BASE ret align 4 proc test_cpu locals cpu_type dd ? cpu_id dd ? cpu_Intel dd ? cpu_AMD dd ? endl mov [cpu_type], 0 xor eax, eax mov [cpu_caps], eax mov [cpu_caps+4], eax xor eax, eax cpuid mov [cpu_vendor], ebx mov [cpu_vendor+4], edx mov [cpu_vendor+8], ecx cmp ebx, dword [intel_str] jne .check_AMD cmp edx, dword [intel_str+4] jne .check_AMD cmp ecx, dword [intel_str+8] jne .check_AMD mov [cpu_Intel], 1 cmp eax, 1 jl .end_cpuid mov eax, 1 cpuid mov [cpu_sign], eax mov [cpu_info], ebx mov [cpu_caps], edx mov [cpu_caps+4],ecx shr eax, 8 and eax, 0x0f ret .end_cpuid: mov eax, [cpu_type] ret .check_AMD: cmp ebx, dword [AMD_str] jne .unknown cmp edx, dword [AMD_str+4] jne .unknown cmp ecx, dword [AMD_str+8] jne .unknown mov [cpu_AMD], 1 cmp eax, 1 jl .unknown mov eax, 1 cpuid mov [cpu_sign], eax mov [cpu_info], ebx mov [cpu_caps], edx mov [cpu_caps+4],ecx shr eax, 8 and eax, 0x0f ret .unknown: mov eax, 1 cpuid mov [cpu_sign], eax mov [cpu_info], ebx mov [cpu_caps], edx mov [cpu_caps+4],ecx shr eax, 8 and eax, 0x0f ret endp intel_str db "GenuineIntel",0 AMD_str db "AuthenticAMD",0 if 0 align 4 init_BIOS32: mov edi, 0xE0000 .pcibios_nxt: cmp dword[edi], '_32_' ; "magic" word je .BIOS32_found .pcibios_nxt2: add edi, 0x10 cmp edi, 0xFFFF0 je .BIOS32_not_found jmp .pcibios_nxt .BIOS32_found: ; magic word found, check control summ movzx ecx, byte[edi + 9] shl ecx, 4 mov esi, edi xor eax, eax cld ; paranoia @@: lodsb add ah, al loop @b jnz .pcibios_nxt2 ; control summ must be zero ; BIOS32 service found ! mov ebp, [edi + 4] mov [bios32_entry], ebp ; check PCI BIOS present mov eax, '$PCI' xor ebx, ebx push cs ; special for 'ret far' from BIOS call ebp test al, al jnz .PCI_BIOS32_not_found ; здесь создаются дискрипторы для PCI BIOS add ebx, OS_BASE dec ecx mov [(pci_code_32-OS_BASE)], cx ;limit 0-15 mov [(pci_data_32-OS_BASE)], cx ;limit 0-15 mov [(pci_code_32-OS_BASE)+2], bx ;base 0-15 mov [(pci_data_32-OS_BASE)+2], bx ;base 0-15 shr ebx, 16 mov [(pci_code_32-OS_BASE)+4], bl ;base 16-23 mov [(pci_data_32-OS_BASE)+4], bl ;base 16-23 shr ecx, 16 and cl, 0x0F mov ch, bh add cx, D32 mov [(pci_code_32-OS_BASE)+6], cx ;lim 16-19 & mov [(pci_data_32-OS_BASE)+6], cx ;base 24-31 mov [(pci_bios_entry-OS_BASE)], edx ; jmp .end .PCI_BIOS32_not_found: ; здесь должна заполнятся pci_emu_dat .BIOS32_not_found: .end: ret end if section '.data' data writeable align 16 _pg_balloc dd LAST_PAGE section '.bss' data writeable align 16 rb 8192-512 __os_stack rb 512 ;CPUID information cpu_vendor rd 3 cpu_sign rd 1 cpu_info rd 1 cpu_caps rd 4