Subversion Repositories Kolibri OS

Rev

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

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