I'm writing a simple UEFI application in NASM assembly, and I'm trying to make an event for a free-running timer, but the call to CreateEvent
always returns EFI_INVALID_PARAMETER
and I'm not sure why.
section .text
_start:
mov [ptrSystemTable], rdx
...
mov rcx, EVT_TIMER
mov rdx, TPL_APPLICATION
mov r8, 0
mov r9, 0
lea rbx, [ptrTimerEvent]
push rbx
mov rax, [ptrSystemTable]
mov rax, [rax + EFI_SYSTEM_TABLE.BootServices]
call [rax + EFI_BOOT_SERVICES.CreateEvent]
cmp rax, EFI_SUCCESS
jne errorCode
...
section .data
ptrSystemTable dq 0
ptrTimerEvent dq 0
; Include file with a bunch of definitions and structures
EVT_TIMER equ 0x80000000
TPL_APPLICATION equ 4
%macro POINTER 0
RESQ 1
alignb 8
%endmacro
struc EFI_SYSTEM_TABLE
...
.BootServices POINTER
...
endstruc
struc EFI_BOOT_SERVICES
...
.CheckEvent POINTER
...
endstruc
According to 2.3.4.2 Detailed Calling Conventions in the UEFI spec:
The integer values are passed from left to right in Rcx, Rdx, R8, and R9 registers. The caller passes arguments five and above onto the stack.
So the arguments I'm passing should be:
Type --> EVT_TIMER
NotifyTpl --> TPL_APPLICATION
NotifyFunction --> 0
*NotifyContext --> 0
*Event --> &ptrTimerEvent
The spec gives multiple reasons why CreateEvent
could return EFI_INVALID_PARAMETER
, but I can't see how any of them are occurring in my code. Any pointers or questions would be greatly appreciated.
The calling convention for UEFI always has 0x20 bytes of free space at the top of the stack before the call. The fifth and subsequent parameters, if present, start at offset 0x20 on the stack.
It's the same as the Windows / Microsoft x64 calling convention.
Also, the stack must be aligned to a multiple of 0x10 before the call. The stack is aligned to an odd multiple of 8 when the function is entered, so you must adjust the stack pointer by an odd multiple of 8 within the function.
default rel ; Use RIP-relative symbol addressing, not absolute
section .text
_start:
sub rsp, 0x28 ; 0x20 bytes of shadow space + 8 to align the stack
mov [ptrSystemTable], rdx
...
mov rcx, EVT_TIMER
mov rdx, TPL_APPLICATION
mov r8, 0
mov r9, 0
lea rax, [ptrTimerEvent]
mov [rsp+0x20], rax ; 5th arg on the stack above the shadow space
mov rax, [ptrSystemTable]
mov rax, [rax + EFI_SYSTEM_TABLE.BootServices]
call [rax + EFI_BOOT_SERVICES.CreateEvent]
cmp rax, EFI_SUCCESS
jne errorCode
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With