Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 8284 $
  9.  
  10. align 4
  11. proc mem_test
  12. ; if we have BIOS with fn E820, skip the test
  13.         cmp     [BOOT_LO.memmap_block_cnt], 0
  14.         jnz     .ret
  15.  
  16.         mov     eax, cr0
  17.         and     eax, not (CR0_CD+CR0_NW)
  18.         or      eax, CR0_CD       ;disable caching
  19.         mov     cr0, eax
  20.         wbinvd                    ;invalidate cache
  21.  
  22.         xor     edi, edi
  23.         mov     ebx, 'TEST'
  24. @@:
  25.         add     edi, 0x100000
  26.         xchg    ebx, dword [edi]
  27.         cmp     dword [edi], 'TEST'
  28.         xchg    ebx, dword [edi]
  29.         je      @b
  30.  
  31.         and     eax, not (CR0_CD+CR0_NW) ;enable caching
  32.         mov     cr0, eax
  33.         inc     dword [BOOT_LO.memmap_block_cnt]
  34.         xor     eax, eax
  35.         mov     [BOOT_LO.memmap_blocks+e820entry.addr.lo], eax
  36.         mov     [BOOT_LO.memmap_blocks+e820entry.addr.hi], eax
  37.         mov     [BOOT_LO.memmap_blocks+e820entry.size.lo], edi
  38.         mov     [BOOT_LO.memmap_blocks+e820entry.size.hi], eax
  39.         inc     eax
  40.         mov     [BOOT_LO.memmap_blocks+e820entry.type], eax
  41. .ret:
  42.         ret
  43. endp
  44.  
  45. align 4
  46. proc init_mem
  47. ; calculate maximum allocatable address and number of allocatable pages
  48.         mov     edi, BOOT_LO.memmap_blocks
  49.         mov     ecx, [edi-4]    ; memmap_block_cnt
  50.         xor     esi, esi; esi will hold total amount of memory
  51.         xor     edx, edx; edx will hold maximum allocatable address
  52. .calcmax:
  53. ; round all to pages
  54.         mov     eax, [edi+e820entry.addr.lo]
  55.         cmp     byte [edi+e820entry.type], 1
  56.         jne     .unusable
  57.  
  58.         test    eax, 0xFFF
  59.         jz      @f
  60.         neg     eax
  61.         and     eax, 0xFFF
  62.         add     [edi+e820entry.addr.lo], eax
  63.         adc     [edi+e820entry.addr.hi], 0
  64.         sub     [edi+e820entry.size.lo], eax
  65.         sbb     [edi+e820entry.size.hi], 0
  66.         jc      .unusable
  67. @@:
  68.         and     [edi+e820entry.size.lo], not 0xFFF
  69.         jz      .unusable
  70. ; ignore memory after 4 GiB
  71.         cmp     [edi+e820entry.addr.hi], 0
  72.         jnz     .unusable
  73.         mov     eax, [edi+e820entry.addr.lo]
  74.         cmp     [edi+e820entry.size.hi], 0
  75.         jnz     .overflow
  76.         add     eax, [edi+e820entry.size.lo]
  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+e820entry.addr.lo]
  86.         mov     [edi+e820entry.size.lo], eax
  87.         add     esi, eax
  88.         jmp     .usable
  89. .unusable:
  90. ;        and     dword [edi+e820entry.size.lo], 0
  91. .usable:
  92.         add     edi, sizeof.e820entry
  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_proc-OS_BASE
  127.         mov     ecx, 8192/4
  128.         cld
  129.         rep stosd
  130.  
  131.         mov     edx, (sys_proc-OS_BASE+PROC.pdt_0)+ 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, PDE_LARGE+PG_SWR
  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_SWR
  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_SWR
  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_proc-OS_BASE+PROC.pdt_0+(page_tabs shr 20)], sys_proc+PROC.pdt_0+PG_SWR-OS_BASE
  176.  
  177.         mov     edi, (sys_proc+PROC.pdt_0-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_LO.memmap_blocks
  196.         mov     edx, [ebx-4]
  197. .scanmap:
  198.         cmp     byte [ebx+e820entry.type], 1
  199.         jne     .next
  200.  
  201.         mov     ecx, [ebx+e820entry.size.lo]
  202.         shr     ecx, 12; ecx = number of pages
  203.         jz      .next
  204.         mov     edi, [ebx+e820entry.addr.lo]
  205.         shr     edi, 12; edi = first page
  206.         mov     eax, edi
  207.         shr     edi, 5
  208.         shl     edi, 2
  209.         add     edi, sys_pgmap-OS_BASE
  210.         and     eax, 31
  211.         jz      .startok
  212.         add     ecx, eax
  213.         sub     ecx, 32
  214.         jbe     .onedword
  215.         push    ecx
  216.         mov     ecx, eax
  217.         or      eax, -1
  218.         shl     eax, cl
  219.         or      [edi], eax
  220.         add     edi, 4
  221.         pop     ecx
  222. .startok:
  223.         push    ecx
  224.         shr     ecx, 5
  225.         or      eax, -1
  226.         rep stosd
  227.         pop     ecx
  228.         and     ecx, 31
  229.         neg     eax
  230.         shl     eax, cl
  231.         dec     eax
  232.         or      [edi], eax
  233.         jmp     .next
  234. .onedword:
  235.         add     ecx, 32
  236.         sub     ecx, eax
  237. @@:
  238.         bts     [edi], eax
  239.         inc     eax
  240.         loop    @b
  241. .next:
  242.         add     ebx, sizeof.e820entry
  243.         dec     edx
  244.         jnz     .scanmap
  245.  
  246. ; mark kernel memory as allocated (unavailable)
  247.         mov     ecx, [tmp_page_tabs]
  248.         mov     edx, [pg_data.pages_count-OS_BASE]
  249.         shr     ecx, 12
  250.         add     ecx, [pg_data.kernel_tables-OS_BASE]
  251.         sub     edx, ecx
  252.         mov     [pg_data.pages_free-OS_BASE], edx
  253.  
  254.         mov     edi, sys_pgmap-OS_BASE
  255.         mov     ebx, ecx
  256.         shr     ecx, 5
  257.         xor     eax, eax
  258.         rep stosd
  259.  
  260.         not     eax
  261.         mov     ecx, ebx
  262.         and     ecx, 31
  263.         shl     eax, cl
  264.         and     [edi], eax
  265.         add     edi, OS_BASE
  266.         mov     [page_start-OS_BASE], edi;
  267.  
  268.         mov     ebx, sys_pgmap
  269.         add     ebx, [pg_data.pagemap_size-OS_BASE]
  270.         mov     [page_end-OS_BASE], ebx
  271.  
  272.         ret
  273. endp
  274.  
  275. align 4
  276.  
  277. init_BIOS32:
  278.         mov     edi, 0xE0000
  279. .pcibios_nxt:
  280.         cmp     dword[edi], '_32_'; "magic" word
  281.         je      .BIOS32_found
  282. .pcibios_nxt2:
  283.         add     edi, 0x10
  284.         cmp     edi, 0xFFFF0
  285.         je      .BIOS32_not_found
  286.         jmp     .pcibios_nxt
  287. .BIOS32_found:                  ; magic word found, check control summ
  288.  
  289.         movzx   ecx, byte[edi + 9]
  290.         shl     ecx, 4
  291.         mov     esi, edi
  292.         xor     eax, eax
  293.         cld      ; paranoia
  294. @@:
  295.         lodsb
  296.         add     ah, al
  297.         loop    @b
  298.         jnz     .pcibios_nxt2; control summ must be zero
  299.     ; BIOS32 service found !
  300.         mov     ebp, [edi + 4]
  301.         mov     [bios32_entry], ebp
  302.     ; check PCI BIOS present
  303.         mov     eax, '$PCI'
  304.         xor     ebx, ebx
  305.         push    cs  ; special for 'ret far' from  BIOS
  306.         call    ebp
  307.         test    al, al
  308.         jnz     .PCI_BIOS32_not_found
  309.  
  310.  ; descriptors for PCI BIOS are created here
  311.  
  312.         add     ebx, OS_BASE
  313.         dec     ecx
  314.         mov     [(pci_code_32-OS_BASE)], cx   ;limit 0-15
  315.         mov     [(pci_data_32-OS_BASE)], cx   ;limit 0-15
  316.  
  317.         mov     [(pci_code_32-OS_BASE)+2], bx ;base  0-15
  318.         mov     [(pci_data_32-OS_BASE)+2], bx ;base  0-15
  319.  
  320.         shr     ebx, 16
  321.         mov     [(pci_code_32-OS_BASE)+4], bl ;base  16-23
  322.         mov     [(pci_data_32-OS_BASE)+4], bl ;base  16-23
  323.  
  324.         shr     ecx, 16
  325.         and     cl, 0x0F
  326.         mov     ch, bh
  327.         add     cx, D32
  328.         mov     [(pci_code_32-OS_BASE)+6], cx ;lim   16-19 &
  329.         mov     [(pci_data_32-OS_BASE)+6], cx ;base  24-31
  330.  
  331.         mov     [(pci_bios_entry-OS_BASE)], edx
  332.          ; jmp .end
  333. .PCI_BIOS32_not_found:
  334.         ; pci_emu_dat structure should be filled here
  335. .BIOS32_not_found:
  336. .end:
  337.         ret
  338.  
  339. align 4
  340. proc test_cpu
  341.            locals
  342.               cpu_type   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.         mov     [cpu_phys_addr_width-OS_BASE], 32
  350.  
  351.         pushfd
  352.         pop     eax
  353.         mov     ecx, eax
  354.         xor     eax, EFLAGS_AC
  355.         push    eax
  356.         popfd
  357.         pushfd
  358.         pop     eax
  359.         xor     eax, ecx
  360.         mov     [cpu_type], CPU_386
  361.         jz      .end_cpuid
  362.         push    ecx
  363.         popfd
  364.  
  365.         mov     [cpu_type], CPU_486
  366.         mov     eax, ecx
  367.         xor     eax, EFLAGS_ID
  368.         push    eax
  369.         popfd
  370.         pushfd
  371.         pop     eax
  372.         xor     eax, ecx
  373.         je      .end_cpuid
  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.  
  382.         cmp     eax, 1
  383.         jl      .end_cpuid
  384.         mov     eax, 1
  385.         cpuid
  386.         mov     [cpu_sign-OS_BASE], eax
  387.         mov     [cpu_info-OS_BASE], ebx
  388.         mov     [cpu_caps-OS_BASE], edx
  389.         mov     [cpu_caps+4-OS_BASE], ecx
  390.  
  391.         bt      edx, CAPS_PAE
  392.         jnc     @f
  393.         mov     [cpu_phys_addr_width-OS_BASE], 36
  394. @@:
  395.         mov     eax, 0x80000000
  396.         cpuid
  397.         cmp     eax, 0x80000008
  398.         jb      @f
  399.         mov     eax, 0x80000008
  400.         cpuid
  401.         mov     [cpu_phys_addr_width-OS_BASE], al
  402. @@:
  403.  
  404.         mov     eax, [cpu_sign-OS_BASE]
  405.         shr     eax, 8
  406.         and     eax, 0x0f
  407.         ret
  408. .end_cpuid:
  409.         mov     eax, [cpu_type]
  410.         ret
  411. endp
  412.  
  413. ACPI_HI_RSDP_WINDOW_START  = 0x000E0000
  414. ACPI_HI_RSDP_WINDOW_END    = 0x00100000
  415. ACPI_RSDP_CHECKSUM_LENGTH  = 20
  416.  
  417. proc acpi_locate_tables uses ebx esi edi
  418.         mov     ebx, [ebx+ACPI_RSDP.RsdtAddress]
  419.         mov     [acpi_rsdt_base-OS_BASE], ebx
  420.         mov     eax, [ebx+ACPI_RSDT.Length]
  421.         mov     [acpi_rsdt_size-OS_BASE], eax
  422.  
  423.         mov     esi, [acpi_rsdt_base-OS_BASE]
  424.         mov     ecx, [esi+ACPI_RSDT.Length]
  425.         lea     edi, [esi+ecx]
  426.         add     esi, sizeof.ACPI_TABLE
  427.         movi    ecx, 1
  428. .next_table:
  429.         cmp     esi, edi
  430.         jae     .done
  431.         lodsd
  432.         cmp     [eax+ACPI_TABLE.Signature], 'SSDT'      ; skip DSDT if present
  433.         jz      .ssdt                                   ; read it from FADT
  434.         cmp     [eax+ACPI_TABLE.Signature], 'FACP'      ; this is FADT
  435.         jz      .fadt
  436.         cmp     [eax+ACPI_TABLE.Signature], 'APIC'      ; this is MADT
  437.         jz      .madt
  438.         cmp     [eax+ACPI_TABLE.Signature], 'HPET'
  439.         jz      .hpet
  440.         jmp     .next_table
  441. .ssdt:
  442.         mov     [acpi_ssdt_base+ecx*4-OS_BASE], eax
  443.         mov     eax, [eax+ACPI_TABLE.Length]
  444.         mov     [acpi_ssdt_size+ecx*4-OS_BASE], eax
  445.         inc     ecx
  446.         jmp     .next_table
  447. .fadt:
  448.         mov     [acpi_fadt_base-OS_BASE], eax
  449.         cmp     [eax+ACPI_FADT.DSDT], 0
  450.         jz      @f
  451.         mov     edx, [eax+ACPI_FADT.DSDT]
  452.         mov     [acpi_ssdt_base-OS_BASE], edx
  453.         mov     edx, [edx+ACPI_TABLE.Length]
  454.         mov     [acpi_ssdt_size-OS_BASE], edx
  455. @@:
  456.         mov     eax, [eax+ACPI_TABLE.Length]
  457.         mov     [acpi_fadt_size-OS_BASE], eax
  458.         jmp     .next_table
  459. .madt:
  460.         mov     [acpi_madt_base-OS_BASE], eax
  461.         mov     eax, [eax+ACPI_TABLE.Length]
  462.         mov     [acpi_madt_size-OS_BASE], eax
  463.         jmp     .next_table
  464. .hpet:
  465.         mov     [acpi_hpet_base-OS_BASE], eax
  466.         mov     eax, [eax+ACPI_TABLE.Length]
  467.         mov     [acpi_hpet_size-OS_BASE], eax
  468.         jmp     .next_table
  469. .done:
  470.         mov     [acpi_ssdt_cnt-OS_BASE], ecx
  471.         ret
  472. endp
  473.  
  474. acpi_locate:
  475.         push    ebx
  476.         push    edi
  477.  
  478. if defined UEFI
  479.         ; UEFI loader knows where RSDP is
  480.         mov     ebx, [BOOT_LO.acpi_rsdp]
  481.         test    ebx, ebx
  482.         jz      .done
  483.         call    .check
  484. else
  485.         movzx   ebx, word [0x40E]
  486.         shl     ebx, 4
  487.         lea     ecx, [ebx+1024]
  488.         call    .check
  489.  
  490.         test    ebx, ebx
  491.         jz      @F
  492.         jmp     .done
  493.  
  494. @@:
  495.         mov     ebx, ACPI_HI_RSDP_WINDOW_START
  496.         mov     edi, ACPI_HI_RSDP_WINDOW_END
  497.         call    .check
  498. end if
  499. .done:
  500.         mov     [acpi_rsdp_base-OS_BASE], ebx
  501.         test    ebx, ebx
  502.         jz      @f
  503.         call    acpi_locate_tables
  504. @@:
  505.         pop     edi
  506.         pop     ebx
  507.         ret
  508.  
  509. .check:
  510.         cmp     [ebx], dword 'RSD '
  511.         jne     .next
  512.         cmp     [ebx+4], dword 'PTR '
  513.         jne     .next
  514.  
  515.         mov     edx, ebx
  516.         mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
  517.         xor     eax, eax
  518. .sum:
  519.         add     al, [edx]
  520.         inc     edx
  521.         loop    .sum
  522.  
  523.         test    al, al
  524.         jnz     .next
  525.         ret
  526. .next:
  527.         add     ebx, 16
  528.         cmp     ebx, edi
  529.         jb      .check
  530.         xor     ebx, ebx
  531.         ret
  532.