Haiku's EFI loader running on the SiFive unmatched (RISC-V)

So, all of my work on the EFI bootloader for RISC-V seems to be paying off.

I got my SiFive unmatched today, and after a little messing around (taking the two boot partitions from the SD card that ships with the SiFive Unmatched, and sticking them onto an SD card with Haiku’s EFI partition and our filesystem) we have our bootloader menu working



This confirms a lot of things:

  1. UEFI in the u-boot code shipping with the SiFive Unmatched is fully working
  2. The system’s FDT is available from UEFI bios services for us to use
  3. qemu’s emulation of rv64gc seems to be spot on.

We have a lot of work to do to merge @X512 's platform support patches… but this is a really encouraging sign early-on.


I am trying to run Qemu 6.0 (that is required to test UEFI and PCI bus) on 32 bit Haiku and I currently get crash here:

00754F90	PUSH	EBP	55
00754F91	MOV	EBP, ESP	89E5
00754F93	PUSH	EDI	57
00754F94	PUSH	ESI	56
00754F95	PUSH	EBX	53
00754F96	CALL	__x86.get_pc_thunk.bx	E8FC57B9FF
00754F9B	ADD	EBX, $0022F761	81C361F72200
00754FA1	SUB	ESP, 28	83EC1C
00754FA4	MOV	ESI, GS:[$00000000]	658B3500000000 // <-- Why GS, not FS as in x86/tls.c ???
00754FB1	TEST	ECX, ECX	85C9
00754FB3	JNE	$00755025	7570
00754FB5	LEA	EAX, [EBX+qemu_mutex_lock_func]	8D83503F0900
00754FBB	LEA	EDI, [EBX+rcu_registry_lock]	8DBBBC9E0A00
00754FC1	MOV	EAX, [EAX]	8B00
00754FC3	PUSH	EDX	52
00754FC4	PUSH	354	6862010000
00754FC9	LEA	EDX, [EBX+$008CE485-got]	8D93899DF4FF

It use global variable with __thread attribute. Simple test code with __thread attribute works fine and it use __tls_get_addr call to access TLS variable instead of x86 segment registers.


Problem was in -fPIE. It will be good to completely disable it in buildtools to avoid confusion. Haiku don’t use Linux executable model.


Now it is working and can run haiku_loader.efi. But keyboard input is not working (both serial and virtual keyboard). @kallisti5, do you have an idea how to get keyboard input for UEFI?

> build/install/bin/qemu-system-riscv64 -M virt -m 256M -serial stdio -parallel none -monitor none -kernel /boot/home/downloads/u-boot.bin -drive file=/boot/data/packages/haiku/generated.riscv64/efi.image,format=raw,if=virtio -device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0 -device ramfb
AddPath: /boot/home/config/non-packaged/add-ons/x86/opengl
Addon: /boot/home/config/non-packaged/add-ons/x86/opengl/libswpipe.so
Addon registered: /boot/home/config/non-packaged/add-ons/x86/opengl/libswpipe.so
AddPath: /boot/system/non-packaged/add-ons/x86/opengl
AddPath: /boot/system/add-ons/x86/opengl
GalliumContext: CreateDisplay: Using llvmpipe (LLVM 9.0.1, 128 bits) driver.
double buffer enabled

OpenSBI v0.9
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |

Platform Name             : riscv-virtio,qemu
Platform Features         : timer,mfdeleg
Platform HART Count       : 1
Firmware Base             : 0x80000000
Firmware Size             : 100 KB
Runtime SBI Version       : 0.2

Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*
Domain0 Region00          : 0x0000000080000000-0x000000008001ffff ()
Domain0 Region01          : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address      : 0x0000000080200000
Domain0 Next Arg1         : 0x000000008f000000
Domain0 Next Mode         : S-mode
Domain0 SysReset          : yes

Boot HART ID              : 0
Boot HART Domain          : root
Boot HART ISA             : rv64imafdcsu
Boot HART Features        : scounteren,mcounteren,time
Boot HART PMP Count       : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 54
Boot HART MHPM Count      : 0
Boot HART MHPM Count      : 0
Boot HART MIDELEG         : 0x0000000000000222
Boot HART MEDELEG         : 0x000000000000b109

