renode / renode

Renode - Antmicro's open source simulation and virtual development framework for complex embedded systems
https://renode.io
Other
1.54k stars 272 forks source link

HiFive Unmatched OpenSBI fw_payload configuration #515

Open Jesse-Millwood opened 11 months ago

Jesse-Millwood commented 11 months ago

Description

I am trying to boot an opensbi fw_payload.elf on the HiFive Unmatched board. All cores get stuck in the _wait_for_boot_hart function.

Usage example

I downloaded the latest release of Renode (1.14.0.29506) and unpacked to an Ubuntu machine.

I build u-boot and included it as the payload in an OpenSBI elf like this:

Build U-Boot

git clone https://source.denx.de/u-boot/u-boot.git
cd u-boot
git checkout v2023.07.02
export CROSS_COMPILE=riscv64-unknown-linux-gnu-
make sifive_unmatched_defconfig
make

Then I build OpenSBI like this:

git clone https://github.com/riscv/opensbi.git
cd opensbi
git checkout v1.3.1
export CROSS_COMPILE=riscv64-unknown-elf-
make PLATFORM=generic FW_PAYLOAD_PATH=${u-boot-dir}/u-boot-dtb.bin

I use the following resc file:

$name?="unmatched"
using sysbus
mach create $name
machine LoadPlatformDescription @platforms/cpus/sifive-fu740.repl
showAnalyzer uart0
showAnalyzer uart1
$payload_elf?=@src/opensbi/build/platform/generic/firmware/fw_payload.elf
$uboot_elf?=@src/u-boot/u-boot

macro reset_fw_payload
"""
    sysbus LoadELF $payload_elf
    sysbus.s7 LogFunctionNames True
    sysbus.u74_1 LogFunctionNames True
    logFile @renode-functionnames.log
    sysbus LoadSymbolsFrom $uboot_elf
    # Set register a0, a1, a2
    s7 SetRegisterUnsafe 10 0x00000010
    s7 SetRegisterUnsafe 11 0xbfe00000
    s7 SetRegisterUnsafe 12 0x00001030
    u74_1 SetRegisterUnsafe 10 0x10
"""
runMacro $reset_fw_payload
machine StartGdbServer 3333

I have tried with and without setting the registers here. I just copied the register values from the qemu run and other examples.

What I see in the renode log is:

09:58:13.9102 [INFO] unmatched: GDB server with all CPUs started on port :3333
09:58:23.8847 [INFO] unmatched: Machine started.
09:58:23.9428 [INFO] s7: Entering function _fw_start (entry) at 0x80000000
09:58:23.9429 [INFO] u74_1: Entering function _fw_start (entry) at 0x80000000
09:58:23.9430 [INFO] s7: Entering function fw_boot_hart (entry) at 0x80000658
09:58:23.9434 [INFO] u74_1: Entering function fw_boot_hart (entry) at 0x80000658
09:58:23.9435 [INFO] s7: Entering function _fw_start+0x10 (guessed) at 0x80000010
09:58:23.9435 [INFO] u74_1: Entering function _fw_start+0x10 (guessed) at 0x80000010
09:58:23.9438 [INFO] s7: Entering function _try_lottery (entry) at 0x8000002A
09:58:23.9438 [INFO] s7: Entering function _wait_relocate_copy_done (entry) at 0x80000160
09:58:23.9439 [INFO] u74_1: Entering function _try_lottery (entry) at 0x8000002A
09:58:23.9439 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9450 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9451 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9451 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9452 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9453 [INFO] u74_1: Entering function _wait_relocate_copy_done (entry) at 0x80000160
09:58:23.9453 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9454 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9455 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9455 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9456 [INFO] u74_1: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9456 [INFO] s7: Entering function _wait_for_boot_hart (entry) at 0x80000436
09:58:23.9457 [INFO] u74_1: Entering function _wait_for_boot_hart (entry) at 0x80000436

I can confirm the same with gdb. Right now I am just trying to get to the u-boot shell.

On QEMU the same fw_payload.elf works fine when loaded to the sifive_u machine with the -bios option.

I do see that the beaglev example seems to load a payload_elf and u-boot fine but that also doesn't have the e51 either. Is there a preferred opensbi config/version for the RISCV machines on Renode?

mateusz-holenko commented 10 months ago

Hi @Jesse-Millwood, thanks for reporting the issue!

We've reproduced that on our end and we are looking into it.

mateusz-holenko commented 10 months ago

It seems like the main difference is that QEMU automatically generates FDT based on the platform configuration and puts it into memory.

A solution for Renode is to explicitly load DTB (this is a file dumped directly from QEMU) with:

sysbus LoadFdt @https://dl.antmicro.com/projects/renode/hifive_unleashed_a00.dtb-s_4671-4b257fb87f9635ada0efd1d8dbd3bc514f9d3c5a 0xbfe00000

After loading this file and setting A1 registers (DTB address) for all cores (again QEMU configures this implicitly) we see the following output in Renode:

