Re: [PATCH v3] platform: generic: Tenstorrent Atlantis support
Anup Patel <[email protected]>
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <CAAhSdy3eS3kt_vdnEirYugSSFt5ng+r9_+9vh7aYxsT+=DAoEg@mail.gmail.com> |
On Fri, Apr 24, 2026 at 11:55 AM Nicholas Piggin <[email protected]> wrote: > > Add the Tenstorrent Atlantis as a generic-platform. This initial support > enables the single_fw_region option, and verifies and prints HART PMA > CSR configuration. > > Signed-off-by: Nicholas Piggin <[email protected]> > --- > Since v2: > - Fix silly 32-bit build issue. > > Since v1: > - Drop the IOMMU since it depends on core PMP changes. I will work > on those in parallel. > > Note the Atlantis hardware is not yet released, and QEMU models are in > the process of being upstreamed, but at the moment not complete. We > will continue to expand support and improve documentation for QEMU/HW > as we get more pieces in place. LGTM. Reviewed-by: Anup Patel <[email protected]> Applied this patch to the riscv/opensbi repo. Thanks, Anup > > Thanks, > Nick > --- > docs/platform/generic.md | 2 + > docs/platform/tt-atlantis.md | 35 +++++ > platform/generic/Kconfig | 6 + > platform/generic/configs/defconfig | 1 + > .../generic/include/tenstorrent/ascalon.h | 12 ++ > platform/generic/include/tenstorrent/pma.h | 18 +++ > platform/generic/tenstorrent/Kconfig | 5 + > platform/generic/tenstorrent/ascalon.c | 53 +++++++ > platform/generic/tenstorrent/atlantis.c | 50 +++++++ > platform/generic/tenstorrent/objects.mk | 12 ++ > platform/generic/tenstorrent/pma.c | 138 ++++++++++++++++++ > 11 files changed, 332 insertions(+) > create mode 100644 docs/platform/tt-atlantis.md > create mode 100644 platform/generic/include/tenstorrent/ascalon.h > create mode 100644 platform/generic/include/tenstorrent/pma.h > create mode 100644 platform/generic/tenstorrent/Kconfig > create mode 100644 platform/generic/tenstorrent/ascalon.c > create mode 100644 platform/generic/tenstorrent/atlantis.c > create mode 100644 platform/generic/tenstorrent/objects.mk > create mode 100644 platform/generic/tenstorrent/pma.c > > diff --git a/docs/platform/generic.md b/docs/platform/generic.md > index c48d6a9a..0b896ede 100644 > --- a/docs/platform/generic.md > +++ b/docs/platform/generic.md > @@ -47,6 +47,7 @@ RISC-V Platforms Using Generic Platform > * **SiFive HiFive Unleashed** (*[sifive_fu540.md]*) > * **Spike** (*[spike.md]*) > * **T-HEAD C9xx series Processors** (*[thead-c9xx.md]*) > +* **Tenstorrent Atlantis Platform** (*[tt-atlantis.md]*) > * **OpenPiton FPGA SoC** (*[fpga-openpiton.md]*) > * **Ariane FPGA SoC** (*[fpga-ariane.md]*) > > @@ -57,5 +58,6 @@ RISC-V Platforms Using Generic Platform > [sifive_fu540.md]: sifive_fu540.md > [spike.md]: spike.md > [thead-c9xx.md]: thead-c9xx.md > +[tt-atlantis.md]: tt-atlantis.md > [fpga-openpiton.md]: fpga-openpiton.md > [fpga-ariane.md]: fpga-ariane.md > diff --git a/docs/platform/tt-atlantis.md b/docs/platform/tt-atlantis.md > new file mode 100644 > index 00000000..b9bdd238 > --- /dev/null > +++ b/docs/platform/tt-atlantis.md > @@ -0,0 +1,35 @@ > +Tenstorrent Atlantis Platform > +============================= > + > +The Tenstorrent Atlantis is an SoC and development board from > +Tenstorrent in partnership with CoreLab Technology. It contains 8 RISC-V > +RVA23 compliant Tenstorrent Ascalon cores with RISC-V AIA, RISC-V IOMMU, > +and a range of devices and IO connectivity. > + > +To build the platform-specific library and firmware images, provide the > +*PLATFORM=generic* parameter to the top level `make` command. > + > +Platform Options > +---------------- > + > +The *Tenstorrent Atlantis* platform does not have any platform-specific > +options. > + > +Building Tenstorrent Atlantis Platform > +-------------------------------------- > + > +The Atlantis Platform is still under development. This section will be > +expanded as firmware and support become available. > + > +QEMU support is currently being developed and initial support has been > +proposed for upstream. To run QEMU that is patched with 'tt-atlantis' > +machine support, run: > + > +``` > +qemu-system-riscv64 -M tt-atlantis -nographic \ > + -bios build/platform/generic/firmware/fw_payload.bin \ > + -kernel <linux_build_dir>/Image > +``` > + > +Recent (6.18) Linux/riscv 64-bit defconfig kernels should run the QEMU > +tt-atlantis machine. > diff --git a/platform/generic/Kconfig b/platform/generic/Kconfig > index 600273d1..d594b140 100644 > --- a/platform/generic/Kconfig > +++ b/platform/generic/Kconfig > @@ -89,6 +89,11 @@ config PLATFORM_STARFIVE_JH7110 > bool "StarFive JH7110 support" > default n > > +config PLATFORM_TENSTORRENT_ATLANTIS > + bool "Tenstorrent Atlantis support" > + select CPU_TENSTORRENT_ASCALON > + default n > + > config PLATFORM_THEAD > bool "THEAD C9xx support" > select THEAD_C9XX_ERRATA > @@ -114,6 +119,7 @@ config PLATFORM_MIPS_P8700_BOSTON > > source "$(OPENSBI_SRC_DIR)/platform/generic/andes/Kconfig" > source "$(OPENSBI_SRC_DIR)/platform/generic/eswin/Kconfig" > +source "$(OPENSBI_SRC_DIR)/platform/generic/tenstorrent/Kconfig" > source "$(OPENSBI_SRC_DIR)/platform/generic/thead/Kconfig" > > endif > diff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig > index 1d3431e7..800f3f14 100644 > --- a/platform/generic/configs/defconfig > +++ b/platform/generic/configs/defconfig > @@ -10,6 +10,7 @@ CONFIG_PLATFORM_SIFIVE_FU540=y > CONFIG_PLATFORM_SIFIVE_FU740=y > CONFIG_PLATFORM_SOPHGO_SG2042=y > CONFIG_PLATFORM_STARFIVE_JH7110=y > +CONFIG_PLATFORM_TENSTORRENT_ATLANTIS=y > CONFIG_PLATFORM_THEAD=y > CONFIG_PLATFORM_MIPS_P8700_EYEQ7H=y > CONFIG_PLATFORM_MIPS_P8700_BOSTON=y > diff --git a/platform/generic/include/tenstorrent/ascalon.h b/platform/generic/include/tenstorrent/ascalon.h > new file mode 100644 > index 00000000..5d7b7635 > --- /dev/null > +++ b/platform/generic/include/tenstorrent/ascalon.h > @@ -0,0 +1,12 @@ > +/* > + * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc. > + * SPDX-License-Identifier: BSD-2-Clause > + */ > + > +#ifndef __TENSTORRENT_ASCALON_H__ > +#define __TENSTORRENT_ASCALON_H__ > + > +void tt_ascalon_discover_pmas_from_boot_hart(void); > +void tt_ascalon_verify_pmas_nonboot_hart(void); > + > +#endif > diff --git a/platform/generic/include/tenstorrent/pma.h b/platform/generic/include/tenstorrent/pma.h > new file mode 100644 > index 00000000..051764ee > --- /dev/null > +++ b/platform/generic/include/tenstorrent/pma.h > @@ -0,0 +1,18 @@ > +/* > + * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc. > + * SPDX-License-Identifier: BSD-2-Clause > + */ > + > +#ifndef __TENSTORRENT_PMA_H__ > +#define __TENSTORRENT_PMA_H__ > + > +/* Max number of PMAs for devices (CPU, IOMMU) for Tenstorrent platforms. */ > +#define TT_MAX_PMAS 32 > + > +u64 tt_pma_get(unsigned int n); > +void tt_pma_set(unsigned int n, u64 pma); > +bool tt_pma_validate(unsigned int i, u64 pma); > +void tt_pma_print(unsigned int i, u64 pma); > + > +#endif > + > diff --git a/platform/generic/tenstorrent/Kconfig b/platform/generic/tenstorrent/Kconfig > new file mode 100644 > index 00000000..76c7fb32 > --- /dev/null > +++ b/platform/generic/tenstorrent/Kconfig > @@ -0,0 +1,5 @@ > +# SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc. > +# SPDX-License-Identifier: BSD-2-Clause > + > +config CPU_TENSTORRENT_ASCALON > + bool > diff --git a/platform/generic/tenstorrent/ascalon.c b/platform/generic/tenstorrent/ascalon.c > new file mode 100644 > index 00000000..485144cd > --- /dev/null > +++ b/platform/generic/tenstorrent/ascalon.c > @@ -0,0 +1,53 @@ > +/* > + * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc. > + * SPDX-License-Identifier: BSD-2-Clause > + */ > + > +#include <sbi/riscv_asm.h> > +#include <sbi/sbi_console.h> > +#include <sbi/sbi_csr_detect.h> > + > +#include <tenstorrent/ascalon.h> > +#include <tenstorrent/pma.h> > + > +#define CSR_PMACFG0 0x7e0 > + > +void tt_ascalon_discover_pmas_from_boot_hart(void) > +{ > + struct sbi_trap_info trap = {0}; > + > + /* Whisper virtual platform does not implement PMA */ > + csr_read_allowed(CSR_PMACFG0, &trap); > + if (trap.cause) > + return; > + > + for (unsigned int i = 0; i < TT_MAX_PMAS; i++) { > + u64 pma = csr_read_num(CSR_PMACFG0 + i); > + if (!tt_pma_validate(i, pma)) { > + sbi_printf("HART%d: Bad boot PMA%02d 0x%016lx\n", > + current_hartid(), i, pma); > + } > + tt_pma_set(i, pma); > + > + if (pma) > + tt_pma_print(i, pma); > + } > +} > + > +void tt_ascalon_verify_pmas_nonboot_hart(void) > +{ > + struct sbi_trap_info trap = {0}; > + > + /* Whisper virtual platform does not implement PMA */ > + csr_read_allowed(CSR_PMACFG0, &trap); > + if (trap.cause) > + return; > + > + for (unsigned int i = 0; i < TT_MAX_PMAS; i++) { > + u64 pma = csr_read_num(CSR_PMACFG0 + i); > + if (pma != tt_pma_get(i)) { > + sbi_printf("HART%d: Bad boot PMA%02d 0x%016lx does not match boot HART\n", > + current_hartid(), i, pma); > + } > + } > +} > diff --git a/platform/generic/tenstorrent/atlantis.c b/platform/generic/tenstorrent/atlantis.c > new file mode 100644 > index 00000000..4c312f7e > --- /dev/null > +++ b/platform/generic/tenstorrent/atlantis.c > @@ -0,0 +1,50 @@ > +/* > + * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc. > + * SPDX-License-Identifier: BSD-2-Clause > + */ > + > +#include <platform_override.h> > +#include <libfdt.h> > +#include <sbi/sbi_error.h> > +#include <sbi/sbi_hart.h> > +#include <sbi/sbi_system.h> > +#include <sbi/sbi_console.h> > + > +#include <tenstorrent/ascalon.h> > +#include <tenstorrent/pma.h> > + > +static int tt_atlantis_final_init(bool cold_boot) > +{ > + if (cold_boot) { > + /* Boot firmware sets HART PMAs. Read and verify them. */ > + tt_ascalon_discover_pmas_from_boot_hart(); > + } else { > + /* Verify nonboot HARTs have PMAs matching boot HART */ > + tt_ascalon_verify_pmas_nonboot_hart(); > + } > + > + return generic_final_init(cold_boot); > +} > + > +static bool tt_atlantis_single_fw_region(void) > +{ > + return true; > +} > + > +static int tt_atlantis_platform_init(const void *fdt, int nodeoff, const struct fdt_match *match) > +{ > + generic_platform_ops.final_init = tt_atlantis_final_init; > + generic_platform_ops.single_fw_region = tt_atlantis_single_fw_region; > + > + return 0; > +} > + > +static const struct fdt_match tt_atlantis_match[] = { > + { .compatible = "tenstorrent,atlantis" }, > + { }, > +}; > + > +const struct fdt_driver tenstorrent_atlantis = { > + .match_table = tt_atlantis_match, > + .init = tt_atlantis_platform_init, > +}; > diff --git a/platform/generic/tenstorrent/objects.mk b/platform/generic/tenstorrent/objects.mk > new file mode 100644 > index 00000000..17da2c5e > --- /dev/null > +++ b/platform/generic/tenstorrent/objects.mk > @@ -0,0 +1,12 @@ > +# > +# SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc. > +# SPDX-License-Identifier: BSD-2-Clause > +# > + > +ifeq ($(PLATFORM_RISCV_XLEN), 64) > +platform-objs-y += tenstorrent/pma.o > +platform-objs-$(CONFIG_CPU_TENSTORRENT_ASCALON) += tenstorrent/ascalon.o > + > +carray-platform_override_modules-$(CONFIG_PLATFORM_TENSTORRENT_ATLANTIS) += tenstorrent_atlantis > +platform-objs-$(CONFIG_PLATFORM_TENSTORRENT_ATLANTIS) += tenstorrent/atlantis.o > +endif > diff --git a/platform/generic/tenstorrent/pma.c b/platform/generic/tenstorrent/pma.c > new file mode 100644 > index 00000000..daf60192 > --- /dev/null > +++ b/platform/generic/tenstorrent/pma.c > @@ -0,0 +1,138 @@ > +/* > + * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc. > + * SPDX-License-Identifier: BSD-2-Clause > + */ > + > +#include <sbi/sbi_error.h> > +#include <sbi/sbi_console.h> > +#include <sbi/sbi_math.h> > +#include <libfdt.h> > +#include <sbi_utils/fdt/fdt_helper.h> > + > +#include <tenstorrent/pma.h> > + > +/* > + * All PMAs in the system should be the same (after boot). The init code > + * must have set PMAs for all HARTs. > + */ > + > +/* > + * Ascalon CPU and IOMMU PMA layout: > + * Field > + * [2:0] Permission [0] Read, [1] Write, [2] Execute > + * [4:3] Memory type 00: Main memory, 01: IO memory relaxed, > + * 10: IO memory channel 0, 11: IO memory channel 1 > + * [6:5] AMO type 00: AMONone, 01: AMOSwap, > + * 10: AMOLogical, 11: AMOArithmetic > + * [7] Cacheability (main memory type) > + * 1: Cacheable, 0: Non-cacheable > + * Combining Capability (IO memory type) > + * 1: Combining allowed, 0: Combining disallowed > + * [8] Routing (coherency) > + * 1: Coherent network, 0: Non-coherent network > + * [11:9] Reserved > + * [51:12] Physical address [51:12] base > + * [63:58] Size log 2 (number of address LSB to ignore when matching) > + * 0 = invalid entry (no match) > + */ > + > +#define PMA_PERMISSION_R 0x1 > +#define PMA_PERMISSION_W 0x2 > +#define PMA_PERMISSION_X 0x4 > +#define PMA_PERMISSION_MASK 0x7 > + > +#define PMA_TYPE_MAIN_MEMORY 0x0 > +#define PMA_TYPE_IO_RELAXED 0x8 > +#define PMA_TYPE_IO_ORDERED_0 0x10 > +#define PMA_TYPE_IO_ORDERED_1 0x18 > +#define PMA_TYPE_MASK 0x18 > + > +#define PMA_AMO_NONE 0x0 > +#define PMA_AMO_SWAP 0x20 > +#define PMA_AMO_LOGICAL 0x40 > +#define PMA_AMO_ARITHMETIC 0x60 > +#define PMA_AMO_MASK 0x60 > + > +#define PMA_MEMORY_CACHEABLE 0x80 > +#define PMA_IO_COMBINING 0x80 > +#define PMA_ROUTING_COHERENT 0x100 > + > +#define PMA_FLAGS_MASK 0x00000000000001ffULL > +#define PMA_ADDRESS_MASK 0x000ffffffffff000ULL > +#define PMA_SIZE_MASK 0xfc00000000000000ULL > +#define PMA_RESERVED_MASK 0x0300000000000e00ULL > + > +#define PMA_SIZE_SHIFT 58 > + > +static u64 tt_pma_size(u64 pma) > +{ > + if ((pma & PMA_SIZE_MASK) == 0) > + return 0; > + > + return 1ULL << ((pma & PMA_SIZE_MASK) >> PMA_SIZE_SHIFT); > +} > + > +static u64 tt_pma_address(u64 pma) > +{ > + return (pma & PMA_ADDRESS_MASK) & ~((tt_pma_size(pma) - 1)); > +} > + > +bool tt_pma_validate(unsigned int i, u64 pma) > +{ > + if (!pma) > + return true; > + > + if (pma & PMA_RESERVED_MASK) { > + sbi_printf("PMA%02u 0x%016lx contains reserved bits\n", i, pma); > + return false; > + } > + > + if (tt_pma_size(pma) < 4096) { > + sbi_printf("PMA%02u 0x%016lx size < 4KB\n", i, pma); > + return false; > + } > + > + if (tt_pma_address(pma) != (pma & PMA_ADDRESS_MASK)) { > + sbi_printf("PMA%02u 0x%016lx address is not aligned to size\n", i, pma); > + return false; > + } > + > + return true; > +} > + > +void tt_pma_print(unsigned int i, u64 pma) > +{ > + sbi_printf("PMA%02d : 0x%016lx-0x%016lx perm:%s%s%s type:%s %s %s amo:%s\n", i, > + tt_pma_address(pma), tt_pma_address(pma) + tt_pma_size(pma) - 1, > + pma & PMA_PERMISSION_R ? "R" : " ", > + pma & PMA_PERMISSION_W ? "W" : " ", > + pma & PMA_PERMISSION_X ? "X" : " ", > + (pma & PMA_TYPE_MASK) == PMA_TYPE_MAIN_MEMORY ? "main-memory" : > + ((pma & PMA_TYPE_MASK) == PMA_TYPE_IO_RELAXED ? "io-relaxed" : > + ((pma & PMA_TYPE_MASK) == PMA_TYPE_IO_ORDERED_0 ? "io-ordered-0" : "io-ordered-1")), > + (pma & PMA_TYPE_MASK) == PMA_TYPE_MAIN_MEMORY ? > + (pma & PMA_MEMORY_CACHEABLE ? "cacheable" : "non-cacheable") : > + (pma & PMA_IO_COMBINING ? "combining" : "non-combining"), > + pma & PMA_ROUTING_COHERENT ? "coherent" : "non-coherent", > + (pma & PMA_AMO_MASK) == PMA_AMO_NONE ? "none" : > + ((pma & PMA_AMO_MASK) == PMA_AMO_SWAP ? "swap" : > + ((pma & PMA_AMO_MASK) == PMA_AMO_LOGICAL ? "logical" : "arithmetic"))); > +} > + > +static u64 pmas[TT_MAX_PMAS]; > + > +void tt_pma_set(unsigned int n, u64 pma) > +{ > + if (n >= TT_MAX_PMAS) > + sbi_panic("PMA exceeded TT_MAX_PMAS"); > + > + pmas[n] = pma; > +} > + > +u64 tt_pma_get(unsigned int n) > +{ > + if (n >= TT_MAX_PMAS) > + sbi_panic("PMA exceeded TT_MAX_PMAS"); > + > + return pmas[n]; > +} > -- > 2.53.0 > > > -- > opensbi mailing list > [email protected] > http://lists.infradead.org/mailman/listinfo/opensbi -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi