Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8.  
  9. align 4
  10. proc mem_test
  11. ; if we have BIOS with fn E820, skip the test
  12.         cmp     [BOOT_LO.memmap_block_cnt], 0
  13.         jnz     .ret
  14.  
  15.         mov     eax, cr0
  16.         and     eax, not (CR0_CD + CR0_NW)
  17.         or      eax, CR0_CD       ;disable caching
  18.         mov     cr0, eax
  19.         wbinvd                    ;invalidate cache
  20.  
  21.         xor     edi, edi
  22.         mov     ebx, 'TEST'
  23. @@:
  24.         add     edi, 0x100000
  25.         xchg    ebx, dword [edi]
  26.         cmp     dword [edi], 'TEST'
  27.         xchg    ebx, dword [edi]
  28.         je      @b
  29.  
  30.         and     eax, not (CR0_CD + CR0_NW) ;enable caching
  31.         mov     cr0, eax
  32.         inc     dword [BOOT_LO.memmap_block_cnt]
  33.         xor     eax, eax
  34.         mov     [BOOT_LO.memmap_blocks + e820entry.addr.lo], eax
  35.         mov     [BOOT_LO.memmap_blocks + e820entry.addr.hi], eax
  36.         mov     [BOOT_LO.memmap_blocks + e820entry.size.lo], edi
  37.         mov     [BOOT_LO.memmap_blocks + e820entry.size.hi], eax
  38.         inc     eax
  39.         mov     [BOOT_LO.memmap_blocks + e820entry.type], eax
  40. .ret:
  41.         ret
  42. endp
  43.  
  44. align 4
  45. proc init_mem
  46. ; calculate maximum allocatable address and number of allocatable pages
  47.         mov     edi, BOOT_LO.memmap_blocks
  48.         mov     ecx, [edi-4]    ; memmap_block_cnt
  49.         xor     esi, esi; esi will hold total amount of memory
  50.         xor     edx, edx; edx will hold maximum allocatable address
  51. .calcmax:
  52. ; round all to pages
  53.         mov     eax, [edi + e820entry.addr.lo]
  54.         cmp     byte [edi + e820entry.type], 1
  55.         jne     .unusable
  56.  
  57.         test    eax, PAGE_SIZE-1
  58.         jz      @f
  59.         neg     eax
  60.         and     eax, PAGE_SIZE-1
  61.         add     [edi + e820entry.addr.lo], eax
  62.         adc     [edi + e820entry.addr.hi], 0
  63.         sub     [edi + e820entry.size.lo], eax
  64.         sbb     [edi + e820entry.size.hi], 0
  65.         jc      .unusable
  66. @@:
  67.         and     [edi + e820entry.size.lo], -PAGE_SIZE
  68.         jz      .unusable
  69. ; ignore memory after 4 GiB
  70.         cmp     [edi + e820entry.addr.hi], 0
  71.         jnz     .unusable
  72.         mov     eax, [edi + e820entry.addr.lo]
  73.         cmp     [edi + e820entry.size.hi], 0
  74.         jnz     .overflow
  75.         add     eax, [edi + e820entry.size.lo]
  76.         jnc     @f
  77. .overflow:
  78.         mov     eax, -PAGE_SIZE
  79. @@:
  80.         cmp     edx, eax
  81.         jae     @f
  82.         mov     edx, eax
  83. @@:
  84.         sub     eax, [edi + e820entry.addr.lo]
  85.         mov     [edi + e820entry.size.lo], eax
  86.         add     esi, eax
  87.         jmp     .usable
  88. .unusable:
  89. ;        and     dword [edi+e820entry.size.lo], 0
  90. .usable:
  91.         add     edi, sizeof.e820entry
  92.         loop    .calcmax
  93. .calculated:
  94.         mov     [MEM_AMOUNT - OS_BASE], esi
  95.         mov     [pg_data.mem_amount - OS_BASE], esi
  96.         shr     esi, 12
  97.         mov     [pg_data.pages_count - OS_BASE], esi
  98.  
  99.         shr     edx, 12
  100.         add     edx, 31
  101.         and     edx, not 31
  102.         shr     edx, 3
  103.         mov     [pg_data.pagemap_size - OS_BASE], edx
  104.  
  105.         add     edx, (sys_pgmap - OS_BASE)+PAGE_SIZE-1
  106.         and     edx, -PAGE_SIZE
  107.         mov     [tmp_page_tabs], edx
  108.  
  109.         mov     edx, esi
  110.         and     edx, -1024
  111.         cmp     edx, (OS_BASE/PAGE_SIZE)
  112.         jbe     @F
  113.         mov     edx, (OS_BASE/PAGE_SIZE)
  114.         jmp     .set
  115. @@:
  116.         cmp     edx, (HEAP_BASE - OS_BASE + HEAP_MIN_SIZE)/PAGE_SIZE
  117.         jae     .set
  118.         mov     edx, (HEAP_BASE - OS_BASE + HEAP_MIN_SIZE)/PAGE_SIZE
  119. .set:
  120.         mov     [pg_data.kernel_pages - OS_BASE], edx
  121.         shr     edx, 10
  122.         mov     [pg_data.kernel_tables - OS_BASE], edx
  123.  
  124.         xor     eax, eax
  125.         mov     edi, sys_proc - OS_BASE
  126.         mov     ecx, 2*PAGE_SIZE/4
  127.         cld
  128.         rep stosd
  129.  
  130.         mov     edx, (sys_proc - OS_BASE + PROC.pdt_0) + (OS_BASE shr 20)
  131.         bt      [cpu_caps - OS_BASE], CAPS_PSE
  132.         jnc     .no_PSE
  133.  
  134.         mov     ebx, cr4
  135.         or      ebx, CR4_PSE
  136.         mov     eax, PDE_LARGE + PG_SWR
  137.         mov     cr4, ebx
  138.         dec     [pg_data.kernel_tables - OS_BASE]
  139.  
  140.         mov     [edx], eax
  141.         add     edx, 4
  142.  
  143.         mov     edi, [tmp_page_tabs]
  144.         jmp     .map_kernel_heap        ; new kernel fits to the first 4Mb - nothing to do with ".map_low"
  145. .no_PSE:
  146.         mov     eax, PG_SWR
  147.         mov     ecx, [tmp_page_tabs]
  148.         shr     ecx, 12
  149. .map_low:
  150.         mov     edi, [tmp_page_tabs]
  151. @@:                                   ;
  152.         stosd
  153.         add     eax, PAGE_SIZE
  154.         dec     ecx
  155.         jnz     @B
  156.  
  157. .map_kernel_heap:
  158.         mov     ecx, [pg_data.kernel_tables - OS_BASE]
  159.         shl     ecx, 10
  160.         xor     eax, eax
  161.         rep stosd
  162.  
  163.         mov     ecx, [pg_data.kernel_tables - OS_BASE]
  164.         mov     eax, [tmp_page_tabs]
  165.         or      eax, PG_SWR
  166.         mov     edi, edx
  167.  
  168. .map_kernel_tabs:
  169.         stosd
  170.         add     eax, PAGE_SIZE
  171.         dec     ecx
  172.         jnz     .map_kernel_tabs
  173.  
  174.         mov     dword [sys_proc-OS_BASE+PROC.pdt_0+(page_tabs shr 20)], sys_proc+PROC.pdt_0+PG_SWR-OS_BASE
  175.  
  176.         mov     edi, (sys_proc + PROC.pdt_0 - OS_BASE)
  177.         lea     esi, [edi + (OS_BASE shr 20)]
  178.         movsd
  179.         movsd
  180.         ret
  181. endp
  182.  
  183. align 4
  184. proc init_page_map
  185. ; mark all memory as unavailable
  186.         mov     edi, sys_pgmap - OS_BASE
  187.         mov     ecx, [pg_data.pagemap_size - OS_BASE]
  188.         shr     ecx, 2
  189.         xor     eax, eax
  190.         cld
  191.         rep stosd
  192.  
  193. ; scan through memory map and mark free areas as available
  194.         mov     ebx, BOOT_LO.memmap_blocks
  195.         mov     edx, [ebx-4]
  196. .scanmap:
  197.         cmp     byte [ebx + e820entry.type], 1
  198.         jne     .next
  199.  
  200.         mov     ecx, [ebx + e820entry.size.lo]
  201.         shr     ecx, 12; ecx = number of pages
  202.         jz      .next
  203.         mov     edi, [ebx + e820entry.addr.lo]
  204.         shr     edi, 12; edi = first page
  205.         mov     eax, edi
  206.         shr     edi, 5
  207.         shl     edi, 2
  208.         add     edi, sys_pgmap - OS_BASE
  209.         and     eax, 31
  210.         jz      .startok
  211.         add     ecx, eax
  212.         sub     ecx, 32
  213.         jbe     .onedword
  214.         push    ecx
  215.         mov     ecx, eax
  216.         or      eax, -1
  217.         shl     eax, cl
  218.         or      [edi], eax
  219.         add     edi, 4
  220.         pop     ecx
  221. .startok:
  222.         push    ecx
  223.         shr     ecx, 5
  224.         or      eax, -1
  225.         rep stosd
  226.         pop     ecx
  227.         and     ecx, 31
  228.         neg     eax
  229.         shl     eax, cl
  230.         dec     eax
  231.         or      [edi], eax
  232.         jmp     .next
  233. .onedword:
  234.         add     ecx, 32
  235.         sub     ecx, eax
  236. @@:
  237.         bts     [edi], eax
  238.         inc     eax
  239.         loop    @b
  240. .next:
  241.         add     ebx, sizeof.e820entry
  242.         dec     edx
  243.         jnz     .scanmap
  244.  
  245. ; mark kernel memory as allocated (unavailable)
  246.         mov     ecx, [tmp_page_tabs]
  247.         mov     edx, [pg_data.pages_count - OS_BASE]
  248.         shr     ecx, 12
  249.         add     ecx, [pg_data.kernel_tables - OS_BASE]
  250.         sub     edx, ecx
  251.         mov     [pg_data.pages_free - OS_BASE], edx
  252.  
  253.         mov     edi, sys_pgmap - OS_BASE
  254.         mov     ebx, ecx
  255.         shr     ecx, 5
  256.         xor     eax, eax
  257.         rep stosd
  258.  
  259.         not     eax
  260.         mov     ecx, ebx
  261.         and     ecx, 31
  262.         shl     eax, cl
  263.         and     [edi], eax
  264.         add     edi, OS_BASE
  265.         mov     [page_start - OS_BASE], edi;
  266.  
  267.         mov     ebx, sys_pgmap
  268.         add     ebx, [pg_data.pagemap_size - OS_BASE]
  269.         mov     [page_end - OS_BASE], ebx
  270.  
  271.         ret
  272. endp
  273.  
  274. align 4
  275.  
  276. init_BIOS32:
  277.         mov     edi, 0xE0000
  278. .pcibios_nxt:
  279.         cmp     dword[edi], '_32_'; "magic" word
  280.         je      .BIOS32_found
  281. .pcibios_nxt2:
  282.         add     edi, 0x10
  283.         cmp     edi, 0xFFFF0
  284.         je      .BIOS32_not_found
  285.         jmp     .pcibios_nxt
  286. .BIOS32_found:                  ; magic word found, check control summ
  287.  
  288.         movzx   ecx, byte[edi + 9]
  289.         shl     ecx, 4
  290.         mov     esi, edi
  291.         xor     eax, eax
  292.         cld      ; paranoia
  293. @@:
  294.         lodsb
  295.         add     ah, al
  296.         loop    @b
  297.         jnz     .pcibios_nxt2; control summ must be zero
  298.     ; BIOS32 service found !
  299.         mov     ebp, [edi + 4]
  300.         mov     [bios32_entry], ebp
  301.     ; check PCI BIOS present
  302.         mov     eax, '$PCI'
  303.         xor     ebx, ebx
  304.         push    cs  ; special for 'ret far' from  BIOS
  305.         call    ebp
  306.         test    al, al
  307.         jnz     .PCI_BIOS32_not_found
  308.  
  309.  ; descriptors for PCI BIOS are created here
  310.  
  311.         add     ebx, OS_BASE
  312.         dec     ecx
  313.         mov     [(pci_code_32 - OS_BASE)], cx   ;limit 0-15
  314.         mov     [(pci_data_32 - OS_BASE)], cx   ;limit 0-15
  315.  
  316.         mov     [(pci_code_32 - OS_BASE)+2], bx ;base  0-15
  317.         mov     [(pci_data_32 - OS_BASE)+2], bx ;base  0-15
  318.  
  319.         shr     ebx, 16
  320.         mov     [(pci_code_32 - OS_BASE)+4], bl ;base  16-23
  321.         mov     [(pci_data_32 - OS_BASE)+4], bl ;base  16-23
  322.  
  323.         shr     ecx, 16
  324.         and     cl, 0x0F
  325.         mov     ch, bh
  326.         add     cx, D32
  327.         mov     [(pci_code_32 - OS_BASE)+6], cx ;lim   16-19 &
  328.         mov     [(pci_data_32 - OS_BASE)+6], cx ;base  24-31
  329.  
  330.         mov     [(pci_bios_entry - OS_BASE)], edx
  331.          ; jmp .end
  332. .PCI_BIOS32_not_found:
  333.         ; pci_emu_dat structure should be filled here
  334. .BIOS32_not_found:
  335. .end:
  336.         ret
  337.  
  338. align 4
  339. proc test_cpu
  340.            locals
  341.               cpu_type   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.         mov     [cpu_phys_addr_width - OS_BASE], 32
  349.  
  350.         pushfd
  351.         pop     eax
  352.         mov     ecx, eax
  353.         xor     eax, EFLAGS_AC
  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, EFLAGS_ID
  367.         push    eax
  368.         popfd
  369.         pushfd
  370.         pop     eax
  371.         xor     eax, ecx
  372.         je      .end_cpuid
  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.  
  381.         cmp     eax, 1
  382.         jl      .end_cpuid
  383.         mov     eax, 1
  384.         cpuid
  385.         mov     [cpu_sign - OS_BASE], eax
  386.         mov     [cpu_info - OS_BASE], ebx
  387.         mov     [cpu_caps - OS_BASE], edx
  388.         mov     [cpu_caps + 4 - OS_BASE], ecx
  389.  
  390.         bt      edx, CAPS_PAE
  391.         jnc     @f
  392.         mov     [cpu_phys_addr_width - OS_BASE], 36
  393. @@:
  394.         mov     eax, 0x80000000
  395.         cpuid
  396.         cmp     eax, 0x80000008
  397.         jb      @f
  398.         mov     eax, 0x80000008
  399.         cpuid
  400.         mov     [cpu_phys_addr_width - OS_BASE], al
  401. @@:
  402.  
  403.         mov     eax, [cpu_sign - OS_BASE]
  404.         shr     eax, 8
  405.         and     eax, 0x0f
  406.         ret
  407. .end_cpuid:
  408.         mov     eax, [cpu_type]
  409.         ret
  410. endp
  411.  
  412. ACPI_RSDP_CHECKSUM_LENGTH  = 20
  413.  
  414. proc acpi_locate_tables uses ebx esi edi
  415.         mov     ebx, [ebx + ACPI_RSDP.RsdtAddress]
  416.         mov     [acpi_rsdt_base - OS_BASE], ebx
  417.         mov     eax, [ebx + ACPI_RSDT.Length]
  418.         mov     [acpi_rsdt_size - OS_BASE], eax
  419.  
  420.         mov     esi, [acpi_rsdt_base - OS_BASE]
  421.         mov     ecx, [esi + ACPI_RSDT.Length]
  422.         lea     edi, [esi + ecx]
  423.         add     esi, sizeof.ACPI_TABLE
  424.         movi    ecx, 1
  425. .next_table:
  426.         cmp     esi, edi
  427.         jae     .done
  428.         lodsd
  429.         cmp     [eax+ACPI_TABLE.Signature], 'SSDT'      ; skip DSDT if present
  430.         jz      .ssdt                                   ; read it from FADT
  431.         cmp     [eax+ACPI_TABLE.Signature], 'FACP'      ; this is FADT
  432.         jz      .fadt
  433.         cmp     [eax+ACPI_TABLE.Signature], 'APIC'      ; this is MADT
  434.         jz      .madt
  435.         cmp     [eax+ACPI_TABLE.Signature], 'HPET'
  436.         jz      .hpet
  437.         jmp     .next_table
  438. .ssdt:
  439.         mov     [acpi_ssdt_base + ecx*4 - OS_BASE], eax
  440.         mov     eax, [eax+ACPI_TABLE.Length]
  441.         mov     [acpi_ssdt_size + ecx*4 - OS_BASE], eax
  442.         inc     ecx
  443.         jmp     .next_table
  444. .fadt:
  445.         mov     [acpi_fadt_base - OS_BASE], eax
  446.         cmp     [eax + ACPI_FADT.DSDT], 0
  447.         jz      @f
  448.         mov     edx, [eax + ACPI_FADT.DSDT]
  449.         mov     [acpi_ssdt_base - OS_BASE], edx
  450.         mov     edx, [edx + ACPI_TABLE.Length]
  451.         mov     [acpi_ssdt_size - OS_BASE], edx
  452. @@:
  453.         mov     eax, [eax + ACPI_TABLE.Length]
  454.         mov     [acpi_fadt_size - OS_BASE], eax
  455.         jmp     .next_table
  456. .madt:
  457.         mov     [acpi_madt_base - OS_BASE], eax
  458.         mov     eax, [eax + ACPI_TABLE.Length]
  459.         mov     [acpi_madt_size - OS_BASE], eax
  460.         jmp     .next_table
  461. .hpet:
  462.         mov     [acpi_hpet_base - OS_BASE], eax
  463.         mov     eax, [eax + ACPI_TABLE.Length]
  464.         mov     [acpi_hpet_size - OS_BASE], eax
  465.         jmp     .next_table
  466. .done:
  467.         mov     [acpi_ssdt_cnt - OS_BASE], ecx
  468.         ret
  469. endp
  470.  
  471. acpi_locate:
  472.         push    ebx
  473.         push    edi
  474.  
  475.         mov     ebx, [BOOT_LO.acpi_rsdp]
  476.         test    ebx, ebx
  477.         jz      .done
  478.         mov     edi, ebx
  479.         call    .check
  480. .done:
  481.         mov     [acpi_rsdp_base - OS_BASE], ebx
  482.         test    ebx, ebx
  483.         jz      @f
  484.         call    acpi_locate_tables
  485. @@:
  486.         pop     edi
  487.         pop     ebx
  488.         ret
  489.  
  490. .check:
  491.         cmp     [ebx], dword 'RSD '
  492.         jne     .next
  493.         cmp     [ebx+4], dword 'PTR '
  494.         jne     .next
  495.  
  496.         mov     edx, ebx
  497.         mov     ecx, ACPI_RSDP_CHECKSUM_LENGTH
  498.         xor     eax, eax
  499. .sum:
  500.         add     al, [edx]
  501.         inc     edx
  502.         loop    .sum
  503.  
  504.         test    al, al
  505.         jnz     .next
  506.         ret
  507. .next:
  508.         add     ebx, 16
  509.         cmp     ebx, edi
  510.         jb      .check
  511.         xor     ebx, ebx
  512.         ret
  513.