On Tue, Jun 30, 2026 at 12:53 PM Joel Stanley <[email protected]> wrote:
>
> From: Alistair Francis <[email protected]>
>
> When using OpenSBI fw_dynamic on the Atlantis board OpenSBI fails
> to print any output, as it hits an error early on
> in the boot process and gets stuck in `sbi_hart_hang()`.
>
> The error occurs in the `sanitize_domain()` function inside OpenSBI.
> `sanitize_domain()` is called after a M-Mode OpenSBI Firmware and a generic
> coverall S-Mode RWX memory region are created. `sanitize_domain()` is
> checking that the next address is executable.
>
> If no next address is provided (which occurs on QEMU with an empty payload),
> then `dom->next_addr` will be 0. On most RISC-V boards address 0 will fall
> inside the coverall S-Mode RWX memory region and pass this check. On
> Atlantis the OpenSBI firmware is running at address 0, so this address
> falls inside the M-Mode only OpenSBI firmware region and fails the check.
>
> Once the check has failed OpenSBI aborts and the user doesn't see any
> messages. This can be fixed by either supplying a payload, or just
> manually forcing a non-zero address (actually just any address that
> isn't the OpenSBI firmware) for next_addr.
>
> This patch ensures that if no kernel is loaded we still specify a
> default kernel_entry so that OpenSBI happily boots and jumps to
> the first address in memory.
>
> Signed-off-by: Alistair Francis <[email protected]>
> Signed-off-by: Joel Stanley <[email protected]>

Reviewed-by: Alistair Francis <[email protected]>

Alistair

> ---
>  hw/riscv/tt_atlantis.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c
> index 1f0cd08ac959..d4fa9c251d3b 100644
> --- a/hw/riscv/tt_atlantis.c
> +++ b/hw/riscv/tt_atlantis.c
> @@ -377,8 +377,16 @@ static void tt_atlantis_machine_done(Notifier *notifier, 
> void *data)
>      if (machine->kernel_filename) {
>          riscv_load_kernel(machine, &boot_info, kernel_start_addr,
>                            true, NULL);
> +        kernel_entry = boot_info.image_low_addr;
> +    } else {
> +        /* If we aren't loading a payload, OpenSBI thinks we are trying to 
> boot
> +         * address 0, which fails `sbi_domain_check_addr()` as that is where
> +         * OpenSBI is running. Instead point OpenSBI to the end of the region
> +         * where it was loaded, which avoids the early hang, allowing the
> +         * system to proceed with the OpenSBI boot output.
> +         */
> +        kernel_entry = kernel_start_addr;
>      }
> -    kernel_entry = boot_info.image_low_addr;
>
>      fdt_load_addr = riscv_compute_fdt_addr(s->memmap[TT_ATL_DDR_LO].base,
>                                             s->memmap[TT_ATL_DDR_LO].size,
> --
> 2.47.3
>
>

Reply via email to