Subversion Repositories Kolibri OS

Rev

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