Subversion Repositories Kolibri OS

Rev

Rev 4429 | Go to most recent revision | Blame | 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: 4390 $
  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.               cpu_id     dd ?
  349.               cpu_Intel  dd ?
  350.               cpu_AMD    dd ?
  351.            endl
  352.  
  353.         xor     eax, eax
  354.         mov     [cpu_type], eax
  355.         mov     [cpu_caps-OS_BASE], eax
  356.         mov     [cpu_caps+4-OS_BASE], eax
  357.         mov     [cpu_phys_addr_width-OS_BASE], 32
  358.  
  359.         pushfd
  360.         pop     eax
  361.         mov     ecx, eax
  362.         xor     eax, 0x40000
  363.         push    eax
  364.         popfd
  365.         pushfd
  366.         pop     eax
  367.         xor     eax, ecx
  368.         mov     [cpu_type], CPU_386
  369.         jz      .end_cpuid
  370.         push    ecx
  371.         popfd
  372.  
  373.         mov     [cpu_type], CPU_486
  374.         mov     eax, ecx
  375.         xor     eax, 0x200000
  376.         push    eax
  377.         popfd
  378.         pushfd
  379.         pop     eax
  380.         xor     eax, ecx
  381.         je      .end_cpuid
  382.  
  383.         xor     eax, eax
  384.         cpuid
  385.  
  386.         mov     [cpu_vendor-OS_BASE], ebx
  387.         mov     [cpu_vendor+4-OS_BASE], edx
  388.         mov     [cpu_vendor+8-OS_BASE], ecx
  389.         cmp     ebx, dword [intel_str-OS_BASE]
  390.         jne     .check_AMD
  391.         cmp     edx, dword [intel_str+4-OS_BASE]
  392.         jne     .check_AMD
  393.         cmp     ecx, dword [intel_str+8-OS_BASE]
  394.         jne     .check_AMD
  395.         mov     [cpu_Intel], 1
  396.         cmp     eax, 1
  397.         jl      .end_cpuid
  398.         mov     eax, 1
  399.         cpuid
  400.         mov     [cpu_sign-OS_BASE], eax
  401.         mov     [cpu_info-OS_BASE], ebx
  402.         mov     [cpu_caps-OS_BASE], edx
  403.         mov     [cpu_caps+4-OS_BASE], ecx
  404.  
  405.         bt      edx, CAPS_PAE
  406.         jnc     @f
  407.         mov     [cpu_phys_addr_width-OS_BASE], 36
  408. @@:
  409.         mov     eax, 0x80000000
  410.         cpuid
  411.         cmp     eax, 0x80000008
  412.         jb      @f
  413.         mov     eax, 0x80000008
  414.         cpuid
  415.         mov     [cpu_phys_addr_width-OS_BASE], al
  416. @@:
  417.  
  418.         mov     eax, [cpu_sign-OS_BASE]
  419.         shr     eax, 8
  420.         and     eax, 0x0f
  421.         ret
  422. .end_cpuid:
  423.         mov     eax, [cpu_type]
  424.         ret
  425.  
  426. .check_AMD:
  427.         cmp     ebx, dword [AMD_str-OS_BASE]
  428.         jne     .unknown
  429.         cmp     edx, dword [AMD_str+4-OS_BASE]
  430.         jne     .unknown
  431.         cmp     ecx, dword [AMD_str+8-OS_BASE]
  432.         jne     .unknown
  433.         mov     [cpu_AMD], 1
  434.         cmp     eax, 1
  435.         jl      .unknown
  436.         mov     eax, 1
  437.         cpuid
  438.         mov     [cpu_sign-OS_BASE], eax
  439.         mov     [cpu_info-OS_BASE], ebx
  440.         mov     [cpu_caps-OS_BASE], edx
  441.         mov     [cpu_caps+4-OS_BASE], ecx
  442.         shr     eax, 8
  443.         and     eax, 0x0f
  444.         ret
  445. .unknown:
  446.         mov     eax, 1
  447.         cpuid
  448.         mov     [cpu_sign-OS_BASE], eax
  449.         mov     [cpu_info-OS_BASE], ebx
  450.         mov     [cpu_caps-OS_BASE], edx
  451.         mov     [cpu_caps+4-OS_BASE], ecx
  452.         shr     eax, 8
  453.         and     eax, 0x0f
  454.         ret
  455. endp
  456.  
  457. iglobal
  458. align 4
  459. acpi_lapic_base   dd 0xfee00000   ; default local apic base
  460. endg
  461.  
  462. uglobal
  463. align 4
  464. acpi_rsdp         rd 1
  465. acpi_rsdt         rd 1
  466. acpi_madt         rd 1
  467.  
  468. acpi_dev_data     rd 1
  469. acpi_dev_size     rd 1
  470.  
  471. acpi_rsdt_base    rd 1
  472. acpi_fadt_base    rd 1
  473. acpi_dsdt_base    rd 1
  474. acpi_dsdt_size    rd 1
  475. acpi_madt_base    rd 1
  476. acpi_ioapic_base  rd 1
  477.  
  478. cpu_count         rd 1
  479. smpt              rd 16
  480. endg
  481.  
  482. ACPI_HI_RSDP_WINDOW_START  equ 0x000E0000
  483. ACPI_HI_RSDP_WINDOW_END    equ 0x00100000
  484. ACPI_RSDP_CHECKSUM_LENGTH  equ 20
  485. ACPI_MADT_SIGN             equ 0x43495041
  486. ACPI_FADT_SIGN             equ 0x50434146
  487.  
  488.  
  489. acpi_locate:
  490.         push    ebx
  491.         mov     ebx, ACPI_HI_RSDP_WINDOW_START
  492. .check:
  493.         cmp     [ebx], dword 0x20445352
  494.         jne     .next
  495.         cmp     [ebx+4], dword 0x20525450
  496.         jne     .next
  497.  
  498.         mov     edx, ebx
  499.         mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
  500.         xor     eax, eax
  501. .sum:
  502.         add     al, [edx]
  503.         inc     edx
  504.         loop    .sum
  505.  
  506.         test    al, al
  507.         jnz     .next
  508.  
  509.         mov     eax, ebx
  510.         pop     ebx
  511.         ret
  512. .next:
  513.         add     ebx, 16
  514.         cmp     ebx, ACPI_HI_RSDP_WINDOW_END
  515.         jb      .check
  516.  
  517.         pop     ebx
  518.         xor     eax, eax
  519.         ret
  520.  
  521. align 4
  522. rsdt_find:           ;ecx= rsdt edx= SIG
  523.         push    ebx
  524.         push    esi
  525.  
  526.         lea     ebx, [ecx+36]
  527.         mov     esi, [ecx+4]
  528.         add     esi, ecx
  529. align 4
  530. .next:
  531.         mov     eax, [ebx]
  532.         cmp     [eax], edx
  533.         je      .done
  534.  
  535.         add     ebx, 4
  536.         cmp     ebx, esi
  537.         jb      .next
  538.  
  539.         xor     eax, eax
  540.         pop     esi
  541.         pop     ebx
  542.         ret
  543.  
  544. .done:
  545.         mov     eax, [ebx]
  546.         pop     esi
  547.         pop     ebx
  548.         ret
  549.  
  550. align 4
  551. check_acpi:
  552.  
  553.         call    acpi_locate
  554.         test    eax, eax
  555.         jz      .done
  556.  
  557.         mov     ecx, [eax+16]
  558.         mov     edx, 0x50434146
  559.         mov     [acpi_rsdt_base-OS_BASE], ecx
  560.         call    rsdt_find
  561.         mov     [acpi_fadt_base-OS_BASE], eax
  562.         test    eax, eax
  563.         jz      @f
  564.  
  565.         mov     eax, [eax+40]
  566.         mov     [acpi_dsdt_base-OS_BASE], eax
  567.         mov     eax, [eax+4]
  568.         mov     [acpi_dsdt_size-OS_BASE], eax
  569.  
  570. @@:
  571.         mov     edx, ACPI_MADT_SIGN
  572.         mov     ecx, [acpi_rsdt_base-OS_BASE]
  573.         call    rsdt_find
  574.         test    eax, eax
  575.         jz      .done
  576.  
  577.         mov     [acpi_madt_base-OS_BASE], eax
  578.         mov     ecx, [eax+36]
  579.         mov     [acpi_lapic_base-OS_BASE], ecx
  580.  
  581.         mov     edi, smpt-OS_BASE
  582.         mov     ebx, [ecx+0x20]
  583.         shr     ebx, 24              ; read APIC ID
  584.  
  585.         mov     [edi], ebx           ; bootstrap always first
  586.         inc     [cpu_count-OS_BASE]
  587.         add     edi, 4
  588.  
  589.         lea     edx, [eax+44]
  590.         mov     ecx, [eax+4]
  591.         add     ecx, eax
  592. .check:
  593.         mov     eax, [edx]
  594.         cmp     al, 0
  595.         jne     .io_apic
  596.  
  597.         shr     eax, 24              ; get APIC ID
  598.         cmp     eax, ebx             ; skip self
  599.         je      .next
  600.  
  601.         test    [edx+4], byte 1      ; is enabled ?
  602.         jz      .next
  603.  
  604.         cmp     [cpu_count-OS_BASE], 16
  605.         jae     .next
  606.  
  607.         stosd                        ; store APIC ID
  608.         inc     [cpu_count-OS_BASE]
  609. .next:
  610.         mov     eax, [edx]
  611.         movzx   eax, ah
  612.         add     edx, eax
  613.         cmp     edx, ecx
  614.         jb      .check
  615. .done:
  616.         ret
  617.  
  618. .io_apic:
  619.         cmp     al, 1
  620.         jne     .next
  621.  
  622.         mov     eax, [edx+4]
  623.         mov     [acpi_ioapic_base-OS_BASE], eax
  624.         jmp     .next
  625.