Subversion Repositories Kolibri OS

Rev

Rev 4593 | Rev 5356 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 5130 $
  9.  
  10.  
  11. MEM_WB     equ 6               ;write-back memory
  12. MEM_WC     equ 1               ;write combined memory
  13. MEM_UC     equ 0               ;uncached memory
  14.  
  15. align 4
  16. proc mem_test
  17. ; if we have BIOS with fn E820, skip the test
  18.         cmp     dword [BOOT_VARS-OS_BASE + 0x9100], 0
  19.         jnz     .ret
  20.  
  21.         mov     eax, cr0
  22.         and     eax, not (CR0_CD+CR0_NW)
  23.         or      eax, CR0_CD       ;disable caching
  24.         mov     cr0, eax
  25.         wbinvd                    ;invalidate cache
  26.  
  27.         xor     edi, edi
  28.         mov     ebx, 'TEST'
  29. @@:
  30.         add     edi, 0x100000
  31.         xchg    ebx, dword [edi]
  32.         cmp     dword [edi], 'TEST'
  33.         xchg    ebx, dword [edi]
  34.         je      @b
  35.  
  36.         and     eax, not (CR0_CD+CR0_NW) ;enable caching
  37.         mov     cr0, eax
  38.         inc     dword [BOOT_VARS-OS_BASE + 0x9100]
  39.         xor     eax, eax
  40.         mov     [BOOT_VARS-OS_BASE + 0x9104], eax
  41.         mov     [BOOT_VARS-OS_BASE + 0x9108], eax
  42.         mov     [BOOT_VARS-OS_BASE + 0x910C], edi
  43.         mov     [BOOT_VARS-OS_BASE + 0x9110], eax
  44.         inc     eax
  45.         mov     [BOOT_VARS-OS_BASE + 0x9114], eax
  46. .ret:
  47.         ret
  48. endp
  49.  
  50. align 4
  51. proc init_mem
  52. ; calculate maximum allocatable address and number of allocatable pages
  53.         mov     edi, BOOT_VARS-OS_BASE + 0x9104
  54.         mov     ecx, [edi-4]
  55.         xor     esi, esi; esi will hold total amount of memory
  56.         xor     edx, edx; edx will hold maximum allocatable address
  57. .calcmax:
  58. ; round all to pages
  59.         mov     eax, [edi]
  60.         cmp     [edi+16], byte 1
  61.         jne     .unusable
  62.  
  63.         test    eax, 0xFFF
  64.         jz      @f
  65.         neg     eax
  66.         and     eax, 0xFFF
  67.         add     [edi], eax
  68.         adc     dword [edi+4], 0
  69.         sub     [edi+8], eax
  70.         sbb     dword [edi+12], 0
  71.         jc      .unusable
  72. @@:
  73.         and     dword [edi+8], not 0xFFF
  74.         jz      .unusable
  75. ; ignore memory after 4 Gb
  76.         cmp     dword [edi+4], 0
  77.         jnz     .unusable
  78.         mov     eax, [edi]
  79.         cmp     dword [edi+12], 0
  80.         jnz     .overflow
  81.         add     eax, [edi+8]
  82.         jnc     @f
  83. .overflow:
  84.         mov     eax, 0xFFFFF000
  85. @@:
  86.         cmp     edx, eax
  87.         jae     @f
  88.         mov     edx, eax
  89. @@:
  90.         sub     eax, [edi]
  91.         mov     [edi+8], eax
  92.         add     esi, eax
  93.         jmp     .usable
  94. .unusable:
  95. ;        and     dword [edi+8], 0
  96. .usable:
  97.         add     edi, 20
  98.         loop    .calcmax
  99. .calculated:
  100.         mov     [MEM_AMOUNT-OS_BASE], esi
  101.         mov     [pg_data.mem_amount-OS_BASE], esi
  102.         shr     esi, 12
  103.         mov     [pg_data.pages_count-OS_BASE], esi
  104.  
  105.         shr     edx, 12
  106.         add     edx, 31
  107.         and     edx, not 31
  108.         shr     edx, 3
  109.         mov     [pg_data.pagemap_size-OS_BASE], edx
  110.  
  111.         add     edx, (sys_pgmap-OS_BASE)+4095
  112.         and     edx, not 4095
  113.         mov     [tmp_page_tabs], edx
  114.  
  115.         mov     edx, esi
  116.         and     edx, -1024
  117.         cmp     edx, (OS_BASE/4096)
  118.         jbe     @F
  119.         mov     edx, (OS_BASE/4096)
  120.         jmp     .set
  121. @@:
  122.         cmp     edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
  123.         jae     .set
  124.         mov     edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
  125. .set:
  126.         mov     [pg_data.kernel_pages-OS_BASE], edx
  127.         shr     edx, 10
  128.         mov     [pg_data.kernel_tables-OS_BASE], edx
  129.  
  130.         xor     eax, eax
  131.         mov     edi, sys_proc-OS_BASE
  132.         mov     ecx, 8192/4
  133.         cld
  134.         rep stosd
  135.  
  136.         mov     edx, (sys_proc-OS_BASE+PROC.pdt_0)+ 0x800; (OS_BASE shr 20)
  137.         bt      [cpu_caps-OS_BASE], CAPS_PSE
  138.         jnc     .no_PSE
  139.  
  140.         mov     ebx, cr4
  141.         or      ebx, CR4_PSE
  142.         mov     eax, PG_LARGE+PG_SW
  143.         mov     cr4, ebx
  144.         dec     [pg_data.kernel_tables-OS_BASE]
  145.  
  146.         mov     [edx], eax
  147.         add     edx, 4
  148.  
  149.         mov     edi, [tmp_page_tabs]
  150.         jmp     .map_kernel_heap        ; new kernel fits to the first 4Mb - nothing to do with ".map_low"
  151. .no_PSE:
  152.         mov     eax, PG_SW
  153.         mov     ecx, [tmp_page_tabs]
  154.         shr     ecx, 12
  155. .map_low:
  156.         mov     edi, [tmp_page_tabs]
  157. @@:                                   ;
  158.         stosd
  159.         add     eax, 0x1000
  160.         dec     ecx
  161.         jnz     @B
  162.  
  163. .map_kernel_heap:
  164.         mov     ecx, [pg_data.kernel_tables-OS_BASE]
  165.         shl     ecx, 10
  166.         xor     eax, eax
  167.         rep stosd
  168.  
  169.         mov     ecx, [pg_data.kernel_tables-OS_BASE]
  170.         mov     eax, [tmp_page_tabs]
  171.         or      eax, PG_SW
  172.         mov     edi, edx
  173.  
  174. .map_kernel_tabs:
  175.         stosd
  176.         add     eax, 0x1000
  177.         dec     ecx
  178.         jnz     .map_kernel_tabs
  179.  
  180.         mov     dword [sys_proc-OS_BASE+PROC.pdt_0+(page_tabs shr 20)], sys_proc+PROC.pdt_0+PG_SW-OS_BASE
  181.  
  182.         mov     edi, (sys_proc+PROC.pdt_0-OS_BASE)
  183.         lea     esi, [edi+(OS_BASE shr 20)]
  184.         movsd
  185.         movsd
  186.         ret
  187. endp
  188.  
  189. align 4
  190. proc init_page_map
  191. ; mark all memory as unavailable
  192.         mov     edi, sys_pgmap-OS_BASE
  193.         mov     ecx, [pg_data.pagemap_size-OS_BASE]
  194.         shr     ecx, 2
  195.         xor     eax, eax
  196.         cld
  197.         rep stosd
  198.  
  199. ; scan through memory map and mark free areas as available
  200.         mov     ebx, BOOT_VARS-OS_BASE + 0x9104
  201.         mov     edx, [ebx-4]
  202. .scanmap:
  203.         cmp     [ebx+16], byte 1
  204.         jne     .next
  205.  
  206.         mov     ecx, [ebx+8]
  207.         shr     ecx, 12; ecx = number of pages
  208.         jz      .next
  209.         mov     edi, [ebx]
  210.         shr     edi, 12; edi = first page
  211.         mov     eax, edi
  212.         shr     edi, 5
  213.         shl     edi, 2
  214.         add     edi, sys_pgmap-OS_BASE
  215.         and     eax, 31
  216.         jz      .startok
  217.         add     ecx, eax
  218.         sub     ecx, 32
  219.         jbe     .onedword
  220.         push    ecx
  221.         mov     ecx, eax
  222.         or      eax, -1
  223.         shl     eax, cl
  224.         or      [edi], eax
  225.         add     edi, 4
  226.         pop     ecx
  227. .startok:
  228.         push    ecx
  229.         shr     ecx, 5
  230.         or      eax, -1
  231.         rep stosd
  232.         pop     ecx
  233.         and     ecx, 31
  234.         neg     eax
  235.         shl     eax, cl
  236.         dec     eax
  237.         or      [edi], eax
  238.         jmp     .next
  239. .onedword:
  240.         add     ecx, 32
  241.         sub     ecx, eax
  242. @@:
  243.         bts     [edi], eax
  244.         inc     eax
  245.         loop    @b
  246. .next:
  247.         add     ebx, 20
  248.         dec     edx
  249.         jnz     .scanmap
  250.  
  251. ; mark kernel memory as allocated (unavailable)
  252.         mov     ecx, [tmp_page_tabs]
  253.         mov     edx, [pg_data.pages_count-OS_BASE]
  254.         shr     ecx, 12
  255.         add     ecx, [pg_data.kernel_tables-OS_BASE]
  256.         sub     edx, ecx
  257.         mov     [pg_data.pages_free-OS_BASE], edx
  258.  
  259.         mov     edi, sys_pgmap-OS_BASE
  260.         mov     ebx, ecx
  261.         shr     ecx, 5
  262.         xor     eax, eax
  263.         rep stosd
  264.  
  265.         not     eax
  266.         mov     ecx, ebx
  267.         and     ecx, 31
  268.         shl     eax, cl
  269.         and     [edi], eax
  270.         add     edi, OS_BASE
  271.         mov     [page_start-OS_BASE], edi;
  272.  
  273.         mov     ebx, sys_pgmap
  274.         add     ebx, [pg_data.pagemap_size-OS_BASE]
  275.         mov     [page_end-OS_BASE], ebx
  276.  
  277.         ret
  278. endp
  279.  
  280. align 4
  281.  
  282. init_BIOS32:
  283.         mov     edi, 0xE0000
  284. .pcibios_nxt:
  285.         cmp     dword[edi], '_32_'; "magic" word
  286.         je      .BIOS32_found
  287. .pcibios_nxt2:
  288.         add     edi, 0x10
  289.         cmp     edi, 0xFFFF0
  290.         je      .BIOS32_not_found
  291.         jmp     .pcibios_nxt
  292. .BIOS32_found:                  ; magic word found, check control summ
  293.  
  294.         movzx   ecx, byte[edi + 9]
  295.         shl     ecx, 4
  296.         mov     esi, edi
  297.         xor     eax, eax
  298.         cld      ; paranoia
  299. @@:
  300.         lodsb
  301.         add     ah, al
  302.         loop    @b
  303.         jnz     .pcibios_nxt2; control summ must be zero
  304.     ; BIOS32 service found !
  305.         mov     ebp, [edi + 4]
  306.         mov     [bios32_entry], ebp
  307.     ; check PCI BIOS present
  308.         mov     eax, '$PCI'
  309.         xor     ebx, ebx
  310.         push    cs  ; special for 'ret far' from  BIOS
  311.         call    ebp
  312.         test    al, al
  313.         jnz     .PCI_BIOS32_not_found
  314.  
  315.  ; здесь создаются дискрипторы для PCI BIOS
  316.  
  317.         add     ebx, OS_BASE
  318.         dec     ecx
  319.         mov     [(pci_code_32-OS_BASE)], cx   ;limit 0-15
  320.         mov     [(pci_data_32-OS_BASE)], cx   ;limit 0-15
  321.  
  322.         mov     [(pci_code_32-OS_BASE)+2], bx ;base  0-15
  323.         mov     [(pci_data_32-OS_BASE)+2], bx ;base  0-15
  324.  
  325.         shr     ebx, 16
  326.         mov     [(pci_code_32-OS_BASE)+4], bl ;base  16-23
  327.         mov     [(pci_data_32-OS_BASE)+4], bl ;base  16-23
  328.  
  329.         shr     ecx, 16
  330.         and     cl, 0x0F
  331.         mov     ch, bh
  332.         add     cx, D32
  333.         mov     [(pci_code_32-OS_BASE)+6], cx ;lim   16-19 &
  334.         mov     [(pci_data_32-OS_BASE)+6], cx ;base  24-31
  335.  
  336.         mov     [(pci_bios_entry-OS_BASE)], edx
  337.          ; jmp .end
  338. .PCI_BIOS32_not_found:
  339.         ; здесь должна заполнятся pci_emu_dat
  340. .BIOS32_not_found:
  341. .end:
  342.         ret
  343.  
  344. align 4
  345. proc test_cpu
  346.            locals
  347.               cpu_type   dd ?
  348.            endl
  349.  
  350.         xor     eax, eax
  351.         mov     [cpu_type], eax
  352.         mov     [cpu_caps-OS_BASE], eax
  353.         mov     [cpu_caps+4-OS_BASE], eax
  354.         mov     [cpu_phys_addr_width-OS_BASE], 32
  355.  
  356.         pushfd
  357.         pop     eax
  358.         mov     ecx, eax
  359.         xor     eax, 0x40000
  360.         push    eax
  361.         popfd
  362.         pushfd
  363.         pop     eax
  364.         xor     eax, ecx
  365.         mov     [cpu_type], CPU_386
  366.         jz      .end_cpuid
  367.         push    ecx
  368.         popfd
  369.  
  370.         mov     [cpu_type], CPU_486
  371.         mov     eax, ecx
  372.         xor     eax, 0x200000
  373.         push    eax
  374.         popfd
  375.         pushfd
  376.         pop     eax
  377.         xor     eax, ecx
  378.         je      .end_cpuid
  379.  
  380.         xor     eax, eax
  381.         cpuid
  382.  
  383.         mov     [cpu_vendor-OS_BASE], ebx
  384.         mov     [cpu_vendor+4-OS_BASE], edx
  385.         mov     [cpu_vendor+8-OS_BASE], ecx
  386.  
  387.         cmp     eax, 1
  388.         jl      .end_cpuid
  389.         mov     eax, 1
  390.         cpuid
  391.         mov     [cpu_sign-OS_BASE], eax
  392.         mov     [cpu_info-OS_BASE], ebx
  393.         mov     [cpu_caps-OS_BASE], edx
  394.         mov     [cpu_caps+4-OS_BASE], ecx
  395.  
  396.         bt      edx, CAPS_PAE
  397.         jnc     @f
  398.         mov     [cpu_phys_addr_width-OS_BASE], 36
  399. @@:
  400.         mov     eax, 0x80000000
  401.         cpuid
  402.         cmp     eax, 0x80000008
  403.         jb      @f
  404.         mov     eax, 0x80000008
  405.         cpuid
  406.         mov     [cpu_phys_addr_width-OS_BASE], al
  407. @@:
  408.  
  409.         mov     eax, [cpu_sign-OS_BASE]
  410.         shr     eax, 8
  411.         and     eax, 0x0f
  412.         ret
  413. .end_cpuid:
  414.         mov     eax, [cpu_type]
  415.         ret
  416. endp
  417.  
  418. iglobal
  419. align 4
  420. acpi_lapic_base   dd 0xfee00000   ; default local apic base
  421. endg
  422.  
  423. uglobal
  424. align 4
  425. acpi_rsdp         rd 1
  426. acpi_rsdt         rd 1
  427. acpi_madt         rd 1
  428.  
  429. acpi_dev_data     rd 1
  430. acpi_dev_size     rd 1
  431.  
  432. acpi_rsdt_base    rd 1
  433. acpi_fadt_base    rd 1
  434. acpi_dsdt_base    rd 1
  435. acpi_dsdt_size    rd 1
  436. acpi_madt_base    rd 1
  437. acpi_ioapic_base  rd 1
  438.  
  439. cpu_count         rd 1
  440. smpt              rd 16
  441. endg
  442.  
  443. ACPI_HI_RSDP_WINDOW_START  equ 0x000E0000
  444. ACPI_HI_RSDP_WINDOW_END    equ 0x00100000
  445. ACPI_RSDP_CHECKSUM_LENGTH  equ 20
  446. ACPI_MADT_SIGN             equ 0x43495041
  447. ACPI_FADT_SIGN             equ 0x50434146
  448.  
  449.  
  450. acpi_locate:
  451.         push    ebx
  452.         mov     ebx, ACPI_HI_RSDP_WINDOW_START
  453. .check:
  454.         cmp     [ebx], dword 0x20445352
  455.         jne     .next
  456.         cmp     [ebx+4], dword 0x20525450
  457.         jne     .next
  458.  
  459.         mov     edx, ebx
  460.         mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
  461.         xor     eax, eax
  462. .sum:
  463.         add     al, [edx]
  464.         inc     edx
  465.         loop    .sum
  466.  
  467.         test    al, al
  468.         jnz     .next
  469.  
  470.         mov     eax, ebx
  471.         pop     ebx
  472.         ret
  473. .next:
  474.         add     ebx, 16
  475.         cmp     ebx, ACPI_HI_RSDP_WINDOW_END
  476.         jb      .check
  477.  
  478.         pop     ebx
  479.         xor     eax, eax
  480.         ret
  481.  
  482. align 4
  483. rsdt_find:           ;ecx= rsdt edx= SIG
  484.         push    ebx
  485.         push    esi
  486.  
  487.         lea     ebx, [ecx+36]
  488.         mov     esi, [ecx+4]
  489.         add     esi, ecx
  490. align 4
  491. .next:
  492.         mov     eax, [ebx]
  493.         cmp     [eax], edx
  494.         je      .done
  495.  
  496.         add     ebx, 4
  497.         cmp     ebx, esi
  498.         jb      .next
  499.  
  500.         xor     eax, eax
  501.         pop     esi
  502.         pop     ebx
  503.         ret
  504.  
  505. .done:
  506.         mov     eax, [ebx]
  507.         pop     esi
  508.         pop     ebx
  509.         ret
  510.  
  511. align 4
  512. check_acpi:
  513.  
  514.         call    acpi_locate
  515.         test    eax, eax
  516.         jz      .done
  517.  
  518.         mov     ecx, [eax+16]
  519.         mov     edx, 0x50434146
  520.         mov     [acpi_rsdt_base-OS_BASE], ecx
  521.         call    rsdt_find
  522.         mov     [acpi_fadt_base-OS_BASE], eax
  523.         test    eax, eax
  524.         jz      @f
  525.  
  526.         mov     eax, [eax+40]
  527.         mov     [acpi_dsdt_base-OS_BASE], eax
  528.         mov     eax, [eax+4]
  529.         mov     [acpi_dsdt_size-OS_BASE], eax
  530.  
  531. @@:
  532.         mov     edx, ACPI_MADT_SIGN
  533.         mov     ecx, [acpi_rsdt_base-OS_BASE]
  534.         call    rsdt_find
  535.         test    eax, eax
  536.         jz      .done
  537.  
  538.         mov     [acpi_madt_base-OS_BASE], eax
  539.         mov     ecx, [eax+36]
  540.         mov     [acpi_lapic_base-OS_BASE], ecx
  541.  
  542.         mov     edi, smpt-OS_BASE
  543.         mov     ebx, [ecx+0x20]
  544.         shr     ebx, 24              ; read APIC ID
  545.  
  546.         mov     [edi], ebx           ; bootstrap always first
  547.         inc     [cpu_count-OS_BASE]
  548.         add     edi, 4
  549.  
  550.         lea     edx, [eax+44]
  551.         mov     ecx, [eax+4]
  552.         add     ecx, eax
  553. .check:
  554.         mov     eax, [edx]
  555.         cmp     al, 0
  556.         jne     .io_apic
  557.  
  558.         shr     eax, 24              ; get APIC ID
  559.         cmp     eax, ebx             ; skip self
  560.         je      .next
  561.  
  562.         test    [edx+4], byte 1      ; is enabled ?
  563.         jz      .next
  564.  
  565.         cmp     [cpu_count-OS_BASE], 16
  566.         jae     .next
  567.  
  568.         stosd                        ; store APIC ID
  569.         inc     [cpu_count-OS_BASE]
  570. .next:
  571.         mov     eax, [edx]
  572.         movzx   eax, ah
  573.         add     edx, eax
  574.         cmp     edx, ecx
  575.         jb      .check
  576. .done:
  577.         ret
  578.  
  579. .io_apic:
  580.         cmp     al, 1
  581.         jne     .next
  582.  
  583.         mov     eax, [edx+4]
  584.         mov     [acpi_ioapic_base-OS_BASE], eax
  585.         jmp     .next
  586.