OpenSBI v1.3.1
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|___/_____|
        | |
        |_|
Platform Name             : SiFive HiFive Unleashed A00
Platform Features         : medeleg
Platform HART Count       : 2
Platform IPI Device       : aclint-mswi
Platform Timer Device     : aclint-mtimer @ 1000000Hz
Platform Console Device   : sifive_uart
Platform HSM Device       : ---
Platform PMU Device       : ---
Platform Reboot Device    : gpio-restart
Platform Shutdown Device  : ---
Platform Suspend Device   : ---
Platform CPPC Device      : ---
Firmware Base             : 0x80000000
Firmware Size             : 200 KB
Firmware RW Offset        : 0x20000
Firmware RW Size          : 72 KB
Firmware Heap Offset      : 0x29000
Firmware Heap Size        : 36 KB (total), 2 KB (reserved), 9 KB (used), 24 KB (free)
Firmware Scratch Size     : 4096 B (total), 760 B (used), 3336 B (free)
Runtime SBI Version       : 1.0
Domain0 Name              : root
Domain0 Boot HART         : 1
Domain0 HARTs             : 0*,1*
Domain0 Region00          : 0x0000000002000000-0x000000000200ffff M: (I,R,W) S/U: ()
Domain0 Region01          : 0x0000000080000000-0x000000008001ffff M: (R,X) S/U: ()
Domain0 Region02          : 0x0000000080020000-0x000000008003ffff M: (R,W) S/U: ()
Domain0 Region03          : 0x0000000000000000-0xffffffffffffffff M: (R,W,X) S/U: (R,W,X)
Domain0 Next Address      : 0x0000000080200000
Domain0 Next Arg1         : 0x0000000082200000
Domain0 Next Mode         : S-mode
Domain0 SysReset          : yes
Domain0 SysSuspend        : yes
Boot HART ID              : 1
Boot HART Domain          : root
Boot HART Priv Version    : v1.10
Boot HART Base ISA        : rv64imafdc
Boot HART ISA Extensions  : time
Boot HART PMP Count       : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 54
Boot HART MHPM Count      : 0
Boot HART MIDELEG         : 0x0000000000000222
Boot HART MEDELEG         : 0x000000000000b109
U-Boot 2023.07.02 (Oct 12 2023 - 17:06:16 +0200)
CPU:   rv64imac
Model: SiFive HiFive Unmatched A00
DRAM:  16 GiB
Core:  28 devices, 19 uclasses, devicetree: separate
MMC:   spi@10050000:mmc@0: 0
Loading Environment from SPIFlash... jedec_spi_nor flash@0: unrecognized JEDEC id bytes: 00, 00, 00
*** Warning - spi_flash_probe_bus_cs() failed, using default environment
EEPROM: Not a SiFive HiFive EEPROM data format - magic bytes don't match
EEPROM dump: (0x25 bytes)
00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
20: 00 00 00 00 00 
Read failed.
In:    serial@10010000
Out:   serial@10010000
Err:   serial@10010000
Model: SiFive HiFive Unmatched A00
Net:   
Error: ethernet@10090000 address not set.
No ethernet found.
Working FDT set to ff7303d0
Hit any key to stop autoboot:  0 

Below is the full resc script we used (with executed function names logging disabled):

$name?="unmatched"
using sysbus
mach create $name
machine LoadPlatformDescription @platforms/cpus/sifive-fu740.repl
showAnalyzer uart0
showAnalyzer uart1
$payload_elf?=$ORIGIN/opensbi/build/platform/generic/firmware/fw_payload.elf
$uboot_elf?=$ORIGIN/u-boot/u-boot

macro reset_fw_payload
"""
    sysbus LoadELF $payload_elf

    # Disable LogFunctionNames, as it impacts performance
    # sysbus.s7 LogFunctionNames True
    # sysbus.u74_1 LogFunctionNames True
    # logFile @renode-functionnames.log

    sysbus LoadSymbolsFrom $uboot_elf
    # Set register a0, a1, a2
    s7 SetRegisterUnsafe 10 0x00000010
    s7 SetRegisterUnsafe 11 0xbfe00000
    s7 SetRegisterUnsafe 12 0x00001030
    u74_1 SetRegisterUnsafe 10 0x10

    # Load fdt file
    # This file can be generated from QEMU by running:
    # `qemu-system-riscv64 -M sifive_u -machine dumpdtb=qemu.dtb`
    sysbus LoadFdt @https://dl.antmicro.com/projects/renode/hifive_unleashed_a00.dtb-s_4671-4b257fb87f9635ada0efd1d8dbd3bc514f9d3c5a 0xbfe00000

    u74_1 SetRegisterUnsafe 11 0xbfe00000
    u74_2 SetRegisterUnsafe 11 0xbfe00000
    u74_3 SetRegisterUnsafe 11 0xbfe00000
    u74_4 SetRegisterUnsafe 11 0xbfe00000
"""
runMacro $reset_fw_payload
machine StartGdbServer 3333