Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 5645 $
  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, PDE_LARGE+PG_SWR
  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_SWR
  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_SWR
  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_SWR-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. acpi_hpet_base    rd 1
  439. hpet_base         rd 1
  440. hpet_period       rd 1
  441. hpet_timers       rd 1
  442.  
  443. cpu_count         rd 1
  444. smpt              rd 16
  445. endg
  446.  
  447. ACPI_HI_RSDP_WINDOW_START equ 0x000E0000
  448. ACPI_HI_RSDP_WINDOW_END   equ 0x00100000
  449. ACPI_RSDP_CHECKSUM_LENGTH equ 20
  450.  
  451. ACPI_HPET_SIGN             equ 0x54455048
  452. ACPI_MADT_SIGN             equ 0x43495041
  453. ACPI_FADT_SIGN             equ 0x50434146
  454.  
  455.  
  456. acpi_locate:
  457.         push    ebx
  458.         mov     ebx, ACPI_HI_RSDP_WINDOW_START
  459. .check:
  460.         cmp     [ebx], dword 0x20445352
  461.         jne     .next
  462.         cmp     [ebx+4], dword 0x20525450
  463.         jne     .next
  464.  
  465.         mov     edx, ebx
  466.         mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
  467.         xor     eax, eax
  468. .sum:
  469.         add     al, [edx]
  470.         inc     edx
  471.         loop    .sum
  472.  
  473.         test    al, al
  474.         jnz     .next
  475.  
  476.         mov     eax, ebx
  477.         pop     ebx
  478.         ret
  479. .next:
  480.         add     ebx, 16
  481.         cmp     ebx, ACPI_HI_RSDP_WINDOW_END
  482.         jb      .check
  483.  
  484.         pop     ebx
  485.         xor     eax, eax
  486.         ret
  487.  
  488. align 4
  489. rsdt_find:           ;ecx= rsdt edx= SIG
  490.         push    ebx
  491.         push    esi
  492.  
  493.         lea     ebx, [ecx+36]
  494.         mov     esi, [ecx+4]
  495.         add     esi, ecx
  496. align 4
  497. .next:
  498.         mov     eax, [ebx]
  499.         cmp     [eax], edx
  500.         je      .done
  501.  
  502.         add     ebx, 4
  503.         cmp     ebx, esi
  504.         jb      .next
  505.  
  506.         xor     eax, eax
  507.         pop     esi
  508.         pop     ebx
  509.         ret
  510.  
  511. .done:
  512.         mov     eax, [ebx]
  513.         pop     esi
  514.         pop     ebx
  515.         ret
  516.  
  517. align 4
  518. check_acpi:
  519.  
  520.         call    acpi_locate
  521.         test    eax, eax
  522.         jz      .done
  523.  
  524.         mov     ecx, [eax+16]
  525.         mov     edx, ACPI_FADT_SIGN
  526.         mov     [acpi_rsdt_base-OS_BASE], ecx
  527.         call    rsdt_find
  528.         mov     [acpi_fadt_base-OS_BASE], eax
  529.         test    eax, eax
  530.         jz      @f
  531.  
  532.         mov     eax, [eax+40]
  533.         mov     [acpi_dsdt_base-OS_BASE], eax
  534.         mov     eax, [eax+4]
  535.         mov     [acpi_dsdt_size-OS_BASE], eax
  536. @@:
  537.         mov     edx, ACPI_HPET_SIGN
  538.         mov     ecx, [acpi_rsdt_base-OS_BASE]
  539.         call    rsdt_find
  540.         test    eax, eax
  541.         jz      @F
  542.  
  543.         mov     [acpi_hpet_base-OS_BASE], eax
  544.         mov     eax, [eax+44]
  545.         mov     [hpet_base-OS_BASE], eax
  546. @@:
  547.         mov     edx, ACPI_MADT_SIGN
  548.         mov     ecx, [acpi_rsdt_base-OS_BASE]
  549.         call    rsdt_find
  550.         test    eax, eax
  551.         jz      .done
  552.  
  553.         mov     [acpi_madt_base-OS_BASE], eax
  554.         mov     ecx, [eax+36]
  555.         mov     [acpi_lapic_base-OS_BASE], ecx
  556.  
  557.         mov     edi, smpt-OS_BASE
  558.         mov     ebx, [ecx+0x20]
  559.         shr     ebx, 24              ; read APIC ID
  560.  
  561.         mov     [edi], ebx           ; bootstrap always first
  562.         inc     [cpu_count-OS_BASE]
  563.         add     edi, 4
  564.  
  565.         lea     edx, [eax+44]
  566.         mov     ecx, [eax+4]
  567.         add     ecx, eax
  568. .check:
  569.         mov     eax, [edx]
  570.         cmp     al, 0
  571.         jne     .io_apic
  572.  
  573.         shr     eax, 24              ; get APIC ID
  574.         cmp     eax, ebx             ; skip self
  575.         je      .next
  576.  
  577.         test    [edx+4], byte 1      ; is enabled ?
  578.         jz      .next
  579.  
  580.         cmp     [cpu_count-OS_BASE], 16
  581.         jae     .next
  582.  
  583.         stosd                        ; store APIC ID
  584.         inc     [cpu_count-OS_BASE]
  585. .next:
  586.         mov     eax, [edx]
  587.         movzx   eax, ah
  588.         add     edx, eax
  589.         cmp     edx, ecx
  590.         jb      .check
  591. .done:
  592.         ret
  593.  
  594. .io_apic:
  595.         cmp     al, 1
  596.         jne     .next
  597.  
  598.         mov     eax, [edx+4]
  599.         mov     [acpi_ioapic_base-OS_BASE], eax
  600.         jmp     .next
  601.  
  602. HPET_PERIOD             equ 0x004
  603. HPET_CFG_ENABLE         equ     1
  604. HPET_CFG               equ 0x010
  605.  
  606. align 4
  607. init_hpet:
  608.         mov     ebx, [hpet_base-OS_BASE]
  609.         test    ebx, ebx
  610.         jz      @F
  611.  
  612.         mov     eax, [ebx]
  613.         and     ah, 0x1F
  614.         inc     ah
  615.         movzx   eax, ah
  616.         mov     [hpet_timers-OS_BASE], eax
  617.  
  618.         mov     eax, [ebx+HPET_PERIOD]
  619.         mov     edx, 0x431BDE83
  620.         mul     edx
  621.         shr     edx, 18
  622.         mov     [hpet_period-OS_BASE], edx
  623.  
  624.         mov     eax, [ebx+HPET_CFG]
  625.         and     eax, not HPET_CFG_ENABLE
  626.         mov     [ebx+HPET_CFG], eax     ;stop main counter
  627.  
  628.         xor     ecx, ecx
  629.         mov     [ebx+0xF0], ecx         ;reset counter
  630.         mov     [ebx+0xF4], ecx
  631.  
  632.         or      eax, HPET_CFG_ENABLE
  633.         mov     [ebx+HPET_CFG], eax     ;and start again
  634. @@:
  635.         ret
  636.  
  637.  
  638.  
  639.  
  640.