Subversion Repositories Kolibri OS

Rev

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