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. > > > > 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,
