public inbox for opensbi@lists.infradead.org
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: opensbi@lists.infradead.org
Cc: Nicholas Piggin <npiggin@gmail.com>
Subject: [PATCH 1/4] platform: generic: Tenstorrent Atlantis support
Date: Tue, 10 Mar 2026 10:49:54 +1000	[thread overview]
Message-ID: <20260310005000.3837512-1-npiggin@gmail.com> (raw)

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 <npiggin@gmail.com>
---
Note the Atlantis hardware is not yet released, and QEMU models are in
the process of being upstreamed, but at the moment not complete. So for
now this can not really be tested with a public implementation, but we
plan to get implementation specific IOMMU MMRs and CPU CSRs into QEMU
that can meaningfully exercise this platform.

There will be some more Atlantis platform pieces to come, but we want to
get started with upstreaming and these are some relatively small and
stable pieces.

The IOMMU support depends on a proposed change to device-tree binding
for the Tenstorrent specific riscv iommu which I posted for RFC here:

https://lore.kernel.org/linux-riscv/20260310003850.3837030-1-npiggin@gmail.com/T/#u

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       |  10 ++
 platform/generic/tenstorrent/pma.c            | 138 ++++++++++++++++++
 11 files changed, 330 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 2627998a..7de5e5a6 100644
--- a/platform/generic/Kconfig
+++ b/platform/generic/Kconfig
@@ -85,6 +85,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
@@ -110,6 +115,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 346058f5..153a3aa0 100644
--- a/platform/generic/configs/defconfig
+++ b/platform/generic/configs/defconfig
@@ -9,6 +9,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..1e4aeb2d
--- /dev/null
+++ b/platform/generic/tenstorrent/objects.mk
@@ -0,0 +1,10 @@
+#
+# SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc.
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+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
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.51.0


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

             reply	other threads:[~2026-03-10  0:50 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-10  0:49 Nicholas Piggin [this message]
2026-03-10  0:49 ` [PATCH 2/4] lib: sbi: Move PMP encoding into a new file Nicholas Piggin
2026-04-01 12:50   ` Joel Stanley
2026-03-10  0:49 ` [PATCH 3/4] lib: sbi: Add hart_ prefix to PMP functions Nicholas Piggin
2026-04-01 12:50   ` Joel Stanley
2026-03-10  0:49 ` [PATCH 4/4] platform: generic: tenstorrent: Add RISC-V IOMMU support Nicholas Piggin
2026-04-01 12:51   ` Joel Stanley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260310005000.3837512-1-npiggin@gmail.com \
    --to=npiggin@gmail.com \
    --cc=opensbi@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox