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?