On 23/6/26 07:20, Alistair Francis wrote:
On Tue, Jun 23, 2026 at 2:38 PM Joel Stanley <[email protected]> wrote:

On Tue, 23 Jun 2026 at 12:11, Alistair Francis <[email protected]> wrote:

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.

Nice.


    Signed-off-by: Alistair Francis <[email protected]>

This reads fine by me. Nick?


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.

This isn't quite true, we're pointing to just after opensbi. The start
of the rest of memory.

Ah yep, good point.


Perhaps:

  Instead point OpenSBI to jump to the end of the region where it
  was loaded, which avoids the early hang in OpenSBI, allowing
  the system to proceed with the OpenSBI boot output.

Sounds good.

Alistair


Thanks for taking a look.

Cheers,

Joel

+         */
+        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