Subversion Repositories Kolibri OS

Rev

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