The value of counter at second iteration is 1. Register RCX contains the GOP pointer. What could be wrong here?
Code: Select all
; Video mode code constant
MODE_CODE_INVALID = 100 ; taking an arbitrary higher mode code
section '.text' code executable readable
;
; find_mode_code_for_1280x1024_resolution
;
; This function finds the video mode code for 1280 x 1024 resolution.
;
; Args:
; @rcx = GOP interface
; @edx = total number of video modes
;
; Returns:
; @eax = video mode code
;
find_mode_code_for_1280x1024_resolution:
push rbp
mov rbp, rsp
sub rsp, 32
total_video_modes equ dword [rbp - 4]
counter equ dword [rbp - 8]
gop equ qword [rbp - 14]
mode_code equ dword [rbp - 18]
mov gop, rcx
mov total_video_modes, edx
mov mode_code, MODE_CODE_INVALID
mov counter, 0
.loop_start:
mov eax, total_video_modes
cmp counter, eax
jae .loop_end
; DEBUG
uefi_call_wrapper ConOut, OutputString, ConOut, debug_msg1
mov rcx, gop
mov edx, counter
; invoke EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode() function
uefi_call_wrapper rcx, QueryMode, rcx, rdx, size_of_info, info
; DEBUG
uefi_call_wrapper ConOut, OutputString, ConOut, debug_msg2
mov rax, qword [info]
mov ecx, dword [rax + \
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.HorizontalResolution]
cmp ecx, 1280
jne .free_pool
mov ecx, dword [rax + \
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.VerticalResolution]
cmp ecx, 1024
jne .free_pool
mov ecx, dword [rax + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION.PixelFormat]
cmp ecx, EFI_GRAPHICS_PIXEL_FORMAT_PixelBlueGreenRedReserved8BitPerColor
jne .free_pool
mov eax, counter
mov mode_code, eax
jmp .loop_end
.free_pool:
mov rcx, qword [info]
uefi_call_wrapper BootServices, FreePool, rcx
.loop_next:
inc counter
jmp .loop_start
.loop_end:
mov eax, MODE_CODE_INVALID
cmp mode_code, eax
je .exit
mov rcx, qword [info]
uefi_call_wrapper BootServices, FreePool, rcx
.exit:
mov eax, mode_code
restore total_video_modes
restore counter
restore gop
restore mode_code
mov rsp, rbp
pop rbp
ret
section '.data' data readable writeable
size_of_info dq 0
info dq 0
debug_msg1 du "@Before calling querymode func", 13, 10, 0
debug_msg2 du "@After calling querymode func", 13, 10, 0
Code: Select all
@Before calling querymode func
@After calling querymode func
@Before calling querymode func
Code: Select all
; Invoke a uefi function
macro uefi_call_wrapper interface, function, arg1, arg2, arg3, arg4, arg5 {
total_arg = 0
if ~ arg5 eq
total_arg = total_arg + 1
if ~ arg5 eq r10
mov r10, arg5
end if
end if
if ~ arg4 eq
total_arg = total_arg + 1
if ~ arg4 eq r9
mov r9, arg4
end if
end if
if ~ arg3 eq
total_arg = total_arg + 1
if ~ arg3 eq r8
mov r8, arg3
end if
end if
if ~ arg2 eq
total_arg = total_arg + 1
if ~ arg2 eq rdx
mov rdx, arg2
end if
end if
if ~ arg1 eq
total_arg = total_arg + 1
if ~ arg1 eq rcx
if ~ arg1 in <ConsoleInHandle, ConIn, \
ConsoleOutHandle, ConOut, \
StandardErrorHandle, StdErr, \
RuntimeServices, BootServices>
mov rcx, arg1
end if
end if
end if
xor rax, rax
mov al, total_arg
if interface in <ConsoleInHandle, ConIn, ConsoleOutHandle, ConOut, \
StandardErrorHandle, StdErr, RuntimeServices, \
BootServices>
mov r14, [system_table]
mov r14, [r14 + EFI_SYSTEM_TABLE.#interface]
else
if ~ interface eq r14
mov r14, interface
end if
end if
if arg1 in <ConsoleInHandle, ConIn, ConsoleOutHandle, ConOut, \
StandardErrorHandle, StdErr, RuntimeServices, BootServices>
mov rcx, r14
end if
if defined EFI_GRAPHICS_OUTPUT_PROTOCOL.#function
mov r14, [r14 + EFI_GRAPHICS_OUTPUT_PROTOCOL.#function]
else if defined EFI_BOOT_SERVICES.#function
mov r14, [r14 + EFI_BOOT_SERVICES.#function]
else if defined EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.#function
mov r14, [r14 + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.#function]
else if defined EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.#function
mov r14, [r14 + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.#function]
else
mov r14, [r14 + function]
end if
call uefi_func
}
;
; Library functions
;
section '.text' code executable readable
;
; uefi_func
;
; Note: See the Microsoft's x64 ABI conventions.
;
uefi_func:
; Save stack pointer
mov qword [uefi_rsptmp], rsp
; Set up new aligned stack:
; As per the Microsoft's x64 calling convention, the stack pointer
; must be 16-byte aligned at the point of any function call.
and esp, 0FFFFFFF0h
; Alignment check on arguments:
; if total_arg is less than 5, we don't need any stack pointer
; alignment. Reason: we only pass 5th and further arguments via the
; stack and it might or might not misalign it.
cmp eax, 5 ; al contains the total_arg from uefi_call_wrapper macro
jb .before_call
bt eax, 0
jnc @f
push rax ; Push dummy rax reg value for stack alignment purpose
; Arguments
@@: cmp al, 5
jb @f
push r10
@@:
.before_call:
; 32 bytes (shadow) space for
; r9
; r8
; rdx
; rcx
sub rsp, 4*8
; call function
call r14
; restore old stack
mov rsp, qword [uefi_rsptmp]
ret
section '.data' data readable writeable
image_handle dq 0
system_table dq 0
uefi_rsptmp dq 0