On Fri, Jun 19, 2026 at 2:52 PM Joel Stanley <[email protected]> wrote:
>
> From: Nicholas Piggin <[email protected]>
>
> OpenSBI hangs before any console output if the domain init code sees the
> next stage is not in an executable region.
>
> If no kernel payload is provided to QEMU, the next stage address is
> NULL, and the riscv virt machine memory map ends up covering the 0
> address with the catch all S-mode RWX region and so OpenSBI prints
> console messages and does not hang until the next stage boot.
>
> The Tenstorrent Atlantis machine address map has RAM starting at 0 and
> it loads OpenSBI there, so it is M-mode and not accessible by S-mode,
> tripping the early check and hang.

Ok, so I looked at this today and I think this commit message and
approach aren't the way to go.

I do think the commit message is a bit confusing and not entirely
accurate. What about something like this (might need a tidy up, but
you should get the point):

commit aac25688634d1afe6735cb71d8dd1ea652fa90d4 (HEAD -> riscv-to-apply.next)
Author: Alistair Francis <[email protected]>
Date:   Tue Jun 23 12:37:47 2026 +1000

   hw/riscv/atlantis: Ensure OpenSBI has a non-zero next_addr

   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]>

diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c
index b40a893a37..dba56ad6e1 100644
--- a/hw/riscv/tt_atlantis.c
+++ b/hw/riscv/tt_atlantis.c
@@ -444,8 +444,15 @@ 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. Let's tell OpenSBI to start running at the start
+         * of memory so we at least let OpenSBI complete.
+         */
+        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,

Reply via email to