Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2227654/?format=api
{ "id": 2227654, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2227654/?format=api", "web_url": "http://patchwork.ozlabs.org/project/opensbi/patch/20260424041725.173235-1-npiggin@gmail.com/", "project": { "id": 67, "url": "http://patchwork.ozlabs.org/api/1.1/projects/67/?format=api", "name": "OpenSBI development", "link_name": "opensbi", "list_id": "opensbi.lists.infradead.org", "list_email": "opensbi@lists.infradead.org", "web_url": "https://github.com/riscv/opensbi", "scm_url": "", "webscm_url": "" }, "msgid": "<20260424041725.173235-1-npiggin@gmail.com>", "date": "2026-04-24T04:17:25", "name": "[v2] platform: generic: Tenstorrent Atlantis support", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "32505549c19b7a2fe9f867c31ca8208c8a6eea00", "submitter": { "id": 69518, "url": "http://patchwork.ozlabs.org/api/1.1/people/69518/?format=api", "name": "Nicholas Piggin", "email": "npiggin@gmail.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/opensbi/patch/20260424041725.173235-1-npiggin@gmail.com/mbox/", "series": [ { "id": 501298, "url": "http://patchwork.ozlabs.org/api/1.1/series/501298/?format=api", "web_url": "http://patchwork.ozlabs.org/project/opensbi/list/?series=501298", "date": "2026-04-24T04:17:25", "name": "[v2] platform: generic: Tenstorrent Atlantis support", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/501298/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2227654/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2227654/checks/", "tags": {}, "headers": { "Return-Path": "\n <opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=Z8rpFJPN;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=l785HNbn;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g206z0ds9z1yDD\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 14:17:47 +1000 (AEST)", "from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1wG7yz-0000000Cd4j-26at;\n\tFri, 24 Apr 2026 04:17:37 +0000", "from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1wG7yw-0000000Cd4J-466L\n\tfor opensbi@lists.infradead.org;\n\tFri, 24 Apr 2026 04:17:36 +0000", "by mail-pj1-x102f.google.com with SMTP id\n 98e67ed59e1d1-35da2d35eccso5169698a91.0\n for <opensbi@lists.infradead.org>;\n Thu, 23 Apr 2026 21:17:34 -0700 (PDT)", "from localhost (193-119-51-209.tpgi.com.au. [193.119.51.209])\n by smtp.gmail.com with ESMTPSA id\n 98e67ed59e1d1-361418c3944sm27416917a91.8.2026.04.23.21.17.31\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 23 Apr 2026 21:17:32 -0700 (PDT)" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:Cc\n\t:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:\n\tResent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:\n\tList-Owner; bh=L1PYUOhin7CJWDLjsvJFAizupP5nbkjuliE2+GzWbmE=; b=Z8rpFJPNhG0Za9\n\tvIgyevALzspuYQwYrkJA5ml9fcIRSSzQDMyuEMrB+IXhdeGYzA7uuU/mQC81p/rRLPefVQDZ9Na63\n\tEy5QlYfA8ZaHmnNFNg+7ptliBk/GyhRlo3xUzL76Elz4ESofQzCl5RQqyANSibTnhqfutinvFH9SO\n\tawJwzaEN4Vx4AQg7zIwAO/gpA6Dl4jjZqfYf9Xj9zISz1BXzTtxqWt17JVKsLlHemTwkUkZd0CKfj\n\tG1Ry5nW/rgnO1i6C9CBRFgafrWJ7WcJYKh1MaeK9ADDCKeZc/ZmbxVW6ZGD12GHRFEYoweTX+ywNU\n\tAuDVAWG2/LwtQG2UjI8A==;", "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1777004253; x=1777609053;\n darn=lists.infradead.org;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:from:to:cc:subject:date:message-id:reply-to;\n bh=V3xY9k1WU5UPKc8de7hw1ZmoKbU2NW58RfuCUeqFdZU=;\n b=l785HNbnC3kNp1F0mTgYtTyz6aJN/E5/dlt72IZIDorPRVi3ItrS7ytN6JfX3kPJkm\n VNJfTBmhkctuX4KzJ5jIEKGKQRiukFfsN/4e+fzBvi4QGizlscWseMUQyq/w7JIiam7u\n XlEdaWkxqPR1IQSLZ7lx+Jew6lvn2mvBR5UuZ0BaZvpFmtyqx2vN4IxV3a5iaaF4vxeM\n OaCYH91wFlSF4YQeaHD+KyW/IwMeew9VNb+nFs0n8g+EswADG3IOGADU39dq23TJ1tkG\n X8oTN7ntSeuIkWz9sAYLoJzBqd4mvVipJznGU0WHKUbonnLDndg2wztmVHFMc7pXpw5a\n t2QA==" ], "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777004253; x=1777609053;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=V3xY9k1WU5UPKc8de7hw1ZmoKbU2NW58RfuCUeqFdZU=;\n b=DY6jyRaMZjmGp+u5U3+jgPRANDcvwjgqnR6+qxxkmYQ++rrOO5Z/SvOLdJjPvUfRNe\n 2hSUlsSxqCzIm1irODBaDM0Dx4IN4Pmd358+BfJP8PPdnjeElJMB07vv5PgXoJrWfBFe\n qQ/pYb7DR3FG3DAixGSlOyS1NDophwTGA9EDAuh+aOdIbc70vFeW+dpRP2R4QPrY8TLT\n pEEWDrqZn9ZzjrAut8s0BdZ2tZrO8QjPZ50MJZm1yqj7CSjwP3MjN7KdQPGeoKJcRcXt\n vEUb6uoX5EGHtgKQmW7Mwhjk9Ou9bD0HRW33GZSXfL8Vk65qVGc+UnWhOUci6JP1Yaoa\n phPg==", "X-Gm-Message-State": "AOJu0Yyt3AhGol0p1FvJLMqBSwmSYd5GWWuHrPlK3QqFf1sOXoqpa79W\n\ttfMJZ0FY0rYLMZLGHKmhiyS47Olz043Zc1At2qJIzlwZyuSnQpCvJzosTb9M6A==", "X-Gm-Gg": "AeBDiesQ+2EwO49nB8R6RUMoUX3Gux5mcw6k5d+C7m9/fdoKLZiQMvl2G5x04EXHncL\n\t/ljkxT20pEjK5jbp/etvi/eeb3DgWo+3q0+ipE/Tu+wEvvSD1WTuHA82wF/YI6gqqzAJ+StQBDF\n\tgCeA9VtPdgJI8kWA72RJmNALxmx3ZC9VJuGKfyKxGU2EOHDqrDNbhspwXPqi+jd6DgzG021/nUv\n\tLMeY48EjN/nEDZzq1cwOD2L02IzHBH1ZCJA1AFwXWPrsdUtc0Ac5sBIhkbmG2zC9jt2bsjCEwcr\n\tFtQZAj5d3TXo3O7ri8yS93lNioEwh3+uvdYqtrwyztsuASF+LzPTVJJkBpvY6cmnO4T4MvFbiJn\n\tGRCuBqf0jdz5FdqMej3SEy2DBP5JIYuPBoBlXpFYCBLCzwoEE6IeDUVpUx4nCc3DGQuvB2DB4XW\n\tr41uUCPLKeQVSllw8yLawOgQc4p7o/EGlPh86SzKAbxRZ/KmLXCHJwHbq1Yl++hqicYsQYFw==", "X-Received": "by 2002:a17:90b:3f8f:b0:35c:30a8:341 with SMTP id\n 98e67ed59e1d1-3614046cd3amr31168263a91.13.1777004253247;\n Thu, 23 Apr 2026 21:17:33 -0700 (PDT)", "From": "Nicholas Piggin <npiggin@gmail.com>", "To": "opensbi@lists.infradead.org", "Cc": "Nicholas Piggin <npiggin@gmail.com>", "Subject": "[PATCH v2] platform: generic: Tenstorrent Atlantis support", "Date": "Fri, 24 Apr 2026 14:17:25 +1000", "Message-ID": "<20260424041725.173235-1-npiggin@gmail.com>", "X-Mailer": "git-send-email 2.53.0", "MIME-Version": "1.0", "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ", "X-CRM114-CacheID": "sfid-20260423_211735_045124_CC626C12 ", "X-CRM114-Status": "GOOD ( 24.32 )", "X-Spam-Score": "-2.1 (--)", "X-Spam-Report": "Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam. The original\n message has been attached to this so you can view it or label\n similar future email. If you have any questions, see\n the administrator of that system for details.\n Content preview: Add the Tenstorrent Atlantis as a generic-platform. This\n initial\n support enables the single_fw_region option, and verifies and prints HART\n PMA CSR configuration. Signed-off-by: Nicholas Piggin --- Since v1: - Drop\n the IOMMU since it depends on core PMP changes. I will work on those in\n parallel. \n Content analysis details: (-2.1 points, 5.0 required)\n pts rule name description\n ---- ----------------------\n --------------------------------------------------\n -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no\n trust\n [2607:f8b0:4864:20:0:0:0:102f listed in]\n [list.dnswl.org]\n 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record\n -0.0 SPF_PASS SPF: sender matches SPF record\n 0.1 DKIM_SIGNED Message has a DKIM or DK signature,\n not necessarily valid\n -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from\n author's\n domain\n -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from\n envelope-from domain\n -0.1 DKIM_VALID Message has at least one valid DKIM or DK\n signature\n -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%\n [score: 0.0000]\n 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail\n provider\n [npiggin(at)gmail.com]", "X-BeenThere": "opensbi@lists.infradead.org", "X-Mailman-Version": "2.1.34", "Precedence": "list", "List-Id": "<opensbi.lists.infradead.org>", "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=unsubscribe>", "List-Archive": "<http://lists.infradead.org/pipermail/opensbi/>", "List-Post": "<mailto:opensbi@lists.infradead.org>", "List-Help": "<mailto:opensbi-request@lists.infradead.org?subject=help>", "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Sender": "\"opensbi\" <opensbi-bounces@lists.infradead.org>", "Errors-To": "opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org" }, "content": "Add the Tenstorrent Atlantis as a generic-platform. This initial support\nenables the single_fw_region option, and verifies and prints HART PMA\nCSR configuration.\n\nSigned-off-by: Nicholas Piggin <npiggin@gmail.com>\n---\nSince v1:\n- Drop the IOMMU since it depends on core PMP changes. I will work\n on those in parallel.\n\nNote the Atlantis hardware is not yet released, and QEMU models are in\nthe process of being upstreamed, but at the moment not complete. We\nwill continue to expand support and improve documentation for QEMU/HW\nas we get more pieces in place.\n\nThanks,\nNick\n---\n docs/platform/generic.md | 2 +\n docs/platform/tt-atlantis.md | 35 +++++\n platform/generic/Kconfig | 6 +\n platform/generic/configs/defconfig | 1 +\n .../generic/include/tenstorrent/ascalon.h | 12 ++\n platform/generic/include/tenstorrent/pma.h | 18 +++\n platform/generic/tenstorrent/Kconfig | 5 +\n platform/generic/tenstorrent/ascalon.c | 53 +++++++\n platform/generic/tenstorrent/atlantis.c | 50 +++++++\n platform/generic/tenstorrent/objects.mk | 10 ++\n platform/generic/tenstorrent/pma.c | 138 ++++++++++++++++++\n 11 files changed, 330 insertions(+)\n create mode 100644 docs/platform/tt-atlantis.md\n create mode 100644 platform/generic/include/tenstorrent/ascalon.h\n create mode 100644 platform/generic/include/tenstorrent/pma.h\n create mode 100644 platform/generic/tenstorrent/Kconfig\n create mode 100644 platform/generic/tenstorrent/ascalon.c\n create mode 100644 platform/generic/tenstorrent/atlantis.c\n create mode 100644 platform/generic/tenstorrent/objects.mk\n create mode 100644 platform/generic/tenstorrent/pma.c", "diff": "diff --git a/docs/platform/generic.md b/docs/platform/generic.md\nindex c48d6a9a..0b896ede 100644\n--- a/docs/platform/generic.md\n+++ b/docs/platform/generic.md\n@@ -47,6 +47,7 @@ RISC-V Platforms Using Generic Platform\n * **SiFive HiFive Unleashed** (*[sifive_fu540.md]*)\n * **Spike** (*[spike.md]*)\n * **T-HEAD C9xx series Processors** (*[thead-c9xx.md]*)\n+* **Tenstorrent Atlantis Platform** (*[tt-atlantis.md]*)\n * **OpenPiton FPGA SoC** (*[fpga-openpiton.md]*)\n * **Ariane FPGA SoC** (*[fpga-ariane.md]*)\n \n@@ -57,5 +58,6 @@ RISC-V Platforms Using Generic Platform\n [sifive_fu540.md]: sifive_fu540.md\n [spike.md]: spike.md\n [thead-c9xx.md]: thead-c9xx.md\n+[tt-atlantis.md]: tt-atlantis.md\n [fpga-openpiton.md]: fpga-openpiton.md\n [fpga-ariane.md]: fpga-ariane.md\ndiff --git a/docs/platform/tt-atlantis.md b/docs/platform/tt-atlantis.md\nnew file mode 100644\nindex 00000000..b9bdd238\n--- /dev/null\n+++ b/docs/platform/tt-atlantis.md\n@@ -0,0 +1,35 @@\n+Tenstorrent Atlantis Platform\n+=============================\n+\n+The Tenstorrent Atlantis is an SoC and development board from\n+Tenstorrent in partnership with CoreLab Technology. It contains 8 RISC-V\n+RVA23 compliant Tenstorrent Ascalon cores with RISC-V AIA, RISC-V IOMMU,\n+and a range of devices and IO connectivity.\n+\n+To build the platform-specific library and firmware images, provide the\n+*PLATFORM=generic* parameter to the top level `make` command.\n+\n+Platform Options\n+----------------\n+\n+The *Tenstorrent Atlantis* platform does not have any platform-specific\n+options.\n+\n+Building Tenstorrent Atlantis Platform\n+--------------------------------------\n+\n+The Atlantis Platform is still under development. This section will be\n+expanded as firmware and support become available.\n+\n+QEMU support is currently being developed and initial support has been\n+proposed for upstream. To run QEMU that is patched with 'tt-atlantis'\n+machine support, run:\n+\n+```\n+qemu-system-riscv64 -M tt-atlantis -nographic \\\n+\t-bios build/platform/generic/firmware/fw_payload.bin \\\n+ -kernel <linux_build_dir>/Image\n+```\n+\n+Recent (6.18) Linux/riscv 64-bit defconfig kernels should run the QEMU\n+tt-atlantis machine.\ndiff --git a/platform/generic/Kconfig b/platform/generic/Kconfig\nindex 600273d1..d594b140 100644\n--- a/platform/generic/Kconfig\n+++ b/platform/generic/Kconfig\n@@ -89,6 +89,11 @@ config PLATFORM_STARFIVE_JH7110\n \tbool \"StarFive JH7110 support\"\n \tdefault n\n \n+config PLATFORM_TENSTORRENT_ATLANTIS\n+\tbool \"Tenstorrent Atlantis support\"\n+\tselect CPU_TENSTORRENT_ASCALON\n+\tdefault n\n+\n config PLATFORM_THEAD\n \tbool \"THEAD C9xx support\"\n \tselect THEAD_C9XX_ERRATA\n@@ -114,6 +119,7 @@ config PLATFORM_MIPS_P8700_BOSTON\n \n source \"$(OPENSBI_SRC_DIR)/platform/generic/andes/Kconfig\"\n source \"$(OPENSBI_SRC_DIR)/platform/generic/eswin/Kconfig\"\n+source \"$(OPENSBI_SRC_DIR)/platform/generic/tenstorrent/Kconfig\"\n source \"$(OPENSBI_SRC_DIR)/platform/generic/thead/Kconfig\"\n \n endif\ndiff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig\nindex 1d3431e7..800f3f14 100644\n--- a/platform/generic/configs/defconfig\n+++ b/platform/generic/configs/defconfig\n@@ -10,6 +10,7 @@ CONFIG_PLATFORM_SIFIVE_FU540=y\n CONFIG_PLATFORM_SIFIVE_FU740=y\n CONFIG_PLATFORM_SOPHGO_SG2042=y\n CONFIG_PLATFORM_STARFIVE_JH7110=y\n+CONFIG_PLATFORM_TENSTORRENT_ATLANTIS=y\n CONFIG_PLATFORM_THEAD=y\n CONFIG_PLATFORM_MIPS_P8700_EYEQ7H=y\n CONFIG_PLATFORM_MIPS_P8700_BOSTON=y\ndiff --git a/platform/generic/include/tenstorrent/ascalon.h b/platform/generic/include/tenstorrent/ascalon.h\nnew file mode 100644\nindex 00000000..5d7b7635\n--- /dev/null\n+++ b/platform/generic/include/tenstorrent/ascalon.h\n@@ -0,0 +1,12 @@\n+/*\n+ * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc.\n+ * SPDX-License-Identifier: BSD-2-Clause\n+ */\n+\n+#ifndef __TENSTORRENT_ASCALON_H__\n+#define __TENSTORRENT_ASCALON_H__\n+\n+void tt_ascalon_discover_pmas_from_boot_hart(void);\n+void tt_ascalon_verify_pmas_nonboot_hart(void);\n+\n+#endif\ndiff --git a/platform/generic/include/tenstorrent/pma.h b/platform/generic/include/tenstorrent/pma.h\nnew file mode 100644\nindex 00000000..051764ee\n--- /dev/null\n+++ b/platform/generic/include/tenstorrent/pma.h\n@@ -0,0 +1,18 @@\n+/*\n+ * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc.\n+ * SPDX-License-Identifier: BSD-2-Clause\n+ */\n+\n+#ifndef __TENSTORRENT_PMA_H__\n+#define __TENSTORRENT_PMA_H__\n+\n+/* Max number of PMAs for devices (CPU, IOMMU) for Tenstorrent platforms. */\n+#define TT_MAX_PMAS\t32\n+\n+u64 tt_pma_get(unsigned int n);\n+void tt_pma_set(unsigned int n, u64 pma);\n+bool tt_pma_validate(unsigned int i, u64 pma);\n+void tt_pma_print(unsigned int i, u64 pma);\n+\n+#endif\n+\ndiff --git a/platform/generic/tenstorrent/Kconfig b/platform/generic/tenstorrent/Kconfig\nnew file mode 100644\nindex 00000000..76c7fb32\n--- /dev/null\n+++ b/platform/generic/tenstorrent/Kconfig\n@@ -0,0 +1,5 @@\n+# SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc.\n+# SPDX-License-Identifier: BSD-2-Clause\n+\n+config CPU_TENSTORRENT_ASCALON\n+\tbool\ndiff --git a/platform/generic/tenstorrent/ascalon.c b/platform/generic/tenstorrent/ascalon.c\nnew file mode 100644\nindex 00000000..485144cd\n--- /dev/null\n+++ b/platform/generic/tenstorrent/ascalon.c\n@@ -0,0 +1,53 @@\n+/*\n+ * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc.\n+ * SPDX-License-Identifier: BSD-2-Clause\n+ */\n+\n+#include <sbi/riscv_asm.h>\n+#include <sbi/sbi_console.h>\n+#include <sbi/sbi_csr_detect.h>\n+\n+#include <tenstorrent/ascalon.h>\n+#include <tenstorrent/pma.h>\n+\n+#define CSR_PMACFG0\t0x7e0\n+\n+void tt_ascalon_discover_pmas_from_boot_hart(void)\n+{\n+\tstruct sbi_trap_info trap = {0};\n+\n+\t/* Whisper virtual platform does not implement PMA */\n+\tcsr_read_allowed(CSR_PMACFG0, &trap);\n+\tif (trap.cause)\n+\t\treturn;\n+\n+\tfor (unsigned int i = 0; i < TT_MAX_PMAS; i++) {\n+\t\tu64 pma = csr_read_num(CSR_PMACFG0 + i);\n+\t\tif (!tt_pma_validate(i, pma)) {\n+\t\t\tsbi_printf(\"HART%d: Bad boot PMA%02d 0x%016lx\\n\",\n+\t\t\t\t current_hartid(), i, pma);\n+\t\t}\n+\t\ttt_pma_set(i, pma);\n+\n+\t\tif (pma)\n+\t\t\ttt_pma_print(i, pma);\n+\t}\n+}\n+\n+void tt_ascalon_verify_pmas_nonboot_hart(void)\n+{\n+\tstruct sbi_trap_info trap = {0};\n+\n+\t/* Whisper virtual platform does not implement PMA */\n+\tcsr_read_allowed(CSR_PMACFG0, &trap);\n+\tif (trap.cause)\n+\t\treturn;\n+\n+\tfor (unsigned int i = 0; i < TT_MAX_PMAS; i++) {\n+\t\tu64 pma = csr_read_num(CSR_PMACFG0 + i);\n+\t\tif (pma != tt_pma_get(i)) {\n+\t\t\tsbi_printf(\"HART%d: Bad boot PMA%02d 0x%016lx does not match boot HART\\n\",\n+\t\t\t\t current_hartid(), i, pma);\n+\t\t}\n+\t}\n+}\ndiff --git a/platform/generic/tenstorrent/atlantis.c b/platform/generic/tenstorrent/atlantis.c\nnew file mode 100644\nindex 00000000..4c312f7e\n--- /dev/null\n+++ b/platform/generic/tenstorrent/atlantis.c\n@@ -0,0 +1,50 @@\n+/*\n+ * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc.\n+ * SPDX-License-Identifier: BSD-2-Clause\n+ */\n+\n+#include <platform_override.h>\n+#include <libfdt.h>\n+#include <sbi/sbi_error.h>\n+#include <sbi/sbi_hart.h>\n+#include <sbi/sbi_system.h>\n+#include <sbi/sbi_console.h>\n+\n+#include <tenstorrent/ascalon.h>\n+#include <tenstorrent/pma.h>\n+\n+static int tt_atlantis_final_init(bool cold_boot)\n+{\n+\tif (cold_boot) {\n+\t\t/* Boot firmware sets HART PMAs. Read and verify them. */\n+\t\ttt_ascalon_discover_pmas_from_boot_hart();\n+\t} else {\n+\t\t/* Verify nonboot HARTs have PMAs matching boot HART */\n+\t\ttt_ascalon_verify_pmas_nonboot_hart();\n+\t}\n+\n+\treturn generic_final_init(cold_boot);\n+}\n+\n+static bool tt_atlantis_single_fw_region(void)\n+{\n+\treturn true;\n+}\n+\n+static int tt_atlantis_platform_init(const void *fdt, int nodeoff, const struct fdt_match *match)\n+{\n+\tgeneric_platform_ops.final_init = tt_atlantis_final_init;\n+\tgeneric_platform_ops.single_fw_region = tt_atlantis_single_fw_region;\n+\n+\treturn 0;\n+}\n+\n+static const struct fdt_match tt_atlantis_match[] = {\n+\t{ .compatible = \"tenstorrent,atlantis\" },\n+\t{ },\n+};\n+\n+const struct fdt_driver tenstorrent_atlantis = {\n+\t.match_table = tt_atlantis_match,\n+\t.init = tt_atlantis_platform_init,\n+};\ndiff --git a/platform/generic/tenstorrent/objects.mk b/platform/generic/tenstorrent/objects.mk\nnew file mode 100644\nindex 00000000..1e4aeb2d\n--- /dev/null\n+++ b/platform/generic/tenstorrent/objects.mk\n@@ -0,0 +1,10 @@\n+#\n+# SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc.\n+# SPDX-License-Identifier: BSD-2-Clause\n+#\n+\n+platform-objs-y += tenstorrent/pma.o\n+platform-objs-$(CONFIG_CPU_TENSTORRENT_ASCALON) += tenstorrent/ascalon.o\n+\n+carray-platform_override_modules-$(CONFIG_PLATFORM_TENSTORRENT_ATLANTIS) += tenstorrent_atlantis\n+platform-objs-$(CONFIG_PLATFORM_TENSTORRENT_ATLANTIS) += tenstorrent/atlantis.o\ndiff --git a/platform/generic/tenstorrent/pma.c b/platform/generic/tenstorrent/pma.c\nnew file mode 100644\nindex 00000000..daf60192\n--- /dev/null\n+++ b/platform/generic/tenstorrent/pma.c\n@@ -0,0 +1,138 @@\n+/*\n+ * SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc.\n+ * SPDX-License-Identifier: BSD-2-Clause\n+ */\n+\n+#include <sbi/sbi_error.h>\n+#include <sbi/sbi_console.h>\n+#include <sbi/sbi_math.h>\n+#include <libfdt.h>\n+#include <sbi_utils/fdt/fdt_helper.h>\n+\n+#include <tenstorrent/pma.h>\n+\n+/*\n+ * All PMAs in the system should be the same (after boot). The init code\n+ * must have set PMAs for all HARTs.\n+ */\n+\n+/*\n+ * Ascalon CPU and IOMMU PMA layout:\n+ * Field\n+ * [2:0]\tPermission\t[0] Read, [1] Write, [2] Execute\n+ * [4:3]\tMemory type\t00: Main memory, 01: IO memory relaxed,\n+ * \t\t\t\t10: IO memory channel 0, 11: IO memory channel 1\n+ * [6:5]\tAMO type\t00: AMONone, 01: AMOSwap,\n+ * \t\t\t\t10: AMOLogical, 11: AMOArithmetic\n+ * [7]\t\tCacheability (main memory type)\n+ * \t\t\t\t1: Cacheable, 0: Non-cacheable\n+ * \t\tCombining Capability (IO memory type)\n+ * \t\t\t\t1: Combining allowed, 0: Combining disallowed\n+ * [8]\t\tRouting (coherency)\n+ * \t\t\t\t1: Coherent network, 0: Non-coherent network\n+ * [11:9]\tReserved\n+ * [51:12]\tPhysical address [51:12] base\n+ * [63:58]\tSize log 2 (number of address LSB to ignore when matching)\n+ * \t\t0 = invalid entry (no match)\n+ */\n+\n+#define PMA_PERMISSION_R\t0x1\n+#define PMA_PERMISSION_W\t0x2\n+#define PMA_PERMISSION_X\t0x4\n+#define PMA_PERMISSION_MASK\t0x7\n+\n+#define PMA_TYPE_MAIN_MEMORY\t0x0\n+#define PMA_TYPE_IO_RELAXED\t0x8\n+#define PMA_TYPE_IO_ORDERED_0\t0x10\n+#define PMA_TYPE_IO_ORDERED_1\t0x18\n+#define PMA_TYPE_MASK\t\t0x18\n+\n+#define PMA_AMO_NONE\t\t0x0\n+#define PMA_AMO_SWAP\t\t0x20\n+#define PMA_AMO_LOGICAL\t\t0x40\n+#define PMA_AMO_ARITHMETIC\t0x60\n+#define PMA_AMO_MASK\t\t0x60\n+\n+#define PMA_MEMORY_CACHEABLE\t0x80\n+#define PMA_IO_COMBINING\t0x80\n+#define PMA_ROUTING_COHERENT\t0x100\n+\n+#define PMA_FLAGS_MASK\t\t0x00000000000001ffULL\n+#define PMA_ADDRESS_MASK\t0x000ffffffffff000ULL\n+#define PMA_SIZE_MASK\t\t0xfc00000000000000ULL\n+#define PMA_RESERVED_MASK\t0x0300000000000e00ULL\n+\n+#define PMA_SIZE_SHIFT\t\t58\n+\n+static u64 tt_pma_size(u64 pma)\n+{\n+\tif ((pma & PMA_SIZE_MASK) == 0)\n+\t\treturn 0;\n+\n+\treturn 1ULL << ((pma & PMA_SIZE_MASK) >> PMA_SIZE_SHIFT);\n+}\n+\n+static u64 tt_pma_address(u64 pma)\n+{\n+\treturn (pma & PMA_ADDRESS_MASK) & ~((tt_pma_size(pma) - 1));\n+}\n+\n+bool tt_pma_validate(unsigned int i, u64 pma)\n+{\n+\tif (!pma)\n+\t\treturn true;\n+\n+\tif (pma & PMA_RESERVED_MASK) {\n+\t\tsbi_printf(\"PMA%02u 0x%016lx contains reserved bits\\n\", i, pma);\n+\t\treturn false;\n+\t}\n+\n+\tif (tt_pma_size(pma) < 4096) {\n+\t\tsbi_printf(\"PMA%02u 0x%016lx size < 4KB\\n\", i, pma);\n+\t\treturn false;\n+\t}\n+\n+\tif (tt_pma_address(pma) != (pma & PMA_ADDRESS_MASK)) {\n+\t\tsbi_printf(\"PMA%02u 0x%016lx address is not aligned to size\\n\", i, pma);\n+\t\treturn false;\n+\t}\n+\n+\treturn true;\n+}\n+\n+void tt_pma_print(unsigned int i, u64 pma)\n+{\n+\tsbi_printf(\"PMA%02d : 0x%016lx-0x%016lx perm:%s%s%s type:%s %s %s amo:%s\\n\", i,\n+\t\t\ttt_pma_address(pma), tt_pma_address(pma) + tt_pma_size(pma) - 1,\n+\t\t\tpma & PMA_PERMISSION_R ? \"R\" : \" \",\n+\t\t\tpma & PMA_PERMISSION_W ? \"W\" : \" \",\n+\t\t\tpma & PMA_PERMISSION_X ? \"X\" : \" \",\n+\t\t\t(pma & PMA_TYPE_MASK) == PMA_TYPE_MAIN_MEMORY ? \"main-memory\" :\n+\t\t\t ((pma & PMA_TYPE_MASK) == PMA_TYPE_IO_RELAXED ? \"io-relaxed\" :\n+\t\t\t ((pma & PMA_TYPE_MASK) == PMA_TYPE_IO_ORDERED_0 ? \"io-ordered-0\" : \"io-ordered-1\")),\n+\t\t\t(pma & PMA_TYPE_MASK) == PMA_TYPE_MAIN_MEMORY ?\n+\t\t\t (pma & PMA_MEMORY_CACHEABLE ? \"cacheable\" : \"non-cacheable\") :\n+\t\t\t (pma & PMA_IO_COMBINING ? \"combining\" : \"non-combining\"),\n+\t\t\tpma & PMA_ROUTING_COHERENT ? \"coherent\" : \"non-coherent\",\n+\t\t\t(pma & PMA_AMO_MASK) == PMA_AMO_NONE ? \"none\" :\n+\t\t\t ((pma & PMA_AMO_MASK) == PMA_AMO_SWAP ? \"swap\" :\n+\t\t\t ((pma & PMA_AMO_MASK) == PMA_AMO_LOGICAL ? \"logical\" : \"arithmetic\")));\n+}\n+\n+static u64 pmas[TT_MAX_PMAS];\n+\n+void tt_pma_set(unsigned int n, u64 pma)\n+{\n+\tif (n >= TT_MAX_PMAS)\n+\t\tsbi_panic(\"PMA exceeded TT_MAX_PMAS\");\n+\n+\tpmas[n] = pma;\n+}\n+\n+u64 tt_pma_get(unsigned int n)\n+{\n+\tif (n >= TT_MAX_PMAS)\n+\t\tsbi_panic(\"PMA exceeded TT_MAX_PMAS\");\n+\n+\treturn pmas[n];\n+}\n", "prefixes": [ "v2" ] }