Subversion Repositories Kolibri OS

Rev

Rev 2129 | Rev 2231 | 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: 2218 $
  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. @@:     lodsb
  292.            add ah, al
  293.            loop @b
  294.            jnz .pcibios_nxt2 ; control summ must be zero
  295.     ; BIOS32 service found !
  296.            mov ebp, [edi + 4]
  297.            mov [bios32_entry], ebp
  298.     ; check PCI BIOS present
  299.            mov eax, '$PCI'
  300.            xor ebx, ebx
  301.            push cs  ; special for 'ret far' from  BIOS
  302.            call ebp
  303.            test al, al
  304.            jnz .PCI_BIOS32_not_found
  305.  
  306.  ; чфхё№ ёючфр■Єё  фшёъЁшяЄюЁ√ фы  PCI BIOS
  307.  
  308.            add ebx, OS_BASE
  309.            dec ecx
  310.            mov [(pci_code_32-OS_BASE)], cx    ;limit 0-15
  311.            mov [(pci_data_32-OS_BASE)], cx    ;limit 0-15
  312.  
  313.            mov [(pci_code_32-OS_BASE)+2], bx  ;base  0-15
  314.            mov [(pci_data_32-OS_BASE)+2], bx  ;base  0-15
  315.  
  316.            shr ebx, 16
  317.            mov [(pci_code_32-OS_BASE)+4], bl  ;base  16-23
  318.            mov [(pci_data_32-OS_BASE)+4], bl  ;base  16-23
  319.  
  320.            shr ecx, 16
  321.            and cl, 0x0F
  322.            mov ch, bh
  323.            add cx, D32
  324.            mov [(pci_code_32-OS_BASE)+6], cx  ;lim   16-19 &
  325.            mov [(pci_data_32-OS_BASE)+6], cx  ;base  24-31
  326.  
  327.            mov [(pci_bios_entry-OS_BASE)], edx
  328.          ; jmp .end
  329. .PCI_BIOS32_not_found:
  330.         ; чфхё№ фюыцэр чряюыэ Єё  pci_emu_dat
  331. .BIOS32_not_found:
  332. .end:
  333.            ret
  334.  
  335. align 4
  336. proc test_cpu
  337.            locals
  338.               cpu_type   dd ?
  339.               cpu_id     dd ?
  340.               cpu_Intel  dd ?
  341.               cpu_AMD    dd ?
  342.            endl
  343.  
  344.            xor eax, eax
  345.            mov [cpu_type], eax
  346.            mov [cpu_caps-OS_BASE], eax
  347.            mov [cpu_caps+4-OS_BASE], eax
  348.  
  349.            pushfd
  350.            pop eax
  351.            mov ecx, eax
  352.            xor eax, 0x40000
  353.            push eax
  354.            popfd
  355.            pushfd
  356.            pop eax
  357.            xor eax, ecx
  358.            mov [cpu_type], CPU_386
  359.            jz .end_cpuid
  360.            push ecx
  361.            popfd
  362.  
  363.            mov [cpu_type], CPU_486
  364.            mov eax, ecx
  365.            xor eax, 0x200000
  366.            push eax
  367.            popfd
  368.            pushfd
  369.            pop eax
  370.            xor eax, ecx
  371.            je .end_cpuid
  372.            mov [cpu_id], 1
  373.  
  374.            xor eax, eax
  375.            cpuid
  376.  
  377.            mov [cpu_vendor-OS_BASE], ebx
  378.            mov [cpu_vendor+4-OS_BASE], edx
  379.            mov [cpu_vendor+8-OS_BASE], ecx
  380.            cmp ebx, dword [intel_str-OS_BASE]
  381.            jne .check_AMD
  382.            cmp edx, dword [intel_str+4-OS_BASE]
  383.            jne .check_AMD
  384.            cmp ecx, dword [intel_str+8-OS_BASE]
  385.            jne .check_AMD
  386.            mov [cpu_Intel], 1
  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.            shr eax, 8
  397.            and eax, 0x0f
  398.            ret
  399. .end_cpuid:
  400.            mov eax, [cpu_type]
  401.            ret
  402.  
  403. .check_AMD:
  404.            cmp ebx, dword [AMD_str-OS_BASE]
  405.            jne .unknown
  406.            cmp edx, dword [AMD_str+4-OS_BASE]
  407.            jne .unknown
  408.            cmp ecx, dword [AMD_str+8-OS_BASE]
  409.            jne .unknown
  410.            mov [cpu_AMD], 1
  411.            cmp eax, 1
  412.            jl .unknown
  413.            mov eax, 1
  414.            cpuid
  415.            mov [cpu_sign-OS_BASE], eax
  416.            mov [cpu_info-OS_BASE],  ebx
  417.            mov [cpu_caps-OS_BASE],  edx
  418.            mov [cpu_caps+4-OS_BASE],ecx
  419.            shr eax, 8
  420.            and eax, 0x0f
  421.            ret
  422. .unknown:
  423.            mov eax, 1
  424.            cpuid
  425.            mov [cpu_sign-OS_BASE], eax
  426.            mov [cpu_info-OS_BASE],  ebx
  427.            mov [cpu_caps-OS_BASE],  edx
  428.            mov [cpu_caps+4-OS_BASE],ecx
  429.            shr eax, 8
  430.            and eax, 0x0f
  431.            ret
  432. endp
  433.  
  434. uglobal
  435. align 4
  436. acpi_rsdp         rd 1
  437. acpi_rsdt         rd 1
  438. acpi_madt         rd 1
  439.  
  440. acpi_rsdt_base    rd 1
  441. acpi_madt_base    rd 1
  442. acpi_lapic_base   rd 1
  443. acpi_ioapic_base  rd 1
  444. endg
  445.  
  446. ACPI_HI_RSDP_WINDOW_START equ 0x000E0000
  447. ACPI_HI_RSDP_WINDOW_END   equ 0x00100000
  448. ACPI_RSDP_CHECKSUM_LENGTH equ 20
  449. ACPI_MADT_SIGN             equ 0x43495041
  450.  
  451.  
  452. acpi_locate:
  453.         push ebx
  454.         mov ebx, ACPI_HI_RSDP_WINDOW_START
  455. .check:
  456.         cmp [ebx], dword 0x20445352
  457.         jne .next
  458.         cmp [ebx+4], dword 0x20525450
  459.         jne .next
  460.  
  461.         mov edx, ebx
  462.         mov ecx, ACPI_RSDP_CHECKSUM_LENGTH
  463.         xor eax, eax
  464. .sum:
  465.         add al, [edx]
  466.         inc edx
  467.         loop .sum
  468.  
  469.         test al, al
  470.         jnz .next
  471.  
  472.         mov eax, ebx
  473.         pop ebx
  474.         ret
  475. .next:
  476.         add ebx, 16
  477.         cmp ebx, ACPI_HI_RSDP_WINDOW_END
  478.         jb .check
  479.  
  480.         pop ebx
  481.         xor eax, eax
  482.         ret
  483.  
  484. align 4
  485. rsdt_find:           ;ecx= rsdt edx= SIG
  486.         push ebx
  487.         push esi
  488.  
  489.         lea ebx, [ecx+36]
  490.         mov esi, [ecx+4]
  491.         add esi, ecx
  492. .next:
  493.         mov eax, [ebx]
  494.         cmp [eax], edx
  495.         je .done
  496.  
  497.         add ebx, 4
  498.         cmp ebx, esi
  499.         jb .next
  500.  
  501.         xor eax, eax
  502.         pop esi
  503.         pop ebx
  504.         ret
  505.  
  506. .done:
  507.         mov eax, [ebx]
  508.         pop esi
  509.         pop ebx
  510.         ret
  511.  
  512.  
  513. align 4
  514.  
  515. check_acpi:
  516.  
  517.         call acpi_locate
  518.         test eax, eax
  519.         jz .done
  520.  
  521.         mov ecx, [eax+16]
  522.         mov edx, ACPI_MADT_SIGN
  523.         mov [acpi_rsdt_base-OS_BASE], ecx
  524.         call rsdt_find
  525.         test eax, eax
  526.         jz .done
  527.  
  528.         mov [acpi_madt_base-OS_BASE], eax
  529.         mov ecx, [eax+36]
  530.         mov [acpi_lapic_base-OS_BASE], ecx
  531.  
  532.         lea edx, [eax+44]
  533.         mov ecx, [eax+4]
  534.         add ecx, eax
  535. .check:
  536.         mov eax, [edx]
  537.         cmp al, 1
  538.         je .ioapic
  539.  
  540. .next:
  541.         movzx eax, ah
  542.         add edx, eax
  543.         cmp edx, ecx
  544.         jb .check
  545. .done:
  546.         ret
  547. .ioapic:
  548.         mov eax, [edx+4]
  549.         mov [acpi_ioapic_base-OS_BASE], eax
  550.         ret
  551.