kolibrios-gitea/kernel/trunk/bootloader/uefi4kos/uefi32kos.asm

985 lines
30 KiB
NASM
Raw Normal View History

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2020. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Version 2, or (at your option) any later version. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format pe efi
entry main
section '.text' code executable readable
include '../../struct.inc'
include '../../macros.inc'
include '../../proc32.inc'
include '../../const.inc'
include 'uefi32.inc'
MEMORY_MAP_SIZE = 0x4000
GOP_BUFFER_SIZE = 0x100
LIP_BUFFER_SIZE = 0x100
FILE_BUFFER_SIZE = 0x1000
KERNEL_BASE = 0x10000
RAMDISK_BASE = 0x100000
CODE_32_SELECTOR = 8
DATA_32_SELECTOR = 16
; linux/arch/x86/include/uapi/asm/e820.h
E820_RAM = 1
E820_RESERVED = 2
E820_ACPI = 3
E820_NVS = 4
E820_UNUSABLE = 5
E820_PMEM = 7
proc load_file stdcall uses ebx esi edi, _root, _name, _buffer, _size, _fatal
mov eax, [_root]
ccall [eax+EFI_FILE_PROTOCOL.Open], eax, file_handle, [_name], \
EFI_FILE_MODE_READ, 0
test eax, eax
jz @f
xor eax, eax
cmp [_fatal], 1
jnz .done
mov ebx, [efi_table]
mov ebx, [ebx+EFI_SYSTEM_TABLE.ConOut]
ccall [ebx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], ebx, \
msg_error_open_file
ccall [ebx+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], ebx, \
[_name]
jmp $
@@:
mov eax, [file_handle]
lea ecx, [_size]
ccall [eax+EFI_FILE_PROTOCOL.Read], eax, ecx, [_buffer]
mov eax, [file_handle]
ccall [eax+EFI_FILE_PROTOCOL.Close], eax
mov eax, [_size]
.done:
ret
endp
proc skip_whitespace
.next_char:
cmp byte[esi], 0
jz .done
cmp byte[esi], 0x20 ; ' '
jz .whitespace
cmp byte[esi], 9 ; '\t'
jz .whitespace
jmp .done
.whitespace:
inc esi
jmp .next_char
.done:
ret
endp
proc skip_until_newline
.next_char:
cmp byte[esi], 0
jz .done
cmp byte[esi], 0xd ; '\r'
jz .done
cmp byte[esi], 0xa ; '\n'
jz .done
inc esi
jmp .next_char
.done:
ret
endp
proc skip_newline
.next_char:
cmp byte[esi], 0xd ; '\r'
jz .newline
cmp byte[esi], 0xa ; '\n'
jz .newline
jmp .done
.newline:
inc esi
jmp .next_char
.done:
ret
endp
proc skip_line
call skip_until_newline
call skip_newline
ret
endp
proc dec2bin
mov edx, 0
.next_char:
movzx eax, byte[esi]
test eax, eax
jz .done
sub eax, '0'
jb .done
cmp eax, 9
ja .done
inc esi
imul edx, 10
add edx, eax
jmp .next_char
.done:
mov eax, edx
ret
endp
proc parse_option
mov ebx, config_options-3*4
.try_next_option:
add ebx, 3*4
mov edi, esi
mov edx, [ebx] ; option name
test edx, edx
jz .done
.next_char:
cmp byte[edx], 0
jnz @f
cmp byte[edi], '='
jz .opt_name_ok
@@:
cmp byte[edi], 0
jz .done
movzx eax, byte[edi]
cmp [edx], al
jnz .try_next_option
inc edi
inc edx
jmp .next_char
.opt_name_ok:
inc edi
mov esi, edi
call dword[ebx+4]
.done:
ret
endp
proc parse_line
.next_line:
cmp byte[esi], 0
jz .done
cmp byte[esi], 0xd ; '\r'
jz .skip
cmp byte[esi], 0xa ; '\n'
jz .skip
cmp byte[esi], '#'
jz .skip
call parse_option
call skip_line
jmp .next_line
.skip:
call skip_line
jmp .next_line
.done:
ret
endp
proc cfg_opt_func_resolution
call dec2bin
xor edx, edx
mov [edx+BOOT_LO.x_res], ax
cmp byte[esi], 'x'
jz @f
cmp byte[esi], '*'
jz @f
jmp .done
@@:
inc esi
call dec2bin
xor edx, edx
mov [edx+BOOT_LO.y_res], ax
mov [cfg_opt_used_resolution], 1
.done:
ret
endp
proc cfg_opt_func_acpi
call dec2bin
mov [cfg_opt_used_acpi], 1
mov [cfg_opt_value_acpi], al
ret
endp
proc cfg_opt_func_debug_print
call dec2bin
mov [cfg_opt_used_debug_print], 1
mov [cfg_opt_value_debug_print], al
ret
endp
proc cfg_opt_func_launcher_start
call dec2bin
mov [cfg_opt_used_launcher_start], 1
mov [cfg_opt_value_launcher_start], al
ret
endp
proc cfg_opt_func_mtrr
call dec2bin
mov [cfg_opt_used_mtrr], 1
mov [cfg_opt_value_mtrr], al
ret
endp
proc cfg_opt_func_ask_params
call dec2bin
mov [cfg_opt_used_ask_params], 1
mov [cfg_opt_value_ask_params], al
ret
endp
proc cfg_opt_func_imgfrom
call dec2bin
mov [cfg_opt_used_imgfrom], 1
mov [cfg_opt_value_imgfrom], al
ret
endp
proc cfg_opt_func_syspath
mov edi, cfg_opt_value_syspath
.next_char:
movzx eax, byte[esi]
cmp al, 0xd ; \r
jz .done
cmp al, 0xa ; \n
jz .done
inc esi
stosb
jmp .next_char
.done:
mov byte[edi], 0
ret
endp
proc parse_config stdcall uses ebx esi edi, _buffer
; mov esi, [_buffer]
mov esi, KERNEL_BASE
.next_line:
call parse_line
cmp byte[esi], 0
jnz .next_line
ret
endp
proc read_options_from_config stdcall uses ebx esi edi
mov ebx, [efi_table]
mov ebx, [ebx+EFI_SYSTEM_TABLE.BootServices]
ccall [ebx+EFI_BOOT_SERVICES.HandleProtocol], [efi_handle], \
lipuuid, lip_interface
test eax, eax
jnz .error
mov eax, [lip_interface]
mov ebx, [efi_table]
mov ebx, [ebx+EFI_SYSTEM_TABLE.BootServices]
ccall [ebx+EFI_BOOT_SERVICES.HandleProtocol], \
[eax+EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle], sfspguid, \
sfsp_interface
test eax, eax
jnz .error
mov eax, [sfsp_interface]
ccall [eax+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume], eax, esp_root
test eax, eax
jnz .error
stdcall load_file, [esp_root], file_name, KERNEL_BASE, \
FILE_BUFFER_SIZE, 0
test eax, eax
jz @f
stdcall parse_config, KERNEL_BASE
@@:
.error:
ret
endp
proc print_vmode uses eax ebx ecx esi edi, _gop_if
mov ebx, [_gop_if]
call clearbuf
mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
mov edi, msg
call num2dec
mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
mov edi, msg+8*2
call num2dec
mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat]
mov edi, msg+16*2
call num2dec
mov eax, [ebx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine]
mov edi, msg+24*2
call num2dec
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg
ret
endp
proc find_vmode_index_by_resolution uses ebx esi edi
mov [cfg_opt_value_vmode], 0
.next_mode:
; mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
; ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
; msg_query_vmode
movzx ecx, [cfg_opt_value_vmode]
mov eax, [gop_interface]
ccall [eax+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], eax, ecx, \
gop_info_size, gop_info
test eax, eax
jz @f
call clearbuf
mov edi, msg
call num2hex
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg
jmp .skip_mode
@@:
mov ecx, [gop_info]
stdcall print_vmode, ecx
; PixelBlueGreenRedReserved8BitPerColor
cmp [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat], 1
jnz .skip_mode
xor edx, edx
mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
cmp ax, [edx+BOOT_LO.x_res]
jnz .skip_mode
mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
cmp ax, [edx+BOOT_LO.y_res]
jnz .skip_mode
jmp .done
.skip_mode:
inc [cfg_opt_value_vmode]
movzx eax, [cfg_opt_value_vmode]
mov ecx, [gop_interface]
mov edx, [ecx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode]
cmp eax, [edx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode]
jnz .next_mode
mov [cfg_opt_used_resolution], 0
mov [cfg_opt_value_ask_params], 1
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_error_no_such_vmode
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg_error
jmp $
.error:
.done:
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_vmode_found
ret
endp
proc ask_for_params
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_ask_for_params
jmp $
.error:
.done:
ret
endp
main:
mov esi, [esp+4]
mov [efi_handle], esi
mov esi, [esp+8]
mov [efi_table], esi
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset], eax, 1
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_u4k_loaded
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_read_options
call read_options_from_config
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_load_kernel
stdcall load_file, [esp_root], kernel_name, KERNEL_BASE, -1, 1
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_load_ramdisk
stdcall load_file, [esp_root], ramdisk_name, RAMDISK_BASE, -1, 1
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_alloc_devicesdat
mov eax, [esi+EFI_SYSTEM_TABLE.BootServices]
ccall [eax+EFI_BOOT_SERVICES.AllocatePages], \
EFI_ALLOCATE_MAX_ADDRESS, EFI_RESERVED_MEMORY_TYPE, 1, \
devicesdat_data
call halt_on_error
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_load_devicesdat
ccall load_file, [esp_root], devicesdat_name, [devicesdat_data], \
[devicesdat_size], 0
mov [devicesdat_size], eax
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_locate_gop_handlers
mov eax, [esi+EFI_SYSTEM_TABLE.BootServices]
ccall [eax+EFI_BOOT_SERVICES.LocateHandle], \
EFI_LOCATE_SEARCH_TYPE.ByProtocol, gopuuid, 0, \
gop_buffer_size, gop_buffer
mov [status], eax
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_gop_buffer_size
call clearbuf
mov eax, [gop_buffer_size]
mov edi, msg
call num2hex
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg
mov eax, [status]
call halt_on_error
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_look_for_gop_handler
mov ebx, gop_buffer
.next_gop_handle:
mov eax, ebx
sub eax, gop_buffer
cmp eax, [gop_buffer_size]
jb @f
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_error_out_of_handlers
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg_error
jmp $
@@:
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_query_handler
mov eax, [esi+EFI_SYSTEM_TABLE.BootServices]
ccall [eax+EFI_BOOT_SERVICES.HandleProtocol], \
[ebx], gopuuid, gop_interface
;mov eax, 0x80000003
test eax, eax
jz @f
call clearbuf
mov edi, msg
call num2hex
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg
add ebx, 4
jmp .next_gop_handle
@@:
call find_rsdp
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_acpi_tables_done
cmp [cfg_opt_used_resolution], 0
jz .not_used_resolution
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_opt_resolution
call clearbuf
xor edx, edx
movzx eax, [edx+BOOT_LO.x_res]
mov edi, msg
call num2dec
xor edx, edx
movzx eax, [edx+BOOT_LO.y_res]
mov edi, msg+8*2
call num2dec
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg
call find_vmode_index_by_resolution
.not_used_resolution:
cmp [cfg_opt_used_debug_print], 0
jz .not_used_debug_print
movzx eax, [cfg_opt_value_debug_print]
xor edx, edx
mov [edx+BOOT_LO.debug_print], al
.not_used_debug_print:
cmp [cfg_opt_value_ask_params], 0
jz @f
call ask_for_params
@@:
movzx ecx, [cfg_opt_value_vmode]
mov eax, [gop_interface]
ccall [eax+EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode], eax, ecx
call halt_on_error
mov ecx, [gop_interface]
mov edx, [ecx+EFI_GRAPHICS_OUTPUT_PROTOCOL.Mode]
mov edi, [edx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.FrameBufferBase.lo]
mov [fb_base], edi
mov ebx, [edx+EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.Mode]
mov eax, [gop_interface]
ccall [eax+EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode], eax, ebx, \
gop_info_size, gop_info
test eax, eax
jnz .error
mov ecx, [gop_info]
mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
xor edx, edx
mov [edx+BOOT_LO.x_res], ax
mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
mov [edx+BOOT_LO.y_res], ax
mov eax, [ecx+EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelsPerScanLine]
shl eax, 2
mov [edx+BOOT_LO.pitch], ax
mov byte[edx+BOOT_LO.pci_data+0], 1 ; PCI access mechanism
mov byte[edx+BOOT_LO.pci_data+1], 8 ; last bus, don't know how to count them
mov byte[edx+BOOT_LO.pci_data+2], 0x10 ; PCI version
mov byte[edx+BOOT_LO.pci_data+3], 0x02
mov dword[edx+BOOT_LO.pci_data+4], 0xe3
; kernel
; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \
; 450000/0x1000, EFI_ALLOCATE_ADDRESS
; ramdisk
; eficall BootServices, AllocatePages, EFI_RESERVED_MEMORY_TYPE, \
; 2880*512/0x1000, EFI_ALLOCATE_ADDRESS
call calc_memmap
; call dump_memmap
mov eax, [efi_table]
mov eax, [eax+EFI_SYSTEM_TABLE.BootServices]
ccall [eax+EFI_BOOT_SERVICES.ExitBootServices], [efi_handle], \
[memory_map_key]
call halt_on_error
cli
xor edx, edx
xor esi, esi
mov [esi+BOOT_LO.bpp], 32
mov [esi+BOOT_LO.vesa_mode], dx
mov [esi+BOOT_LO.bank_switch], edx
mov edi, [fb_base]
mov [esi+BOOT_LO.lfb], edi
movzx eax, [cfg_opt_value_mtrr]
mov [esi+BOOT_LO.mtrr], al
movzx eax, [cfg_opt_value_launcher_start]
mov [esi+BOOT_LO.launcher_start], al
movzx eax, [cfg_opt_value_debug_print]
mov [esi+BOOT_LO.debug_print], al
mov [esi+BOOT_LO.dma], dl
; mov qword[esi+BOOT_LO.pci_data], 0
mov [esi+BOOT_LO.apm_entry], edx
mov [esi+BOOT_LO.apm_version], dx
mov [esi+BOOT_LO.apm_flags], dx
mov [esi+BOOT_LO.apm_code_32], dx
mov [esi+BOOT_LO.apm_code_16], dx
mov [esi+BOOT_LO.apm_data_16], dx
mov [esi+BOOT_LO.bios_hd_cnt], dl
movzx eax, [cfg_opt_value_imgfrom]
mov [esi+BOOT_LO.rd_load_from], al
mov eax, dword[devicesdat_size]
mov [edx+BOOT_LO.devicesdat_size], eax
mov eax, dword[devicesdat_data]
mov [edx+BOOT_LO.devicesdat_data], eax
mov esi, cfg_opt_value_syspath
mov edi, BOOT_LO.syspath
mov ecx, 0x17
rep movsb
lgdt [cs:GDTR]
mov ax, DATA_32_SELECTOR
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
push CODE_32_SELECTOR
lea eax, [.next]
push eax
retf
.next:
mov eax, cr0
and eax, not CR0_PG
mov cr0, eax
mov eax, cr4
and eax, not CR4_PAE
mov cr4, eax
push KERNEL_BASE
retn
.error:
mov esi, [efi_table]
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_error
jmp $
halt_on_error:
test eax, eax
jz @f
call clearbuf
mov edi, msg
call num2hex
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_error
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, msg
jmp $
@@:
ret
proc find_rsdp
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_look_for_rsdp
mov edi, [esi+EFI_SYSTEM_TABLE.ConfigurationTable]
mov ecx, [esi+EFI_SYSTEM_TABLE.NumberOfTableEntries]
.next_table:
dec ecx
js .all_tables_done
; EFI_ACPI_TABLE_GUID
cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0x0], 0x8868e871
jnz .not_acpi20
cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0x4], 0x11d3e4f1
jnz .not_acpi20
cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0x8], 0x800022bc
jnz .not_acpi20
cmp dword[edi+EFI_CONFIGURATION_TABLE.VendorGUID+0xc], 0x81883cc7
jnz .not_acpi20
mov eax, [edi+EFI_CONFIGURATION_TABLE.VendorTable]
mov edx, BOOT_LO.acpi_rsdp
mov [edx], eax
mov eax, [esi+EFI_SYSTEM_TABLE.ConOut]
ccall [eax+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString], eax, \
msg_rsdp_found
jmp .all_tables_done
.not_acpi20:
add edi, sizeof.EFI_CONFIGURATION_TABLE
jmp .next_table
.all_tables_done:
ret
endp
proc calc_memmap
mov eax, [esi+EFI_SYSTEM_TABLE.BootServices]
ccall [eax+EFI_BOOT_SERVICES.AllocatePages], EFI_ALLOCATE_ANY_PAGES, \
EFI_RESERVED_MEMORY_TYPE, MEMORY_MAP_SIZE/0x1000, memory_map
call halt_on_error
mov eax, [esi+EFI_SYSTEM_TABLE.BootServices]
ccall [eax+EFI_BOOT_SERVICES.GetMemoryMap], memory_map_size, \
[memory_map], memory_map_key, descriptor_size, descriptor_ver
call halt_on_error
push esi
mov edi, BOOT_LO.memmap_blocks
mov dword[edi-4], 0 ; memmap_block_cnt
mov esi, [memory_map]
mov ebx, esi
add ebx, [memory_map_size]
.next_descr:
call add_uefi_memmap
add esi, [descriptor_size]
cmp esi, ebx
jb .next_descr
pop esi
ret
endp
; linux/arch/x86/platform/efi/efi.c
; do_add_efi_memmap
proc add_uefi_memmap
cmp [BOOT_LO.memmap_block_cnt], MAX_MEMMAP_BLOCKS
jz .done
mov eax, [esi+EFI_MEMORY_DESCRIPTOR.PhysicalStart.lo]
mov edx, [esi+EFI_MEMORY_DESCRIPTOR.PhysicalStart.hi]
mov [edi+e820entry.addr.lo], eax
mov [edi+e820entry.addr.hi], edx
mov eax, [esi+EFI_MEMORY_DESCRIPTOR.NumberOfPages.lo]
mov edx, [esi+EFI_MEMORY_DESCRIPTOR.NumberOfPages.hi]
shld edx, eax, 12
shl eax, 12
mov [edi+e820entry.size.lo], eax
mov [edi+e820entry.size.hi], edx
mov ecx, [esi+EFI_MEMORY_DESCRIPTOR.Type]
cmp ecx, EFI_LOADER_CODE
jz .mem_ram_if_wb
cmp ecx, EFI_LOADER_DATA
jz .mem_ram_if_wb
cmp ecx, EFI_BOOT_SERVICES_CODE
jz .mem_ram_if_wb
cmp ecx, EFI_BOOT_SERVICES_DATA
jz .mem_ram_if_wb
cmp ecx, EFI_CONVENTIONAL_MEMORY
jz .mem_ram_if_wb
cmp ecx, EFI_ACPI_RECLAIM_MEMORY
mov eax, E820_ACPI
jz .type_done
cmp ecx, EFI_ACPI_MEMORY_NVS
mov eax, E820_NVS
jz .type_done
cmp ecx, EFI_UNUSABLE_MEMORY
mov eax, E820_UNUSABLE
jz .type_done
cmp ecx, EFI_PERSISTENT_MEMORY
mov eax, E820_PMEM
jz .type_done
jmp .reserved
.mem_ram_if_wb:
test [esi+EFI_MEMORY_DESCRIPTOR.Attribute.lo], EFI_MEMORY_WB
mov eax, E820_RAM
jnz .type_done
.reserved:
mov eax, E820_RESERVED
.type_done:
mov [edi+e820entry.type], eax
cmp eax, E820_RAM
jnz @f
inc [BOOT_LO.memmap_block_cnt]
add edi, sizeof.e820entry
@@:
.done:
ret
endp
proc num2dec
pushad
xor ecx, ecx
mov ebx, 10
.next_digit:
xor edx, edx
div ebx
push edx
inc ecx
test eax, eax
jnz .next_digit
.next_char:
pop eax
add eax, '0'
stosw
loop .next_char
popad
ret
endp
proc num2hex
pushad
xchg edx, eax
mov ecx, 8
.next_tetra:
rol edx, 4
movzx eax, dl
and eax, 0x0f
movzx eax, byte[hex+eax]
stosw
loop .next_tetra
popad
ret
endp
hex db '0123456789ABCDEF'
proc clearbuf
pushad
mov eax, 0x0020
mov ecx, 79
mov edi, msg
rep stosw
popad
ret
endp
section '.data' data readable writeable
efi_handle dd 0
efi_table dd 0
GDTR:
dw 3*8-1
dq GDT
GDT:
dw 0, 0, 0, 0
dw 0FFFFh,0,9A00h,0CFh ; 32-bit code
dw 0FFFFh,0,9200h,0CFh ; flat data
fb_base dd 0
gopuuid db EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
gop_buffer_size dd GOP_BUFFER_SIZE
gop_handle dd 0
gop_interface dd 0
gop_info_size dd 0
gop_info dd 0
lipuuid db EFI_LOADED_IMAGE_PROTOCOL_GUID
lip_buffer_size dd LIP_BUFFER_SIZE
lip_handle dd 0
lip_interface dd 0
sfspguid db EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID
sfsp_interface dd 0
esp_root dd ?
file_handle dd ?
file_name du "\EFI\KOLIBRIOS\KOLIBRI.INI",0
kernel_name du "\EFI\KOLIBRIOS\KOLIBRI.KRN",0
ramdisk_name du "\EFI\KOLIBRIOS\KOLIBRI.IMG",0
devicesdat_name du "\EFI\KOLIBRIOS\DEVICES.DAT",0
file_buffer_size dd FILE_BUFFER_SIZE-1 ; leave the last byte for \0
config_options dd cfg_opt_name_resolution, cfg_opt_func_resolution, \
cfg_opt_cmnt_resolution, \
cfg_opt_name_acpi, cfg_opt_func_acpi, cfg_opt_cmnt_acpi, \
cfg_opt_name_debug_print, cfg_opt_func_debug_print, \
cfg_opt_cmnt_debug_print, \
cfg_opt_name_launcher_start, cfg_opt_func_launcher_start, \
cfg_opt_cmnt_launcher_start, \
cfg_opt_name_mtrr, cfg_opt_func_mtrr, cfg_opt_cmnt_mtrr, \
cfg_opt_name_ask_params, cfg_opt_func_ask_params, \
cfg_opt_cmnt_ask_params, \
cfg_opt_name_imgfrom, cfg_opt_func_imgfrom, \
cfg_opt_cmnt_imgfrom, \
cfg_opt_name_syspath, cfg_opt_func_syspath, \
cfg_opt_cmnt_syspath, \
0
cfg_opt_name_resolution db "resolution",0
cfg_opt_name_acpi db "acpi",0
cfg_opt_name_debug_print db "debug_print",0
cfg_opt_name_launcher_start db "launcher_start",0
cfg_opt_name_mtrr db "mtrr",0
cfg_opt_name_ask_params db "ask_params",0
cfg_opt_name_imgfrom db "imgfrom",0
cfg_opt_name_syspath db "syspath",0
cfg_opt_cmnt_resolution db "# Graphic mode",0
cfg_opt_cmnt_acpi db "# ACPI settings",0xa, \
"# 0: don't use",0xa, \
"# 1: parse ACPI tables",0xa, \
"# 2: + call _PIC method",0xa, \
"# 3: + get APIC interrupts",0xa,0
cfg_opt_cmnt_debug_print db "# Duplicate debug output to the screen",0
cfg_opt_cmnt_launcher_start db "# Start LAUNCHER app after kernel is loaded",0
cfg_opt_cmnt_mtrr db "# Configure MTRR's",0
cfg_opt_cmnt_ask_params db "# Interrupt booting to ask the user for boot", \
" params",0
cfg_opt_cmnt_imgfrom db "# Where to load ramdisk image from",0
cfg_opt_cmnt_syspath db "# Path to /sys directory",0
cfg_opt_used_resolution db 0
cfg_opt_used_acpi db 0
cfg_opt_used_debug_print db 0
cfg_opt_used_launcher_start db 0
cfg_opt_used_mtrr db 0
cfg_opt_used_ask_params db 0
cfg_opt_used_imgfrom db 0
cfg_opt_used_syspath db 0
cfg_opt_value_vmode db 0
cfg_opt_value_acpi db 0
cfg_opt_value_debug_print db 0
cfg_opt_value_launcher_start db 1
cfg_opt_value_mtrr db 0
cfg_opt_value_ask_params db 0
cfg_opt_value_imgfrom db RD_LOAD_FROM_MEMORY
cfg_opt_value_syspath db "/RD/1",0
rb 20
memory_map_key dd 0
descriptor_size dd 0
descriptor_ver dd 0
memory_map_size dd MEMORY_MAP_SIZE
msg_u4k_loaded du "uefi32kos loaded",13,10,0
msg_read_options du "Read options from config file",13,10,0
msg_load_kernel du "Load kernel",13,10,0
msg_load_ramdisk du "Load ramdisk",13,10,0
msg_load_devicesdat du "Load DEVICES.DAT",13,10,0
msg_alloc_devicesdat du "Allocate memory for DEVICES.DAT",13,10,0
msg_locate_gop_handlers du "Locate GOP handlers",13,10,0
msg_look_for_gop_handler du "Look for GOP handler",13,10,0
msg_query_handler du "Query handler",13,10,0
msg_query_vmode du "Query vmode",13,10,0
msg_vmode_found du "Video mode found",13,10,0
msg_look_for_rsdp du "Look for RSDP",13,10,0
msg_rsdp_found du "RSDP found",13,10,0
msg_acpi_tables_done du "ACPI tables done",13,10,0
msg_ask_for_params du "Ask for params",13,10,0
msg_set_graphic_mode du "Set graphic mode",13,10,0
msg_success du "Success!",13,10,0
msg_gop_buffer_size du "GOP buffer size",13,10,0
msg_opt_resolution du "option resolution: ",0
msg_error du "Error!",13,10,0
msg_error_no_such_vmode du "No such vmode",13,10,0
msg_error_out_of_handlers du "Out of handlers",13,10,0
msg_error_open_file du "Error: can't open file ",0
msg du 79 dup " ",13,10,0
efi_fs_info_id db EFI_FILE_SYSTEM_INFO_ID
efi_fs_info_size dq sizeof.EFI_FILE_SYSTEM_INFO
efi_fs_info EFI_FILE_SYSTEM_INFO
memory_map dd ?
gop_buffer rd GOP_BUFFER_SIZE/4
devicesdat_data dd 0xffffffff
devicesdat_size dd 0x1000
status dd ?
section '.reloc' fixups data discardable