Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2020-2021. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;; Version 2, or (at your option) any later version.            ;;
  6. ;;                                                              ;;
  7. ;; Written by Ivan Baravy                                       ;;
  8. ;;                                                              ;;
  9. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10.  
  11. format pe64 efi
  12. entry main
  13.  
  14. section '.text' code executable readable
  15.  
  16. include '../../struct.inc'
  17. include '../../macros.inc'
  18. include '../../kglobals.inc'
  19. fastcall fix fstcall
  20. include 'proc64.inc'
  21. include '../../const.inc'
  22.  
  23. purge DQ
  24. include 'uefi64.inc'
  25.  
  26. MEMORY_MAP_SIZE = 0x10000
  27. PROTOCOL_HANDLERS_BUFFER_SIZE = 0x100
  28. FILE_BUFFER_SIZE = 0x1000
  29.  
  30. KERNEL_TRAMPOLINE = 0x8f80      ; just before BOOT_LO
  31. KERNEL_BASE  =  0x10000
  32. RAMDISK_BASE = 0x100000
  33. MAX_FILE_SIZE = 0x10000000
  34.  
  35. CODE_32_SELECTOR = 8
  36. DATA_32_SELECTOR = 16
  37. CODE_64_SELECTOR = 24
  38.  
  39. ; linux/arch/x86/include/uapi/asm/e820.h
  40. E820_RAM       = 1
  41. E820_RESERVED  = 2
  42. E820_ACPI      = 3
  43. E820_NVS       = 4
  44. E820_UNUSABLE  = 5
  45. E820_PMEM      = 7
  46.  
  47. load_file:
  48. virtual at rsp+8
  49.   .root   dq ?
  50.   .name   dq ?
  51.   .buffer dq ?
  52.   .size   dq ?
  53.   .fatal  dq ?
  54. end virtual
  55.         mov     r10, [.root]
  56.         mov     r11, [.name]
  57.         fstcall [r10+EFI_FILE_PROTOCOL.Open], r10, file_handle, \
  58.                 r11, EFI_FILE_MODE_READ, 0
  59.         test    eax, eax
  60.         jz      @f
  61.         xor     eax, eax
  62.         cmp     [.fatal], 1
  63.         jnz     .done
  64.         mov     rbx, [efi_table]
  65.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  66.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  67.                 msg_error_open_file
  68.         mov     rbx, [efi_table]
  69.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  70.         mov     r10, [.name]
  71.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, r10
  72.         jmp     $
  73. @@:
  74.  
  75.         lea     rdx, [.size]
  76.         mov     r8, [.buffer]
  77.         mov     r10, [file_handle]
  78.         fstcall [r10+EFI_FILE_PROTOCOL.Read], [file_handle], rdx, r8
  79.         mov     r10, [file_handle]
  80.         fstcall [r10+EFI_FILE_PROTOCOL.Close], [file_handle]
  81.         mov     rax, [.size]
  82. .done:
  83.         push    rax
  84.         call    clearbuf
  85.         mov     rdi, msg
  86.         call    num2dec
  87.         push    rbx
  88.         mov     rbx, [efi_table]
  89.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  90.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  91.                 msg_file_size
  92.         pop     rbx
  93.         push    rbx
  94.         mov     rbx, [efi_table]
  95.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  96.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  97.         pop     rbx
  98.         pop     rax
  99.         ret     8*5
  100.  
  101. skip_whitespace:
  102. .next_char:
  103.         cmp     byte[rsi], 0
  104.         jz      .done
  105.         cmp     byte[rsi], 0x20 ; ' '
  106.         jz      .whitespace
  107.         cmp     byte[rsi], 9    ; '\t'
  108.         jz      .whitespace
  109.         jmp     .done
  110. .whitespace:
  111.         inc     rsi
  112.         jmp     .next_char
  113. .done:
  114.         ret
  115.  
  116. skip_until_newline:
  117. .next_char:
  118.         cmp     byte[rsi], 0
  119.         jz      .done
  120.         cmp     byte[rsi], 0xd  ; '\r'
  121.         jz      .done
  122.         cmp     byte[rsi], 0xa  ; '\n'
  123.         jz      .done
  124.         inc     rsi
  125.         jmp     .next_char
  126. .done:
  127.         ret
  128.  
  129. skip_newline:
  130. .next_char:
  131.         cmp     byte[rsi], 0xd  ; '\r'
  132.         jz      .newline
  133.         cmp     byte[rsi], 0xa  ; '\n'
  134.         jz      .newline
  135.         jmp     .done
  136. .newline:
  137.         inc     rsi
  138.         jmp     .next_char
  139. .done:
  140.         ret
  141.  
  142. skip_line:
  143.         call    skip_until_newline
  144.         call    skip_newline
  145.         ret
  146.  
  147. dec2bin:
  148.         mov     edx, 0
  149. .next_char:
  150.         movzx   eax, byte[rsi]
  151.         test    eax, eax
  152.         jz      .done
  153.         sub     eax, '0'
  154.         jb      .done
  155.         cmp     eax, 9
  156.         ja      .done
  157.         inc     rsi
  158.         imul    edx, 10
  159.         add     edx, eax
  160.         jmp     .next_char
  161. .done:
  162.         mov     eax, edx
  163.         ret
  164.  
  165. parse_option:
  166.         mov     rbx, config_options-3*8
  167. .try_next_option:
  168.         add     rbx, 3*8
  169.         mov     rdi, rsi
  170.         mov     rdx, [rbx]      ; option name
  171.         test    rdx, rdx
  172.         jz      .done
  173. .next_char:
  174.         cmp     byte[rdx], 0
  175.         jnz     @f
  176.         cmp     byte[rdi], '='
  177.         jz      .opt_name_ok
  178. @@:
  179.         cmp     byte[rdi], 0
  180.         jz      .done
  181.         movzx   eax, byte[rdi]
  182.         cmp     [rdx], al
  183.         jnz     .try_next_option
  184.         inc     rdi
  185.         inc     rdx
  186.         jmp     .next_char
  187. .opt_name_ok:
  188.         inc     rdi
  189.         mov     rsi, rdi
  190.         call    qword[rbx+8]
  191. .done:
  192.         ret
  193.  
  194. parse_line:
  195. .next_line:
  196.         cmp     byte[rsi], 0
  197.         jz      .done
  198.         cmp     byte[rsi], 0xd  ; '\r'
  199.         jz      .skip
  200.         cmp     byte[rsi], 0xa  ; '\n'
  201.         jz      .skip
  202.         cmp     byte[rsi], '#'
  203.         jz      .skip
  204.         call    parse_option
  205.         call    skip_line
  206.         jmp     .next_line
  207. .skip:
  208.         call    skip_line
  209.         jmp     .next_line
  210. .done:
  211.         ret
  212.  
  213. cfg_opt_func_resolution:
  214.         call    dec2bin
  215.         xor     edx, edx
  216.         mov     [rdx+BOOT_LO.x_res], ax
  217.         cmp     byte[rsi], 'x'
  218.         jz      @f
  219.         cmp     byte[rsi], '*'
  220.         jz      @f
  221.         jmp     .done
  222. @@:
  223.         inc     rsi
  224.         call    dec2bin
  225.         xor     edx, edx
  226.         mov     [rdx+BOOT_LO.y_res], ax
  227.         mov     [cfg_opt_used_resolution], 1
  228. .done:
  229.         ret
  230.  
  231. cfg_opt_func_acpi:
  232.         call    dec2bin
  233.         mov     [cfg_opt_used_acpi], 1
  234.         mov     [cfg_opt_value_acpi], al
  235.         ret
  236.  
  237. cfg_opt_func_debug_print:
  238.         call    dec2bin
  239.         mov     [cfg_opt_used_debug_print], 1
  240.         mov     [cfg_opt_value_debug_print], al
  241.         ret
  242.  
  243. cfg_opt_func_launcher_start:
  244.         call    dec2bin
  245.         mov     [cfg_opt_used_launcher_start], 1
  246.         mov     [cfg_opt_value_launcher_start], al
  247.         ret
  248.  
  249. cfg_opt_func_mtrr:
  250.         call    dec2bin
  251.         mov     [cfg_opt_used_mtrr], 1
  252.         mov     [cfg_opt_value_mtrr], al
  253.         ret
  254.  
  255. cfg_opt_func_ask_params:
  256.         call    dec2bin
  257.         mov     [cfg_opt_used_ask_params], 1
  258.         mov     [cfg_opt_value_ask_params], al
  259.         ret
  260.  
  261. cfg_opt_func_imgfrom:
  262.         call    dec2bin
  263.         mov     [cfg_opt_used_imgfrom], 1
  264.         mov     [cfg_opt_value_imgfrom], al
  265.         ret
  266.  
  267. cfg_opt_func_syspath:
  268.         mov     rdi, cfg_opt_value_syspath
  269. .next_char:
  270.         movzx   eax, byte[rsi]
  271.         cmp     al, 0xd ; \r
  272.         jz      .done
  273.         cmp     al, 0xa ; \n
  274.         jz      .done
  275.         inc     rsi
  276.         stosb
  277.         jmp     .next_char
  278. .done:
  279.         mov     byte[rdi], 0
  280.         ret
  281.  
  282. parse_config:
  283. virtual at rsp+8
  284.   .buffer      dq ?
  285. end virtual
  286. ;        mov     rsi, [.buffer]
  287.         push    rbx
  288.         mov     rbx, [efi_table]
  289.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  290.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  291.                 msg_parsing_config
  292.         pop     rbx
  293.         mov     rsi, KERNEL_BASE
  294. .next_line:
  295.         call    parse_line
  296.         cmp     byte[rsi], 0
  297.         jnz     .next_line
  298.         ret     1*8
  299.  
  300. read_options_from_config:
  301.         mov     rbx, [efi_table]
  302.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
  303.         fstcall [rbx+EFI_BOOT_SERVICES.HandleProtocol], [efi_handle], lip_guid, \
  304.                 lip_interface
  305.         test    eax, eax
  306.         jz      @f
  307.         push    rbx
  308.         mov     rbx, [efi_table]
  309.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  310.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  311.                 msg_error_efi_lip_handle
  312.         pop     rbx
  313.         jmp     $
  314. @@:
  315.         mov     r10, [lip_interface]
  316.         mov     rbx, [efi_table]
  317.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
  318.         fstcall [rbx+EFI_BOOT_SERVICES.HandleProtocol], \
  319.                 [r10+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle], sfsp_guid, \
  320.                 sfsp_interface
  321.         test    eax, eax
  322.         jz      @f
  323.         push    rbx
  324.         mov     rbx, [efi_table]
  325.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  326.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  327.                 msg_error_lip_dev_sfsp
  328.         pop     rbx
  329.         jmp     $
  330. @@:
  331.         mov     r10, [sfsp_interface]
  332.         fstcall [r10+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume], \
  333.                 [sfsp_interface], esp_root
  334.         test    eax, eax
  335.         jz      @f
  336.         push    rbx
  337.         mov     rbx, [efi_table]
  338.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  339.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  340.                 msg_error_sfsp_openvolume
  341.         pop     rbx
  342.         jmp     $
  343. @@:
  344.         push    0 ; not fatal, i.e. it's ok to not find this file
  345.         push    FILE_BUFFER_SIZE
  346.         push    KERNEL_BASE
  347. ;        push    file_name
  348.         mov     rax, file_name
  349.         push    rax
  350.         push    [esp_root]
  351.         call    load_file
  352.  
  353.         test    eax, eax
  354.         jz      @f
  355.         push    KERNEL_BASE
  356.         call    parse_config
  357. @@:
  358.  
  359. .error:
  360.         ret
  361.  
  362. print_vmode:
  363.         push    rax rbx rcx rdx rsi rdi
  364.         mov     rbx, rcx
  365.         call    clearbuf
  366.         mov     eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
  367.         mov     rdi, msg
  368.         call    num2dec
  369.         mov     eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
  370.         mov     rdi, msg+8*2
  371.         call    num2dec
  372.  
  373.         mov     eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat]
  374.         mov     rdi, msg+16*2
  375.         call    num2dec
  376.  
  377.         mov     eax, [rbx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine]
  378.         mov     rdi, msg+24*2
  379.         call    num2dec
  380.         mov     rbx, [efi_table]
  381.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  382.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  383.         pop     rdi rsi rdx rcx rbx rax
  384.         ret
  385.  
  386. find_vmode_index_by_resolution:
  387.         mov     [cfg_opt_used_resolution], 1
  388.         mov     [cfg_opt_value_vmode], 0
  389. .next_mode:
  390.         movzx   edx, [cfg_opt_value_vmode]
  391.         mov     r10, [gop_interface]
  392.         fstcall [r10+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], [gop_interface], \
  393.                 rdx, gop_info_size, gop_info
  394.         cmp     rax, EFI_SUCCESS
  395.         jnz     .error
  396.         mov     rcx, [gop_info]
  397.         call    print_vmode
  398.         ; PixelBlueGreenRedReserved8BitPerColor
  399.         cmp     [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat], 1
  400.         jnz     .skip_mode
  401.         xor     edx, edx
  402.         mov     eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
  403.         cmp     ax, [rdx+BOOT_LO.x_res]
  404.         jnz     .skip_mode
  405.         mov     eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
  406.         cmp     ax, [rdx+BOOT_LO.y_res]
  407.         jnz     .skip_mode
  408.         jmp     .done
  409. .skip_mode:
  410.         inc     [cfg_opt_value_vmode]
  411.         movzx   eax, [cfg_opt_value_vmode]
  412.         mov     rcx, [gop_interface]
  413.         mov     rdx, [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode]
  414.         cmp     eax, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode]
  415.         jnz     .next_mode
  416.         mov     [cfg_opt_used_resolution], 0
  417.         mov     [cfg_opt_value_ask_params], 1
  418.  
  419.         mov     rbx, [efi_table]
  420.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  421.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  422.                 msg_error_no_such_vmode
  423.         mov     rbx, [efi_table]
  424.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  425.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  426.                 msg_error
  427.         jmp     $
  428. .error:
  429. .done:
  430.         ret
  431.  
  432. ask_for_params:
  433.         ret
  434.  
  435.         xor     ebx, ebx
  436. .next_mode:
  437.         call    clearbuf
  438.         mov     eax, ebx
  439.         lea     rdi, [msg]
  440.         call    num2dec
  441.  
  442.         push    rbx
  443.         mov     r10, [gop_interface]
  444.         fstcall [r10+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], [gop_interface], \
  445.                 rbx, gop_info_size, gop_info
  446.         cmp     rax, EFI_SUCCESS
  447.         jnz     .error
  448.         mov     rcx, [gop_info]
  449.         ; PixelBlueGreenRedReserved8BitPerColor
  450.         cmp     [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat], 1
  451.         jnz     .skip
  452.         mov     eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
  453.         lea     rdi, [msg+4*2]
  454.         call    num2dec
  455.         mov     eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
  456.         lea     rdi, [msg+9*2]
  457.         call    num2dec
  458. ;        mov     eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine]
  459. ;        lea     rdi, [msg+14*2]
  460. ;        call    num2dec
  461. .skip:
  462.         mov     rbx, [efi_table]
  463.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  464.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  465.         cmp     rax, EFI_SUCCESS
  466.         jnz     .error
  467.  
  468.         pop     rbx
  469.         inc     rbx
  470.         mov     rcx, [gop_interface]
  471.         mov     rdx, [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode]
  472.         cmp     ebx, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode]
  473.         jnz     .next_mode
  474.  
  475.  
  476.         mov     rbx, [efi_table]
  477.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConIn]
  478.         fstcall [rbx+SIMPLE_INPUT_INTERFACE.Reset], rbx, 1
  479.         cmp     rax, EFI_SUCCESS
  480.         jnz     .error
  481.         xor     ecx, ecx
  482.     @@:
  483.         push    rcx
  484.         mov     rbx, [efi_table]
  485.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConIn]
  486.         fstcall [rbx+SIMPLE_INPUT_INTERFACE.ReadKeyStroke], rbx, msg
  487.         pop     rcx
  488.         mov     rdx, EFI_DEVICE_ERROR
  489.         cmp     rax, rdx
  490.         jz      .error
  491.         mov     rdx, EFI_NOT_READY
  492.         cmp     rax, rdx
  493.         jz      @b
  494. ;        cmp     rax, EFI_SUCCESS
  495.         movzx   eax, word[msg+2]
  496. ;jmp .key_done
  497.         cmp     al, 0x0D
  498.         jz      .key_done
  499.         imul    ecx, 10
  500.         sub     eax, '0'
  501.         add     ecx, eax
  502.         jmp     @b
  503. .key_done:
  504.         mov     [cfg_opt_value_vmode], cl
  505. .error:
  506. .done:
  507.         ret
  508.  
  509. detect_pci_config:
  510.         fstcall get_protocol_interface, pcirbiop_guid
  511.         mov     [pcirbiop_interface], rax
  512.         mov     r10, rax
  513.         fstcall [r10+EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Configuration], r10, \
  514.                 pcirbiop_resources
  515. ;        fstcall dump_pci_resources
  516.         fstcall get_last_pci_bus
  517.         call    clearbuf
  518.         movzx   eax, [pci_last_bus]
  519.         mov     rdi, msg
  520.         call    num2hex
  521.         push    rbx
  522.         mov     rbx, [efi_table]
  523.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  524.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  525.                 msg_pci_last_bus
  526.         pop     rbx
  527.         push    rbx
  528.         mov     rbx, [efi_table]
  529.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  530.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  531.         pop     rbx
  532.         ret
  533.  
  534. proc get_last_pci_bus
  535.         mov     rsi, [pcirbiop_resources]
  536. .next_resource:
  537.         cmp     [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Type], \
  538.                 EFI_RESOURCE_DESCRIPTOR_TYPE.END_TAG
  539.         jz      .not_found
  540.         mov     rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.RangeMaximum]
  541.         cmp     [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.ResourceType], \
  542.                 EFI_RESOURCE_TYPE.BUS
  543.         jz      .found
  544.         movzx   eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Length]
  545.         lea     rsi, [rsi+rax+3]
  546.         jmp     .next_resource
  547. .found:
  548.         mov     [pci_last_bus], al
  549. .not_found:
  550.         ret
  551. endp
  552.  
  553. proc main _efi_handle, _efi_table
  554.         mov     [efi_handle], rcx
  555.         mov     [efi_table], rdx
  556.  
  557.         mov     rbx, [efi_table]
  558.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  559.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset], rbx, 1
  560.         test    eax, eax
  561.         jz      @f
  562.         jmp     $       ; what can I do here?
  563. @@:
  564.         mov     rbx, [efi_table]
  565.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  566.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  567.                 msg_u4k_loaded
  568.  
  569.         mov     rbx, [efi_table]
  570.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  571.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  572.                 msg_detect_pci_config
  573.  
  574.         call    detect_pci_config
  575.  
  576.         mov     rbx, [efi_table]
  577.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  578.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  579.                 msg_read_options
  580.         call    read_options_from_config
  581.  
  582.         ; read kernel file
  583.         mov     rbx, [efi_table]
  584.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  585.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  586.                 msg_load_kernel
  587.         push    1       ; fatal
  588.         push    MAX_FILE_SIZE
  589.         push    KERNEL_BASE
  590. ;        push    kernel_name
  591.         mov     rax, kernel_name
  592.         push    rax
  593.         push    [esp_root]
  594.         call    load_file
  595.  
  596.         ; read ramdisk image
  597.         mov     rbx, [efi_table]
  598.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  599.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  600.                 msg_load_ramdisk
  601.         push    1       ; fatal
  602.         push    MAX_FILE_SIZE
  603.         push    RAMDISK_BASE
  604. ;        push    ramdisk_name
  605.         mov     rax, ramdisk_name
  606.         push    rax
  607.         push    [esp_root]
  608.         call    load_file
  609.  
  610.         ; alloc buffer for devices.dat
  611.         mov     rbx, [efi_table]
  612.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  613.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  614.                 msg_alloc_devicesdat
  615.         mov     rbx, [efi_table]
  616.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
  617.         fstcall [rbx+EFI_BOOT_SERVICES.AllocatePages], \
  618.                 EFI_ALLOCATE_MAX_ADDRESS, EFI_RESERVED_MEMORY_TYPE, 1, \
  619.                 devicesdat_data
  620.         cmp     eax, EFI_SUCCESS
  621.         jnz     .error
  622.  
  623.         ; read devices.dat
  624.         mov     rbx, [efi_table]
  625.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  626.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  627.                 msg_load_devicesdat
  628.  
  629.         push    0 ; not fatal
  630.         push    [devicesdat_size]
  631.         push    [devicesdat_data]
  632. ;        push    devicesdat_name
  633.         mov     rax, devicesdat_name
  634.         push    rax
  635.         push    [esp_root]
  636.         call    load_file
  637.         mov     [devicesdat_size], rax
  638.  
  639.         mov     rbx, [efi_table]
  640.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  641.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  642.                 msg_locate_gop_interface
  643.  
  644.         fstcall get_protocol_interface, gop_guid
  645.         mov     [gop_interface], rax
  646.  
  647.         call    find_rsdp
  648.  
  649.         mov     rbx, [efi_table]
  650.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  651.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  652.                 msg_acpi_tables_done
  653.  
  654.         cmp     [cfg_opt_used_resolution], 0
  655.         jz      .not_used_resolution
  656.         mov     rbx, [efi_table]
  657.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  658.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  659.                 msg_opt_resolution
  660.         call    clearbuf
  661.         xor     edx, edx
  662.         movzx   eax, [rdx+BOOT_LO.x_res]
  663.         mov     rdi, msg
  664.         call    num2dec
  665.         xor     edx, edx
  666.         movzx   eax, [rdx+BOOT_LO.y_res]
  667.         mov     rdi, msg+8*2
  668.         call    num2dec
  669.         mov     rbx, [efi_table]
  670.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  671.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  672.         call    find_vmode_index_by_resolution
  673. .not_used_resolution:
  674.         cmp     [cfg_opt_used_debug_print], 0
  675.         jz      .not_used_debug_print
  676.         movzx   eax, [cfg_opt_value_debug_print]
  677.         xor     edx, edx
  678.         mov     [rdx+BOOT_LO.debug_print], al
  679. .not_used_debug_print:
  680.  
  681.         cmp     [cfg_opt_value_ask_params], 0
  682.         jz      @f
  683.         call    ask_for_params
  684. @@:
  685.  
  686.         movzx   edx, [cfg_opt_value_vmode]
  687.         mov     r10, [gop_interface]
  688.         fstcall [r10+EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode], [gop_interface], rdx
  689.         test    eax, eax
  690.         jz      @f
  691.         call    clearbuf
  692.         mov     rdi, msg
  693.         call    num2hex
  694.         mov     rbx, [efi_table]
  695.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  696.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  697.         mov     rbx, [efi_table]
  698.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  699.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  700.                 msg_error
  701.         jmp     $
  702. @@:
  703.  
  704.         mov     rcx, [gop_interface]
  705.         mov     rdx, [rcx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode]
  706.         mov     rdi, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.FrameBufferBase]
  707.         mov     [fb_base], rdi
  708.  
  709.         mov     ebx, [rdx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.Mode]
  710.         mov     rax, [gop_interface]
  711.         fstcall [rax+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], [gop_interface], \
  712.                 rbx, gop_info_size, gop_info
  713.         test    eax, eax
  714.         jz      @f
  715.         jmp     .error
  716. @@:
  717.         mov     rcx, [gop_info]
  718.         mov     eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
  719.         xor     rdx, rdx
  720.         mov     [rdx+BOOT_LO.x_res], ax
  721.         mov     eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
  722.         mov     [rdx+BOOT_LO.y_res], ax
  723.         mov     eax, [rcx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine]
  724.         shl     eax, 2
  725.         mov     [rdx+BOOT_LO.pitch], ax
  726.  
  727.         mov     [rdx+BOOT_LO.pci_data.access_mechanism], 1
  728.         movzx   eax, [pci_last_bus]
  729.         mov     [rdx+BOOT_LO.pci_data.last_bus], al
  730.         mov     [rdx+BOOT_LO.pci_data.version], 0x0300  ; PCI 3.0
  731.         mov     [rdx+BOOT_LO.pci_data.pm_entry], 0
  732.  
  733.         ; kernel
  734. ;        fstcall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \
  735. ;                450000/0x1000, EFI_ALLOCATE_ADDRESS
  736.  
  737.         ; ramdisk
  738. ;        fstcall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \
  739. ;                2880*512/0x1000, EFI_ALLOCATE_ADDRESS
  740.  
  741.         call    calc_memmap
  742. ;        fstcall dump_memmap
  743.  
  744.         mov     rbx, [efi_table]
  745.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
  746.         fstcall [rbx+EFI_BOOT_SERVICES.ExitBootServices], [efi_handle], \
  747.                 [memory_map_key]
  748.         call    halt_on_error
  749.  
  750.         cli
  751.  
  752.         xor     edx, edx
  753.         xor     esi, esi
  754.         mov     [esi+BOOT_LO.bpp], 32
  755.         mov     [esi+BOOT_LO.vesa_mode], dx
  756.         mov     [esi+BOOT_LO.bank_switch], edx
  757.         mov     rdi, [fb_base]
  758.         mov     [esi+BOOT_LO.lfb], edi
  759.  
  760.         movzx   eax, [cfg_opt_value_mtrr]
  761.         mov     [esi+BOOT_LO.mtrr], al
  762.  
  763.         movzx   eax, [cfg_opt_value_launcher_start]
  764.         mov     [esi+BOOT_LO.launcher_start], al
  765.  
  766.         movzx   eax, [cfg_opt_value_debug_print]
  767.         mov     [esi+BOOT_LO.debug_print], al
  768.  
  769.         mov     [esi+BOOT_LO.dma], dl
  770. ;        mov     qword[esi+BOOT_LO.pci_data], 0
  771.         mov     [esi+BOOT_LO.apm_entry], edx
  772.         mov     [esi+BOOT_LO.apm_version], dx
  773.         mov     [esi+BOOT_LO.apm_flags], dx
  774.         mov     [esi+BOOT_LO.apm_code_32], dx
  775.         mov     [esi+BOOT_LO.apm_code_16], dx
  776.         mov     [esi+BOOT_LO.apm_data_16], dx
  777.         mov     [esi+BOOT_LO.bios_hd_cnt], dl
  778.  
  779.         movzx   eax, [cfg_opt_value_imgfrom]
  780.         mov     [esi+BOOT_LO.rd_load_from], al
  781.  
  782.         mov     eax, dword[devicesdat_size]
  783.         mov     [rdx+BOOT_LO.devicesdat_size], eax
  784.         mov     eax, dword[devicesdat_data]
  785.         mov     [rdx+BOOT_LO.devicesdat_data], eax
  786.  
  787.         mov     rsi, cfg_opt_value_syspath
  788.         mov     rdi, BOOT_LO.syspath
  789.         mov     ecx, 0x17
  790.         rep movsb
  791.  
  792.         ; kernel trampoline
  793.         mov     rsi, kernel_trampoline
  794.         mov     rdi, KERNEL_TRAMPOLINE
  795.         mov     ecx, kernel_trampoline.size
  796.         rep movsb
  797.  
  798.         mov     rax, GDTR
  799.         lgdt    [cs:rax]
  800.  
  801.         mov     ax, DATA_32_SELECTOR
  802.         mov     ds, ax
  803.         mov     es, ax
  804.         mov     fs, ax
  805.         mov     gs, ax
  806.         mov     ss, ax
  807.  
  808.         push    CODE_32_SELECTOR
  809.         mov     rax, KERNEL_TRAMPOLINE
  810.         push    rax
  811.         retf
  812.  
  813. .error:
  814.         mov     rbx, [efi_table]
  815.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  816.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  817.                 msg_error
  818.         jmp     $
  819. endp
  820.  
  821. halt_on_error:
  822.         test    eax, eax
  823.         jz      @f
  824.         call    clearbuf
  825.         mov     rdi, msg
  826.         call    num2hex
  827.         mov     rbx, [efi_table]
  828.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  829.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  830.                 msg_error
  831.         mov     rbx, [efi_table]
  832.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  833.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  834.         jmp     $
  835. @@:
  836.         ret
  837.  
  838. proc get_protocol_interface uses rbx, _guid
  839.         mov     [_guid], rcx
  840.         mov     [prot_handlers_buffer_size], PROTOCOL_HANDLERS_BUFFER_SIZE
  841.         mov     rbx, [efi_table]
  842.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
  843.         fstcall [rbx+EFI_BOOT_SERVICES.LocateHandle], \
  844.                 EFI_LOCATE_SEARCH_TYPE.ByProtocol, [_guid], 0, \
  845.                 prot_handlers_buffer_size, prot_handlers_buffer
  846.         mov     [status], rax
  847.  
  848.         mov     rbx, [efi_table]
  849.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  850.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  851.                 msg_protocol_buffer_size
  852.         call    clearbuf
  853.         mov     rax, [prot_handlers_buffer_size]
  854.         mov     rdi, msg
  855.         call    num2hex
  856.         mov     rbx, [efi_table]
  857.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  858.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  859.  
  860.         mov     rax, [status]
  861.         test    eax, eax
  862.         jz      @f
  863.         call    clearbuf
  864.         mov     rdi, msg
  865.         call    num2hex
  866.         mov     rbx, [efi_table]
  867.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  868.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  869.                 msg_error
  870.         mov     rbx, [efi_table]
  871.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  872.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  873.         jmp     $
  874. @@:
  875.  
  876.         mov     rbx, [efi_table]
  877.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  878.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  879.                 msg_look_for_handler
  880.  
  881.         mov     rbx, prot_handlers_buffer
  882. .try_next_handle:
  883.         mov     rax, rbx
  884.         mov     rcx, prot_handlers_buffer
  885.         sub     rax, rcx
  886.         cmp     rax, [prot_handlers_buffer_size]
  887.         jb      @f
  888.         push    rbx
  889.         mov     rbx, [efi_table]
  890.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  891.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  892.                 msg_error_out_of_handlers
  893.         pop     rbx
  894.         push    rbx
  895.         mov     rbx, [efi_table]
  896.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  897.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  898.                 msg_error
  899.         pop     rbx
  900.         jmp     $
  901. @@:
  902.         push    rbx
  903.         mov     rbx, [efi_table]
  904.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  905.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  906.                 msg_query_handler
  907.         pop     rbx
  908.  
  909.         mov     r10, rbx
  910.         push    rbx
  911.         mov     rbx, [efi_table]
  912.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
  913.         fstcall [rbx+EFI_BOOT_SERVICES.HandleProtocol], qword[r10], [_guid], \
  914.                 prot_interface
  915.         pop     rbx
  916. ;mov rax, 0x8000_0000_0000_0003
  917.         test    eax, eax
  918.         jz      @f
  919.         call    clearbuf
  920.         mov     rdi, msg
  921.         call    num2hex
  922.         push    rbx
  923.         mov     rbx, [efi_table]
  924.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  925.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  926.         pop     rbx
  927.  
  928.         add     rbx, 8
  929.         jmp     .try_next_handle
  930. @@:
  931.         mov     rax, [prot_interface]
  932.         ret
  933. endp
  934.  
  935.  
  936. find_rsdp:
  937.         push    rbx
  938.         mov     rbx, [efi_table]
  939.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  940.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  941.                 msg_look_for_rsdp
  942.         pop     rbx
  943.  
  944.         mov     rbx, [efi_table]
  945.         mov     rdi, [rbx+EFI_SYSTEM_TABLE.ConfigurationTable]
  946.         mov     rcx, [rbx+EFI_SYSTEM_TABLE.NumberOfTableEntries]
  947.         mov     rax, 0x11d3e4f18868e871
  948.         mov     rdx, 0x81883cc7800022bc
  949. .next_table:
  950.         dec     ecx
  951.         js      .all_tables_done
  952.         cmp     [rdi+0], rax
  953.         jnz     .not_acpi20
  954.         cmp     [rdi+8], rdx
  955.         jnz     .not_acpi20
  956.         mov     rax, [rdi+16]
  957.         mov     rdx, BOOT_LO.acpi_rsdp
  958.         mov     [rdx], eax
  959.         jmp     .all_tables_done
  960. .not_acpi20:
  961.         add     rdi, 24
  962.         jmp     .next_table
  963. .all_tables_done:
  964.         ret
  965.  
  966. proc dump_pci_resources
  967.         xor     eax, eax
  968.         mov     rsi, [pcirbiop_resources]
  969.         push    rbx
  970.         mov     rbx, [efi_table]
  971.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  972.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  973.                 msg_dump_pci_resources
  974.         pop     rbx
  975. .next_resource:
  976.         call    clearbuf
  977.         movzx   eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Type]
  978.         cmp     eax, EFI_RESOURCE_DESCRIPTOR_TYPE.END_TAG
  979.         jz      .done
  980.         mov     rdi, msg
  981.         call    num2hex
  982.         push    rbx
  983.         mov     rbx, [efi_table]
  984.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  985.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  986.         pop     rbx
  987.         call    clearbuf
  988.         movzx   eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.ResourceType]
  989.         mov     rdi, msg
  990.         call    num2dec
  991.         mov     rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.RangeMinimum]
  992.         mov     rdi, msg+2*2
  993.         call    num2hex
  994.         mov     rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.RangeMaximum]
  995.         mov     rdi, msg+19*2
  996.         call    num2hex
  997.         mov     rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.TranslationOffset]
  998.         mov     rdi, msg+36*2
  999.         call    num2hex
  1000.         mov     rax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.AddressLength]
  1001.         mov     rdi, msg+53*2
  1002.         call    num2hex
  1003.         push    rbx
  1004.         mov     rbx, [efi_table]
  1005.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  1006.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  1007.         pop     rbx
  1008.         movzx   eax, [rsi+EFI_QWORD_ADDRESS_SPACE_DESCRIPTOR.Length]
  1009.         add     eax, 3
  1010.         add     rsi, rax
  1011.         jmp     .next_resource
  1012. .done:
  1013.         ret
  1014. endp
  1015.  
  1016. calc_memmap:
  1017.         mov     rbx, [efi_table]
  1018.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
  1019.         fstcall [rbx+EFI_BOOT_SERVICES.AllocatePages], EFI_ALLOCATE_ANY_PAGES, \
  1020.                 EFI_RESERVED_MEMORY_TYPE, MEMORY_MAP_SIZE/0x1000, memory_map
  1021.         call    halt_on_error
  1022.  
  1023.         mov     rbx, [efi_table]
  1024.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.BootServices]
  1025.         fstcall [rbx+EFI_BOOT_SERVICES.GetMemoryMap], memory_map_size, \
  1026.                 [memory_map], memory_map_key, descriptor_size, descriptor_ver
  1027.         call    halt_on_error
  1028.  
  1029.         mov     rdi, BOOT_LO.memmap_blocks
  1030.         mov     dword[rdi-4], 0 ; memmap_block_cnt
  1031.         mov     rsi, [memory_map]
  1032.         mov     rbx, rsi
  1033.         add     rbx, [memory_map_size]
  1034. .next_descr:
  1035.         call    add_uefi_memmap
  1036.         add     rsi, [descriptor_size]
  1037.         cmp     rsi, rbx
  1038.         jb      .next_descr
  1039.         ret
  1040.  
  1041. proc dump_memmap
  1042.         xor     eax, eax
  1043.         mov     rsi, BOOT_LO.memmap_blocks
  1044.         mov     ebx, [rax+BOOT_LO.memmap_block_cnt]
  1045.  
  1046.         call    clearbuf
  1047.         mov     eax, ebx
  1048.         mov     rdi, msg
  1049.         call    num2dec
  1050.         push    rbx
  1051.         mov     rbx, [efi_table]
  1052.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  1053.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, \
  1054.                 msg_memmap
  1055.         pop     rbx
  1056.         push    rbx
  1057.         mov     rbx, [efi_table]
  1058.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  1059.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  1060.         pop     rbx
  1061.         call    clearbuf
  1062. .next_mapping:
  1063.         dec     ebx
  1064.         js      .done
  1065.         mov     rax, rsi
  1066.         mov     rcx, BOOT_LO.memmap_blocks
  1067.         sub     rax, rcx
  1068.         mov     ecx, sizeof.e820entry
  1069.         xor     edx, edx
  1070.         div     ecx
  1071.         mov     rdi, msg
  1072.         call    num2dec
  1073.         mov     rax, [rsi+e820entry.addr]
  1074.         mov     rdi, msg+4*2
  1075.         call    num2hex
  1076.         mov     rax, [rsi+e820entry.size]
  1077.         mov     rdi, msg+24*2
  1078.         call    num2hex
  1079.         push    rbx
  1080.         mov     rbx, [efi_table]
  1081.         mov     rbx, [rbx+EFI_SYSTEM_TABLE.ConOut]
  1082.         fstcall [rbx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], rbx, msg
  1083.         pop     rbx
  1084.         add     rsi, sizeof.e820entry
  1085.         jmp     .next_mapping
  1086. .done:
  1087.         ret
  1088. endp
  1089.  
  1090. ; linux/arch/x86/platform/efi/efi.c
  1091. ; do_add_efi_memmap
  1092. add_uefi_memmap:
  1093.         xor     eax, eax
  1094.         cmp     [rax+BOOT_LO.memmap_block_cnt], MAX_MEMMAP_BLOCKS
  1095.         jz      .done
  1096.  
  1097.         mov     rax, [rsi+EFI_MEMORY_DESCRIPTOR.PhysicalStart]
  1098.         mov     [rdi+e820entry.addr], rax
  1099.  
  1100.         mov     rax, [rsi+EFI_MEMORY_DESCRIPTOR.NumberOfPages]
  1101.         shl     rax, 12
  1102.         mov     [rdi+e820entry.size], rax
  1103.  
  1104.         mov     ecx, [rsi+EFI_MEMORY_DESCRIPTOR.Type]
  1105.         cmp     ecx, EFI_LOADER_CODE
  1106.         jz      .mem_ram_if_wb
  1107.         cmp     ecx, EFI_LOADER_DATA
  1108.         jz      .mem_ram_if_wb
  1109.         cmp     ecx, EFI_BOOT_SERVICES_CODE
  1110.         jz      .mem_ram_if_wb
  1111.         cmp     ecx, EFI_BOOT_SERVICES_DATA
  1112.         jz      .mem_ram_if_wb
  1113.         cmp     ecx, EFI_CONVENTIONAL_MEMORY
  1114.         jz      .mem_ram_if_wb
  1115.         cmp     ecx, EFI_ACPI_RECLAIM_MEMORY
  1116.         mov     eax, E820_ACPI
  1117.         jz      .type_done
  1118.         cmp     ecx, EFI_ACPI_MEMORY_NVS
  1119.         mov     eax, E820_NVS
  1120.         jz      .type_done
  1121.         cmp     ecx, EFI_UNUSABLE_MEMORY
  1122.         mov     eax, E820_UNUSABLE
  1123.         jz      .type_done
  1124.         cmp     ecx, EFI_PERSISTENT_MEMORY
  1125.         mov     eax, E820_PMEM
  1126.         jz      .type_done
  1127.         jmp     .reserved
  1128. .mem_ram_if_wb:
  1129.         test    [rsi+EFI_MEMORY_DESCRIPTOR.Attribute], dword EFI_MEMORY_WB
  1130.         mov     eax, E820_RAM
  1131.         jnz     .type_done
  1132. .reserved:
  1133.         mov     eax, E820_RESERVED
  1134. .type_done:
  1135.         mov     [rdi+e820entry.type], eax
  1136.         cmp     eax, E820_RAM
  1137.         jnz     @f
  1138.         xor     eax, eax
  1139.         inc     [rax+BOOT_LO.memmap_block_cnt]
  1140.         add     rdi, sizeof.e820entry
  1141. @@:
  1142. .done:
  1143.         ret
  1144.  
  1145.  
  1146. num2dec:
  1147.         push    rax rbx rcx rdx rsi rdi
  1148.  
  1149.         xor     ecx, ecx
  1150.         mov     ebx, 10
  1151. .next_digit:
  1152.         xor     edx, edx
  1153.         div     ebx
  1154.         push    rdx
  1155.         inc     ecx
  1156.         test    eax, eax
  1157.         jnz     .next_digit
  1158.  
  1159. .next_char:
  1160.         pop     rax
  1161.         add     eax, '0'
  1162.         stosw
  1163.         loop    .next_char
  1164.  
  1165.         pop     rdi rsi rdx rcx rbx rax
  1166.         ret
  1167.  
  1168.  
  1169. num2hex:
  1170.         push    rax rbx rcx rdx rsi rdi
  1171.  
  1172.         xchg    rdx, rax
  1173.         mov     ecx, 16
  1174. .next_tetra:
  1175.         rol     rdx, 4
  1176.         movzx   eax, dl
  1177.         and     eax, 0x0f
  1178.         movzx   eax, byte[hex+eax]
  1179.         stosw
  1180.         loop    .next_tetra
  1181.  
  1182.         pop     rdi rsi rdx rcx rbx rax
  1183.         ret
  1184.  
  1185. hex db '0123456789ABCDEF'
  1186.  
  1187. clearbuf:
  1188.         push    rax rbx rcx rdx rsi rdi
  1189.         mov     eax, 0x0020
  1190.         mov     ecx, 79
  1191.         mov     rdi, msg
  1192.         rep stosw
  1193.         pop     rdi rsi rdx rcx rbx rax
  1194.         ret
  1195.  
  1196. use32
  1197. kernel_trampoline:
  1198. org KERNEL_TRAMPOLINE
  1199.         mov     eax, cr0
  1200.         and     eax, not CR0_PG
  1201.         mov     cr0, eax
  1202.  
  1203.         mov     ecx, MSR_AMD_EFER
  1204.         rdmsr
  1205.         btr     eax, 8                  ; LME
  1206.         wrmsr
  1207.  
  1208.         mov     eax, cr4
  1209.         and     eax, not CR4_PAE
  1210.         mov     cr4, eax
  1211.  
  1212.         push    KERNEL_BASE
  1213.         retn
  1214.  
  1215. align 16
  1216. GDTR:
  1217.         dw 4*8-1
  1218.         dq GDT
  1219. align 16
  1220. GDT:
  1221.         dw 0, 0, 0, 0
  1222.         dw 0FFFFh,0,9A00h,0CFh          ; 32-bit code
  1223.         dw 0FFFFh,0,9200h,0CFh          ; flat data
  1224.         dw 0FFFFh,0,9A00h,0AFh          ; 64-bit code
  1225. assert $ < BOOT_LO
  1226. kernel_trampoline.size = $ - KERNEL_TRAMPOLINE
  1227.  
  1228. section '.rodata' data readable
  1229. gop_guid        db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
  1230. lip_guid        db EFI_LOADED_IMAGE_PROTOCOL_GUID
  1231. sfsp_guid       db EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID
  1232. pcirbiop_guid   db EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID
  1233.  
  1234. file_name       du '\EFI\KOLIBRIOS\KOLIBRI.INI',0
  1235. kernel_name     du '\EFI\KOLIBRIOS\KOLIBRI.KRN',0
  1236. ramdisk_name    du '\EFI\KOLIBRIOS\KOLIBRI.IMG',0
  1237. devicesdat_name du '\EFI\KOLIBRIOS\DEVICES.DAT',0
  1238.  
  1239. config_options  dq cfg_opt_name_resolution, cfg_opt_func_resolution, \
  1240.                    cfg_opt_cmnt_resolution, \
  1241.                    cfg_opt_name_acpi,  cfg_opt_func_acpi, cfg_opt_cmnt_acpi, \
  1242.                    cfg_opt_name_debug_print, cfg_opt_func_debug_print, \
  1243.                    cfg_opt_cmnt_debug_print, \
  1244.                    cfg_opt_name_launcher_start, cfg_opt_func_launcher_start, \
  1245.                    cfg_opt_cmnt_launcher_start, \
  1246.                    cfg_opt_name_mtrr,  cfg_opt_func_mtrr, cfg_opt_cmnt_mtrr, \
  1247.                    cfg_opt_name_ask_params,  cfg_opt_func_ask_params, \
  1248.                    cfg_opt_cmnt_ask_params, \
  1249.                    cfg_opt_name_imgfrom, cfg_opt_func_imgfrom, \
  1250.                    cfg_opt_cmnt_imgfrom, \
  1251.                    cfg_opt_name_syspath, cfg_opt_func_syspath, \
  1252.                    cfg_opt_cmnt_syspath, \
  1253.                    0
  1254.  
  1255. cfg_opt_name_resolution     db "resolution",0
  1256. cfg_opt_name_acpi           db "acpi",0
  1257. cfg_opt_name_debug_print    db "debug_print",0
  1258. cfg_opt_name_launcher_start db "launcher_start",0
  1259. cfg_opt_name_mtrr           db "mtrr",0
  1260. cfg_opt_name_ask_params     db "ask_params",0
  1261. cfg_opt_name_imgfrom        db "imgfrom",0
  1262. cfg_opt_name_syspath        db "syspath",0
  1263.  
  1264. cfg_opt_cmnt_resolution     db "# Graphic mode",0
  1265. cfg_opt_cmnt_acpi           db "# ACPI settings",0xa, \
  1266.                                "#   0: don't use",0xa, \
  1267.                                "#   1: parse ACPI tables",0xa, \
  1268.                                "#   2: + call _PIC method",0xa, \
  1269.                                "#   3: + get APIC interrupts",0xa,0
  1270. cfg_opt_cmnt_debug_print    db "# Duplicate debug output to the screen",0
  1271. cfg_opt_cmnt_launcher_start db "# Start LAUNCHER app after kernel is loaded",0
  1272. cfg_opt_cmnt_mtrr           db "# Configure MTRR's",0
  1273. cfg_opt_cmnt_ask_params     db "# Interrupt booting to ask the user for boot", \
  1274.                                " params",0
  1275. cfg_opt_cmnt_imgfrom        db "# Where to load ramdisk image from",0
  1276. cfg_opt_cmnt_syspath        db "# Path to /sys directory",0
  1277.  
  1278. msg_u4k_loaded            du "uefi64kos loaded",13,10,0
  1279. msg_detect_pci_config     du "Detect PCI configuration",13,10,0
  1280. msg_dump_pci_resources    du "Dump PCI resources",13,10,0
  1281. msg_pci_last_bus          du "Last PCI bus",13,10,0
  1282. msg_read_options          du "Read options from config file",13,10,0
  1283. msg_file_size             du "File size:",13,10,0
  1284. msg_parsing_config        du "Parsing config file",13,10,0
  1285. msg_load_kernel           du "Load kernel",13,10,0
  1286. msg_load_ramdisk          du "Load ramdisk",13,10,0
  1287. msg_load_devicesdat       du "Load DEVICES.DAT",13,10,0
  1288. msg_alloc_devicesdat      du "Allocate memory for DEVICES.DAT",13,10,0
  1289. msg_locate_gop_interface  du "Locate GOP interface",13,10,0
  1290. msg_look_for_handler      du "Look for protocol handler",13,10,0
  1291. msg_query_handler         du "Query handler",13,10,0
  1292. msg_query_vmode           du "Query vmode",13,10,0
  1293. msg_vmode_found           du "Video mode found",13,10,0
  1294. msg_look_for_rsdp         du "Look for RSDP",13,10,0
  1295. msg_rsdp_found            du "RSDP found",13,10,0
  1296. msg_acpi_tables_done      du "ACPI tables done",13,10,0
  1297. msg_ask_for_params        du "Ask for params",13,10,0
  1298. msg_set_graphic_mode      du "Set graphic mode",13,10,0
  1299. msg_success               du "Success!",13,10,0
  1300. msg_protocol_buffer_size  du "Protocol buffer size",13,10,0
  1301. msg_opt_resolution        du "Option resolution: ",0
  1302. msg_memmap                du "Memmap",13,10,0
  1303. msg_error                 du "Error!",13,10,0
  1304. msg_error_efi_lip_handle  du "efi_handle can't handle LIP",13,10,0
  1305. msg_error_lip_dev_sfsp    du "LIP device handle can't handle SFSP",13,10,0
  1306. msg_error_sfsp_openvolume du "SFSP OpenVolume failed",13,10,0
  1307. msg_error_no_such_vmode   du "No such vmode",13,10,0
  1308. msg_error_out_of_handlers du "Out of handlers",13,10,0
  1309. msg_error_open_file       du "Error: can't open file ",0
  1310. msg_error_exit_boot_services du "Error: Exit boot services",13,10,0
  1311. msg                       du 79 dup " ",13,10,0
  1312.  
  1313. section '.data' data readable writeable
  1314. efi_handle  dq 0
  1315. efi_table   dq 0
  1316. ;uefi_rsptmp dq 0
  1317.  
  1318. fb_base         dq 0
  1319.  
  1320. prot_handlers_buffer_size dq ?
  1321. prot_interface  dq ?
  1322. gop_interface   dq 0
  1323. gop_info_size   dq 0
  1324. gop_info        dq 0
  1325.  
  1326. lip_interface   dq 0
  1327.  
  1328. sfsp_interface  dq 0
  1329.  
  1330. esp_root        dq ?
  1331. file_handle     dq ?
  1332. file_buffer_size dq FILE_BUFFER_SIZE-1  ; leave the last byte for \0
  1333.  
  1334. pcirbiop_interface dq ?
  1335. pcirbiop_resources dq ?
  1336. pci_last_bus db 254
  1337.  
  1338. cfg_opt_used_resolution     db 0
  1339. cfg_opt_used_acpi           db 0
  1340. cfg_opt_used_debug_print    db 0
  1341. cfg_opt_used_launcher_start db 0
  1342. cfg_opt_used_mtrr           db 0
  1343. cfg_opt_used_ask_params     db 0
  1344. cfg_opt_used_imgfrom        db 0
  1345. cfg_opt_used_syspath        db 0
  1346.  
  1347. cfg_opt_value_vmode          db 0
  1348. cfg_opt_value_acpi           db 0
  1349. cfg_opt_value_debug_print    db 0
  1350. cfg_opt_value_launcher_start db 1
  1351. cfg_opt_value_mtrr           db 0
  1352. cfg_opt_value_ask_params     db 0
  1353. cfg_opt_value_imgfrom        db RD_LOAD_FROM_MEMORY
  1354. cfg_opt_value_syspath        db "/RD/1",0
  1355.                              rb 20
  1356.  
  1357. memory_map_key  dq 0
  1358. descriptor_size dq 0
  1359. descriptor_ver  dq 0
  1360. memory_map_size dq MEMORY_MAP_SIZE
  1361.  
  1362. efi_fs_info_id db EFI_FILE_SYSTEM_INFO_ID
  1363. efi_fs_info_size dq sizeof.EFI_FILE_SYSTEM_INFO
  1364. efi_fs_info EFI_FILE_SYSTEM_INFO
  1365.  
  1366. memory_map      dq ?
  1367. prot_handlers_buffer rq PROTOCOL_HANDLERS_BUFFER_SIZE/8
  1368. ;gop_buffer      rq PROTOCOL_HANDLERS_BUFFER_SIZE/8
  1369. pcirbio_buffer  rq PROTOCOL_HANDLERS_BUFFER_SIZE/8
  1370. devicesdat_data dq 0xffffffff
  1371. devicesdat_size dq 0x1000
  1372. status          dq ?
  1373.  
  1374. section '.reloc' fixups data discardable
  1375.