U-Boot 2021.04-00604-ga1e95e3805 (Apr 09 2021 - 18:20:46 -0500)

CPU:   rv64imafdcsu
Model: riscv-virtio,qemu
DRAM:  256 MiB
In:    uart@10000000
Out:   uart@10000000
Err:   uart@10000000
Net:   No ethernet found.
Hit any key to stop autoboot:  0 

Device 0: 1af4 VirtIO Block Device
            Type: Hard Disk
            Capacity: 32.0 MB = 0.0 GB (65536 x 512)
... is now current device
Scanning virtio 0:1...
** Unable to read file / **
Failed to load '/'
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Scanning disk virtio-blk#8...
Found 2 disks
** Unable to read file ubootefi.var **
Failed to load EFI variables
BootOrder not defined
EFI boot manager: Cannot load any image
Found EFI removable media binary efi/boot/bootriscv64.efi
423866 bytes read in 2 ms (202.1 MiB/s)
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
Booting /efi\boot\bootriscv64.efi

        no boot path found, scan for all partitions...

Could not locate any supported boot devices!



We use the UEFI API to read keys, so it is probably QEMU or uboot problem. To me QEMU args looks ok, maybe you can try a simpler one without mentioning XHCI.

Problem is the same if not using XHCI controller. Serial console have no response to Haiku boot loader menu, but it works for u-boot console. Also haiku_loader.efi crashes if connecting 2 virtio disks (I use separate disks for UEFI boot loader and OS image). haiku_loader.riscv on TinyEMU works fine with many disks.

This is also suspicious: libfdt fdt_check_header(): FDT_ERR_BADMAGIC, but Fedora Linux image boots fine on this Qemu build.

Then I don’t think I can help much. I use -serial:file:debug.log and -monitor stdio in my setups. That way you might be able to use the monitor. It seems to have a sendkey keys command.

I found that enter key is working, but arrow keys are not, so it is character codes problem. That will be easy to fix. May be related to some Terminal incompatibilities.


It’s possible to navigate the boot menu with some other keys (tab, and maybe vi-style using j and k as up/down). I use this for the openfirmware version because the arrow keys are not reported at all by openfirmware on the machines I’m testing on.

1 Like

Tab works, j/k have no effect. Following sequence is produced when pressing arrow keys:

key: (char: 0, code: 65494)
key: (char: 79, code: 0)
key: (char: 66, code: 0)

Anybody knows how to turn off u-boot press any key countdown? It is annoying and slows down boot.

1 Like

@kallisti5 does the Sifive board have a an integrated gpu or did you use an external card?

I have a Radeon HD 6xxx plugged into it… however the boot menu is seen over serial. The Unmatched has a microusb port on the back which acts as a serial port for debugging. Handy!

Weird, it is working on the unleashed for me over serial and in qemu over serial and the virtio framebuffer. For the qemu framebuffer, try adding -m virt -device virtio-gpu


Do you have working GOP framebuffer on u-boot UEFI? What u-boot image and full qemu command line are you using?

I tried -device virtio-gpu, -device ramfb and GOP protocol was not found in each case:

=> bootefi selftest
Scanning disk virtio-blk#0...
** Unrecognized filesystem type **
Found 3 disks
No EFI system partition

Testing EFI API implementation

Number of tests to execute: 37


Setting up 'graphical output'
Graphical output protocol is not available.
Setting up 'graphical output' succeeded

I think you can do “setenv bootdelay 0” or something like that?

1 Like

@kallisti5, can you upload binary dump of FDT (*.dtb) used in board?

The u-boot binaries have a built-in dtb for the board they’re compiled for. However, the dts is here:

Here’s the binary:


One more thing to check: do you have following errors when running your u-boot.bin in Qemu? When running on real hardware? u-boot.bin may be broken.

libfdt fdt_check_header(): FDT_ERR_BADMAGIC


efi/fdt: Probing for device trees from UEFI...
efi/fdt: Valid FDT from UEFI table 2 (4096)
1 Like