EFI calling convention on RISC-V (illegal-instruction)
16:11 14 Feb 2026

I wan create a simple EFI application in assembly for RISC-V for the purpose of education. Have want to port a working x86_64 example in assembly to RISC-V, but struggling with the correct calling convention I think.

The (working) code snippet for x86_64:

.text

.global _start
_start:
    movq 64(%rdx), %rcx     /* Save EFI SystemTable->EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL address */
    movq 8(%rcx), %rax      /* Save EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL->OutputString address */
    leaq (msg), %rdx        /* Load UTF-16 message */
    subq $32, %rsp
    call *%rax              /* Invoke EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL->OutputString */
    addq $32, %rsp
    ret


.data
msg:
.byte 'H'
.byte 0
.byte 'e'
.byte 0
.byte 'l'
.byte 0
.byte 'l'
.byte 0
.byte 'o'
.byte 0
.byte ' '
.byte 0
.byte 'W'
.byte 0
.byte 'o'
.byte 0
.byte 'r'
.byte 0
.byte 'l'
.byte 0
.byte 'd'
.byte 0
.byte '!'
.byte 0
.byte '\r'
.byte 0
.byte '\n'
.byte 0
.byte 0
.byte 0

Should simple output Hello World! on the EFI console.

My current not working RISC-V implementation:

.global _start
_start:
    mv t0, a1
    mv t1, t0
    addi t1, t1, 64
    mv t2, t1
    addi t2, t2, 8
    mv a0, t1
    la a1, msg
    jalr x0, 0(t2)
    ret

When I want to try to execute the code in a QEMU instance or on real hardware (VisionFive 2) running U-Boot I get an illegal-instruction exception:

StarFive # fatload mmc 1:3 0x50000000 hello.efi
12318 bytes read in 3 ms (3.9 MiB/s)
StarFive # bootefi 0x50000000                  
Card did not respond to voltage select! : -110
Cannot persist EFI variables without system partition
Booting /hello.efi
Unhandled exception: Illegal instruction
EPC: 00000000fff3501c RA: 00000000fff86346 TVAL: 0000000000000000
EPC: 000000004020101c RA: 0000000040252346 reloc adjusted

SP:  00000000ff716b50 GP:  0000000000000000 TP:  0000000000000002
T0:  00000000fff34fd0 T1:  00000000fff35010 T2:  00000000fff35018
S0:  00000000ff716d28 S1:  00000000ff716d20 A0:  00000000fff3010
A1:  00000000fe6cc000 A2:  0000000000000000 A3:  0000000000000000
A4:  00000000ff73f450 A5:  00000000fe6ca000 A6:  00000000fffd4bf0
A7:  0000000000000020 S2:  0000000000000000 S3:  000000000000301e
S4:  00000000fe70b040 S5:  0000000000000000 S6:  0000000000000000
S7:  00000000ff73f200 S8:  0000000000000000 S9:  0000000000000000
S10: 00000000ff737d90 S11: 0000000000000001 T3:  000000000000001f
T4:  0000000000000000 T5:  0000000000000000 T6:  00000000ff716cb0

Code: 0000 0000 8498 fffd 0000 0000 a9f0 ff72 (0000)
UEFI image [0x00000000fe6c9000:0x00000000fe6cc01d] '/hello.efi'


resetting ...

I'm quite new with the RISC-V instruction set, so it might be possible that I misunderstood the usage from jalr. The code runs fine when I don't make the EFI call in the above code.

Is there also a elegant solution to debug the issue?

assembly riscv calling-convention u-boot uefi