[{"id":3679676,"web_url":"http://patchwork.ozlabs.org/comment/3679676/","msgid":"<23a86057-03d9-427b-af7f-d59dc730a3e3@linaro.org>","list_archive_url":null,"date":"2026-04-21T05:52:59","subject":"Re: [PATCH v3 09/13] hw/riscv: Add Tenstorrent Atlantis machine","submitter":{"id":85046,"url":"http://patchwork.ozlabs.org/api/people/85046/","name":"Philippe Mathieu-Daudé","email":"philmd@linaro.org"},"content":"On 21/4/26 07:31, Joel Stanley wrote:\n> The Tenstorrent Atlantis platform is a collaboration between Tenstorrent\n> and CoreLab Technology. It is based on the Atlantis SoC, which includes\n> the Ascalon-X CPU and other IP from Tenstorrent and CoreLab Technology.\n> \n> The Tenstorrent Ascalon-X is a high performance 64-bit RVA23 compliant\n> RISC-V CPU.\n> \n> This adds the machine containing serial console, interrupt controllers\n> and device tree support.\n> \n>    qemu-system-riscv64 -M tt-atlantis -m 512M \\\n>     -kernel Image -initrd rootfs.cpio -nographic\n> \n> If there is no kernel provided the simple payload is loaded to avoid\n> OpenSBI hanging with no messages.\n> \n> Signed-off-by: Joel Stanley <joel@jms.id.au>\n> Co-Developed-by: Nicholas Piggin <npiggin@gmail.com>\n> ---\n> v3:\n>    - Merge simple payload change into this patch\n>    - Fix fw_cfg_init_mem_dma API change\n>    - Clean up irqchip #defines\n>    - Add Michael and Nick as reviewers\n>    - create_fdt_pmu was copying RISCVCPU by value\n>    - Remove unused platform_bus\n> ---\n>   MAINTAINERS                       |  11 +\n>   docs/system/riscv/tt_atlantis.rst |  38 ++\n>   docs/system/target-riscv.rst      |   1 +\n>   include/hw/riscv/tt_atlantis.h    |  77 ++++\n>   hw/riscv/tt_atlantis.c            | 638 ++++++++++++++++++++++++++++++\n>   hw/riscv/Kconfig                  |  15 +\n>   hw/riscv/meson.build              |   1 +\n>   7 files changed, 781 insertions(+)\n>   create mode 100644 docs/system/riscv/tt_atlantis.rst\n>   create mode 100644 include/hw/riscv/tt_atlantis.h\n>   create mode 100644 hw/riscv/tt_atlantis.c\n\nReviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>","headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.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 unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256\n header.s=google header.b=ypuX3bzn;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0BNl6KJJz1yGt\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 15:53:27 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wF42q-0002ey-KW; Tue, 21 Apr 2026 01:53:12 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <philmd@linaro.org>) id 1wF42j-0002eD-Jf\n for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:53:06 -0400","from mail-wr1-x436.google.com ([2a00:1450:4864:20::436])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <philmd@linaro.org>) id 1wF42h-0002ZB-2l\n for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:53:05 -0400","by mail-wr1-x436.google.com with SMTP id\n ffacd0b85a97d-43fe608cb92so2535517f8f.2\n for <qemu-devel@nongnu.org>; Mon, 20 Apr 2026 22:53:02 -0700 (PDT)","from [192.168.69.228] (88-187-86-199.subs.proxad.net.\n [88.187.86.199]) by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-43fe4cc2cacsm34704413f8f.13.2026.04.20.22.52.59\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Mon, 20 Apr 2026 22:53:00 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=linaro.org; s=google; t=1776750781; x=1777355581; darn=nongnu.org;\n h=content-transfer-encoding:in-reply-to:from:references:cc:to\n :content-language:subject:user-agent:mime-version:date:message-id\n :from:to:cc:subject:date:message-id:reply-to;\n bh=hYyaQPMXQZpIgqQHWX5QcNv1/agzaF1UDpVMXODrRIU=;\n b=ypuX3bzn7IBN0o9kWlrB9OT2J6Uu4UgxWG/ov9pp/u9hRsSkBGYVo8CXi2l86RQdBD\n uCiK451SNHbxNJQ8R8AjkgoHQPLVvFHgacJwwcpkUjQRHcbcJ8fqPRVK32SbNt2dqAhJ\n 8V5U6OFMiERnwjRRC9Cabk2f5wXqdU4Wr+/tsINXxJlygJyArAcbkD4Stc/Wli5VzTAf\n Hyvo4Y2H3swKG0aGAn+ycEQYkUzoHCu/I/BQzlkiaPCqXIUOdaKVmYUN5rX4JfRd0iGK\n pxMKWMlKbpS6umceAxCx2r57nJ0NxtrPq9ntelxAWWDupIevxtq6tZFj3W9njPuQA1g9\n qnrw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776750781; x=1777355581;\n h=content-transfer-encoding:in-reply-to:from:references:cc:to\n :content-language:subject:user-agent:mime-version:date:message-id\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=hYyaQPMXQZpIgqQHWX5QcNv1/agzaF1UDpVMXODrRIU=;\n b=k0INflEChPuQSm5BWZ+PXQJCUnUTIdMjJZ9AXsgAna8MqGlMtm1y11hQ6Vu3kzMfgX\n k5qVcFBR/5KvKY5+FeBh9KHRUVdZw5RMjydJTfalIv6C/J3qLlhHTYeQYwwAAe1NjoM3\n q2AQnqc6MsgsFYAj99Jw5dKloWrktv3FwDXOBpjZ0kuulyDXzuoECrt85krUt47J6lwo\n PHsjp4yR7fl0zurRxt6a3twxb/5rt+XAVqjJqz4C8TGMT4As8x0qpr8rRHPf6+99LHCP\n K2g3S1aK6Qn6D79AnChdGYLLqkyAS5DftQiFIAdJCPGVNLPt57QlxLPGAMXbEhXcb2EC\n XLCA==","X-Forwarded-Encrypted":"i=1;\n AFNElJ+GvFPAMVYF/WJSPLaQ60TuF8CsSnDw1rQLjKM8S8oBUr9C4rMDIfI98sZpZ+v99o+LQMqWz4EHojmh@nongnu.org","X-Gm-Message-State":"AOJu0YyQP/LNks4YJDCMfLMt+nEmLyY16g4p/x21hZo+bWUJOxm+ngoM\n TvYkrwl34c6nJksrpe8XIn/cdelJY13upNkeopQh3rMLWrp0FRc8YBx0G19mfuBXc9A=","X-Gm-Gg":"AeBDiettxIs6eY3zVyNw9x6yRpYzYp2UelOE21kPs1P0f3UGw4+10oavNDHepgNE0So\n mdkpNcr3GaWKJ76lXMNsgfz6h01dWiHzHTDnysN7l6Al995xlH5eCLstCjh1hbGQ0RzxFWtpna/\n I9XDMu9e/37OHx8fujb4gOiJehq+Pa5jsEkb3qspCecCnsEyfvlYVsCdpKm/8zDdoVnd34ae0db\n INTsigONg/KBkbXey7EYWpd1DWVZwkrravhOiMFzJhRMXMc5MNP+dqgsw0YoR0xIghcVw7+aFew\n rfjPC/Q9/z4PmKY4aRDq4KgWY3J1X6x2NRjlKZRdO0cTaPlS70c37k1cdBgUdAq1Jh18L8f37ke\n YjrlEe/ndxQXC1zEyJglMyPYUeMM+LcCOr2SCjfeEO2IgrLfzX+X7sfhP0hAdSajmthtkMmxlKY\n en5PbonIBQ3kfvyFO+kF1qtljyi7aWhkcIShQFGItV/sGAwQNymR1Ro1IyHjIHijiy1mqRS6tLn\n IPL","X-Received":"by 2002:a05:6000:18a8:b0:43f:dd91:b022 with SMTP id\n ffacd0b85a97d-43fe3e0a2a9mr25001592f8f.35.1776750780955;\n Mon, 20 Apr 2026 22:53:00 -0700 (PDT)","Message-ID":"<23a86057-03d9-427b-af7f-d59dc730a3e3@linaro.org>","Date":"Tue, 21 Apr 2026 07:52:59 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3 09/13] hw/riscv: Add Tenstorrent Atlantis machine","Content-Language":"en-US","To":"Joel Stanley <joel@jms.id.au>,\n Alistair Francis <alistair.francis@wdc.com>,\n Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>","Cc":"Michael Ellerman <mpe@kernel.org>, Nicholas Piggin <npiggin@gmail.com>,\n Joel Stanley <jms@oss.tenstorrent.com>,\n Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>, qemu-riscv@nongnu.org,\n qemu-devel@nongnu.org","References":"<20260421053140.752059-1-joel@jms.id.au>\n <20260421053140.752059-10-joel@jms.id.au>","From":"=?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= <philmd@linaro.org>","In-Reply-To":"<20260421053140.752059-10-joel@jms.id.au>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","Received-SPF":"pass client-ip=2a00:1450:4864:20::436;\n envelope-from=philmd@linaro.org; helo=mail-wr1-x436.google.com","X-Spam_score_int":"-20","X-Spam_score":"-2.1","X-Spam_bar":"--","X-Spam_report":"(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"qemu development <qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"}},{"id":3680367,"web_url":"http://patchwork.ozlabs.org/comment/3680367/","msgid":"<aeiQ6bV4nEEhmGUP@ZEVORN-PC.localdomain>","list_archive_url":null,"date":"2026-04-22T09:12:29","subject":"Re: [PATCH v3 09/13] hw/riscv: Add Tenstorrent Atlantis machine","submitter":{"id":92265,"url":"http://patchwork.ozlabs.org/api/people/92265/","name":"Chao Liu","email":"chao.liu.zevorn@gmail.com"},"content":"On Tue, Apr 21, 2026 at 03:31:34PM +1000, Joel Stanley wrote:\n> The Tenstorrent Atlantis platform is a collaboration between Tenstorrent\n> and CoreLab Technology. It is based on the Atlantis SoC, which includes\n> the Ascalon-X CPU and other IP from Tenstorrent and CoreLab Technology.\n> \n> The Tenstorrent Ascalon-X is a high performance 64-bit RVA23 compliant\n> RISC-V CPU.\n> \n> This adds the machine containing serial console, interrupt controllers\n> and device tree support.\n> \n>   qemu-system-riscv64 -M tt-atlantis -m 512M \\\n>    -kernel Image -initrd rootfs.cpio -nographic\n> \n> If there is no kernel provided the simple payload is loaded to avoid\n> OpenSBI hanging with no messages.\n> \n> Signed-off-by: Joel Stanley <joel@jms.id.au>\n> Co-Developed-by: Nicholas Piggin <npiggin@gmail.com>\n> ---\n> v3:\n>   - Merge simple payload change into this patch\n>   - Fix fw_cfg_init_mem_dma API change\n>   - Clean up irqchip #defines\n>   - Add Michael and Nick as reviewers\n>   - create_fdt_pmu was copying RISCVCPU by value\n>   - Remove unused platform_bus\nReviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>\n\nThanks,\nChao\n> ---\n>  MAINTAINERS                       |  11 +\n>  docs/system/riscv/tt_atlantis.rst |  38 ++\n>  docs/system/target-riscv.rst      |   1 +\n>  include/hw/riscv/tt_atlantis.h    |  77 ++++\n>  hw/riscv/tt_atlantis.c            | 638 ++++++++++++++++++++++++++++++\n>  hw/riscv/Kconfig                  |  15 +\n>  hw/riscv/meson.build              |   1 +\n>  7 files changed, 781 insertions(+)\n>  create mode 100644 docs/system/riscv/tt_atlantis.rst\n>  create mode 100644 include/hw/riscv/tt_atlantis.h\n>  create mode 100644 hw/riscv/tt_atlantis.c\n> \n> diff --git a/MAINTAINERS b/MAINTAINERS\n> index e1942a86eba5..635a380945fd 100644\n> --- a/MAINTAINERS\n> +++ b/MAINTAINERS\n> @@ -1760,6 +1760,17 @@ F: hw/*/*sifive*.c\n>  F: include/hw/*/*sifive*.h\n>  F: tests/functional/test_riscv64_sifive_u.py\n>  \n> +Tenstorrent Machines\n> +M: Joel Stanley <joel@jms.id.au>\n> +R: Nicholas Piggin <npiggin@gmail.com>\n> +R: Michael Ellerman <mpe@kernel.org>\n> +L: qemu-riscv@nongnu.org\n> +S: Supported\n> +F: docs/system/riscv/tt_*.rst\n> +F: hw/riscv/tt_*.c\n> +F: hw/riscv/aia.[ch]\n> +F: include/hw/riscv/tt_*.h\n> +\n>  AMD Microblaze-V Generic Board\n>  M: Sai Pavan Boddu <sai.pavan.boddu@amd.com>\n>  S: Maintained\n> diff --git a/docs/system/riscv/tt_atlantis.rst b/docs/system/riscv/tt_atlantis.rst\n> new file mode 100644\n> index 000000000000..640cabf7b046\n> --- /dev/null\n> +++ b/docs/system/riscv/tt_atlantis.rst\n> @@ -0,0 +1,38 @@\n> +Tenstorrent Atlantis (``tt-atlantis``)\n> +======================================\n> +\n> +The Tenstorrent Atlantis platform is a collaboration between Tenstorrent\n> +and CoreLab Technology. It is based on the Atlantis SoC, which includes\n> +the Ascalon-X CPU and other IP from Tenstorrent and CoreLab Technology.\n> +\n> +The Tenstorrent Ascalon-X is a high performance 64-bit RVA23 compliant\n> +RISC-V CPU.\n> +\n> +Features\n> +--------\n> +\n> +* 8-core Ascalon-X CPU Cluster\n> +* Dual x32 LPDDR5 @ 6400 MT/s\n> +* RISC-V compliant Advanced Interrupt Architecture\n> +* PCIe Gen4\n> +* RISC-V compliant IOMMU\n> +* GPU and Video subsystem\n> +* 2x USB3.1 & 2x USB2.0\n> +* 2x 1GbE Ethernet\n> +* 2x eMMC5.1/SDIO3.0 storage\n> +* Extensive connectivity (SPI, I2C, UART, GPIO, CANFD)\n> +\n> +Note: the QEMU tt-atlantis machine does not model the platform\n> +exactly or all devices, but it is undergoing improvement.\n> +\n> +Supported software\n> +------------------\n> +\n> +The Tenstorrent Ascalon CPUs avoid proprietary or non-standard\n> +extensions, so compatibility with existing software is generally\n> +good. The QEMU tt-atlantis machine works with upstream OpenSBI\n> +and Linux with default configurations.\n> +\n> +The development board hardware will require some implementation\n> +specific setup in firmware which is being developed and may\n> +become a requirement or option for the tt-atlantis machine.\n> diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst\n> index 3ad5d1ddafbb..a8e6b3342186 100644\n> --- a/docs/system/target-riscv.rst\n> +++ b/docs/system/target-riscv.rst\n> @@ -71,6 +71,7 @@ undocumented; you can get a complete list by running\n>     riscv/mips\n>     riscv/shakti-c\n>     riscv/sifive_u\n> +   riscv/tt_atlantis\n>     riscv/virt\n>     riscv/xiangshan-kunminghu\n>  \n> diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h\n> new file mode 100644\n> index 000000000000..f7f79e9f2c53\n> --- /dev/null\n> +++ b/include/hw/riscv/tt_atlantis.h\n> @@ -0,0 +1,77 @@\n> +/*\n> + * Tenstorrent Atlantis RISC-V System on Chip\n> + *\n> + * SPDX-License-Identifier: GPL-2.0-or-later\n> + *\n> + * Copyright 2025 Tenstorrent, Joel Stanley <joel@jms.id.au>\n> + */\n> +\n> +#ifndef HW_RISCV_TT_ATLANTIS_H\n> +#define HW_RISCV_TT_ATLANTIS_H\n> +\n> +#include \"hw/core/boards.h\"\n> +#include \"hw/core/sysbus.h\"\n> +#include \"hw/intc/riscv_imsic.h\"\n> +#include \"hw/riscv/riscv_hart.h\"\n> +\n> +#define TYPE_TT_ATLANTIS_MACHINE MACHINE_TYPE_NAME(\"tt-atlantis\")\n> +OBJECT_DECLARE_SIMPLE_TYPE(TTAtlantisState, TT_ATLANTIS_MACHINE)\n> +\n> +struct TTAtlantisState {\n> +    /*< private >*/\n> +    MachineState parent;\n> +\n> +    /*< public >*/\n> +    Notifier machine_done;\n> +    FWCfgState *fw_cfg;\n> +    const MemMapEntry *memmap;\n> +\n> +    RISCVHartArrayState soc;\n> +    DeviceState *irqchip;\n> +\n> +    int fdt_size;\n> +};\n> +\n> +enum {\n> +    TT_ATL_SYSCON_IRQ = 10,\n> +    TT_ATL_UART0_IRQ = 38,\n> +    TT_ATL_UART1_IRQ = 39,\n> +    TT_ATL_UART2_IRQ = 40,\n> +    TT_ATL_UART3_IRQ = 41,\n> +    TT_ATL_UART4_IRQ = 42,\n> +};\n> +\n> +enum {\n> +    TT_ATL_ACLINT,\n> +    TT_ATL_BOOTROM,\n> +    TT_ATL_DDR_LO,\n> +    TT_ATL_DDR_HI,\n> +    TT_ATL_FW_CFG,\n> +    TT_ATL_I2C0,\n> +    TT_ATL_MAPLIC,\n> +    TT_ATL_MIMSIC,\n> +    TT_ATL_PCIE_ECAM0,\n> +    TT_ATL_PCIE_ECAM1,\n> +    TT_ATL_PCIE_ECAM2,\n> +    TT_ATL_PCIE_MMIO0,\n> +    TT_ATL_PCIE_PIO0,\n> +    TT_ATL_PCIE_MMIO0_32,\n> +    TT_ATL_PCIE_MMIO0_64,\n> +    TT_ATL_PCIE_MMIO1,\n> +    TT_ATL_PCIE_PIO1,\n> +    TT_ATL_PCIE_MMIO1_32,\n> +    TT_ATL_PCIE_MMIO1_64,\n> +    TT_ATL_PCIE_MMIO2,\n> +    TT_ATL_PCIE_PIO2,\n> +    TT_ATL_PCIE_MMIO2_32,\n> +    TT_ATL_PCIE_MMIO2_64,\n> +    TT_ATL_PCI_MMU_CFG,\n> +    TT_ATL_SAPLIC,\n> +    TT_ATL_SIMSIC,\n> +    TT_ATL_SYSCON,\n> +    TT_ATL_TIMER,\n> +    TT_ATL_UART0,\n> +    TT_ATL_WDT0,\n> +};\n> +\n> +#endif\n> diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c\n> new file mode 100644\n> index 000000000000..a556ff79c8c8\n> --- /dev/null\n> +++ b/hw/riscv/tt_atlantis.c\n> @@ -0,0 +1,638 @@\n> +/*\n> + * Tenstorrent Atlantis RISC-V System on Chip\n> + *\n> + * SPDX-License-Identifier: GPL-2.0-or-later\n> + *\n> + * Copyright 2025 Tenstorrent, Joel Stanley <joel@jms.id.au>\n> + */\n> +\n> +#include \"qemu/osdep.h\"\n> +#include \"qemu/cutils.h\"\n> +#include \"qemu/error-report.h\"\n> +#include \"qemu/guest-random.h\"\n> +#include \"qemu/units.h\"\n> +\n> +#include \"hw/core/boards.h\"\n> +#include \"hw/core/loader.h\"\n> +#include \"hw/core/sysbus.h\"\n> +\n> +#include \"target/riscv/cpu.h\"\n> +#include \"target/riscv/pmu.h\"\n> +\n> +#include \"hw/riscv/boot.h\"\n> +#include \"hw/riscv/numa.h\"\n> +#include \"hw/riscv/riscv_hart.h\"\n> +\n> +#include \"hw/char/serial-mm.h\"\n> +#include \"hw/intc/riscv_aclint.h\"\n> +#include \"hw/intc/riscv_aplic.h\"\n> +#include \"hw/misc/pvpanic.h\"\n> +\n> +#include \"system/system.h\"\n> +#include \"system/device_tree.h\"\n> +\n> +#include \"hw/riscv/tt_atlantis.h\"\n> +\n> +#include \"aia.h\"\n> +\n> +#define TT_IRQCHIP_NUM_MSIS       255\n> +#define TT_IRQCHIP_NUM_SOURCES    128\n> +#define TT_IRQCHIP_NUM_PRIO_BITS  3\n> +#define TT_IRQCHIP_GUESTS         7 /* aia_guests */\n> +\n> +#define FDT_PCI_ADDR_CELLS    3\n> +#define FDT_PCI_INT_CELLS     1\n> +#define FDT_MAX_INT_CELLS     2\n> +#define FDT_MAX_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \\\n> +                                 1 + FDT_MAX_INT_CELLS)\n> +\n> +#define TT_ACLINT_MTIME_SIZE    0x8050\n> +#define TT_ACLINT_MTIME         0x0\n> +#define TT_ACLINT_MTIMECMP      0x8000\n> +#define TT_ACLINT_TIMEBASE_FREQ 1000000000\n> +\n> +static const MemMapEntry tt_atlantis_memmap[] = {\n> +    /* Keep sorted with :'<,'>!sort -g -k 4 */\n> +    [TT_ATL_DDR_LO] =           { 0x00000000,    0x80000000 },\n> +    [TT_ATL_BOOTROM] =          { 0x80000000,        0x2000 },\n> +    [TT_ATL_FW_CFG] =           { 0x80002000,          0xff }, /* qemu only */\n> +    [TT_ATL_SYSCON] =           { 0x80004000,        0x1000 }, /* qemu only */\n> +    [TT_ATL_MIMSIC] =           { 0xa0000000,      0x200000 },\n> +    [TT_ATL_ACLINT] =           { 0xa2180000,       0x10000 },\n> +    [TT_ATL_SIMSIC] =           { 0xa4000000,      0x200000 },\n> +    [TT_ATL_TIMER] =            { 0xa8020000,       0x10000 },\n> +    [TT_ATL_WDT0] =             { 0xa8030000,       0x10000 },\n> +    [TT_ATL_UART0] =            { 0xb0100000,       0x10000 },\n> +    [TT_ATL_MAPLIC] =           { 0xcc000000,     0x4000000 },\n> +    [TT_ATL_SAPLIC] =           { 0xe8000000,     0x4000000 },\n> +    [TT_ATL_DDR_HI] =          { 0x100000000,  0x1000000000 },\n> +    [TT_ATL_PCIE_ECAM0] =    { 0x01110000000,    0x10000000 },\n> +    [TT_ATL_PCIE_ECAM1] =    { 0x01120000000,    0x10000000 },\n> +    [TT_ATL_PCIE_ECAM2] =    { 0x01130000000,    0x10000000 },\n> +    [TT_ATL_PCIE_MMIO0] =    { 0x10000000000, 0x10000000000 },\n> +    [TT_ATL_PCIE_MMIO1] =    { 0x20000000000, 0x10000000000 },\n> +    [TT_ATL_PCIE_MMIO2] =    { 0x30000000000, 0x10000000000 },\n> +};\n> +\n> +static uint32_t next_phandle(void)\n> +{\n> +    static uint32_t phandle = 1;\n> +    return phandle++;\n> +}\n> +\n> +static void create_fdt_cpus(TTAtlantisState *s, uint32_t *intc_phandles)\n> +{\n> +    uint32_t cpu_phandle;\n> +    void *fdt = MACHINE(s)->fdt;\n> +\n> +    for (int cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {\n> +        RISCVCPU *cpu_ptr = &s->soc.harts[cpu];\n> +        g_autofree char *cpu_name = NULL;\n> +        g_autofree char *intc_name = NULL;\n> +\n> +        cpu_phandle = next_phandle();\n> +\n> +        cpu_name = g_strdup_printf(\"/cpus/cpu@%d\", s->soc.hartid_base + cpu);\n> +        qemu_fdt_add_subnode(fdt, cpu_name);\n> +\n> +        qemu_fdt_setprop_string(fdt, cpu_name, \"mmu-type\", \"riscv,sv57\");\n> +\n> +        riscv_isa_write_fdt(cpu_ptr, fdt, cpu_name);\n> +\n> +        qemu_fdt_setprop_cell(fdt, cpu_name, \"riscv,cbom-block-size\",\n> +                cpu_ptr->cfg.cbom_blocksize);\n> +\n> +        qemu_fdt_setprop_cell(fdt, cpu_name, \"riscv,cboz-block-size\",\n> +                cpu_ptr->cfg.cboz_blocksize);\n> +\n> +        qemu_fdt_setprop_cell(fdt, cpu_name, \"riscv,cbop-block-size\",\n> +                cpu_ptr->cfg.cbop_blocksize);\n> +\n> +        qemu_fdt_setprop_string(fdt, cpu_name, \"compatible\", \"riscv\");\n> +        qemu_fdt_setprop_string(fdt, cpu_name, \"status\", \"okay\");\n> +        qemu_fdt_setprop_cell(fdt, cpu_name, \"reg\", s->soc.hartid_base + cpu);\n> +        qemu_fdt_setprop_string(fdt, cpu_name, \"device_type\", \"cpu\");\n> +        qemu_fdt_setprop_cell(fdt, cpu_name, \"phandle\", cpu_phandle);\n> +\n> +        intc_phandles[cpu] = next_phandle();\n> +\n> +        intc_name = g_strdup_printf(\"%s/interrupt-controller\", cpu_name);\n> +        qemu_fdt_add_subnode(fdt, intc_name);\n> +        qemu_fdt_setprop_cell(fdt, intc_name, \"phandle\",\n> +                              intc_phandles[cpu]);\n> +        qemu_fdt_setprop_string(fdt, intc_name, \"compatible\",\n> +                                \"riscv,cpu-intc\");\n> +        qemu_fdt_setprop(fdt, intc_name, \"interrupt-controller\", NULL, 0);\n> +        qemu_fdt_setprop_cell(fdt, intc_name, \"#interrupt-cells\", 1);\n> +    }\n> +}\n> +\n> +static void create_fdt_memory_node(TTAtlantisState *s,\n> +                                   hwaddr addr, hwaddr size)\n> +{\n> +    void *fdt = MACHINE(s)->fdt;\n> +    g_autofree char *name = g_strdup_printf(\"/memory@%\"HWADDR_PRIX, addr);\n> +    qemu_fdt_add_subnode(fdt, name);\n> +    qemu_fdt_setprop_sized_cells(fdt, name, \"reg\", 2, addr, 2, size);\n> +    qemu_fdt_setprop_string(fdt, name, \"device_type\", \"memory\");\n> +}\n> +\n> +static void create_fdt_memory(TTAtlantisState *s)\n> +{\n> +    hwaddr size_lo = MACHINE(s)->ram_size;\n> +    hwaddr size_hi = 0;\n> +\n> +    if (size_lo > s->memmap[TT_ATL_DDR_LO].size) {\n> +        size_lo = s->memmap[TT_ATL_DDR_LO].size;\n> +        size_hi = MACHINE(s)->ram_size - size_lo;\n> +    }\n> +\n> +    create_fdt_memory_node(s, s->memmap[TT_ATL_DDR_LO].base, size_lo);\n> +    if (size_hi) {\n> +        /*\n> +         * The first part of the HI address is aliased at the LO address\n> +         * so do not include that as usable memory. Is there any way\n> +         * (or good reason) to describe that aliasing 2GB with DT?\n> +         */\n> +        create_fdt_memory_node(s, s->memmap[TT_ATL_DDR_HI].base + size_lo,\n> +                               size_hi);\n> +    }\n> +}\n> +\n> +static void create_fdt_aclint(TTAtlantisState *s, uint32_t *intc_phandles)\n> +{\n> +    void *fdt = MACHINE(s)->fdt;\n> +    g_autofree char *name = NULL;\n> +    g_autofree uint32_t *aclint_mtimer_cells = NULL;\n> +    uint32_t aclint_cells_size;\n> +    hwaddr addr;\n> +\n> +    aclint_mtimer_cells = g_new0(uint32_t, s->soc.num_harts * 2);\n> +\n> +    for (int cpu = 0; cpu < s->soc.num_harts; cpu++) {\n> +        aclint_mtimer_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);\n> +        aclint_mtimer_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_TIMER);\n> +    }\n> +    aclint_cells_size = s->soc.num_harts * sizeof(uint32_t) * 2;\n> +\n> +    addr = s->memmap[TT_ATL_ACLINT].base;\n> +\n> +    name = g_strdup_printf(\"/soc/mtimer@%\"HWADDR_PRIX, addr);\n> +    qemu_fdt_add_subnode(fdt, name);\n> +    qemu_fdt_setprop_string(fdt, name, \"compatible\", \"riscv,aclint-mtimer\");\n> +    qemu_fdt_setprop_sized_cells(fdt, name, \"reg\",\n> +                                 2, addr + TT_ACLINT_MTIME,\n> +                                 2, 0x1000,\n> +                                 2, addr + TT_ACLINT_MTIMECMP,\n> +                                 2, 0x1000);\n> +    qemu_fdt_setprop(fdt, name, \"interrupts-extended\",\n> +                     aclint_mtimer_cells, aclint_cells_size);\n> +}\n> +\n> +static void create_fdt_one_imsic(void *fdt, const MemMapEntry *mem, int cpus,\n> +                                 uint32_t *intc_phandles, uint32_t msi_phandle,\n> +                                 int irq_line, uint32_t imsic_guest_bits)\n> +{\n> +    g_autofree char *name = NULL;\n> +    g_autofree uint32_t *imsic_cells = g_new0(uint32_t, cpus * 2);\n> +\n> +    for (int cpu = 0; cpu < cpus; cpu++) {\n> +        imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);\n> +        imsic_cells[cpu * 2 + 1] = cpu_to_be32(irq_line);\n> +    }\n> +\n> +    name = g_strdup_printf(\"/soc/interrupt-controller@%\"HWADDR_PRIX, mem->base);\n> +    qemu_fdt_add_subnode(fdt, name);\n> +    qemu_fdt_setprop_string(fdt, name, \"compatible\", \"riscv,imsics\");\n> +\n> +    qemu_fdt_setprop_cell(fdt, name, \"#interrupt-cells\", 0);\n> +    qemu_fdt_setprop(fdt, name, \"interrupt-controller\", NULL, 0);\n> +    qemu_fdt_setprop(fdt, name, \"msi-controller\", NULL, 0);\n> +    qemu_fdt_setprop(fdt, name, \"interrupts-extended\",\n> +                     imsic_cells, sizeof(uint32_t) * cpus * 2);\n> +    qemu_fdt_setprop_sized_cells(fdt, name, \"reg\", 2, mem->base, 2, mem->size);\n> +    qemu_fdt_setprop_cell(fdt, name, \"riscv,num-ids\", TT_IRQCHIP_NUM_MSIS);\n> +\n> +    if (imsic_guest_bits) {\n> +        qemu_fdt_setprop_cell(fdt, name, \"riscv,guest-index-bits\",\n> +                              imsic_guest_bits);\n> +    }\n> +    qemu_fdt_setprop_cell(fdt, name, \"phandle\", msi_phandle);\n> +}\n> +\n> +static void create_fdt_one_aplic(void *fdt,\n> +                                 const MemMapEntry *mem,\n> +                                 uint32_t msi_phandle,\n> +                                 uint32_t *intc_phandles,\n> +                                 uint32_t aplic_phandle,\n> +                                 uint32_t aplic_child_phandle,\n> +                                 int irq_line, int num_harts)\n> +{\n> +    g_autofree char *name =\n> +        g_strdup_printf(\"/soc/interrupt-controller@%\"HWADDR_PRIX, mem->base);\n> +    g_autofree uint32_t *aplic_cells = g_new0(uint32_t, num_harts * 2);\n> +\n> +    for (int cpu = 0; cpu < num_harts; cpu++) {\n> +        aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);\n> +        aplic_cells[cpu * 2 + 1] = cpu_to_be32(irq_line);\n> +    }\n> +\n> +    qemu_fdt_add_subnode(fdt, name);\n> +    qemu_fdt_setprop_string(fdt, name, \"compatible\", \"riscv,aplic\");\n> +    qemu_fdt_setprop_cell(fdt, name, \"#address-cells\", 0);\n> +    qemu_fdt_setprop_cell(fdt, name, \"#interrupt-cells\", 2);\n> +    qemu_fdt_setprop(fdt, name, \"interrupt-controller\", NULL, 0);\n> +\n> +    qemu_fdt_setprop(fdt, name, \"interrupts-extended\",\n> +                     aplic_cells, num_harts * sizeof(uint32_t) * 2);\n> +    qemu_fdt_setprop_cell(fdt, name, \"msi-parent\", msi_phandle);\n> +\n> +    qemu_fdt_setprop_sized_cells(fdt, name, \"reg\", 2, mem->base, 2, mem->size);\n> +    qemu_fdt_setprop_cell(fdt, name, \"riscv,num-sources\",\n> +                          TT_IRQCHIP_NUM_SOURCES);\n> +\n> +    if (aplic_child_phandle) {\n> +        qemu_fdt_setprop_cell(fdt, name, \"riscv,children\",\n> +                              aplic_child_phandle);\n> +        qemu_fdt_setprop_cells(fdt, name, \"riscv,delegation\",\n> +                               aplic_child_phandle, 1, TT_IRQCHIP_NUM_SOURCES);\n> +    }\n> +\n> +    qemu_fdt_setprop_cell(fdt, name, \"phandle\", aplic_phandle);\n> +}\n> +\n> +static void create_fdt_pmu(TTAtlantisState *s)\n> +{\n> +    g_autofree char *pmu_name = g_strdup_printf(\"/pmu\");\n> +    void *fdt = MACHINE(s)->fdt;\n> +    RISCVCPU *hart = &s->soc.harts[0];\n> +\n> +    qemu_fdt_add_subnode(fdt, pmu_name);\n> +    qemu_fdt_setprop_string(fdt, pmu_name, \"compatible\", \"riscv,pmu\");\n> +    riscv_pmu_generate_fdt_node(fdt, hart->pmu_avail_ctrs, pmu_name);\n> +}\n> +\n> +static void create_fdt_cpu(TTAtlantisState *s, const MemMapEntry *memmap,\n> +                           uint32_t aplic_s_phandle,\n> +                           uint32_t imsic_s_phandle)\n> +{\n> +    MachineState *ms = MACHINE(s);\n> +    void *fdt = MACHINE(s)->fdt;\n> +    g_autofree uint32_t *intc_phandles = NULL;\n> +\n> +    qemu_fdt_add_subnode(fdt, \"/cpus\");\n> +    qemu_fdt_setprop_cell(fdt, \"/cpus\", \"timebase-frequency\",\n> +                          TT_ACLINT_TIMEBASE_FREQ);\n> +    qemu_fdt_setprop_cell(fdt, \"/cpus\", \"#size-cells\", 0x0);\n> +    qemu_fdt_setprop_cell(fdt, \"/cpus\", \"#address-cells\", 0x1);\n> +\n> +    intc_phandles = g_new0(uint32_t, ms->smp.cpus);\n> +\n> +    create_fdt_cpus(s, intc_phandles);\n> +\n> +    create_fdt_memory(s);\n> +\n> +    create_fdt_aclint(s, intc_phandles);\n> +\n> +    /* M-level IMSIC node */\n> +    uint32_t msi_m_phandle = next_phandle();\n> +    create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_MIMSIC], ms->smp.cpus,\n> +                         intc_phandles, msi_m_phandle,\n> +                         IRQ_M_EXT, 0);\n> +\n> +    /* S-level IMSIC node */\n> +    create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_SIMSIC], ms->smp.cpus,\n> +                         intc_phandles, imsic_s_phandle,\n> +                         IRQ_S_EXT, imsic_num_bits(TT_IRQCHIP_GUESTS + 1));\n> +\n> +    uint32_t aplic_m_phandle = next_phandle();\n> +\n> +    /* M-level APLIC node */\n> +    create_fdt_one_aplic(fdt, &s->memmap[TT_ATL_MAPLIC],\n> +                         msi_m_phandle, intc_phandles,\n> +                         aplic_m_phandle, aplic_s_phandle,\n> +                         IRQ_M_EXT, s->soc.num_harts);\n> +\n> +    /* S-level APLIC node */\n> +    create_fdt_one_aplic(fdt, &s->memmap[TT_ATL_SAPLIC],\n> +                         imsic_s_phandle, intc_phandles,\n> +                         aplic_s_phandle, 0,\n> +                         IRQ_S_EXT, s->soc.num_harts);\n> +}\n> +\n> +static void create_fdt_reset(void *fdt, const MemMapEntry *mem)\n> +{\n> +    uint32_t syscon_phandle = next_phandle();\n> +    char *name;\n> +\n> +    name = g_strdup_printf(\"/soc/syscon@%\"HWADDR_PRIX, mem->base);\n> +    qemu_fdt_add_subnode(fdt, name);\n> +    qemu_fdt_setprop_string(fdt, name, \"compatible\", \"syscon\");\n> +    qemu_fdt_setprop_sized_cells(fdt, name, \"reg\", 2, mem->base, 2, mem->size);\n> +    qemu_fdt_setprop_cell(fdt, name, \"phandle\", syscon_phandle);\n> +    g_free(name);\n> +\n> +    name = g_strdup_printf(\"/poweroff\");\n> +    qemu_fdt_add_subnode(fdt, name);\n> +    qemu_fdt_setprop_string(fdt, name, \"compatible\", \"syscon-poweroff\");\n> +    qemu_fdt_setprop_cell(fdt, name, \"regmap\", syscon_phandle);\n> +    qemu_fdt_setprop_cell(fdt, name, \"offset\", 0x0);\n> +    qemu_fdt_setprop_cell(fdt, name, \"value\", PVPANIC_SHUTDOWN);\n> +    g_free(name);\n> +}\n> +\n> +static void create_fdt_uart(void *fdt, const MemMapEntry *mem, int irq,\n> +                            int irqchip_phandle)\n> +{\n> +    g_autofree char *name = g_strdup_printf(\"/soc/serial@%\"HWADDR_PRIX,\n> +                                            mem->base);\n> +\n> +    qemu_fdt_add_subnode(fdt, name);\n> +    qemu_fdt_setprop_string(fdt, name, \"compatible\", \"ns16550a\");\n> +    qemu_fdt_setprop_sized_cells(fdt, name, \"reg\", 2, mem->base, 2, mem->size);\n> +    qemu_fdt_setprop_cell(fdt, name, \"reg-shift\", 2);\n> +    qemu_fdt_setprop_cell(fdt, name, \"reg-io-width\", 4);\n> +    qemu_fdt_setprop_cell(fdt, name, \"clock-frequency\", 3686400);\n> +    qemu_fdt_setprop_cell(fdt, name, \"interrupt-parent\", irqchip_phandle);\n> +    qemu_fdt_setprop_cells(fdt, name, \"interrupts\", irq, 0x4);\n> +\n> +    qemu_fdt_setprop_string(fdt, \"/chosen\", \"stdout-path\", name);\n> +    qemu_fdt_setprop_string(fdt, \"/aliases\", \"serial0\", name);\n> +}\n> +\n> +static void create_fdt_fw_cfg(void *fdt, const MemMapEntry *mem)\n> +{\n> +    g_autofree char *name = g_strdup_printf(\"/fw-cfg@%\"HWADDR_PRIX, mem->base);\n> +\n> +    qemu_fdt_add_subnode(fdt, name);\n> +    qemu_fdt_setprop_string(fdt, name, \"compatible\", \"qemu,fw-cfg-mmio\");\n> +    qemu_fdt_setprop_sized_cells(fdt, name, \"reg\", 2, mem->base, 2, mem->size);\n> +    qemu_fdt_setprop(fdt, name, \"dma-coherent\", NULL, 0);\n> +}\n> +\n> +static void finalize_fdt(TTAtlantisState *s)\n> +{\n> +    uint32_t aplic_s_phandle = next_phandle();\n> +    uint32_t imsic_s_phandle = next_phandle();\n> +    void *fdt = MACHINE(s)->fdt;\n> +\n> +    create_fdt_cpu(s, s->memmap, aplic_s_phandle, imsic_s_phandle);\n> +\n> +    /*\n> +     * We want to do this, but the Linux aplic driver was broken before v6.16\n> +     *\n> +     * qemu_fdt_setprop_cell(MACHINE(s)->fdt, \"/soc\", \"interrupt-parent\",\n> +     *                       aplic_s_phandle);\n> +     */\n> +\n> +    create_fdt_reset(fdt, &s->memmap[TT_ATL_SYSCON]);\n> +\n> +    create_fdt_uart(fdt, &s->memmap[TT_ATL_UART0], TT_ATL_UART0_IRQ,\n> +                    aplic_s_phandle);\n> +}\n> +\n> +static void create_fdt(TTAtlantisState *s)\n> +{\n> +    MachineState *ms = MACHINE(s);\n> +    uint8_t rng_seed[32];\n> +    g_autofree char *name = NULL;\n> +    void *fdt;\n> +\n> +    fdt = create_device_tree(&s->fdt_size);\n> +    if (!fdt) {\n> +        error_report(\"create_device_tree() failed\");\n> +        exit(1);\n> +    }\n> +    ms->fdt = fdt;\n> +\n> +    qemu_fdt_setprop_string(fdt, \"/\", \"model\",\n> +                            \"Tenstorrent Atlantis RISC-V Machine\");\n> +    qemu_fdt_setprop_string(fdt, \"/\", \"compatible\", \"tenstorrent,atlantis\");\n> +    qemu_fdt_setprop_cell(fdt, \"/\", \"#size-cells\", 0x2);\n> +    qemu_fdt_setprop_cell(fdt, \"/\", \"#address-cells\", 0x2);\n> +\n> +    qemu_fdt_add_subnode(fdt, \"/soc\");\n> +    qemu_fdt_setprop(fdt, \"/soc\", \"ranges\", NULL, 0);\n> +    qemu_fdt_setprop_string(fdt, \"/soc\", \"compatible\", \"simple-bus\");\n> +    qemu_fdt_setprop_cell(fdt, \"/soc\", \"#size-cells\", 0x2);\n> +    qemu_fdt_setprop_cell(fdt, \"/soc\", \"#address-cells\", 0x2);\n> +\n> +    qemu_fdt_add_subnode(fdt, \"/chosen\");\n> +\n> +    /* Pass seed to RNG */\n> +    qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));\n> +    qemu_fdt_setprop(fdt, \"/chosen\", \"rng-seed\", rng_seed, sizeof(rng_seed));\n> +\n> +    qemu_fdt_add_subnode(fdt, \"/aliases\");\n> +\n> +    create_fdt_fw_cfg(fdt, &s->memmap[TT_ATL_FW_CFG]);\n> +    create_fdt_pmu(s);\n> +}\n> +\n> +static DeviceState *create_reboot_device(const MemMapEntry *mem)\n> +{\n> +    DeviceState *dev = qdev_new(TYPE_PVPANIC_MMIO_DEVICE);\n> +    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);\n> +\n> +    qdev_prop_set_uint32(dev, \"events\", PVPANIC_SHUTDOWN | PVPANIC_PANICKED);\n> +\n> +    sysbus_realize_and_unref(sbd, &error_fatal);\n> +    sysbus_mmio_map(sbd, 0, mem->base);\n> +\n> +    return dev;\n> +}\n> +\n> +static FWCfgState *create_fw_cfg(const MemMapEntry *mem, int num_cpus)\n> +{\n> +    FWCfgState *fw_cfg;\n> +    hwaddr base = mem->base;\n> +\n> +    fw_cfg = fw_cfg_init_mem_dma(base + 8, base, 8, base + 16,\n> +                                 &address_space_memory);\n> +    fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, num_cpus);\n> +\n> +    return fw_cfg;\n> +}\n> +\n> +static void tt_atlantis_machine_done(Notifier *notifier, void *data)\n> +{\n> +    TTAtlantisState *s = container_of(notifier, TTAtlantisState, machine_done);\n> +    MachineState *machine = MACHINE(s);\n> +    hwaddr start_addr = s->memmap[TT_ATL_DDR_LO].base;\n> +    hwaddr mem_size;\n> +    target_ulong firmware_end_addr, kernel_start_addr;\n> +    const char *firmware_name = riscv_default_firmware_name(&s->soc);\n> +    uint64_t fdt_load_addr;\n> +    uint64_t kernel_entry;\n> +    RISCVBootInfo boot_info;\n> +\n> +    /*\n> +     * A user provided dtb must include everything, including\n> +     * dynamic sysbus devices. Our FDT needs to be finalized.\n> +     */\n> +    if (machine->dtb == NULL) {\n> +        finalize_fdt(s);\n> +    }\n> +\n> +    mem_size = machine->ram_size;\n> +    if (mem_size > s->memmap[TT_ATL_DDR_LO].size) {\n> +        mem_size = s->memmap[TT_ATL_DDR_LO].size;\n> +    }\n> +    riscv_boot_info_init_discontig_mem(&boot_info, &s->soc,\n> +                                       s->memmap[TT_ATL_DDR_LO].base,\n> +                                       mem_size);\n> +\n> +    firmware_end_addr = riscv_find_and_load_firmware(machine, &boot_info,\n> +                                                     firmware_name,\n> +                                                     &start_addr, NULL);\n> +\n> +    kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info,\n> +                                                     firmware_end_addr);\n> +    if (machine->kernel_filename) {\n> +        riscv_load_kernel(machine, &boot_info, kernel_start_addr,\n> +                          true, NULL);\n> +    } else {\n> +        riscv_setup_halting_payload(&boot_info, kernel_start_addr);\n> +    }\n> +    kernel_entry = boot_info.image_low_addr;\n> +\n> +    fdt_load_addr = riscv_compute_fdt_addr(s->memmap[TT_ATL_DDR_LO].base,\n> +                                           s->memmap[TT_ATL_DDR_LO].size,\n> +                                           machine, &boot_info);\n> +    riscv_load_fdt(fdt_load_addr, machine->fdt);\n> +\n> +    /* load the reset vector */\n> +    riscv_setup_rom_reset_vec(machine, &s->soc, start_addr,\n> +                              s->memmap[TT_ATL_BOOTROM].base,\n> +                              s->memmap[TT_ATL_BOOTROM].size,\n> +                              kernel_entry,\n> +                              fdt_load_addr);\n> +\n> +}\n> +\n> +static void tt_atlantis_machine_init(MachineState *machine)\n> +{\n> +    TTAtlantisState *s = TT_ATLANTIS_MACHINE(machine);\n> +\n> +    MemoryRegion *system_memory = get_system_memory();\n> +    MemoryRegion *ram_hi = g_new(MemoryRegion, 1);\n> +    MemoryRegion *ram_lo = g_new(MemoryRegion, 1);\n> +    MemoryRegion *bootrom = g_new(MemoryRegion, 1);\n> +    ram_addr_t lo_ram_size, hi_ram_size;\n> +    int hart_count = machine->smp.cpus;\n> +    int base_hartid = 0;\n> +\n> +    s->memmap = tt_atlantis_memmap;\n> +\n> +    object_initialize_child(OBJECT(machine), \"soc\", &s->soc,\n> +                            TYPE_RISCV_HART_ARRAY);\n> +    object_property_set_str(OBJECT(&s->soc), \"cpu-type\", machine->cpu_type,\n> +                            &error_abort);\n> +    object_property_set_int(OBJECT(&s->soc), \"hartid-base\", base_hartid,\n> +                            &error_abort);\n> +    object_property_set_int(OBJECT(&s->soc), \"num-harts\", hart_count,\n> +                            &error_abort);\n> +    object_property_set_int(OBJECT(&s->soc), \"resetvec\",\n> +                            s->memmap[TT_ATL_BOOTROM].base,\n> +                            &error_abort);\n> +    sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);\n> +\n> +    s->irqchip = riscv_create_aia(true, TT_IRQCHIP_GUESTS,\n> +                                  TT_IRQCHIP_NUM_SOURCES,\n> +                                  &s->memmap[TT_ATL_MAPLIC],\n> +                                  &s->memmap[TT_ATL_SAPLIC],\n> +                                  &s->memmap[TT_ATL_MIMSIC],\n> +                                  &s->memmap[TT_ATL_SIMSIC],\n> +                                  0, base_hartid, hart_count,\n> +                                  TT_IRQCHIP_NUM_MSIS,\n> +                                  TT_IRQCHIP_NUM_PRIO_BITS);\n> +\n> +    riscv_aclint_mtimer_create(s->memmap[TT_ATL_ACLINT].base,\n> +            TT_ACLINT_MTIME_SIZE,\n> +            base_hartid, hart_count,\n> +            TT_ACLINT_MTIMECMP,\n> +            TT_ACLINT_MTIME,\n> +            TT_ACLINT_TIMEBASE_FREQ, true);\n> +\n> +    /* DDR */\n> +\n> +    /* The high address covers all of RAM, the low address just the first 2GB */\n> +    lo_ram_size = s->memmap[TT_ATL_DDR_LO].size;\n> +    hi_ram_size = s->memmap[TT_ATL_DDR_HI].size;\n> +    if (machine->ram_size > hi_ram_size) {\n> +        char *sz = size_to_str(hi_ram_size);\n> +        error_report(\"RAM size is too large, maximum is %s\", sz);\n> +        g_free(sz);\n> +        exit(EXIT_FAILURE);\n> +    }\n> +\n> +    memory_region_init_alias(ram_lo, OBJECT(machine), \"ram.low\", machine->ram,\n> +                             0, lo_ram_size);\n> +    memory_region_init_alias(ram_hi, OBJECT(machine), \"ram.high\", machine->ram,\n> +                             0, hi_ram_size);\n> +    memory_region_add_subregion(system_memory,\n> +                                s->memmap[TT_ATL_DDR_LO].base, ram_lo);\n> +    memory_region_add_subregion(system_memory,\n> +                                s->memmap[TT_ATL_DDR_HI].base, ram_hi);\n> +\n> +    /* Boot ROM */\n> +    memory_region_init_rom(bootrom, NULL, \"tt-atlantis.bootrom\",\n> +                           s->memmap[TT_ATL_BOOTROM].size, &error_fatal);\n> +    memory_region_add_subregion(system_memory, s->memmap[TT_ATL_BOOTROM].base,\n> +                                bootrom);\n> +\n> +    /*\n> +     * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the\n> +     * device tree cannot be altered and we get FDT_ERR_NOSPACE.\n> +     */\n> +    s->fw_cfg = create_fw_cfg(&s->memmap[TT_ATL_FW_CFG], machine->smp.cpus);\n> +    rom_set_fw(s->fw_cfg);\n> +\n> +    /* Reboot and exit */\n> +    create_reboot_device(&s->memmap[TT_ATL_SYSCON]);\n> +\n> +    /* UART */\n> +    serial_mm_init(system_memory, s->memmap[TT_ATL_UART0].base, 2,\n> +                   qdev_get_gpio_in(s->irqchip, TT_ATL_UART0_IRQ),\n> +                   115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);\n> +\n> +    /* Load or create device tree */\n> +    if (machine->dtb) {\n> +        machine->fdt = load_device_tree(machine->dtb, &s->fdt_size);\n> +        if (!machine->fdt) {\n> +            error_report(\"load_device_tree() failed\");\n> +            exit(1);\n> +        }\n> +    } else {\n> +        create_fdt(s);\n> +    }\n> +\n> +    s->machine_done.notify = tt_atlantis_machine_done;\n> +    qemu_add_machine_init_done_notifier(&s->machine_done);\n> +}\n> +\n> +static void tt_atlantis_machine_class_init(ObjectClass *oc, const void *data)\n> +{\n> +    MachineClass *mc = MACHINE_CLASS(oc);\n> +\n> +    mc->desc = \"Tenstorrent Atlantis RISC-V SoC\";\n> +    mc->init = tt_atlantis_machine_init;\n> +    mc->max_cpus = 8;\n> +    mc->default_cpus = 8;\n> +    mc->default_ram_size = 2 * GiB;\n> +    mc->default_cpu_type = TYPE_RISCV_CPU_TT_ASCALON;\n> +    mc->block_default_type = IF_VIRTIO;\n> +    mc->no_cdrom = 1;\n> +    mc->default_ram_id = \"tt_atlantis.ram\";\n> +}\n> +\n> +static const TypeInfo tt_atlantis_types[] = {\n> +    {\n> +        .name       = MACHINE_TYPE_NAME(\"tt-atlantis\"),\n> +        .parent     = TYPE_MACHINE,\n> +        .class_init = tt_atlantis_machine_class_init,\n> +        .instance_size = sizeof(TTAtlantisState),\n> +    },\n> +};\n> +\n> +DEFINE_TYPES(tt_atlantis_types)\n> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig\n> index 0222c93f878b..0601ae1a7494 100644\n> --- a/hw/riscv/Kconfig\n> +++ b/hw/riscv/Kconfig\n> @@ -120,6 +120,21 @@ config SPIKE\n>      select RISCV_ACLINT\n>      select SIFIVE_PLIC\n>  \n> +config TENSTORRENT\n> +    bool\n> +    default y\n> +    depends on RISCV64\n> +    imply PCI_DEVICES\n> +    imply TEST_DEVICES\n> +    select DEVICE_TREE\n> +    select RISCV_NUMA\n> +    select PVPANIC_MMIO\n> +    select SERIAL_MM\n> +    select RISCV_ACLINT\n> +    select RISCV_APLIC\n> +    select RISCV_IMSIC\n> +    select FW_CFG_DMA\n> +\n>  config XIANGSHAN_KUNMINGHU\n>      bool\n>      default y\n> diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build\n> index e53c180d0d10..026e79591f4b 100644\n> --- a/hw/riscv/meson.build\n> +++ b/hw/riscv/meson.build\n> @@ -9,6 +9,7 @@ riscv_ss.add(when: 'CONFIG_SIFIVE_E', if_true: files('sifive_e.c'))\n>  riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: files('sifive_u.c'))\n>  riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c'))\n>  riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: files('microchip_pfsoc.c'))\n> +riscv_ss.add(when: 'CONFIG_TENSTORRENT', if_true: files('tt_atlantis.c'))\n>  riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))\n>  riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files(\n>  \t'riscv-iommu.c', 'riscv-iommu-pci.c', 'riscv-iommu-sys.c', 'riscv-iommu-hpm.c'))\n> -- \n> 2.47.3\n> \n>","headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.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 unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=aDvh2yVC;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0tn94BbVz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 19:13:33 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wFTde-0000j6-Ri; Wed, 22 Apr 2026 05:12:54 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <chao.liu.zevorn@gmail.com>)\n id 1wFTdb-0000ib-5r\n for qemu-devel@nongnu.org; Wed, 22 Apr 2026 05:12:52 -0400","from mail-vs1-xe43.google.com ([2607:f8b0:4864:20::e43])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <chao.liu.zevorn@gmail.com>)\n id 1wFTdX-0003OI-C8\n for qemu-devel@nongnu.org; Wed, 22 Apr 2026 05:12:50 -0400","by mail-vs1-xe43.google.com with SMTP id\n ada2fe7eead31-6121f20650dso1670841137.1\n for <qemu-devel@nongnu.org>; Wed, 22 Apr 2026 02:12:47 -0700 (PDT)","from ZEVORN-PC.localdomain ([162.244.208.119])\n by smtp.gmail.com with ESMTPSA id\n ada2fe7eead31-61a52772936sm4646328137.8.2026.04.22.02.12.40\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 22 Apr 2026 02:12:45 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1776849166; x=1777453966; darn=nongnu.org;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to;\n bh=35vLnWJ0nHMr81blPLBwnE+BuA2XRBm7dV2qjsoGTMg=;\n b=aDvh2yVCA/gxQUSU+kvoZpO/Dau61SoRqSyTqmdfV+bw+qsVH3aH1qgQvof78LV+oS\n +Nke/93caeknalaN2kFnxoquNOT22mKjkMFrP22rM18DGKkbmNGt81nv4g89u5lLaFpI\n PQFHv5TSH7Rzps/SnA7SYy27IFFk3PcEtS2I37xlBKdtUM/my0haoux4pXebZk9ixx0C\n /Bq4KjFYidoKsfJbr9AEHvi4eoqAzqmoGRWwIti5+7MHya38w3ccnSiHD/ejy9w8KeZf\n WO7nuyQVFC20gqISXDk5GX+4PEdy3CtmHHh8jcSQ2H2EzbTZiV0+FlEliLvaZnD9w+lq\n GLFw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776849166; x=1777453966;\n h=in-reply-to:content-disposition:mime-version:references:message-id\n :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=35vLnWJ0nHMr81blPLBwnE+BuA2XRBm7dV2qjsoGTMg=;\n b=XLBvCzwZeXxoWBbzqy0uUVs0z4taWMxXPr1/FxXoUaVc358cts0Tpnonmrgaz8ltfu\n Vgz0mmV3WFs56aLxldLvmeD1OjoLXm9UJ85p/YX/N/cu1cwlKee0i1QRb1zHRntv5ocW\n YNLdp5vZo1vXmTr+7JKX7mPc2HmIq23s3l7t/IG1++4dRHMR2CkV8lIdlF3V8o+Vmltv\n 5gnj4i9hhxW00Xu9bPlw1bxpztYVKxb1KDiEVtRqg3T5kJhNj2I4iL6sOTameLTfNkAa\n dX/Whq3izCzjexX95JBCLqUy/OIRe2IdB/5ZzIiITEj+vJfkyMAnL1PQ4urH5OcKir0Q\n c2EA==","X-Forwarded-Encrypted":"i=1;\n AFNElJ9GC75hWy4/KRvLrG8VHaMysfgrLhrWQAuKoqUsDqArqVa9KwfkXRPZyVynHq9dJlVzwf1mzmfvTWUf@nongnu.org","X-Gm-Message-State":"AOJu0YyHI6xeT3U8C8v47WiRwd4TSQDhOKGhSEvOMWvBNYDPNE5ByXLs\n Bp7VDX+zqcOpGN5V6DteHlutLgzEGzGSdVcz85B/komfAwjdQTC8X8Kk","X-Gm-Gg":"AeBDieszA6CzAUPemGCPi1xH4yMiQVUb5D72w+Ghaeltwm5ZCUgIj9xfZVV/+bXNXAk\n A/CwsAYBU1D980XrSSgC7cIktw9Q+q7KcNrfRcAnqgFtlX3nD9ttaaqgaXU0evTSLDJevcA8mcq\n EwDbL7sNUCP8GHztMgUde3aFcnQIGBeqEUPgsN8GSbsh79UaZDFZSMI+AkuwyEy5JXJv2zL0i+d\n fIPhr/uevRsc3qDpiriQBl2o83MPpkbmNhYI2t6m3K2WZ2RqyATPEL7Rthf/SplbNBGhae/mRo1\n fUQT0Ij/s3Fp6l5Y09NoURM9IbWNkM+8G161H+xYwnfWmz1xHQjao3cCDB7n82qIBFORj2/Y3mv\n qD7SgP82gGkwXXIWOeg92vkgzST5FpBncDQPuqPepCS3XX9BsKYwuVTXKgbsqMTDx6y0hlDbJjr\n ceuXjkyHhmAzSbtjDis2IqdW+D4w0Ka14iKXy5yZ8pdefdkO0pIquldHoIQxS/H/yC612zWUEcY\n CTr7CroU6k=","X-Received":"by 2002:a05:6102:32ce:b0:606:49d:183f with SMTP id\n ada2fe7eead31-616f773a1f9mr9166813137.26.1776849165873;\n Wed, 22 Apr 2026 02:12:45 -0700 (PDT)","Date":"Wed, 22 Apr 2026 17:12:29 +0800","From":"Chao Liu <chao.liu.zevorn@gmail.com>","To":"Joel Stanley <joel@jms.id.au>","Cc":"Alistair Francis <alistair.francis@wdc.com>,\n Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>,\n Michael Ellerman <mpe@kernel.org>,\n Nicholas Piggin <npiggin@gmail.com>, Joel Stanley <jms@oss.tenstorrent.com>,\n Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>, qemu-riscv@nongnu.org,\n qemu-devel@nongnu.org","Subject":"Re: [PATCH v3 09/13] hw/riscv: Add Tenstorrent Atlantis machine","Message-ID":"<aeiQ6bV4nEEhmGUP@ZEVORN-PC.localdomain>","References":"<20260421053140.752059-1-joel@jms.id.au>\n <20260421053140.752059-10-joel@jms.id.au>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20260421053140.752059-10-joel@jms.id.au>","Received-SPF":"pass client-ip=2607:f8b0:4864:20::e43;\n envelope-from=chao.liu.zevorn@gmail.com; helo=mail-vs1-xe43.google.com","X-Spam_score_int":"-20","X-Spam_score":"-2.1","X-Spam_bar":"--","X-Spam_report":"(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"qemu development <qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"}}]