Subversion Repositories Kolibri OS

Rev

Rev 9899 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 9958 $
  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, PAGE_SIZE-1
  59.         jz      @f
  60.         neg     eax
  61.         and     eax, PAGE_SIZE-1
  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], -PAGE_SIZE
  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, -PAGE_SIZE
  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)+PAGE_SIZE-1
  107.         and     edx, -PAGE_SIZE
  108.         mov     [tmp_page_tabs], edx
  109.  
  110.         mov     edx, esi
  111.         and     edx, -1024
  112.         cmp     edx, (OS_BASE/PAGE_SIZE)
  113.         jbe     @F
  114.         mov     edx, (OS_BASE/PAGE_SIZE)
  115.         jmp     .set
  116. @@:
  117.         cmp     edx, (HEAP_BASE - OS_BASE + HEAP_MIN_SIZE)/PAGE_SIZE
  118.         jae     .set
  119.         mov     edx, (HEAP_BASE - OS_BASE + HEAP_MIN_SIZE)/PAGE_SIZE
  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, 2*PAGE_SIZE/4
  128.         cld
  129.         rep stosd
  130.  
  131.         mov     edx, (sys_proc - OS_BASE + PROC.pdt_0) + (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, PAGE_SIZE
  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, PAGE_SIZE
  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_RSDP_CHECKSUM_LENGTH  = 20
  414.  
  415. proc acpi_locate_tables uses ebx esi edi
  416.         mov     ebx, [ebx + ACPI_RSDP.RsdtAddress]
  417.         mov     [acpi_rsdt_base - OS_BASE], ebx
  418.         mov     eax, [ebx + ACPI_RSDT.Length]
  419.         mov     [acpi_rsdt_size - OS_BASE], eax
  420.  
  421.         mov     esi, [acpi_rsdt_base - OS_BASE]
  422.         mov     ecx, [esi + ACPI_RSDT.Length]
  423.         lea     edi, [esi + ecx]
  424.         add     esi, sizeof.ACPI_TABLE
  425.         movi    ecx, 1
  426. .next_table:
  427.         cmp     esi, edi
  428.         jae     .done
  429.         lodsd
  430.         cmp     [eax+ACPI_TABLE.Signature], 'SSDT'      ; skip DSDT if present
  431.         jz      .ssdt                                   ; read it from FADT
  432.         cmp     [eax+ACPI_TABLE.Signature], 'FACP'      ; this is FADT
  433.         jz      .fadt
  434.         cmp     [eax+ACPI_TABLE.Signature], 'APIC'      ; this is MADT
  435.         jz      .madt
  436.         cmp     [eax+ACPI_TABLE.Signature], 'HPET'
  437.         jz      .hpet
  438.         jmp     .next_table
  439. .ssdt:
  440.         mov     [acpi_ssdt_base + ecx*4 - OS_BASE], eax
  441.         mov     eax, [eax+ACPI_TABLE.Length]
  442.         mov     [acpi_ssdt_size + ecx*4 - OS_BASE], eax
  443.         inc     ecx
  444.         jmp     .next_table
  445. .fadt:
  446.         mov     [acpi_fadt_base - OS_BASE], eax
  447.         cmp     [eax + ACPI_FADT.DSDT], 0
  448.         jz      @f
  449.         mov     edx, [eax + ACPI_FADT.DSDT]
  450.         mov     [acpi_ssdt_base - OS_BASE], edx
  451.         mov     edx, [edx + ACPI_TABLE.Length]
  452.         mov     [acpi_ssdt_size - OS_BASE], edx
  453. @@:
  454.         mov     eax, [eax + ACPI_TABLE.Length]
  455.         mov     [acpi_fadt_size - OS_BASE], eax
  456.         jmp     .next_table
  457. .madt:
  458.         mov     [acpi_madt_base - OS_BASE], eax
  459.         mov     eax, [eax + ACPI_TABLE.Length]
  460.         mov     [acpi_madt_size - OS_BASE], eax
  461.         jmp     .next_table
  462. .hpet:
  463.         mov     [acpi_hpet_base - OS_BASE], eax
  464.         mov     eax, [eax + ACPI_TABLE.Length]
  465.         mov     [acpi_hpet_size - OS_BASE], eax
  466.         jmp     .next_table
  467. .done:
  468.         mov     [acpi_ssdt_cnt - OS_BASE], ecx
  469.         ret
  470. endp
  471.  
  472. acpi_locate:
  473.         push    ebx
  474.         push    edi
  475.  
  476.         mov     ebx, [BOOT_LO.acpi_rsdp]
  477.         test    ebx, ebx
  478.         jz      .done
  479.         mov     edi, ebx
  480.         call    .check
  481. .done:
  482.         mov     [acpi_rsdp_base - OS_BASE], ebx
  483.         test    ebx, ebx
  484.         jz      @f
  485.         call    acpi_locate_tables
  486. @@:
  487.         pop     edi
  488.         pop     ebx
  489.         ret
  490.  
  491. .check:
  492.         cmp     [ebx], dword 'RSD '
  493.         jne     .next
  494.         cmp     [ebx+4], dword 'PTR '
  495.         jne     .next
  496.  
  497.         mov     edx, ebx
  498.         mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
  499.         xor     eax, eax
  500. .sum:
  501.         add     al, [edx]
  502.         inc     edx
  503.         loop    .sum
  504.  
  505.         test    al, al
  506.         jnz     .next
  507.         ret
  508. .next:
  509.         add     ebx, 16
  510.         cmp     ebx, edi
  511.         jb      .check
  512.         xor     ebx, ebx
  513.         ret
  514.