From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749636191400.80177433771007; Mon, 20 Apr 2026 22:33:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3jd-0000RE-S1; Tue, 21 Apr 2026 01:33:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3jW-0000PF-1N for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:15 -0400 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3jS-0004OO-1z for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:13 -0400 Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-36146ae9dd4so2853127a91.3 for ; Mon, 20 Apr 2026 22:33:09 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749588; x=1777354388; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=3ppIvCHSoxfKxKlEXcLNRGER0aNeuOrWaORT80Wayz0=; b=UOz6AhKXoigxVy5sBlBhhX4Jwzlh42hxOk+8Z3Ntc+aj7eMogxFgILbjbeyV3DJR1x WEpByapvfrno1mW+u3regaFwBGgwF9qrlaRUF19QhSVtNzMXE/uXfs2lxTDXBlcksHD4 TBFWXEPGCcWXZHz43FizDXLV14QOVhNAvu2VaH8BDvyK1puova4YHBJYy7GoXSLf2K2u zuMKVxllZjD8g2bw7IN8648FVmjy0Ze6Znv6GZ3K7q51BDI+t5RM3VrD6NwZbCyJ4Gn/ TDAf7WRp+6CdrOhXzG52T8IjeuLxcwqNg+MtFii48NeecmZx8vygL0nr2FVkllCObwaZ 50xQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749588; x=1777354388; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3ppIvCHSoxfKxKlEXcLNRGER0aNeuOrWaORT80Wayz0=; b=m6MvFsdjj0XNxsITGoMNqIDkfH+laceoUOOTjL3JM0M+W0oLHD2BmcuRztztf/5eYw wYq5G5rDPgA3leHcNFT+E0i2B0jfHfaAfY9wrevSdeIUyM9heVm8LfhmFlHmPIPvvKON j/xnCmtsh9geEgNvh137nWOnuIhb9CglLKi1uiXkNJ4ys7NxXozV6UFYTF1Wif6vAWX1 tqnPShEzSUR98ZAQFUcutFUjC9iuWJQfcnB5qyERHb8hSivSgjhI1btHGAFx3tzKq/eq l7YXC4eQI3Jyzajoo+YrSP492H61zIiYE81soJMyAP+o82FAd5TG2KrCT2ZAh1RtF6ry 7ZnA== X-Forwarded-Encrypted: i=1; AFNElJ+ZH+wgJkdiorssPo6pUy+R9Fp3M+P7Eso025xJS21Sv+utu1VUXgFyUfFKG8iSc5Nx5pMi4D6sre8f@nongnu.org X-Gm-Message-State: AOJu0YzBnJYZn4eM77OHP/zrGol3T/UOTTvqcwrIdIs1wepYyYAleznE ZzGXkWsS7ndfqCVCPFGKDFPugoS3dafWmXz7PV43Xou/TJZxp85lhe7U X-Gm-Gg: AeBDievQApzAsoJg9oVer2e9E+d82F/u8QW/JWnwlFlDQXWV/S7DEcQ4ADDBh0jfajr TYR9g7EmfTf/0qzhmpo+q0ciTokXsJgo4ktjfs2NXAlN0qXFu/9CdF6IjzOxjzR7CinX+1s7a8t g/BNE/aPEze95VBGy0lC3ADmC+NXCJzIJDM4wLOQ6BpMxovEANhieNSDC4m3fVDsITWMlZw+gFY iIEyUPmVyQJewhwCH9WxJfUbSZfc7VfdkHUi8jH20Ky112bxcdy9fWzdMCHvXKbmjo0pfRzEt5H azu/Yc2rwv+CVdRFBebqlNst+al3UbXEJgFaDsRPjHYLUrc+ecfh6/UhuqsjwhF32+X8vkwF/vz LT0yDLdmJ8z6Y1zhWz/CAzZqPLrlPjLDSDIbIjY9DBZ8AEnokEeP6g7OHue8WnkzoIlcWkFnQW+ IInxBccHb5Kks4aVXTKpkZgj0+IUfgnIl8KHsCzN1Y0my66EXc4vqKO4XnyAKN61pAyPCcI6bRL FEIBclAh605htwVSECIpYpY9blVBGL786DE1w== X-Received: by 2002:a17:90b:3f84:b0:359:1130:1047 with SMTP id 98e67ed59e1d1-36140468c28mr16076858a91.17.1776749588157; Mon, 20 Apr 2026 22:33:08 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Chris Rauer , Michael Ellerman , Nicholas Piggin , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Hao Wu Subject: [PATCH v3 01/13] hw/i2c: Add designware i2c controller Date: Tue, 21 Apr 2026 15:31:26 +1000 Message-ID: <20260421053140.752059-2-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1032; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x1032.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749639761154100 Content-Type: text/plain; charset="utf-8" From: Chris Rauer In the past this model has been submitted for use with the arm virt machine, however in this case it will be used by the upcoming Tenstorrent Atlantis RISC-V machine. This is a re-submission of the model with Chris' permission, with a light touch of updates to make it build with qemu master. Reviewed-by: Hao Wu Signed-off-by: Chris Rauer Link: https://lore.kernel.org/qemu-devel/20220110214755.810343-2-venture@go= ogle.com [jms: rebase and minor build fixes for class_init and reset callback] Signed-off-by: Joel Stanley --- v2: Add trace event for read and write, document Alano and myself as reviewers. --- MAINTAINERS | 8 + include/hw/i2c/designware_i2c.h | 101 ++++ hw/i2c/designware_i2c.c | 818 ++++++++++++++++++++++++++++++++ hw/i2c/Kconfig | 4 + hw/i2c/meson.build | 1 + hw/i2c/trace-events | 4 + 6 files changed, 936 insertions(+) create mode 100644 include/hw/i2c/designware_i2c.h create mode 100644 hw/i2c/designware_i2c.c diff --git a/MAINTAINERS b/MAINTAINERS index aa4267b15806..e1942a86eba5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2716,6 +2716,14 @@ S: Orphan F: hw/gpio/pcf8574.c F: include/gpio/pcf8574.h =20 +DesignWare I2C +M: Chris Rauer +R: Alano Song +R: Joel Stanley +S: Maintained +F: hw/i2c/designware_i2c.c +F: include/hw/i2c/designware_i2c.h + Generic Loader M: Alistair Francis S: Maintained diff --git a/include/hw/i2c/designware_i2c.h b/include/hw/i2c/designware_i2= c.h new file mode 100644 index 000000000000..0d8f904f51b7 --- /dev/null +++ b/include/hw/i2c/designware_i2c.h @@ -0,0 +1,101 @@ +/* + * DesignWare I2C Module. + * + * Copyright 2021 Google LLC + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef DESIGNWARE_I2C_H +#define DESIGNWARE_I2C_H + +#include "hw/i2c/i2c.h" +#include "hw/core/irq.h" +#include "hw/core/sysbus.h" + +/* Size of the FIFO buffers. */ +#define DESIGNWARE_I2C_RX_FIFO_SIZE 16 +#define DESIGNWARE_I2C_TX_FIFO_SIZE 16 + +typedef enum DesignWareI2CStatus { + DW_I2C_STATUS_IDLE, + DW_I2C_STATUS_SENDING_ADDRESS, + DW_I2C_STATUS_SENDING, + DW_I2C_STATUS_RECEIVING, +} DesignWareI2CStatus; + +/* + * struct DesignWareI2CState - DesignWare I2C device state. + * @bus: The underlying I2C Bus + * @irq: GIC interrupt line to fire on events + * @ic_con: : I2C control register + * @ic_tar: I2C target address register + * @ic_sar: I2C slave address register + * @ic_ss_scl_hcnt: Standard speed i2c clock scl high count register + * @ic_ss_scl_lcnt: Standard speed i2c clock scl low count register + * @ic_fs_scl_hcnt: Fast mode or fast mode plus i2c clock scl high count + * register + * @ic_fs_scl_lcnt:Fast mode or fast mode plus i2c clock scl low count + * register + * @ic_intr_mask: I2C Interrupt Mask Register + * @ic_raw_intr_stat: I2C raw interrupt status register + * @ic_rx_tl: I2C receive FIFO threshold register + * @ic_tx_tl: I2C transmit FIFO threshold register + * @ic_enable: I2C enable register + * @ic_status: I2C status register + * @ic_txflr: I2C transmit fifo level register + * @ic_rxflr: I2C receive fifo level register + * @ic_sda_hold: I2C SDA hold time length register + * @ic_tx_abrt_source: The I2C transmit abort source register + * @ic_sda_setup: I2C SDA setup register + * @ic_enable_status: I2C enable status register + * @ic_fs_spklen: I2C SS, FS or FM+ spike suppression limit + * @ic_comp_param_1: Component parameter register + * @ic_comp_version: I2C component version register + * @ic_comp_type: I2C component type register + * @rx_fifo: The FIFO buffer for receiving in FIFO mode. + * @rx_cur: The current position of rx_fifo. + * @status: The current status of the SMBus. + */ +typedef struct DesignWareI2CState { + SysBusDevice parent; + + MemoryRegion iomem; + + I2CBus *bus; + qemu_irq irq; + + uint32_t ic_con; + uint32_t ic_tar; + uint32_t ic_sar; + uint32_t ic_ss_scl_hcnt; + uint32_t ic_ss_scl_lcnt; + uint32_t ic_fs_scl_hcnt; + uint32_t ic_fs_scl_lcnt; + uint32_t ic_intr_mask; + uint32_t ic_raw_intr_stat; + uint32_t ic_rx_tl; + uint32_t ic_tx_tl; + uint32_t ic_enable; + uint32_t ic_status; + uint32_t ic_txflr; + uint32_t ic_rxflr; + uint32_t ic_sda_hold; + uint32_t ic_tx_abrt_source; + uint32_t ic_sda_setup; + uint32_t ic_enable_status; + uint32_t ic_fs_spklen; + uint32_t ic_comp_param_1; + uint32_t ic_comp_version; + uint32_t ic_comp_type; + + uint8_t rx_fifo[DESIGNWARE_I2C_RX_FIFO_SIZE]; + uint8_t rx_cur; + + DesignWareI2CStatus status; +} DesignWareI2CState; + +#define TYPE_DESIGNWARE_I2C "designware-i2c" +#define DESIGNWARE_I2C(obj) OBJECT_CHECK(DesignWareI2CState, (obj), \ + TYPE_DESIGNWARE_I2C) + +#endif /* DESIGNWARE_I2C_H */ diff --git a/hw/i2c/designware_i2c.c b/hw/i2c/designware_i2c.c new file mode 100644 index 000000000000..3e0e7dab2333 --- /dev/null +++ b/hw/i2c/designware_i2c.c @@ -0,0 +1,818 @@ +/* + * DesignWare I2C Module. + * + * Copyright 2021 Google LLC + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" + +#include "hw/i2c/designware_i2c.h" +#include "migration/vmstate.h" +#include "qemu/bitops.h" +#include "qemu/guest-random.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qemu/units.h" +#include "trace.h" + +enum DesignWareI2CRegister { + DW_IC_CON =3D 0x00, + DW_IC_TAR =3D 0x04, + DW_IC_SAR =3D 0x08, + DW_IC_DATA_CMD =3D 0x10, + DW_IC_SS_SCL_HCNT =3D 0x14, + DW_IC_SS_SCL_LCNT =3D 0x18, + DW_IC_FS_SCL_HCNT =3D 0x1c, + DW_IC_FS_SCL_LCNT =3D 0x20, + DW_IC_INTR_STAT =3D 0x2c, + DW_IC_INTR_MASK =3D 0x30, + DW_IC_RAW_INTR_STAT =3D 0x34, + DW_IC_RX_TL =3D 0x38, + DW_IC_TX_TL =3D 0x3c, + DW_IC_CLR_INTR =3D 0x40, + DW_IC_CLR_RX_UNDER =3D 0x44, + DW_IC_CLR_RX_OVER =3D 0x48, + DW_IC_CLR_TX_OVER =3D 0x4c, + DW_IC_CLR_RD_REQ =3D 0x50, + DW_IC_CLR_TX_ABRT =3D 0x54, + DW_IC_CLR_RX_DONE =3D 0x58, + DW_IC_CLR_ACTIVITY =3D 0x5c, + DW_IC_CLR_STOP_DET =3D 0x60, + DW_IC_CLR_START_DET =3D 0x64, + DW_IC_CLR_GEN_CALL =3D 0x68, + DW_IC_ENABLE =3D 0x6c, + DW_IC_STATUS =3D 0x70, + DW_IC_TXFLR =3D 0x74, + DW_IC_RXFLR =3D 0x78, + DW_IC_SDA_HOLD =3D 0x7c, + DW_IC_TX_ABRT_SOURCE =3D 0x80, + DW_IC_SLV_DATA_NACK_ONLY =3D 0x84, + DW_IC_DMA_CR =3D 0x88, + DW_IC_DMA_TDLR =3D 0x8c, + DW_IC_DMA_RDLR =3D 0x90, + DW_IC_SDA_SETUP =3D 0x94, + DW_IC_ACK_GENERAL_CALL =3D 0x98, + DW_IC_ENABLE_STATUS =3D 0x9c, + DW_IC_FS_SPKLEN =3D 0xa0, + DW_IC_CLR_RESTART_DET =3D 0xa8, + DW_IC_COMP_PARAM_1 =3D 0xf4, + DW_IC_COMP_VERSION =3D 0xf8, + DW_IC_COMP_TYPE =3D 0xfc, +}; + +/* DW_IC_CON fields */ +#define DW_IC_CON_STOP_DET_IF_MASTER_ACTIV BIT(10) +#define DW_IC_CON_RX_FIFO_FULL_HLD_CTRL BIT(9) +#define DW_IC_CON_TX_EMPTY_CTRL BIT(8) +#define DW_IC_CON_STOP_IF_ADDRESSED BIT(7) +#define DW_IC_CON_SLAVE_DISABLE BIT(6) +#define DW_IC_CON_IC_RESTART_EN BIT(5) +#define DW_IC_CON_10BITADDR_MASTER BIT(4) +#define DW_IC_CON_10BITADDR_SLAVE BIT(3) +#define DW_IC_CON_SPEED(rv) extract32((rv), 1, 2) +#define DW_IC_CON_MASTER_MODE BIT(0) + +/* DW_IC_TAR fields */ +#define DW_IC_TAR_IC_10BITADDR_MASTER BIT(12) +#define DW_IC_TAR_SPECIAL BIT(11) +#define DW_IC_TAR_GC_OR_START BIT(10) +#define DW_IC_TAR_ADDRESS(rv) extract32((rv), 0, 10) + +/* DW_IC_DATA_CMD fields */ +#define DW_IC_DATA_CMD_RESTART BIT(10) +#define DW_IC_DATA_CMD_STOP BIT(9) +#define DW_IC_DATA_CMD_CMD BIT(8) +#define DW_IC_DATA_CMD_DAT(rv) extract32((rv), 0, 8) + +/* DW_IC_INTR_STAT/INTR_MASK/RAW_INTR_STAT fields */ +#define DW_IC_INTR_RESTART_DET BIT(12) +#define DW_IC_INTR_GEN_CALL BIT(11) +#define DW_IC_INTR_START_DET BIT(10) +#define DW_IC_INTR_STOP_DET BIT(9) +#define DW_IC_INTR_ACTIVITY BIT(8) +#define DW_IC_INTR_RX_DONE BIT(7) +#define DW_IC_INTR_TX_ABRT BIT(6) +#define DW_IC_INTR_RD_REQ BIT(5) +#define DW_IC_INTR_TX_EMPTY BIT(4) /* Hardware clear only. */ +#define DW_IC_INTR_TX_OVER BIT(3) +#define DW_IC_INTR_RX_FULL BIT(2) /* Hardware clear only. */ +#define DW_IC_INTR_RX_OVER BIT(1) +#define DW_IC_INTR_RX_UNDER BIT(0) + +/* DW_IC_ENABLE fields */ +#define DW_IC_ENABLE_TX_CMD_BLOCK BIT(2) +#define DW_IC_ENABLE_ABORT BIT(1) +#define DW_IC_ENABLE_ENABLE BIT(0) + +/* DW_IC_STATUS fields */ +#define DW_IC_STATUS_SLV_ACTIVITY BIT(6) +#define DW_IC_STATUS_MST_ACTIVITY BIT(5) +#define DW_IC_STATUS_RFF BIT(4) +#define DW_IC_STATUS_RFNE BIT(3) +#define DW_IC_STATUS_TFE BIT(2) +#define DW_IC_STATUS_TFNF BIT(1) +#define DW_IC_STATUS_ACTIVITY BIT(0) + +/* DW_IC_TX_ABRT_SOURCE fields */ +#define DW_IC_TX_TX_FLUSH_CNT extract32((rv), 23, 9) +#define DW_IC_TX_ABRT_USER_ABRT BIT(16) +#define DW_IC_TX_ABRT_SLVRD_INTX BIT(15) +#define DW_IC_TX_ABRT_SLV_ARBLOST BIT(14) +#define DW_IC_TX_ABRT_SLVFLUSH_TXFIFO BIT(13) +#define DW_IC_TX_ARB_LOST BIT(12) +#define DW_IC_TX_ABRT_MASTER_DIS BIT(11) +#define DW_IC_TX_ABRT_10B_RD_NORSTRT BIT(10) +#define DW_IC_TX_ABRT_SBYTE_NORSTRT BIT(9) +#define DW_IC_TX_ABRT_HS_NORSTRT BIT(8) +#define DW_IC_TX_ABRT_SBYTE_ACKDET BIT(7) +#define DW_IC_TX_ABRT_HS_ACKDET BIT(6) +#define DW_IC_TX_ABRT_GCALL_READ BIT(5) +#define DW_IC_TX_ABRT_GCALL_NOACK BIT(4) +#define DW_IC_TX_ABRT_TXDATA_NOACK BIT(3) +#define DW_IC_TX_ABRT_10ADDR2_NOACK BIT(2) +#define DW_IC_TX_ABRT_10ADDR1_NOACK BIT(1) +#define DW_IC_TX_ABRT_7B_ADDR_NOACK BIT(0) + + +/* IC_ENABLE_STATUS fields */ +#define DW_IC_ENABLE_STATUS_SLV_RX_DATA_LOST BIT(2) +#define DW_IC_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY BIT(1) +#define DW_IC_ENABLE_STATUS_IC_EN BIT(0) + +/* Masks for writable registers. */ +#define DW_IC_CON_MASK 0x000003ff +#define DW_IC_TAR_MASK 0x00000fff +#define DW_IC_SAR_MASK 0x000003ff +#define DW_IC_SS_SCL_HCNT_MASK 0x0000ffff +#define DW_IC_SS_SCL_LCNT_MASK 0x0000ffff +#define DW_IC_FS_SCL_HCNT_MASK 0x0000ffff +#define DW_IC_FS_SCL_LCNT_MASK 0x0000ffff +#define DW_IC_INTR_MASK_MASK 0x00001fff +#define DW_IC_ENABLE_MASK 0x00000007 +#define DW_IC_SDA_HOLD_MASK 0x00ffffff +#define DW_IC_SDA_SETUP_MASK 0x000000ff +#define DW_IC_FS_SPKLEN_MASK 0x000000ff + +/* Reset values */ +#define DW_IC_CON_INIT_VAL 0x7d +#define DW_IC_TAR_INIT_VAL 0x1055 +#define DW_IC_SAR_INIT_VAL 0x55 +#define DW_IC_SS_SCL_HCNT_INIT_VAL 0x190 +#define DW_IC_SS_SCL_LCNT_INIT_VAL 0x1d6 +#define DW_IC_FS_SCL_HCNT_INIT_VAL 0x3c +#define DW_IC_FS_SCL_LCNT_INIT_VAL 0x82 +#define DW_IC_INTR_MASK_INIT_VAL 0x8ff +#define DW_IC_STATUS_INIT_VAL 0x6 +#define DW_IC_SDA_HOLD_INIT_VAL 0x1 +#define DW_IC_SDA_SETUP_INIT_VAL 0x64 +#define DW_IC_FS_SPKLEN_INIT_VAL 0x2 + +#define DW_IC_COMP_PARAM_1_HAS_ENCODED_PARAMS BIT(7) +#define DW_IC_COMP_PARAM_1_HAS_DMA 0 /* bit 6 - DMA disabled.= */ +#define DW_IC_COMP_PARAM_1_INTR_IO BIT(5) +#define DW_IC_COMP_PARAM_1_HC_COUNT_VAL 0 /* bit 4 - disabled */ +#define DW_IC_COMP_PARAM_1_HIGH_SPEED_MODE (BIT(2) | BIT(3)) +#define DW_IC_COMP_PARAM_1_APB_DATA_WIDTH_32 BIT(1) /* bits 0, 1 */ +#define DW_IC_COMP_PARAM_1_INIT_VAL \ + (DW_IC_COMP_PARAM_1_APB_DATA_WIDTH_32 | \ + DW_IC_COMP_PARAM_1_HIGH_SPEED_MODE | \ + DW_IC_COMP_PARAM_1_HC_COUNT_VAL | \ + DW_IC_COMP_PARAM_1_INTR_IO | \ + DW_IC_COMP_PARAM_1_HAS_DMA | \ + DW_IC_COMP_PARAM_1_HAS_ENCODED_PARAMS | \ + ((DESIGNWARE_I2C_RX_FIFO_SIZE - 1) << 8) | \ + ((DESIGNWARE_I2C_TX_FIFO_SIZE - 1) << 16)) +#define DW_IC_COMP_VERSION_INIT_VAL 0x3132302a +#define DW_IC_COMP_TYPE_INIT_VAL 0x44570140 + +static void dw_i2c_update_irq(DesignWareI2CState *s) +{ + int level; + uint32_t intr =3D s->ic_raw_intr_stat & s->ic_intr_mask; + + level =3D !!((intr & DW_IC_INTR_RX_UNDER) | + (intr & DW_IC_INTR_RX_OVER) | + (intr & DW_IC_INTR_RX_FULL) | + (intr & DW_IC_INTR_TX_OVER) | + (intr & DW_IC_INTR_TX_EMPTY) | + (intr & DW_IC_INTR_RD_REQ) | + (intr & DW_IC_INTR_TX_ABRT) | + (intr & DW_IC_INTR_RX_DONE) | + (intr & DW_IC_INTR_ACTIVITY) | + (intr & DW_IC_INTR_STOP_DET) | + (intr & DW_IC_INTR_START_DET) | + (intr & DW_IC_INTR_GEN_CALL) | + (intr & DW_IC_INTR_RESTART_DET) + ); + qemu_set_irq(s->irq, level); +} + +static uint32_t dw_i2c_read_ic_data_cmd(DesignWareI2CState *s) +{ + uint32_t value =3D s->rx_fifo[s->rx_cur]; + + if (s->status !=3D DW_I2C_STATUS_RECEIVING) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Attempted to read from RX fifo when not in rece= ive " + "state.\n", DEVICE(s)->canonical_path); + if (s->status !=3D DW_I2C_STATUS_IDLE) { + s->ic_raw_intr_stat &=3D ~DW_IC_INTR_RX_UNDER; + dw_i2c_update_irq(s); + } + return 0; + } + + s->rx_cur =3D (s->rx_cur + 1) % DESIGNWARE_I2C_RX_FIFO_SIZE; + + if (s->ic_rxflr > 0) { + s->ic_rxflr--; + } else { + s->ic_raw_intr_stat &=3D ~DW_IC_INTR_RX_UNDER; + dw_i2c_update_irq(s); + return 0; + } + + if (s->ic_rxflr <=3D s->ic_rx_tl) { + s->ic_raw_intr_stat &=3D ~DW_IC_INTR_RX_FULL; + dw_i2c_update_irq(s); + } + + return value; +} + +static uint64_t dw_i2c_read(void *opaque, hwaddr offset, unsigned size) +{ + uint64_t value =3D 0; + + DesignWareI2CState *s =3D opaque; + + switch (offset) { + case DW_IC_CON: + value =3D s->ic_con; + break; + case DW_IC_TAR: + value =3D s->ic_tar; + break; + case DW_IC_SAR: + qemu_log_mask(LOG_UNIMP, "%s: unsupported read - ic_sar\n", + DEVICE(s)->canonical_path); + value =3D s->ic_sar; + break; + case DW_IC_DATA_CMD: + value =3D dw_i2c_read_ic_data_cmd(s); + break; + case DW_IC_SS_SCL_HCNT: + value =3D s->ic_ss_scl_hcnt; + break; + case DW_IC_SS_SCL_LCNT: + value =3D s->ic_ss_scl_lcnt; + break; + case DW_IC_FS_SCL_HCNT: + value =3D s->ic_fs_scl_hcnt; + break; + case DW_IC_FS_SCL_LCNT: + value =3D s->ic_fs_scl_lcnt; + break; + case DW_IC_INTR_STAT: + value =3D s->ic_raw_intr_stat & s->ic_intr_mask; + break; + case DW_IC_INTR_MASK: + value =3D s->ic_intr_mask; + break; + case DW_IC_RAW_INTR_STAT: + value =3D s->ic_raw_intr_stat; + break; + case DW_IC_RX_TL: + value =3D s->ic_rx_tl; + break; + case DW_IC_TX_TL: + value =3D s->ic_tx_tl; + break; + case DW_IC_CLR_INTR: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_GEN_CALL | + DW_IC_INTR_RESTART_DET | + DW_IC_INTR_START_DET | + DW_IC_INTR_STOP_DET | + DW_IC_INTR_ACTIVITY | + DW_IC_INTR_RX_DONE | + DW_IC_INTR_TX_ABRT | + DW_IC_INTR_RD_REQ | + DW_IC_INTR_TX_OVER | + DW_IC_INTR_RX_OVER | + DW_IC_INTR_RX_UNDER); + s->ic_tx_abrt_source =3D 0; + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_RX_UNDER: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_RX_UNDER); + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_RX_OVER: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_RX_OVER); + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_TX_OVER: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_TX_OVER); + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_RD_REQ: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_RD_REQ); + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_TX_ABRT: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_TX_ABRT); + s->ic_tx_abrt_source =3D 0; + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_RX_DONE: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_RX_DONE); + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_ACTIVITY: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_ACTIVITY); + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_STOP_DET: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_STOP_DET); + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_START_DET: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_START_DET); + dw_i2c_update_irq(s); + break; + case DW_IC_CLR_GEN_CALL: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_GEN_CALL); + dw_i2c_update_irq(s); + break; + case DW_IC_ENABLE: + value =3D s->ic_enable; + break; + case DW_IC_STATUS: + value =3D s->ic_status; + break; + case DW_IC_TXFLR: + value =3D s->ic_txflr; + break; + case DW_IC_RXFLR: + value =3D s->ic_rxflr; + break; + case DW_IC_SDA_HOLD: + value =3D s->ic_sda_hold; + break; + case DW_IC_TX_ABRT_SOURCE: + value =3D s->ic_tx_abrt_source; + break; + case DW_IC_SLV_DATA_NACK_ONLY: + qemu_log_mask(LOG_UNIMP, + "%s: unsupported read - ic_slv_data_nack_only\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_DMA_CR: + qemu_log_mask(LOG_UNIMP, "%s: unsupported read - ic_dma_cr\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_DMA_TDLR: + qemu_log_mask(LOG_UNIMP, "%s: unsupported read - ic_dma_tdlr\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_DMA_RDLR: + qemu_log_mask(LOG_UNIMP, "%s: unsupported read - ic_dma_rdlr\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_SDA_SETUP: + value =3D s->ic_sda_setup; + break; + case DW_IC_ACK_GENERAL_CALL: + qemu_log_mask(LOG_UNIMP, "%s: unsupported read - ic_ack_general_ca= ll\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_ENABLE_STATUS: + value =3D s->ic_enable_status; + break; + case DW_IC_FS_SPKLEN: + value =3D s->ic_fs_spklen; + break; + case DW_IC_CLR_RESTART_DET: + s->ic_raw_intr_stat &=3D ~(DW_IC_INTR_RESTART_DET); + break; + case DW_IC_COMP_PARAM_1: + value =3D s->ic_comp_param_1; + break; + case DW_IC_COMP_VERSION: + value =3D s->ic_comp_version; + break; + case DW_IC_COMP_TYPE: + value =3D s->ic_comp_type; + break; + + /* This register is invalid at this point. */ + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: read from invalid offset 0x%" HWADDR_PRIx "\n", + DEVICE(s)->canonical_path, offset); + break; + } + + trace_dw_i2c_read(DEVICE(s)->canonical_path, offset, value); + + return value; +} + +static void dw_i2c_write_ic_con(DesignWareI2CState *s, uint32_t value) +{ + if (value & DW_IC_CON_RX_FIFO_FULL_HLD_CTRL) { + qemu_log_mask(LOG_UNIMP, + "%s: unsupported ic_con flag - RX_FIFO_FULL_HLD_CTRL= \n", + DEVICE(s)->canonical_path); + } + + if (!(s->ic_enable & DW_IC_ENABLE_ENABLE)) { + s->ic_con =3D value & DW_IC_CON_MASK; + } else { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid setting to ic_con %d when ic_enable[0]= =3D=3D1\n", + DEVICE(s)->canonical_path, value); + } +} + +static void dw_i2c_reset_to_idle(DesignWareI2CState *s) +{ + s->ic_enable_status &=3D ~DW_IC_ENABLE_STATUS_IC_EN; + s->ic_raw_intr_stat &=3D ~DW_IC_INTR_TX_EMPTY; + s->ic_raw_intr_stat &=3D ~DW_IC_INTR_RX_FULL; + s->ic_raw_intr_stat &=3D ~DW_IC_INTR_RX_UNDER; + s->ic_raw_intr_stat &=3D ~DW_IC_INTR_RX_OVER; + s->ic_rxflr =3D 0; + s->ic_status &=3D ~DW_IC_STATUS_ACTIVITY; + s->status =3D DW_I2C_STATUS_IDLE; + dw_i2c_update_irq(s); +} + +static void dw_ic_tx_abort(DesignWareI2CState *s, uint32_t src) +{ + s->ic_tx_abrt_source |=3D src; + s->ic_raw_intr_stat |=3D DW_IC_INTR_TX_ABRT; + dw_i2c_reset_to_idle(s); + dw_i2c_update_irq(s); +} + +static void dw_i2c_write_ic_data_cmd(DesignWareI2CState *s, uint32_t value) +{ + int recv =3D !!(value & DW_IC_DATA_CMD_CMD); + + if (s->status =3D=3D DW_I2C_STATUS_IDLE || + s->ic_raw_intr_stat & DW_IC_INTR_TX_ABRT) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Attempted to write to TX fifo when it is held i= n " + "reset.\n", DEVICE(s)->canonical_path); + return; + } + + /* Send the address if it hasn't been sent yet. */ + if (s->status =3D=3D DW_I2C_STATUS_SENDING_ADDRESS) { + int rv =3D i2c_start_transfer(s->bus, DW_IC_TAR_ADDRESS(s->ic_tar)= , recv); + if (rv) { + dw_ic_tx_abort(s, DW_IC_TX_ABRT_7B_ADDR_NOACK); + return; + } + s->status =3D recv ? DW_I2C_STATUS_RECEIVING : DW_I2C_STATUS_SENDI= NG; + } + + /* Send data */ + if (!recv) { + int rv =3D i2c_send(s->bus, DW_IC_DATA_CMD_DAT(value)); + if (rv) { + i2c_end_transfer(s->bus); + dw_ic_tx_abort(s, DW_IC_TX_ABRT_TXDATA_NOACK); + return; + } + dw_i2c_update_irq(s); + } + + /* Restart command */ + if (value & DW_IC_DATA_CMD_RESTART && s->ic_con & DW_IC_CON_IC_RESTART= _EN) { + s->ic_raw_intr_stat |=3D DW_IC_INTR_RESTART_DET | + DW_IC_INTR_START_DET | + DW_IC_INTR_ACTIVITY; + s->ic_status |=3D DW_IC_STATUS_ACTIVITY; + dw_i2c_update_irq(s); + + if (i2c_start_transfer(s->bus, DW_IC_TAR_ADDRESS(s->ic_tar), recv)= ) { + dw_ic_tx_abort(s, DW_IC_TX_ABRT_7B_ADDR_NOACK); + return; + } + + s->status =3D recv ? DW_I2C_STATUS_RECEIVING : DW_I2C_STATUS_SENDI= NG; + } + + /* Receive data */ + if (recv) { + uint8_t pos =3D (s->rx_cur + s->ic_rxflr) % DESIGNWARE_I2C_RX_FIFO= _SIZE; + + if (s->ic_rxflr < DESIGNWARE_I2C_RX_FIFO_SIZE) { + s->rx_fifo[pos] =3D i2c_recv(s->bus); + s->ic_rxflr++; + } else { + s->ic_raw_intr_stat |=3D DW_IC_INTR_RX_OVER; + dw_i2c_update_irq(s); + } + + if (s->ic_rxflr > s->ic_rx_tl) { + s->ic_raw_intr_stat |=3D DW_IC_INTR_RX_FULL; + dw_i2c_update_irq(s); + } + if (value & DW_IC_DATA_CMD_STOP) { + i2c_nack(s->bus); + } + } + + /* Stop command */ + if (value & DW_IC_DATA_CMD_STOP) { + s->ic_raw_intr_stat |=3D DW_IC_INTR_STOP_DET; + s->ic_status &=3D ~DW_IC_STATUS_ACTIVITY; + s->ic_raw_intr_stat &=3D ~DW_IC_INTR_TX_EMPTY; + i2c_end_transfer(s->bus); + dw_i2c_update_irq(s); + } +} + +static void dw_i2c_write_ic_enable(DesignWareI2CState *s, uint32_t value) +{ + if (value & DW_IC_ENABLE_ENABLE && !(s->ic_con & DW_IC_CON_SLAVE_DISAB= LE)) { + qemu_log_mask(LOG_UNIMP, + "%s: Designware I2C slave mode is not supported.\n", + DEVICE(s)->canonical_path); + return; + } + + s->ic_enable =3D value & DW_IC_ENABLE_MASK; + + if (value & DW_IC_ENABLE_ABORT || value & DW_IC_ENABLE_TX_CMD_BLOCK) { + dw_ic_tx_abort(s, DW_IC_TX_ABRT_USER_ABRT); + return; + } + + if (value & DW_IC_ENABLE_ENABLE) { + s->ic_enable_status |=3D DW_IC_ENABLE_STATUS_IC_EN; + s->ic_status |=3D DW_IC_STATUS_ACTIVITY; + s->ic_raw_intr_stat |=3D DW_IC_INTR_ACTIVITY | + DW_IC_INTR_START_DET | + DW_IC_INTR_TX_EMPTY; + s->status =3D DW_I2C_STATUS_SENDING_ADDRESS; + dw_i2c_update_irq(s); + } else if ((value & DW_IC_ENABLE_ENABLE) =3D=3D 0) { + dw_i2c_reset_to_idle(s); + } + +} + +static void dw_i2c_write_ic_rx_tl(DesignWareI2CState *s, uint32_t value) +{ + /* Note that a value of 0 for ic_rx_tl indicates a threashold of 1. */ + if (value > DESIGNWARE_I2C_RX_FIFO_SIZE - 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid setting to ic_rx_tl %d\n", + DEVICE(s)->canonical_path, value); + s->ic_rx_tl =3D DESIGNWARE_I2C_RX_FIFO_SIZE - 1; + } else { + s->ic_rx_tl =3D value; + } + + if (s->ic_rxflr > s->ic_rx_tl && s->ic_enable & DW_IC_ENABLE_ENABLE) { + s->ic_raw_intr_stat |=3D DW_IC_INTR_RX_FULL; + } else { + s->ic_raw_intr_stat &=3D ~DW_IC_INTR_RX_FULL; + } + dw_i2c_update_irq(s); +} + +static void dw_i2c_write_ic_tx_tl(DesignWareI2CState *s, uint32_t value) +{ + /* + * Note that a value of 0 for ic_tx_tl indicates a threashold of 1. + * However, the tx threshold is not used in the model because commands= are + * always sent out as soon as they are written. + */ + if (value > DESIGNWARE_I2C_TX_FIFO_SIZE - 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid setting to ic_tx_tl %d\n", + DEVICE(s)->canonical_path, value); + s->ic_tx_tl =3D DESIGNWARE_I2C_TX_FIFO_SIZE - 1; + } else { + s->ic_tx_tl =3D value; + } +} + +static void dw_i2c_write(void *opaque, hwaddr offset, uint64_t value, + unsigned size) +{ + DesignWareI2CState *s =3D opaque; + + trace_dw_i2c_write(DEVICE(s)->canonical_path, offset, value); + + /* The order of the registers are their order in memory. */ + switch (offset) { + case DW_IC_CON: + dw_i2c_write_ic_con(s, value); + break; + case DW_IC_TAR: + s->ic_tar =3D value & DW_IC_TAR_MASK; + break; + case DW_IC_SAR: + qemu_log_mask(LOG_UNIMP, "%s: unsupported write - ic_sar\n", + DEVICE(s)->canonical_path); + s->ic_sar =3D value & DW_IC_SAR_MASK; + break; + case DW_IC_DATA_CMD: + dw_i2c_write_ic_data_cmd(s, value); + break; + case DW_IC_SS_SCL_HCNT: + s->ic_ss_scl_hcnt =3D value & DW_IC_SS_SCL_HCNT_MASK; + break; + case DW_IC_SS_SCL_LCNT: + s->ic_ss_scl_lcnt =3D value & DW_IC_SS_SCL_LCNT_MASK; + break; + case DW_IC_FS_SCL_HCNT: + s->ic_fs_scl_hcnt =3D value & DW_IC_FS_SCL_HCNT_MASK; + break; + case DW_IC_FS_SCL_LCNT: + s->ic_fs_scl_lcnt =3D value & DW_IC_FS_SCL_LCNT_MASK; + break; + case DW_IC_INTR_MASK: + s->ic_intr_mask =3D value & DW_IC_INTR_MASK_MASK; + dw_i2c_update_irq(s); + break; + case DW_IC_RX_TL: + dw_i2c_write_ic_rx_tl(s, value); + break; + case DW_IC_TX_TL: + dw_i2c_write_ic_tx_tl(s, value); + break; + case DW_IC_ENABLE: + dw_i2c_write_ic_enable(s, value); + break; + case DW_IC_SDA_HOLD: + s->ic_sda_hold =3D value & DW_IC_SDA_HOLD_MASK; + break; + case DW_IC_SLV_DATA_NACK_ONLY: + qemu_log_mask(LOG_UNIMP, + "%s: unsupported write - ic_slv_data_nack_only\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_DMA_CR: + qemu_log_mask(LOG_UNIMP, "%s: unsupported write - ic_dma_cr\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_DMA_TDLR: + qemu_log_mask(LOG_UNIMP, "%s: unsupported write - ic_dma_tdlr\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_DMA_RDLR: + qemu_log_mask(LOG_UNIMP, "%s: unsupported write - ic_dma_rdlr\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_SDA_SETUP: + s->ic_sda_setup =3D value & DW_IC_SDA_SETUP_MASK; + break; + case DW_IC_ACK_GENERAL_CALL: + qemu_log_mask(LOG_UNIMP, + "%s: unsupported write - ic_ack_general_call\n", + DEVICE(s)->canonical_path); + break; + case DW_IC_FS_SPKLEN: + s->ic_fs_spklen =3D value & DW_IC_FS_SPKLEN_MASK; + break; + + /* This register is invalid at this point. */ + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: write to invalid offset or readonly register 0x= %" + HWADDR_PRIx "\n", + DEVICE(s)->canonical_path, offset); + break; + } +} + +static const MemoryRegionOps designware_i2c_ops =3D { + .read =3D dw_i2c_read, + .write =3D dw_i2c_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + .unaligned =3D false, + }, +}; + +static void designware_i2c_enter_reset(Object *obj, ResetType type) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(obj); + + s->ic_con =3D DW_IC_CON_INIT_VAL; + s->ic_tar =3D DW_IC_TAR_INIT_VAL; + s->ic_sar =3D DW_IC_SAR_INIT_VAL; + s->ic_ss_scl_hcnt =3D DW_IC_SS_SCL_HCNT_INIT_VAL; + s->ic_ss_scl_lcnt =3D DW_IC_SS_SCL_LCNT_INIT_VAL; + s->ic_fs_scl_hcnt =3D DW_IC_FS_SCL_HCNT_INIT_VAL; + s->ic_fs_scl_lcnt =3D DW_IC_FS_SCL_LCNT_INIT_VAL; + s->ic_intr_mask =3D DW_IC_INTR_MASK_INIT_VAL; + s->ic_raw_intr_stat =3D 0; + s->ic_rx_tl =3D 0; + s->ic_tx_tl =3D 0; + s->ic_enable =3D 0; + s->ic_status =3D DW_IC_STATUS_INIT_VAL; + s->ic_txflr =3D 0; + s->ic_rxflr =3D 0; + s->ic_sda_hold =3D DW_IC_SDA_HOLD_INIT_VAL; + s->ic_tx_abrt_source =3D 0; + s->ic_sda_setup =3D DW_IC_SDA_SETUP_INIT_VAL; + s->ic_enable_status =3D 0; + s->ic_fs_spklen =3D DW_IC_FS_SPKLEN_INIT_VAL; + s->ic_comp_param_1 =3D DW_IC_COMP_PARAM_1_INIT_VAL; + s->ic_comp_version =3D DW_IC_COMP_VERSION_INIT_VAL; + s->ic_comp_type =3D DW_IC_COMP_TYPE_INIT_VAL; + + s->rx_cur =3D 0; + s->status =3D DW_I2C_STATUS_IDLE; +} + +static void designware_i2c_hold_reset(Object *obj, ResetType type) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(obj); + + qemu_irq_lower(s->irq); +} + +static const VMStateDescription vmstate_designware_i2c =3D { + .name =3D TYPE_DESIGNWARE_I2C, + .version_id =3D 0, + .minimum_version_id =3D 0, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(ic_con, DesignWareI2CState), + VMSTATE_UINT32(ic_tar, DesignWareI2CState), + VMSTATE_UINT32(ic_sar, DesignWareI2CState), + VMSTATE_UINT32(ic_ss_scl_hcnt, DesignWareI2CState), + VMSTATE_UINT32(ic_ss_scl_lcnt, DesignWareI2CState), + VMSTATE_UINT32(ic_fs_scl_hcnt, DesignWareI2CState), + VMSTATE_UINT32(ic_fs_scl_lcnt, DesignWareI2CState), + VMSTATE_UINT32(ic_intr_mask, DesignWareI2CState), + VMSTATE_UINT32(ic_raw_intr_stat, DesignWareI2CState), + VMSTATE_UINT32(ic_rx_tl, DesignWareI2CState), + VMSTATE_UINT32(ic_tx_tl, DesignWareI2CState), + VMSTATE_UINT32(ic_enable, DesignWareI2CState), + VMSTATE_UINT32(ic_status, DesignWareI2CState), + VMSTATE_UINT32(ic_txflr, DesignWareI2CState), + VMSTATE_UINT32(ic_rxflr, DesignWareI2CState), + VMSTATE_UINT32(ic_sda_hold, DesignWareI2CState), + VMSTATE_UINT32(ic_tx_abrt_source, DesignWareI2CState), + VMSTATE_UINT32(ic_sda_setup, DesignWareI2CState), + VMSTATE_UINT32(ic_enable_status, DesignWareI2CState), + VMSTATE_UINT32(ic_fs_spklen, DesignWareI2CState), + VMSTATE_UINT32(ic_comp_param_1, DesignWareI2CState), + VMSTATE_UINT32(ic_comp_version, DesignWareI2CState), + VMSTATE_UINT32(ic_comp_type, DesignWareI2CState), + VMSTATE_UINT32(status, DesignWareI2CState), + VMSTATE_UINT8_ARRAY(rx_fifo, DesignWareI2CState, + DESIGNWARE_I2C_RX_FIFO_SIZE), + VMSTATE_UINT8(rx_cur, DesignWareI2CState), + VMSTATE_END_OF_LIST(), + }, +}; + +static void designware_i2c_smbus_init(Object *obj) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(obj); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + + sysbus_init_irq(sbd, &s->irq); + + memory_region_init_io(&s->iomem, obj, &designware_i2c_ops, s, + "regs", 4 * KiB); + sysbus_init_mmio(sbd, &s->iomem); + + s->bus =3D i2c_init_bus(DEVICE(s), "i2c-bus"); +} + +static void designware_i2c_class_init(ObjectClass *klass, const void *data) +{ + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->desc =3D "Designware I2C"; + dc->vmsd =3D &vmstate_designware_i2c; + rc->phases.enter =3D designware_i2c_enter_reset; + rc->phases.hold =3D designware_i2c_hold_reset; +} + +static const TypeInfo designware_i2c_types[] =3D { + { + .name =3D TYPE_DESIGNWARE_I2C, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(DesignWareI2CState), + .class_init =3D designware_i2c_class_init, + .instance_init =3D designware_i2c_smbus_init, + }, +}; +DEFINE_TYPES(designware_i2c_types); diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig index 596a7a3165ad..d3f394edeb9c 100644 --- a/hw/i2c/Kconfig +++ b/hw/i2c/Kconfig @@ -18,6 +18,10 @@ config ARM_SBCON_I2C bool select BITBANG_I2C =20 +config DESIGNWARE_I2C + bool + select I2C + config ACPI_SMBUS bool select SMBUS diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build index c459adcb596c..88aea35662dd 100644 --- a/hw/i2c/meson.build +++ b/hw/i2c/meson.build @@ -11,6 +11,7 @@ i2c_ss.add(when: 'CONFIG_MPC_I2C', if_true: files('mpc_i2= c.c')) i2c_ss.add(when: 'CONFIG_ALLWINNER_I2C', if_true: files('allwinner-i2c.c')) i2c_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('microbit_i2c.c')) i2c_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_smbus.c')) +i2c_ss.add(when: 'CONFIG_DESIGNWARE_I2C', if_true: files('designware_i2c.c= ')) i2c_ss.add(when: 'CONFIG_SMBUS_EEPROM', if_true: files('smbus_eeprom.c')) i2c_ss.add(when: 'CONFIG_ARM_SBCON_I2C', if_true: files('arm_sbcon_i2c.c')) i2c_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_i2c.c')) diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events index 1ad0e95c0e60..8a78d2d3c8de 100644 --- a/hw/i2c/trace-events +++ b/hw/i2c/trace-events @@ -61,3 +61,7 @@ pca954x_read_data(uint8_t value) "PCA954X read data: 0x%0= 2x" =20 imx_i2c_read(const char *id, const char *reg, uint64_t ofs, uint64_t value= ) "%s:[%s (0x%" PRIx64 ")] -> 0x%02" PRIx64 imx_i2c_write(const char *id, const char *reg, uint64_t ofs, uint64_t valu= e) "%s:[%s (0x%" PRIx64 ")] <- 0x%02" PRIx64 + +# designware_i2c.c +dw_i2c_read(const char *id, uint64_t ofs, uint64_t value) "%s: offset 0x%0= 2" PRIx64 " -> value: 0x%02" PRIx64 +dw_i2c_write(const char *id, uint64_t ofs, uint64_t value) "%s: offset: 0x= %02" PRIx64 " <- value: 0x%02" PRIx64 --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749737450455.61248611687233; Mon, 20 Apr 2026 22:35:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3jb-0000QE-D2; Tue, 21 Apr 2026 01:33:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3jX-0000Pd-Og for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:15 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3jW-0004P0-42 for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:15 -0400 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-356337f058aso2458593a91.2 for ; Mon, 20 Apr 2026 22:33:13 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749592; x=1777354392; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=GEoNIH1lDbG3wacvRNg9ITqfxSNVJqno7NS+0+CTsdk=; b=Zx/F43IsTX6YCJ5KU5L2OCLuLMwc5wJ6Tcw+cRNHeGc1kb44bbapEYN44TtRs484Xi RLE69Kts54kcIvMqq0ZNQMG6scYUvyVgOCqHvByHvG1y93nWQWi0qxkEP8qcDLDmWPwg ymCHErXyWLAhbPDoauzi10SfWcAG6SMsWPMT89JBJ020k7/Jovhx0UFqt7I2DQF957Fl o+drbJvDOpvYNQ2HEOoWEUoD5bsHNDa1I1Ih9t3hE1K2ITIsP2LOrAZANLqvKoc0TXuv eYZv2VthIA62X/9Qx13btmDsrkUUZp7vtxu9ZzmZwKtqAOYJOOU0/e3iAWri2iXuyMDW mWnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749592; x=1777354392; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=GEoNIH1lDbG3wacvRNg9ITqfxSNVJqno7NS+0+CTsdk=; b=gOZAB4ePlWMbDbTz3iADdG8A4iRPXRUn2s6iKWwM6BFqPO6BLraFoSqY6RCAZCBEEY BedHKwB4sPTgKHRHOXeyfxzNqHGABRbbFa5BN7eDYeot9/Jp+/TE9VM7IKrau2U6WdES Z680SXifWRG44hsejxGiFZGz92x0xlk+wswUybfAAGhrcd8ORpdqL2x58cjxD/XViEJ4 ry7zFcWZjh3+rFVgFuvbWYpqaN2v88/LO7BUPNY77qJihzz90uXJAtKqzW+wGNRf9Ck5 sY5RI1w/5D1J3C+qFYJ7se3kbmeW0ubLMny38onWBh8tYy+x20CvOQxYfNtX4d3iExW9 8Ecw== X-Forwarded-Encrypted: i=1; AFNElJ+zWELj63EvdZZkCJfYFf1hSn+wHd6oZPtihdIFy9oUDO6qzq1ele710fRo0yU6at+MDVdL09RSNhnx@nongnu.org X-Gm-Message-State: AOJu0YyAXV3DJ1hUoKXa2BW7MCygaLHb0MPhOoUh5RBsdqHwa26c4PHR ncWV8Wt4Dwko3yylJSHD27SbeJrvMOGwK8J83bYPhuB6NZFGYIeqAEW5 X-Gm-Gg: AeBDieuDMxn+BQaogjMLpBfDRhNHFqCnUImq+Ya0/4qwiKiqK4OXs6if3NVndVh4d6F JG2d9ViI2Comqc/H0wQtC9FsglXDgihPn0ZfJ5mkarlYe52D4t3y6n2Fl3MnvtmubjicJgcHD2N N/9VubCs3FFJnMtHZr4kTT+KG6jO9lPH+jqAKbIAsj1q68QcBCt5TE8Gjo+JXipqxhXNOqrQaGt SvJqLgYhR/tLrreaQBliXXJjQJyYCuE4kdhMNIoovmWKjBc3YEsMActibngCQsRAZ0pM4nq66z6 8bPBcTUpeXA8l1CY2jxy73eCiUT4v3MT0BTn7/80CzlWWlS/A/KQjuE3AVtDh+qzj0LL/Z/eYXi 2OypTNWsKvMpmLRidEZ++Bbcgq25gwRN9jc/CGMqib+fJzegD09DsnQAOs5zDjQcPrJG6Ne7rex gWiHmglPYpjzIrIhaKfKYbboxj2reOhqWDtf27HbiFV7v7VFEWdw4qsUPtaAvXRUhCv+KG2ANDG Dioz0GBVoWUp5dNj9Z4BNmXrncOberyz+OXaQ== X-Received: by 2002:a17:90b:5865:b0:35d:a557:e41 with SMTP id 98e67ed59e1d1-3614046f978mr17751470a91.14.1776749592559; Mon, 20 Apr 2026 22:33:12 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Nicholas Piggin , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 02/13] hw/riscv/boot: Describe discontiguous memory in boot_info Date: Tue, 21 Apr 2026 15:31:27 +1000 Message-ID: <20260421053140.752059-3-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x1030.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749738483154100 Content-Type: text/plain; charset="utf-8" From: Nicholas Piggin Machines that have discontiguous memory may need to adjust where firmware and images are loaded at boot. Provide an interface for machines to describe a discontiguous low/high RAM scheme for this purpose. Signed-off-by: Nicholas Piggin Reviewed-by: Daniel Henrique Barboza Signed-off-by: Joel Stanley --- include/hw/riscv/boot.h | 7 +++++++ hw/riscv/boot.c | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index f00b3ca12245..115e3222174f 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -28,6 +28,10 @@ #define RISCV64_BIOS_BIN "opensbi-riscv64-generic-fw_dynamic.bin" =20 typedef struct RISCVBootInfo { + /* First contiguous RAM region. If size is zero then assume entire RAM= */ + hwaddr ram_low_start; + hwaddr ram_low_size; + ssize_t kernel_size; hwaddr image_low_addr; hwaddr image_high_addr; @@ -43,6 +47,9 @@ bool riscv_is_32bit(RISCVHartArrayState *harts); char *riscv_plic_hart_config_string(int hart_count); =20 void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts); +void riscv_boot_info_init_discontig_mem(RISCVBootInfo *info, + RISCVHartArrayState *harts, + hwaddr start, hwaddr size); vaddr riscv_calc_kernel_start_addr(RISCVBootInfo *info, hwaddr firmware_end_addr); hwaddr riscv_find_and_load_firmware(MachineState *machine, diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 9086793b7a7b..5c9547429a36 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -69,11 +69,22 @@ char *riscv_plic_hart_config_string(int hart_count) =20 void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts) { + info->ram_low_start =3D 0; + info->ram_low_size =3D 0; info->kernel_size =3D 0; info->initrd_size =3D 0; info->is_32bit =3D riscv_is_32bit(harts); } =20 +void riscv_boot_info_init_discontig_mem(RISCVBootInfo *info, + RISCVHartArrayState *harts, + hwaddr start, hwaddr size) +{ + riscv_boot_info_init(info, harts); + info->ram_low_start =3D start; + info->ram_low_size =3D size; +} + vaddr riscv_calc_kernel_start_addr(RISCVBootInfo *info, hwaddr firmware_end_addr) { if (info->is_32bit) { --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749635128512.902447380201; Mon, 20 Apr 2026 22:33:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3jf-0000Rr-8b; Tue, 21 Apr 2026 01:33:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3jd-0000RC-LI for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:21 -0400 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3jb-0004Ps-BR for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:21 -0400 Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-35fb7c1a455so1532739a91.3 for ; Mon, 20 Apr 2026 22:33:18 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749597; x=1777354397; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=qMiQ/2bg5K29I5LaNwUIpqsoMgOLYq0sBwrJOA2TBI0=; b=DSeSo6spCvqZ4vUzbCpK8shAsDrOOWZ9MWRTHtK099TNR2m/4o4FbuU/C46iPVwxrU zamSbpln8hAa24z/DyyXobKrcwcIOCBroc33SGGLWbIcEWH0i/ZejdilMjbf5y7xHVc9 JyPk05c2+G4/ckZ3TtZdVbMnnIFB2HK5Ox8GV2ij8NUJoTuZpSlOOPDTye8zJz8HaErL /1MtPI1qY3hYy2Ev/iwecE3W7b5A0bmR2KEmvuKr1fZeSd6/rG96pWKYTLvW3OZuyGdn jkQbnVPSD9C5VES8aSJTM1QHBrLICwSwrb+QO7QNLoHmNVzlaQS7msd5mXDcmk6vUrw5 Ez3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749597; x=1777354397; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=qMiQ/2bg5K29I5LaNwUIpqsoMgOLYq0sBwrJOA2TBI0=; b=JK39AQSnLFE2rdy4fFAF18908MNtHZ8RuMMw4ErIi930Qq/HH8oVCkPEJF8MJ7Tnyi exRsM/4g6SW6gchadQNRQWb3bJlcsLg5LS4+p91EAmBDSYOMUbLdDmGWpDtoUt3/wgIz gE1c8kCqCDiqd6gY38clzJvWq9DHRajLiYGlA1+H+9JlieWpS8t6LVDl16QwjzOcAe5r 4MGN9W+hwNhGuQUZ9ddWokytcY4IgIpINtMy2jia4F5yTaZXu6obWbM0Mv20d9aU3LDp Et2JDh6ea1Et8i+XtGdagt/MFuRZ1ulwmU+KXtNR7gmG3ZIR0/XyiFvtAEiQyj+k2lzv exMw== X-Forwarded-Encrypted: i=1; AFNElJ/lx/DmvF8ZgEgWtdQTLXQCOoDaVyAm9UFTjS65TC9PlQWxejD6f/vFqDJ5ZtZbvGjZARQDJda1AroK@nongnu.org X-Gm-Message-State: AOJu0YzWqGxd4IqkwxBzB+lN4y5ie/Ppbp4uCNGNvPlIPVR/924An4am NcAd3dzdBUdjvU/xCKnKRn5V2uH42xQw6rKmec6iENsYcfQ6n4ezVEoJtVBLyw== X-Gm-Gg: AeBDiesfzDHHO3Jw5ToSmBFeatwK1ub0BEVAAJ6RQCyOAjH3MpDoIA9L/WACA6urya7 r1HCzEJGX34+P1NzFGXLn8uqRvhj6uefWqyV6h3qhidVakvjfKF4e3bN1DJAk6cRfqS8F8ZkFNJ 1BkgYe4Iy2SeSBlxbZzeB3Wk9ZoEtvftRdbC7G/NUF+pHEvYEdpQK+WVf35FVteXexh5UElTG0j 11PKqWFutVd0KJNCtsCxj7hZp7hBmxWdnNPlX6prePIrecX7BlHYPQYvpPdH8k3UM5wJGo/UN/H 0B0O4hmKD+EWlS2HRIIGvK8dka13gwxK1+OKa+IgZyyy2AhoXcCi57KvOK9ZkcWUnK0z1d/ghFG VpKQg4mge48+9hTo+/bPAilTNS8j4yhT3otB8N1Gbzw6w8AQ7EqyJ8IdIV4Q4CpK/d9JiJMoEx9 OBZCtlki0EYYXQTQHj3vMounBm74dStMsxSbNjXdLgjfrGnOiu648bf0xFfujXFtwUF3rK1fZ2E HZZWzN2SK0xlk2DjKFrWdTsesXdwg32h+r2tw== X-Received: by 2002:a17:90b:55cc:b0:35e:30bc:804d with SMTP id 98e67ed59e1d1-3614048adcdmr16132017a91.15.1776749596982; Mon, 20 Apr 2026 22:33:16 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Nicholas Piggin , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 03/13] hw/riscv/boot: Account for discontiguous memory when loading firmware Date: Tue, 21 Apr 2026 15:31:28 +1000 Message-ID: <20260421053140.752059-4-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1032; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x1032.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749639808158500 Content-Type: text/plain; charset="utf-8" From: Nicholas Piggin This loads firmware into the first (low) memory range, accounting for machines having discontiguous memory regions. Signed-off-by: Nicholas Piggin Reviewed-by: Daniel Henrique Barboza Signed-off-by: Joel Stanley --- v3: Call riscv_boot_info_init before riscv_find_and_load_firmware in sifive_u --- include/hw/riscv/boot.h | 5 ++++- hw/riscv/boot.c | 18 ++++++++++++------ hw/riscv/microchip_pfsoc.c | 6 ++++-- hw/riscv/opentitan.c | 6 ++++-- hw/riscv/shakti_c.c | 6 +++++- hw/riscv/sifive_u.c | 6 ++++-- hw/riscv/spike.c | 6 ++++-- hw/riscv/virt.c | 7 ++++--- hw/riscv/xiangshan_kmh.c | 6 +++++- 9 files changed, 46 insertions(+), 20 deletions(-) diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 115e3222174f..fb90bf12399e 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -53,13 +53,16 @@ void riscv_boot_info_init_discontig_mem(RISCVBootInfo *= info, vaddr riscv_calc_kernel_start_addr(RISCVBootInfo *info, hwaddr firmware_end_addr); hwaddr riscv_find_and_load_firmware(MachineState *machine, + RISCVBootInfo *info, const char *default_machine_firmware, hwaddr *firmware_load_addr, symbol_fn_t sym_cb); const char *riscv_default_firmware_name(RISCVHartArrayState *harts); char *riscv_find_firmware(const char *firmware_filename, const char *default_machine_firmware); -hwaddr riscv_load_firmware(const char *firmware_filename, +hwaddr riscv_load_firmware(MachineState *machine, + RISCVBootInfo *info, + const char *firmware_filename, hwaddr *firmware_load_addr, symbol_fn_t sym_cb); void riscv_load_kernel(MachineState *machine, diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 5c9547429a36..3ea95c175c14 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -145,6 +145,7 @@ char *riscv_find_firmware(const char *firmware_filename, } =20 hwaddr riscv_find_and_load_firmware(MachineState *machine, + RISCVBootInfo *info, const char *default_machine_firmware, hwaddr *firmware_load_addr, symbol_fn_t sym_cb) @@ -157,7 +158,8 @@ hwaddr riscv_find_and_load_firmware(MachineState *machi= ne, =20 if (firmware_filename) { /* If not "none" load the firmware */ - firmware_end_addr =3D riscv_load_firmware(firmware_filename, + firmware_end_addr =3D riscv_load_firmware(machine, info, + firmware_filename, firmware_load_addr, sym_cb= ); g_free(firmware_filename); } @@ -165,10 +167,13 @@ hwaddr riscv_find_and_load_firmware(MachineState *mac= hine, return firmware_end_addr; } =20 -hwaddr riscv_load_firmware(const char *firmware_filename, +hwaddr riscv_load_firmware(MachineState *machine, + RISCVBootInfo *info, + const char *firmware_filename, hwaddr *firmware_load_addr, symbol_fn_t sym_cb) { + uint64_t mem_size =3D info->ram_low_size ?: machine->ram_size; uint64_t firmware_entry, firmware_end; ssize_t firmware_size; =20 @@ -197,7 +202,7 @@ hwaddr riscv_load_firmware(const char *firmware_filenam= e, =20 firmware_size =3D load_image_targphys_as(firmware_filename, *firmware_load_addr, - current_machine->ram_size, NULL, + mem_size, NULL, NULL); =20 if (firmware_size > 0) { @@ -212,7 +217,7 @@ hwaddr riscv_load_firmware(const char *firmware_filenam= e, static void riscv_load_initrd(MachineState *machine, RISCVBootInfo *info) { const char *filename =3D machine->initrd_filename; - uint64_t mem_size =3D machine->ram_size; + uint64_t mem_size =3D info->ram_low_size ?: machine->ram_size; void *fdt =3D machine->fdt; hwaddr start, end; ssize_t size; @@ -258,6 +263,7 @@ void riscv_load_kernel(MachineState *machine, bool load_initrd, symbol_fn_t sym_cb) { + uint64_t mem_size =3D info->ram_low_size ?: machine->ram_size; const char *kernel_filename =3D machine->kernel_filename; ssize_t kernel_size; void *fdt =3D machine->fdt; @@ -289,7 +295,7 @@ void riscv_load_kernel(MachineState *machine, } =20 kernel_size =3D load_image_targphys_as(kernel_filename, kernel_start_a= ddr, - current_machine->ram_size, NULL, = NULL); + mem_size, NULL, NULL); if (kernel_size > 0) { info->kernel_size =3D kernel_size; info->image_low_addr =3D kernel_start_addr; @@ -385,7 +391,7 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwadd= r dram_size, dtb_start =3D QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); =20 if (dtb_start_limit && (dtb_start < dtb_start_limit)) { - error_report("No enough memory to place DTB after kernel/initrd"); + error_report("Not enough memory to place DTB after kernel/initrd"); exit(1); } =20 diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 743f31f00578..1d1ddb05a882 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -618,18 +618,20 @@ static void microchip_icicle_kit_machine_init(Machine= State *machine) firmware_load_addr =3D RESET_VECTOR; } =20 + riscv_boot_info_init(&boot_info, &s->soc.u_cpus); + /* Load the firmware if necessary */ firmware_end_addr =3D firmware_load_addr; if (firmware_name) { char *filename =3D riscv_find_firmware(firmware_name, NULL); if (filename) { - firmware_end_addr =3D riscv_load_firmware(filename, + firmware_end_addr =3D riscv_load_firmware(machine, &boot_info, + filename, &firmware_load_addr, N= ULL); g_free(filename); } } =20 - riscv_boot_info_init(&boot_info, &s->soc.u_cpus); if (machine->kernel_filename) { kernel_start_addr =3D riscv_calc_kernel_start_addr(&boot_info, firmware_end_addr= ); diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c index 309125e854bc..8cd660dd4154 100644 --- a/hw/riscv/opentitan.c +++ b/hw/riscv/opentitan.c @@ -99,12 +99,14 @@ static void opentitan_machine_init(MachineState *machin= e) memory_region_add_subregion(sys_mem, memmap[IBEX_DEV_RAM].base, machine->ram); =20 + riscv_boot_info_init(&boot_info, &s->soc.cpus); + if (machine->firmware) { hwaddr firmware_load_addr =3D memmap[IBEX_DEV_RAM].base; - riscv_load_firmware(machine->firmware, &firmware_load_addr, NULL); + riscv_load_firmware(machine, &boot_info, machine->firmware, + &firmware_load_addr, NULL); } =20 - riscv_boot_info_init(&boot_info, &s->soc.cpus); if (machine->kernel_filename) { riscv_load_kernel(machine, &boot_info, memmap[IBEX_DEV_RAM].base, diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c index 49a39b30212d..eb720d9cdf5d 100644 --- a/hw/riscv/shakti_c.c +++ b/hw/riscv/shakti_c.c @@ -45,6 +45,7 @@ static void shakti_c_machine_state_init(MachineState *mst= ate) { ShaktiCMachineState *sms =3D RISCV_SHAKTI_MACHINE(mstate); MemoryRegion *system_memory =3D get_system_memory(); + RISCVBootInfo boot_info; hwaddr firmware_load_addr =3D shakti_c_memmap[SHAKTI_C_RAM].base; =20 /* Initialize SoC */ @@ -57,8 +58,11 @@ static void shakti_c_machine_state_init(MachineState *ms= tate) shakti_c_memmap[SHAKTI_C_RAM].base, mstate->ram); =20 + riscv_boot_info_init(&boot_info, &sms->soc.cpus); + if (mstate->firmware) { - riscv_load_firmware(mstate->firmware, &firmware_load_addr, NULL); + riscv_load_firmware(mstate, &boot_info, mstate->firmware, + &firmware_load_addr, NULL); } =20 /* ROM reset vector */ diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 7ec67b256514..dda8687bfdd8 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -589,11 +589,13 @@ static void sifive_u_machine_init(MachineState *machi= ne) break; } =20 + riscv_boot_info_init(&boot_info, &s->soc.u_cpus); + firmware_name =3D riscv_default_firmware_name(&s->soc.u_cpus); - firmware_end_addr =3D riscv_find_and_load_firmware(machine, firmware_n= ame, + firmware_end_addr =3D riscv_find_and_load_firmware(machine, &boot_info, + firmware_name, &start_addr, NULL); =20 - riscv_boot_info_init(&boot_info, &s->soc.u_cpus); if (machine->kernel_filename) { kernel_start_addr =3D riscv_calc_kernel_start_addr(&boot_info, firmware_end_addr= ); diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 35c696f891d8..6ee915a8ba4e 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -281,9 +281,12 @@ static void spike_board_init(MachineState *machine) } } =20 + riscv_boot_info_init(&boot_info, &s->soc[0]); + /* Load firmware */ if (firmware_name) { - firmware_end_addr =3D riscv_load_firmware(firmware_name, + firmware_end_addr =3D riscv_load_firmware(machine, &boot_info, + firmware_name, &firmware_load_addr, htif_symbol_callback); g_free(firmware_name); @@ -293,7 +296,6 @@ static void spike_board_init(MachineState *machine) create_fdt(s, memmap, riscv_is_32bit(&s->soc[0]), htif_custom_base); =20 /* Load kernel */ - riscv_boot_info_init(&boot_info, &s->soc[0]); if (machine->kernel_filename) { kernel_start_addr =3D riscv_calc_kernel_start_addr(&boot_info, firmware_end_addr= ); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index a1c323e66dfd..4501d5581b62 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1457,7 +1457,10 @@ static void virt_machine_done(Notifier *notifier, vo= id *data) } } =20 - firmware_end_addr =3D riscv_find_and_load_firmware(machine, firmware_n= ame, + riscv_boot_info_init(&boot_info, &s->soc[0]); + + firmware_end_addr =3D riscv_find_and_load_firmware(machine, &boot_info, + firmware_name, &start_addr, NULL); =20 pflash_blk0 =3D pflash_cfi01_get_blk(s->flash[0]); @@ -1480,8 +1483,6 @@ static void virt_machine_done(Notifier *notifier, voi= d *data) } } =20 - riscv_boot_info_init(&boot_info, &s->soc[0]); - if (machine->kernel_filename && !kernel_entry) { kernel_start_addr =3D riscv_calc_kernel_start_addr(&boot_info, firmware_end_addr= ); diff --git a/hw/riscv/xiangshan_kmh.c b/hw/riscv/xiangshan_kmh.c index 436e51c1c593..247a0b5d1f21 100644 --- a/hw/riscv/xiangshan_kmh.c +++ b/hw/riscv/xiangshan_kmh.c @@ -166,6 +166,7 @@ static void xiangshan_kmh_machine_init(MachineState *ma= chine) const MemMapEntry *memmap =3D xiangshan_kmh_memmap; MemoryRegion *system_memory =3D get_system_memory(); hwaddr start_addr =3D memmap[XIANGSHAN_KMH_DRAM].base; + RISCVBootInfo boot_info; =20 /* Initialize SoC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, @@ -177,13 +178,16 @@ static void xiangshan_kmh_machine_init(MachineState *= machine) memmap[XIANGSHAN_KMH_DRAM].base, machine->ram); =20 + riscv_boot_info_init(&boot_info, &s->soc.cpus); + /* ROM reset vector */ riscv_setup_rom_reset_vec(machine, &s->soc.cpus, start_addr, memmap[XIANGSHAN_KMH_ROM].base, memmap[XIANGSHAN_KMH_ROM].size, 0, 0); if (machine->firmware) { - riscv_load_firmware(machine->firmware, &start_addr, NULL); + riscv_load_firmware(machine, &boot_info, machine->firmware, + &start_addr, NULL); } =20 /* Note: dtb has been integrated into firmware(OpenSBI) when compiling= */ --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749634997471.4812436644861; Mon, 20 Apr 2026 22:33:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3ji-0000Tb-Tn; Tue, 21 Apr 2026 01:33:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3jg-0000SF-JE for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:25 -0400 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3jf-0004QO-0s for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:24 -0400 Received: by mail-pj1-x102b.google.com with SMTP id 98e67ed59e1d1-35fc258aaa4so2359402a91.2 for ; Mon, 20 Apr 2026 22:33:22 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749602; x=1777354402; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=UOf+lRYb8kBYFx9GhbOqJp0Zp/ZahLQSb+Dx2wr2ujs=; b=O92i3bQT0LnSoQ95Y8TW9sugIOMFp2usuxLSRmUwiqd1ZZSW0ai6zfyOVt4xMmcvrr Lz9cC7mn/ghH8/arYX3H3TO0ghrFqdNmBcS7/FMV614mhFf9OcTo9i/aF9oj/DHaGKdu joOwO2SUq4kTWAIaJpwi3JmoEr9oOG2b0RgHDprGB9k6qdtoKxZ7IifWuCu+Qj1uOz/W B0qUHSI2TGFzUqhiANCeYgrnCArJkzOYVvjkto/169UBwtga8GxWs7JmaomWfXMWcU5Y zAEpGMmTC2UM+tcQiAOjTAaXVmotIZcgUZWXiLEP8th/U91EYftknczcB86KLdZsQv5H E8hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749602; x=1777354402; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=UOf+lRYb8kBYFx9GhbOqJp0Zp/ZahLQSb+Dx2wr2ujs=; b=IkyxSgdio4xn3d/KvtK+J9MPknjDiW8/HoHMq80nT+OcGtCI4VR28PJKEvL3h2BRxM 5BX/ERRb6R+btdDwA+YihrZYmQFaemtC7Gq91V2586U0BFagT4p/5WdMDi17Mxn3nnV4 fe0ov3gw5PGUgFcCZbag2HUijbL2LFkJfLZVqgEdtTa8hp97j1e9GjtvxkxsBTOtY/+Y K1Pg42WhMHwMUXSnvFzKppEvSV15s6kh2kmWXU0uFsIUAPaWgz8mnyT+8GsHvJ3c6F79 KoQVxnvIjEQq2bWhQ5771WQdmsB1ZxOmYGcNLOT5EMM4x3AAePwfZ4BxwA1MXO4uSShR Iy7g== X-Forwarded-Encrypted: i=1; AFNElJ/ZkYlv1TXrtKx3SUwz6DSZPHjqvxVVLZ9ubS1nj4ZsBOMIYFhNT+5I7IyYem0kY+XzTvSlU9rsgjx/@nongnu.org X-Gm-Message-State: AOJu0Yzi4JjcqmjSMqO/OzgGJzd1b3BKfXIpshTcEs6bUV9mRX5EL2Oa 7aY1y5wrmsx0ysyydSukgor81AR7TEiPyVtaDF62oMguYs/ozZsSA+tf X-Gm-Gg: AeBDietmlcwFPms1xYMG5ClEYG4pUkgRPwhGCwnGouTygImkyVHMSyxmj/2LBkrSXWm OORXM7i+jcXIumlSnQtXF1/nP+HuYOScX46XW9yLQ90QEkkzyT03csaRUD5tJ2VUwSYyOTAPS8n c0fEj7/NWTjL8twf3CaRlXLUWTYQChZRYb52f6bFGUzHutFE2UJQxjuw+9MwSCxboA0yNj1MrI5 KrV2cwzQtxpBpMxVlaT5gPUDu+PxkYCimGADGXXmgaWqQrm4wF19gPatEEL9XPLPE1cb/JZCcj6 SD7ngpI8N/K6Ubtl/edT+PPbZck3ztNYHZnbLLWWqRGYPCu4mBq92J/3cOclza6idjXTujizlPP Hne1V81EJ4PxSE4lb8nAwRGTefy33R9IqSeaIh6S9XIlfn3zTs9xYeYs/Mb72OsW6Bwl/IasG44 /Tksc/NU96KCbvtxHOMcjx+NbhGn7LQTPFiqCTJLsMzzYTaC+lIAleNl2YP30dFq48ghlDGlEqc Z7VyzXnMt2UmQk06t1zSUNF6ST2iDLFAHL7eVvywQtX+pZ7 X-Received: by 2002:a17:90b:2fc8:b0:35e:5a4c:9069 with SMTP id 98e67ed59e1d1-3614048a431mr16791897a91.14.1776749601522; Mon, 20 Apr 2026 22:33:21 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Nicholas Piggin , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 04/13] hw/riscv/boot: Provide a simple halting payload Date: Tue, 21 Apr 2026 15:31:29 +1000 Message-ID: <20260421053140.752059-5-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102b; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x102b.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749639740158500 Content-Type: text/plain; charset="utf-8" From: Nicholas Piggin OpenSBI hangs before any console output if the domain init code sees the next stage is not in an executable region. If no kernel payload is provided to QEMU, the next stage address is NULL, and the riscv virt machine memory map ends up covering the 0 address with the catch all S-mode RWX region and so OpenSBI prints console messages and does not hang until the next stage boot. The soon to be added Tenstorrent Atlantis board address map has RAM starting at 0 and it loads OpenSBI there, so it is M-mode and not accessible by S-mode, tripping the early check and hang. Add a helper to set up a simple payload that gets OpenSBI messages to console. Signed-off-by: Nicholas Piggin Reviewed-by: Daniel Henrique Barboza Signed-off-by: Joel Stanley --- v3: MachineState argument was unused --- include/hw/riscv/boot.h | 1 + hw/riscv/boot.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index fb90bf12399e..a1eb377474b9 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -78,6 +78,7 @@ void riscv_setup_rom_reset_vec(MachineState *machine, RIS= CVHartArrayState *harts hwaddr rom_base, hwaddr rom_size, uint64_t kernel_entry, uint64_t fdt_load_addr); +void riscv_setup_halting_payload(RISCVBootInfo *info, hwaddr addr); void riscv_rom_copy_firmware_info(MachineState *machine, RISCVHartArrayState *harts, hwaddr rom_base, diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 3ea95c175c14..3a97fd1441f7 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -518,6 +518,26 @@ void riscv_setup_rom_reset_vec(MachineState *machine, = RISCVHartArrayState *harts kernel_entry); } =20 +/* Simple payload so OpenSBI does not hang early with no output */ +void riscv_setup_halting_payload(RISCVBootInfo *info, hwaddr addr) +{ + int i; + uint32_t payload_vec[] =3D { + 0x10500073, /* 1: wfi */ + 0xffdff06f, /* j 1b */ + }; + /* copy in the payload vector in little_endian byte order */ + for (i =3D 0; i < ARRAY_SIZE(payload_vec); i++) { + payload_vec[i] =3D cpu_to_le32(payload_vec[i]); + } + rom_add_blob_fixed_as("mrom.payload", payload_vec, sizeof(payload_vec), + addr, &address_space_memory); + + info->kernel_size =3D sizeof(payload_vec); + info->image_low_addr =3D addr; + info->image_high_addr =3D info->image_low_addr + info->kernel_size; +} + void riscv_setup_direct_kernel(hwaddr kernel_addr, hwaddr fdt_addr) { CPUState *cs; --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749691986316.28047434513076; Mon, 20 Apr 2026 22:34:51 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3jn-0000Ui-W5; Tue, 21 Apr 2026 01:33:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3jm-0000Tw-5u for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:30 -0400 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3jk-0004Qp-1S for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:29 -0400 Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-35f9ab079bdso2375591a91.2 for ; Mon, 20 Apr 2026 22:33:27 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749607; x=1777354407; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=ydffm29M3UFYZDVjOj+sDFBPSA4JBsRXfTOmE1aAgI4=; b=O0pTDuvJy2q/Tkox5NwRWV2IpC651Oa7W4WegGlseic9sa3bmLiLmOlTk6Ar0XtLZg 6RqYa8qZE7LWvZNZl1bfYER/mZJ1qwGRioE54DZvZnOpX0JTgVRXWazdGX0A6fBNZIy9 Fys0Vdc9mNfXDsibxY9xmpEUwYzy/yBdmoUWMMpKnReGc9175bnKDu99qSK0QDrAydXi ni2XhE46hpLNkEGOmqVm2xi84mJCcljxTDFnorFiZW1AvYh50/x8mJILfoZ+/1TR3KFK M+6YSGmVZPPPcGRrXVfCR7EdCrlGdIPsQ64NhphKOv15AJkBk+6QLtqdEsfsBjbQjhOk nVwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749607; x=1777354407; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ydffm29M3UFYZDVjOj+sDFBPSA4JBsRXfTOmE1aAgI4=; b=TN0GoX73gDOt72m7EvT2sPQUMRlljtErjaQnyqmEAnA6ulViLylwzVpf7ILsBLghHy 1djxMI/4977KfX5rdxlUpoQ8qH1uh2WT5fahuJwLe/zomsFbN1/KcKojOuodGvtoLOrI DG0wOVHGZskZTad8QHTgTWm3HfP/6ZU72Qoys4x+T/QYaK+77PSXLGEa4EJdcsF2Is2c LzVNrrQgyr1+msjM4gCw8rbBhFeYk3oJeJtjnu4q087lDq4rqjpXV50rSOzSJQQ/YGwk qyS9S+vGuJVKEwBRrQQ11jmTHqrk+pqkWTMV2ByIopnbtR2QFG89g5iTTAVOx2IJf+Wg T1tw== X-Forwarded-Encrypted: i=1; AFNElJ/9+QkEmMfQQ0vGxpShzbYmCJPA7HhiTyCuaClvdNVjcs5760DpyaQobkk7/eyiH8BzmVBcps+j4Nip@nongnu.org X-Gm-Message-State: AOJu0YyJr8yxOsotwgLxvyA8ksOh7hSLyWUe7l7NIr3sD/S3MvfMIOiy r85bvSctaEY1//5fdKPQDbA+zKlfthFP/26Zgl5DwCMTfOjVJr+7Od3e X-Gm-Gg: AeBDieuu4+2kWx1YhadLov9GmHe/JYdTQC/CQ0G/1eq8Bl+pEeiGcNFuDseLCFgK2u7 j1yrt4058I6vTmfLoRqXZSMh0GDigCAo2BRoK+HVcy1aPa4cOrpdfnpDnaLS45rWgiuJEw5PoOx hyJTf8FOn4X3NATM8M2FlUZeBpbBF7nkeBKF3Qtww6Inz2kTOHvNlHzUZjgHiCii869vgfLcReG rg2urZNqGAx7hNgxxvp0rH5o8AdMVnPSH2Cb++Zkcr1REn8kYc45Ef6gS1KzzLhAbvHYc2IXS8J 4JyVFZ8kyO1ZVH/vRcoYkSTYt6qw8FZxJ2sNJNu6lazXAFtVF5I22+1yMPDc4svyJELtjvL/8as zsilDeMetcoWOQkYeke3yifcxFG/JnnsRvfTCuo1UKVceoN3MYGyrfmYF4kPCAscCUvLUTryNGV DCX4ngFI9cz7XbiJFq0FLweZ3XkizuzcEQBP1NrNwTwPWB77MHV7qHCu4e0t/3pre3H/oP2OTvp nGIYzIOAlOxNd9pmxQNCpiBn07ZmFtX0WplJez/GYEGqOqF X-Received: by 2002:a17:90b:1850:b0:35f:b46e:e329 with SMTP id 98e67ed59e1d1-361403ca60emr18206986a91.6.1776749606569; Mon, 20 Apr 2026 22:33:26 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Michael Ellerman , Nicholas Piggin , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Nutty Liu Subject: [PATCH v3 05/13] hw/riscv/virt: Move AIA initialisation to helper file Date: Tue, 21 Apr 2026 15:31:30 +1000 Message-ID: <20260421053140.752059-6-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1032; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x1032.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749694041158500 Content-Type: text/plain; charset="utf-8" The AIA init will be used by any server class riscv machine. Separate it out in order to share code with such systems. The virt machine keeps machine specific #defines such as VIRT_IRQCHIP_NUM_MSIS, VIRT_IRQCHIP_NUM_PRIO_BITS. Reviewed-by: Daniel Henrique Barboza Reviewed-by: Nutty Liu Signed-off-by: Joel Stanley Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- v3: - Add r-b - Move fewer things out of virt machine into aia common code, as they are virt machine specific and not part of aia. Done as part of this movement patch to avoid moving them out only put them back in the next patch. --- hw/riscv/aia.h | 26 +++++++++++ include/hw/riscv/virt.h | 1 - hw/riscv/aia.c | 89 ++++++++++++++++++++++++++++++++++++++ hw/riscv/virt-acpi-build.c | 2 + hw/riscv/virt.c | 87 +++++-------------------------------- hw/riscv/meson.build | 2 +- 6 files changed, 129 insertions(+), 78 deletions(-) create mode 100644 hw/riscv/aia.h create mode 100644 hw/riscv/aia.c diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h new file mode 100644 index 000000000000..dbb833340276 --- /dev/null +++ b/hw/riscv/aia.h @@ -0,0 +1,26 @@ +/* + * QEMU RISC-V Advanced Interrupt Architecture (AIA) + * + * Copyright (C) 2019 Western Digital Corporation or its affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_RISCV_AIA_H +#define HW_RISCV_AIA_H + +#include "exec/hwaddr.h" + +#define VIRT_IRQCHIP_NUM_SOURCES 96 + +uint32_t imsic_num_bits(uint32_t count); + +DeviceState *riscv_create_aia(bool msimode, int aia_guests, + const MemMapEntry *aplic_m, + const MemMapEntry *aplic_s, + const MemMapEntry *imsic_m, + const MemMapEntry *imsic_s, + int socket, int base_hartid, int hart_count, + uint32_t num_msis, uint32_t num_prio_bits); + +#endif diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 18a2a323a344..ad858deb76ad 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -135,7 +135,6 @@ enum { bool virt_is_acpi_enabled(RISCVVirtState *s); bool virt_is_iommu_sys_enabled(RISCVVirtState *s); void virt_acpi_setup(RISCVVirtState *vms); -uint32_t imsic_num_bits(uint32_t count); =20 /* * The virt machine physical address space used by some of the devices diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c new file mode 100644 index 000000000000..c724612a50a5 --- /dev/null +++ b/hw/riscv/aia.c @@ -0,0 +1,89 @@ +/* + * QEMU RISC-V Advanced Interrupt Architecture (AIA) + * + * Copyright (C) 2019 Western Digital Corporation or its affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "system/kvm.h" +#include "hw/intc/riscv_aplic.h" +#include "hw/intc/riscv_imsic.h" + +#include "aia.h" + +uint32_t imsic_num_bits(uint32_t count) +{ + uint32_t ret =3D 0; + + while (BIT(ret) < count) { + ret++; + } + + return ret; +} + +DeviceState *riscv_create_aia(bool msimode, int aia_guests, + const MemMapEntry *aplic_m, + const MemMapEntry *aplic_s, + const MemMapEntry *imsic_m, + const MemMapEntry *imsic_s, + int socket, int base_hartid, int hart_count, + uint32_t num_msis, uint32_t num_prio_bits) +{ + int i; + hwaddr addr =3D 0; + uint32_t guest_bits; + DeviceState *aplic_s_dev =3D NULL; + DeviceState *aplic_m_dev =3D NULL; + + if (msimode) { + if (!kvm_enabled()) { + /* Per-socket M-level IMSICs */ + addr =3D imsic_m->base + socket * (1U << IMSIC_MMIO_GROUP_MIN_= SHIFT); + for (i =3D 0; i < hart_count; i++) { + riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0), + base_hartid + i, true, 1, + num_msis); + } + } + + /* Per-socket S-level IMSICs */ + guest_bits =3D imsic_num_bits(aia_guests + 1); + addr =3D imsic_s->base + socket * (1U << IMSIC_MMIO_GROUP_MIN_SHIF= T); + for (i =3D 0; i < hart_count; i++) { + riscv_imsic_create(addr + i * IMSIC_HART_SIZE(guest_bits), + base_hartid + i, false, 1 + aia_guests, + num_msis); + } + } + + if (!kvm_enabled()) { + /* Per-socket M-level APLIC */ + aplic_m_dev =3D riscv_aplic_create(aplic_m->base + + socket * aplic_m->size, + aplic_m->size, + (msimode) ? 0 : base_hartid, + (msimode) ? 0 : hart_count, + VIRT_IRQCHIP_NUM_SOURCES, + num_prio_bits, + msimode, true, NULL); + } + + /* Per-socket S-level APLIC */ + aplic_s_dev =3D riscv_aplic_create(aplic_s->base + + socket * aplic_s->size, + aplic_s->size, + (msimode) ? 0 : base_hartid, + (msimode) ? 0 : hart_count, + VIRT_IRQCHIP_NUM_SOURCES, + num_prio_bits, + msimode, false, aplic_m_dev); + + if (kvm_enabled() && msimode) { + riscv_aplic_set_kvm_msicfgaddr(RISCV_APLIC(aplic_s_dev), addr); + } + + return kvm_enabled() ? aplic_s_dev : aplic_m_dev; +} diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c index fd6ca5dbc4ff..145f8d92ad69 100644 --- a/hw/riscv/virt-acpi-build.c +++ b/hw/riscv/virt-acpi-build.c @@ -42,6 +42,8 @@ #include "system/kvm.h" #include "system/reset.h" =20 +#include "aia.h" + #define ACPI_BUILD_TABLE_SIZE 0x20000 #define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index)) =20 diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 4501d5581b62..ce0fd6f50c4a 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -59,6 +59,8 @@ #include "hw/virtio/virtio-iommu.h" #include "hw/uefi/var-service-api.h" =20 +#include "aia.h" + /* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU= . */ static bool virt_use_kvm_aia_aplic_imsic(RISCVVirtAIAType aia_type) { @@ -509,17 +511,6 @@ static void create_fdt_socket_plic(RISCVVirtState *s, } } =20 -uint32_t imsic_num_bits(uint32_t count) -{ - uint32_t ret =3D 0; - - while (BIT(ret) < count) { - ret++; - } - - return ret; -} - static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr, uint32_t *intc_phandles, uint32_t msi_pha= ndle, bool m_mode, uint32_t imsic_guest_bits) @@ -1293,68 +1284,6 @@ static DeviceState *virt_create_plic(const MemMapEnt= ry *memmap, int socket, memmap[VIRT_PLIC].size); } =20 -static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_gue= sts, - const MemMapEntry *memmap, int socket, - int base_hartid, int hart_count) -{ - int i; - hwaddr addr =3D 0; - uint32_t guest_bits; - DeviceState *aplic_s =3D NULL; - DeviceState *aplic_m =3D NULL; - bool msimode =3D aia_type =3D=3D VIRT_AIA_TYPE_APLIC_IMSIC; - - if (msimode) { - if (!kvm_enabled()) { - /* Per-socket M-level IMSICs */ - addr =3D memmap[VIRT_IMSIC_M].base + - socket * VIRT_IMSIC_GROUP_MAX_SIZE; - for (i =3D 0; i < hart_count; i++) { - riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0), - base_hartid + i, true, 1, - VIRT_IRQCHIP_NUM_MSIS); - } - } - - /* Per-socket S-level IMSICs */ - guest_bits =3D imsic_num_bits(aia_guests + 1); - addr =3D memmap[VIRT_IMSIC_S].base + socket * VIRT_IMSIC_GROUP_MAX= _SIZE; - for (i =3D 0; i < hart_count; i++) { - riscv_imsic_create(addr + i * IMSIC_HART_SIZE(guest_bits), - base_hartid + i, false, 1 + aia_guests, - VIRT_IRQCHIP_NUM_MSIS); - } - } - - if (!kvm_enabled()) { - /* Per-socket M-level APLIC */ - aplic_m =3D riscv_aplic_create(memmap[VIRT_APLIC_M].base + - socket * memmap[VIRT_APLIC_M].size, - memmap[VIRT_APLIC_M].size, - (msimode) ? 0 : base_hartid, - (msimode) ? 0 : hart_count, - VIRT_IRQCHIP_NUM_SOURCES, - VIRT_IRQCHIP_NUM_PRIO_BITS, - msimode, true, NULL); - } - - /* Per-socket S-level APLIC */ - aplic_s =3D riscv_aplic_create(memmap[VIRT_APLIC_S].base + - socket * memmap[VIRT_APLIC_S].size, - memmap[VIRT_APLIC_S].size, - (msimode) ? 0 : base_hartid, - (msimode) ? 0 : hart_count, - VIRT_IRQCHIP_NUM_SOURCES, - VIRT_IRQCHIP_NUM_PRIO_BITS, - msimode, false, aplic_m); - - if (kvm_enabled() && msimode) { - riscv_aplic_set_kvm_msicfgaddr(RISCV_APLIC(aplic_s), addr); - } - - return kvm_enabled() ? aplic_s : aplic_m; -} - static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip) { DeviceState *dev; @@ -1617,9 +1546,15 @@ static void virt_machine_init(MachineState *machine) s->irqchip[i] =3D virt_create_plic(s->memmap, i, base_hartid, hart_count); } else { - s->irqchip[i] =3D virt_create_aia(s->aia_type, s->aia_guests, - s->memmap, i, base_hartid, - hart_count); + s->irqchip[i] =3D riscv_create_aia(s->aia_type =3D=3D VIRT_AIA= _TYPE_APLIC_IMSIC, + s->aia_guests, + &s->memmap[VIRT_APLIC_M], + &s->memmap[VIRT_APLIC_S], + &s->memmap[VIRT_IMSIC_M], + &s->memmap[VIRT_IMSIC_S], + i, base_hartid, hart_count, + VIRT_IRQCHIP_NUM_MSIS, + VIRT_IRQCHIP_NUM_PRIO_BITS); } =20 /* Try to use different IRQCHIP instance based device type */ diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build index 533472e22aef..e53c180d0d10 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -1,5 +1,5 @@ riscv_ss =3D ss.source_set() -riscv_ss.add(files('boot.c')) +riscv_ss.add(files('boot.c', 'aia.c')) riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c')) riscv_ss.add(files('riscv_hart.c')) riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c')) --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749729377766.3448944341137; Mon, 20 Apr 2026 22:35:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3jt-0000Vl-6X; Tue, 21 Apr 2026 01:33:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3jq-0000V7-VW for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:35 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3jp-0004RH-1v for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:34 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-36146ae9dd4so2853503a91.3 for ; Mon, 20 Apr 2026 22:33:32 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749611; x=1777354411; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=gQzUKnDEDxeEJKHujdd1Mmnc0S04pC7+ydkmi3SAr9M=; b=VGBV9R5tGG5Mr6TyL0eTkRnn9dQVTiQyP8JtiprsV5UmuJ6vTgehebMBX3jOWx5Y2n XrznYw8WIQX4CFyRRqct96/aqG6L3mJS9lVWiSEYpNJf4ekdco5ktvjDN6J1K5SLnWLL pdbViD3eWa7FaJv9Ec9k5z7meDKXTInTTRYkGEjhvHKJZrxuU9WBYRVxF9dAP3xPT/OG D4PQsKNrcNmy9yzHwDaHsjhddNr4fCHCnlj1d1uzhtyblCmx17v/ynzChC6x0RwAJIbg /fUWFHU4h+1f448osQUy8K2FEVvprU7Xcgy8znv+weOJfkkSiNviGC2Xjoo6jX5p965c gGPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749611; x=1777354411; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gQzUKnDEDxeEJKHujdd1Mmnc0S04pC7+ydkmi3SAr9M=; b=GQ8xI4t3mbgVYO47nMHpuKo1OLAGvQ6KxWsgE8x5BlSBeAtB3I0uk6uF4B1DBCnLLE r63TYqYGpgrJvLq4bd73egybHip95qFGn7BivUmFzTOYLV+LxnNMCwG3JCPClGrYG/vu 2Ew0Q2qy903Ry9Ws6aaTLyo0TPQ0PxquUrOdotxtW0yKrrr3W/jlg6h0wnTEkenWMaKM E21UVnhCsD2Z/yu8Co4bIocAeaWaSzUJqlDQiETBGCuDQ/YjXySUWAALJqS9LhO3LC1f MpPEMS5i8JtNpe1b48SmIgj3xcVvz7x9Y5I6stwfXNFGTzagWcPAzrl9wF88amqYPqIy j21Q== X-Forwarded-Encrypted: i=1; AFNElJ/NHaxa+nxNAieu0b9XeHbaUmSCpxltclAYUd7Bv1R0G8hraKKkxtrGjGUYIJVcYTNeDpN5zzIpGfwV@nongnu.org X-Gm-Message-State: AOJu0YxoQ8CSSkBz4PL/wmnn6KaO3tAy3C82QaRaYi+wdt9d4t9niePB ipkqEEd1qkGa1Dz4nKtE8m1qae7V+CIPqm85T2tY2vO3pt2ksqY9Nbf0tfULtQ== X-Gm-Gg: AeBDievYkXY2fXeIStX6KRAANIUp6NkgS1zSKbApe3E9FlZMOmPViUXNvprEX/BL/T+ ba4mdzQFCJx3SJF7gqC7NL6AIdSQmtX34katqu+0fvdjbJHouzniDrgiIaGlnYELIOgI3xxalxg osQccCPsgdWIfP8SFLJdZcGZuTUaTcUJDXTzDHtR2L9xtr9YmWXknKOX6QMWm/WEhvEcNmGwK2p CYvfSSQoE0GvUuqdP9CSIk2uLiJMFqB1rp5hbE78h43nhL3tNVaEv6ezjnOSCKubiYzq/o5+pfu L6upJbCxMAkt7r8bAD9nttDz5RWqVrUs32123/sh0hRzTjjn+X2FywgPlUKN5zykxUer0GyG5Ht REZKRzjc97fRWqDHX3UoH7wHjqN9H6I87BJAMDMfvgS0iuV282Hlidn+aGvTvAm+tlE3n73rL5A vCpMc2+7KksfN7/NcBWnkvcR0b78oPN0ExmBFbt60Go33nM3+vQIydLeU5h3gKJ/+plHCjisJoc HdtCpvEoD5h3NGfRHAwEWf0TdObFF1rjmwMxA== X-Received: by 2002:a17:90b:4b87:b0:35b:9b77:d7c with SMTP id 98e67ed59e1d1-36140469b55mr17537204a91.14.1776749611380; Mon, 20 Apr 2026 22:33:31 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Michael Ellerman , Nicholas Piggin , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Nutty Liu Subject: [PATCH v3 06/13] hw/riscv/aia: Provide number of irq sources Date: Tue, 21 Apr 2026 15:31:31 +1000 Message-ID: <20260421053140.752059-7-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749730461154100 Content-Type: text/plain; charset="utf-8" Instead of hard coding the number of IRQ sources used by the APLIC pass it in as a parameter. This allows other machines to configure this as required. The maximum number of sources is 1023. Reviewed-by: Nutty Liu Reviewed-by: Daniel Henrique Barboza Signed-off-by: Joel Stanley Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- v3: Add r-b --- hw/riscv/aia.h | 3 +-- include/hw/riscv/virt.h | 1 + hw/riscv/aia.c | 8 ++++++-- hw/riscv/virt-acpi-build.c | 25 ++++++++++++++++--------- hw/riscv/virt.c | 2 ++ 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h index dbb833340276..5ad0a902be0d 100644 --- a/hw/riscv/aia.h +++ b/hw/riscv/aia.h @@ -11,11 +11,10 @@ =20 #include "exec/hwaddr.h" =20 -#define VIRT_IRQCHIP_NUM_SOURCES 96 - uint32_t imsic_num_bits(uint32_t count); =20 DeviceState *riscv_create_aia(bool msimode, int aia_guests, + uint16_t num_sources, const MemMapEntry *aplic_m, const MemMapEntry *aplic_s, const MemMapEntry *imsic_m, diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index ad858deb76ad..36a2def41096 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -64,6 +64,7 @@ struct RISCVVirtState { struct GPEXHost *gpex_host; OnOffAuto iommu_sys; uint16_t pci_iommu_bdf; + uint16_t num_sources; }; =20 enum { diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c index c724612a50a5..82ea9d48ea75 100644 --- a/hw/riscv/aia.c +++ b/hw/riscv/aia.c @@ -25,6 +25,7 @@ uint32_t imsic_num_bits(uint32_t count) } =20 DeviceState *riscv_create_aia(bool msimode, int aia_guests, + uint16_t num_sources, const MemMapEntry *aplic_m, const MemMapEntry *aplic_s, const MemMapEntry *imsic_m, @@ -38,6 +39,9 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guest= s, DeviceState *aplic_s_dev =3D NULL; DeviceState *aplic_m_dev =3D NULL; =20 + /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */ + g_assert(num_sources <=3D 1023); + if (msimode) { if (!kvm_enabled()) { /* Per-socket M-level IMSICs */ @@ -66,7 +70,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guest= s, aplic_m->size, (msimode) ? 0 : base_hartid, (msimode) ? 0 : hart_count, - VIRT_IRQCHIP_NUM_SOURCES, + num_sources, num_prio_bits, msimode, true, NULL); } @@ -77,7 +81,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guest= s, aplic_s->size, (msimode) ? 0 : base_hartid, (msimode) ? 0 : hart_count, - VIRT_IRQCHIP_NUM_SOURCES, + num_sources, num_prio_bits, msimode, false, aplic_m_dev); =20 diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c index 145f8d92ad69..9ef3ef842a28 100644 --- a/hw/riscv/virt-acpi-build.c +++ b/hw/riscv/virt-acpi-build.c @@ -146,6 +146,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtSta= te *s) } =20 static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count, + uint16_t num_sources, uint64_t mmio_base, uint64_t mmio_siz= e, const char *hid) { @@ -153,9 +154,12 @@ static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8= _t socket_count, uint32_t gsi_base; uint8_t socket; =20 + /* The RISC-V Advanced Interrupt Architecture, Chapter 1.2. Limits */ + g_assert(num_sources <=3D 1023); + for (socket =3D 0; socket < socket_count; socket++) { plic_aplic_addr =3D mmio_base + mmio_size * socket; - gsi_base =3D VIRT_IRQCHIP_NUM_SOURCES * socket; + gsi_base =3D num_sources * socket; Aml *dev =3D aml_device("IC%.02X", socket); aml_append(dev, aml_name_decl("_HID", aml_string("%s", hid))); aml_append(dev, aml_name_decl("_UID", aml_int(socket))); @@ -474,10 +478,13 @@ static void build_dsdt(GArray *table_data, socket_count =3D riscv_socket_count(ms); =20 if (s->aia_type =3D=3D VIRT_AIA_TYPE_NONE) { - acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_PLIC].ba= se, - memmap[VIRT_PLIC].size, "RSCV0001"); + acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources, + memmap[VIRT_PLIC].base, + memmap[VIRT_PLIC].size, + "RSCV0001"); } else { - acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_APLIC_S]= .base, + acpi_dsdt_add_plic_aplic(scope, socket_count, s->num_sources, + memmap[VIRT_APLIC_S].base, memmap[VIRT_APLIC_S].size, "RSCV0002"); } =20 @@ -494,15 +501,15 @@ static void build_dsdt(GArray *table_data, } else if (socket_count =3D=3D 2) { virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base, memmap[VIRT_VIRTIO].size, - VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0, + VIRTIO_IRQ + s->num_sources, 0, VIRTIO_COUNT); - acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES= ); + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources); } else { virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base, memmap[VIRT_VIRTIO].size, - VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0, + VIRTIO_IRQ + s->num_sources, 0, VIRTIO_COUNT); - acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES= * 2); + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + s->num_sources * 2); } =20 aml_append(dsdt, scope); @@ -581,7 +588,7 @@ static void build_madt(GArray *table_data, for (socket =3D 0; socket < riscv_socket_count(ms); socket++) { aplic_addr =3D s->memmap[VIRT_APLIC_S].base + s->memmap[VIRT_APLIC_S].size * socket; - gsi_base =3D VIRT_IRQCHIP_NUM_SOURCES * socket; + gsi_base =3D s->num_sources * socket; build_append_int_noprefix(table_data, 0x1A, 1); /* Type */ build_append_int_noprefix(table_data, 36, 1); /* Length */ build_append_int_noprefix(table_data, 1, 1); /* Version = */ diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index ce0fd6f50c4a..6c5bcd43dc54 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1548,6 +1548,7 @@ static void virt_machine_init(MachineState *machine) } else { s->irqchip[i] =3D riscv_create_aia(s->aia_type =3D=3D VIRT_AIA= _TYPE_APLIC_IMSIC, s->aia_guests, + s->num_sources, &s->memmap[VIRT_APLIC_M], &s->memmap[VIRT_APLIC_S], &s->memmap[VIRT_IMSIC_M], @@ -1691,6 +1692,7 @@ static void virt_machine_instance_init(Object *obj) s->oem_table_id =3D g_strndup(ACPI_BUILD_APPNAME8, 8); s->acpi =3D ON_OFF_AUTO_AUTO; s->iommu_sys =3D ON_OFF_AUTO_AUTO; + s->num_sources =3D VIRT_IRQCHIP_NUM_SOURCES; } =20 static char *virt_get_aia_guests(Object *obj, Error **errp) --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749653461416.9995448553907; Mon, 20 Apr 2026 22:34:13 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3jw-0000WN-UU; Tue, 21 Apr 2026 01:33:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3jv-0000Vx-1u for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:39 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3jt-0004Rt-LY for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:38 -0400 Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-354a18c48b5so3596809a91.1 for ; Mon, 20 Apr 2026 22:33:37 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749616; x=1777354416; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=NEFNzmQsiyEBdi81S342OEi8MVF55bQv2FFp5njPfbI=; b=XZXU6DgnhHZYlufiofrjSjI0Y7pNReyHKxCw2lO80BlgLverjYcDbeb2q/WqOWOx5x xJBHMrAdzpVGrCgHT+iiYxHBiP9xw/zJCyuvS8OqVCBLsoxwMZr+rVfiCGDnxsq4HqE6 O5ABCJTad4aSV5ZSMSRNEttiaM5MHzwKW7rK236YMR4y8ypwX3NdVJv00+fjCLq1jY1l IXqbIfz1gXb2kOEDXt2CC629mks5XV+cP648ARNpFl1rw4RNiWf9+D0ltmDo3eJGv2ih ToVmwQIz06lRx6NqFB0flesVDpKXjffzAxlDgkCH72Owkiq/80FDb6JtfbD7Xtg0NogN RXbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749616; x=1777354416; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NEFNzmQsiyEBdi81S342OEi8MVF55bQv2FFp5njPfbI=; b=Ap4VjRP1Z7BCspxDvt8z7ybDYwbRktbgFIAVF0rHFhIJyHVnBXY/W5NPNT2HU37TAm p82J9ATLYbVFoUmhkjgwzpKqOuhLptJzhz26GlrDNIeEfI7SPcu+d6lDKxyYWpKZPNCo 8qLmnQvJXSxlGe41/vn5MSznr/sZO1naBABF6EuVtM8/GDHpQLzIaUwVnCab5CWFGB2D 2hB+yFKWMZ0MW9PWWiTANl4RiizgpqWokcmSeKDmCH9o9WAm25wIIu0xzNI1AyTAk7WO 2b9dlvGGm31qfvKsP94iNy2BIiZzp7p8gkoFLcoFQSNHQbixCrlllZYRp/JSu/BanUfS TG0A== X-Forwarded-Encrypted: i=1; AFNElJ/wjdnPk4BlQeZweJpvqwpE6W8apjIC3SXZWlCjjZHRAOWuC2ExfSIJQf06uYSnNVbvzCuUfIYS76HE@nongnu.org X-Gm-Message-State: AOJu0YyCdacN/wJo6GoaXTGt7nIGAHNqEbDSaXyO8uUByKudveFy88pr bXFp9+GQ9PBcg+2bKE/+M8CDflCoK2wSyO2t588rheZBSuxuPJtyB1W/ X-Gm-Gg: AeBDievvrGJEzGSOS1OEqSavTjn19M0i+35mB3a7WREq+4PJx0MCrY1dxIl+1qHJ4Jj HGvrQCscnCEkL7T4ot341aHbdsaRrwFKJ+/FglcFZhpgo0ridEGJ/7bLY8Cm4ttBSy57TlkMump wi8Cfw0xGQ2LPjUPxQEM+HF/XxYhR1SUNoRfPaqVw6On/SwHmL8mppqkmiSOb6S1USRjQUPlIrO l5F8Domn0SNAvRPD7X1iMcVrPNRjacQWZ9dgsX+VVT4eZ71o8jQZQc9tswQOzGVuxMOf5saqDG+ bRVOqPb9h39vNW3JES6QslmA1hAkEgrOFnWl/etJ7XSvWccb1ueiyFmG5VWVLtQRPTFJ6BYyEKP fKbrzfxt0e77MHCU+rLSCVvYTtiKV6OQqCJmHaGBbuRpTLel4GoNaq7e29ORcaAixKVOR3BTlVy 6oS5tQZZRDpuUzJYaE9pgpIjHWli2QBbbRqt1cZg0dQxsZ4bj6ut9pqwIRoOt466dkxxQK3B73H Fh8A9jewQfRHepFOqqJFerluz4VFHZGeKyQNw== X-Received: by 2002:a17:90b:1dc2:b0:35f:b306:5d47 with SMTP id 98e67ed59e1d1-361403af9c4mr17483230a91.1.1776749616289; Mon, 20 Apr 2026 22:33:36 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Nicholas Piggin , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 07/13] target/riscv: tt-ascalon: Enable Zkr extension Date: Tue, 21 Apr 2026 15:31:32 +1000 Message-ID: <20260421053140.752059-8-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x102f.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749655838158500 Content-Type: text/plain; charset="utf-8" From: Nicholas Piggin Ascalon supports Zkr and the SEED CSR. Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- target/riscv/cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 72c6f4f0f14b..df01a729bc6d 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -3189,6 +3189,7 @@ static const TypeInfo riscv_cpu_type_infos[] =3D { .cfg.ext_zba =3D true, .cfg.ext_zbb =3D true, .cfg.ext_zbs =3D true, + .cfg.ext_zkr =3D true, .cfg.ext_zkt =3D true, .cfg.ext_zvbb =3D true, .cfg.ext_zvbc =3D true, --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749692052770.8524177229419; Mon, 20 Apr 2026 22:34:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3k1-0000Y0-2W; Tue, 21 Apr 2026 01:33:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3jz-0000XD-6c for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:43 -0400 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3jx-0004SZ-MV for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:42 -0400 Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-35fc258aaa4so2359580a91.2 for ; Mon, 20 Apr 2026 22:33:41 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749620; x=1777354420; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=2q0G8FN7I4cT2MFC0mi2tKNSJeFLTR85NiFHhp78wA4=; b=erismwWSrOUSGlbdl2AvdShDpsLOOEYdY3NJ5w7Xm/k7zHEm7rxKB1fOmADgID0nbn 8s9NMQ6pX4FnSzWV0+RthaeJNkVzfunNVFU/26avykHtRHhQVdPwpSTmJxaL0XzAgicl OsynoQgeUWzWoDlPr1Q4L09LxIDTcb9UpXoReNwa2zCZUaDiiT2S9l7PLjTc+UZ1nHdQ 14MjqYzFQhiASa6guD+jIZnG104n+x4PET4JOlcA7cn+ZD9ryHnaOHXJLbmt0FwWTDcR 4T/Hyz8psgaKlKkKfnH6G0EWwY/ylLNEm/2Tp3WhyZ0Csb7uFZ7EpMtbIYY01bfNy9EC 78mA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749620; x=1777354420; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2q0G8FN7I4cT2MFC0mi2tKNSJeFLTR85NiFHhp78wA4=; b=ZQyQYWu9oiyjngBauWYmX0p3ueSZCrBYXhS9zXVXE7hkpdsOg/e9UUUL94Wi/q8I4b hnbmyVAqRAeW7km4jGkGwOH7P6JeqZ4/O7OuUbJnXChHNdh7cQvg6f9zc5VqTmk3owix 1bquEZ6+TjzMajUu3D3IPqnA2E0ftLURIsyA4HZNp9qPxF7wa6yy8LZlKOCZBME4iCmT f2IVROYkHhojLmKks1wTVVUzerKvyak/02rSUSIQSRRUin+htQ8XE9l8cRf34tHnCRSq NBGo8tg1Yi0WwB1VQaJRNBBcJXHd65xd1Zup6IPIpgBnsCJaJnPnI9R6Z+E+Y93QVLwu npUw== X-Forwarded-Encrypted: i=1; AFNElJ9Qqky4n8ejohbtyc00xJHWG+95tptpTIOjb9TEbHlbmT5YJfSJRbK6NBLgTcIV5QEx2ogQ2YcltXWC@nongnu.org X-Gm-Message-State: AOJu0YxPppJ1LPtKPgBvN1/frkCPTZJL/ChKUXs4VO/SKvKqFYc4JqTg UCUApHut+dfHJ+CKxwMhIukVOqndU5y3hgPqfIjopNl0soqoWSU155Ej7xrWhA== X-Gm-Gg: AeBDiesHIbrlYGcNwmCSclPNMnxRJL9rpZ7BHG1KTwAnpntVF7Li6dpwxqUwSYvIapJ xjxwDjNxTIa8uoALAkKLDGjHkd1F6IGnms9jg49gP5yf0w/M7qN39yxOnX49PCNgT5aSXJFUZC/ VAhVxxUpAoN5urd6QhNcdmPBzWQcxXq4ghIRBdyTpMZoRSlHmk0+QxuNLm7EKt4GHsS9yzIqSBx l0y35FkYEXEzQCVmaXqP1i6lCWPaWHY7H71XWk1Fxslh+h2GUX190yYPRIiorHFDIw/ypfmMOKw JooMivacPdIG5gwkcPIR4/FR3RdJCIQnvnetlLyOPBqwLhQHjuNbL0SOSAM60QukrGkTLJsTyFW ZbeYZcU80+jeLXWNBFGPI1nUb+L6UJc08ayIkcQJuZ55J/qaJ4l6FeLxkWrsLLqHnhGgqxqYJtN Cb7T2sn2xYbOKIp3NoJzX/4DB4wKt7gbO1iO7mougoB1Vj2HG+WFYd/yq0LgnfoGitmAGpFd0qV Yzu6ECnTY1XDPKryCO3T5avXovRjjHcfM5glQ== X-Received: by 2002:a17:90b:5286:b0:35f:9ab2:a5a6 with SMTP id 98e67ed59e1d1-361403d5b55mr15467475a91.2.1776749620509; Mon, 20 Apr 2026 22:33:40 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Nicholas Piggin , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 08/13] target/riscv: tt-ascalon: Add Svadu extension Date: Tue, 21 Apr 2026 15:31:33 +1000 Message-ID: <20260421053140.752059-9-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x1033.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749693942158500 Content-Type: text/plain; charset="utf-8" From: Nicholas Piggin Ascalon supports Svadu (hardware A/D bit updates). QEMU makes Svadu and Svade mutually exclusive, remove Svade so Ascalon comes up with Svadu working. Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- target/riscv/cpu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index df01a729bc6d..0997bd3324b1 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -3203,7 +3203,6 @@ static const TypeInfo riscv_cpu_type_infos[] =3D { .cfg.ext_ssaia =3D true, .cfg.ext_sscofpmf =3D true, .cfg.ext_sstc =3D true, - .cfg.ext_svade =3D true, .cfg.ext_svinval =3D true, .cfg.ext_svnapot =3D true, .cfg.ext_svpbmt =3D true, --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749699477327.5886693781101; Mon, 20 Apr 2026 22:34:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3kL-0000fe-BZ; Tue, 21 Apr 2026 01:34:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3k6-0000ai-7v for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:50 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3k2-0004Uv-8V for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:49 -0400 Received: by mail-pj1-x102e.google.com with SMTP id 98e67ed59e1d1-35dac556bb2so2116211a91.1 for ; Mon, 20 Apr 2026 22:33:45 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749625; x=1777354425; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=fBORH+ks+KD9P+CqshoQVHYbjPv0IIt3trFhODZ57t4=; b=FMg2uS4ulSFiM1VWB4DHXDx6DRgt/z7zhshrueNqHdPyIKUC6+M5hy9UFPVBu4iCgu Aw+4yuUYRhnW2P+ATYIfo73yml5nTNeAL019Jrt4DcR82l8DL+cRjs8M9TDYRR+g8RC6 emxR4XVAhHmlFQC+4K/p7bLZN5tImaJcYgKCOmFBy+qXiwfYJgCOBx4XSHvKQYgv+RQZ bjX+QcH4butlO1dePsvMVDZPFv43DqEKYnGoy0AbaAafyDHUoyZMC4TFjpFcCna1k+G4 wv1BVivRtt4drv+zmTP+EmVayqmoohoDgRVm6QuzeDN0QBZ2yxGs0LCpnVFaDz1VGNYE qggA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749625; x=1777354425; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fBORH+ks+KD9P+CqshoQVHYbjPv0IIt3trFhODZ57t4=; b=obG6mgwI/Qdc6dRi2l+TbOyDhhhWCLJ8ntAf5kby/YnmNv1Oz9ur7QwVwK7SB6yqbn 8mIVYwjJsIlY+kx4JGLTwHGVfdxzQEYY45VTS5DtEm8b8aDxp+6K2YX6A5YyKXdu2Zou QdBUrTsDZz27cKIdsq7W7hVKUFFGQ+CWc9IKS2dqTY3xiNDf99z3avRaDNPGRCButQkm zeAKnTK1/DQqGVvasHvjUktXgh7J+DINQIMX4j8cUCTLaAWOxMbLW48o2tLuPYW2wQ0I kpMZwuh7hozNQlAZCzOT0SHAoJLM7oirHnSbS+FVmXZa3pQKTYkMp8+CbJ+QCrJPZgT8 IqRw== X-Forwarded-Encrypted: i=1; AFNElJ+tUFGUTxud2yVvlwMoGEGXWegAd87JfjjIkuZihkOPZ1mpHqeAYP+x4jYxC/tkHbdgO3Mq+4xWmXjx@nongnu.org X-Gm-Message-State: AOJu0YwGhzbMEDDS1oP8z0DjRTGm6/h+jtREmDWK4NRogX8owWqYKVT7 F9nootnHonMOjhBlatuv18HBrR8JeJfgy8osfX4PZ5ZazExRfu0mxvHxb209tg== X-Gm-Gg: AeBDieuAIpnoTEmHMrkjBvG6CTFpKp8YxxvPvOIXNUx0zD7Y15zj1O5GvtB2tHBn7Xn g5xBQlzI1uIV/eCs7LdQQFhHmXUbOLAPLoQYwXYURG/Yx52YCMDzid1NVWnyPbqZdu8sH0dyy0p NUlb8hysEoJHCJcs042dba98cfPMQcmileFds3+r9aKAtoSCJGq8xCY0++TPCdz8uwsM34elfnS LJYop28kx/Weo4QMOzKmahcwOoFyGKzFst8kdLZ/TdOuZ9OF+yqVP+0CXY5yUpwFIOyZRt2U4LQ N6GXew2sJHZxxZ/paxHaHKsTbKj8aHmSxuGTPo8uYP3Img/J94ZXeakws6rT6JhuT9rvFIKgYRW Fm9NX6uOvMrSy+qdZqtI/vwE12fE8kXtQBMnw6aSc/dOq67hFW8Iz1G16JTDuK/Mc4irddp9cqe xwZjuEqozDd8nxXWt40MFB8/8aDl+AXZfXY/ZOTxQ+gclCGzvBR2OCH0opA5L+ewP/E8ZVIS+kl D4kLty1M0WuPBAmTG2uSiLnar/ZPsw6S2tiUQ== X-Received: by 2002:a17:90a:910:b0:361:472e:3be6 with SMTP id 98e67ed59e1d1-361472e4e85mr8721441a91.26.1776749624861; Mon, 20 Apr 2026 22:33:44 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Michael Ellerman , Nicholas Piggin , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 09/13] hw/riscv: Add Tenstorrent Atlantis machine Date: Tue, 21 Apr 2026 15:31:34 +1000 Message-ID: <20260421053140.752059-10-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102e; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x102e.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749701970154100 Content-Type: text/plain; charset="utf-8" The Tenstorrent Atlantis platform is a collaboration between Tenstorrent and CoreLab Technology. It is based on the Atlantis SoC, which includes the Ascalon-X CPU and other IP from Tenstorrent and CoreLab Technology. The Tenstorrent Ascalon-X is a high performance 64-bit RVA23 compliant RISC-V CPU. This adds the machine containing serial console, interrupt controllers and device tree support. qemu-system-riscv64 -M tt-atlantis -m 512M \ -kernel Image -initrd rootfs.cpio -nographic If there is no kernel provided the simple payload is loaded to avoid OpenSBI hanging with no messages. Signed-off-by: Joel Stanley Co-Developed-by: Nicholas Piggin Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- v3: - Merge simple payload change into this patch - Fix fw_cfg_init_mem_dma API change - Clean up irqchip #defines - Add Michael and Nick as reviewers - create_fdt_pmu was copying RISCVCPU by value - Remove unused platform_bus --- MAINTAINERS | 11 + docs/system/riscv/tt_atlantis.rst | 38 ++ docs/system/target-riscv.rst | 1 + include/hw/riscv/tt_atlantis.h | 77 ++++ hw/riscv/tt_atlantis.c | 638 ++++++++++++++++++++++++++++++ hw/riscv/Kconfig | 15 + hw/riscv/meson.build | 1 + 7 files changed, 781 insertions(+) create mode 100644 docs/system/riscv/tt_atlantis.rst create mode 100644 include/hw/riscv/tt_atlantis.h create mode 100644 hw/riscv/tt_atlantis.c diff --git a/MAINTAINERS b/MAINTAINERS index e1942a86eba5..635a380945fd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1760,6 +1760,17 @@ F: hw/*/*sifive*.c F: include/hw/*/*sifive*.h F: tests/functional/test_riscv64_sifive_u.py =20 +Tenstorrent Machines +M: Joel Stanley +R: Nicholas Piggin +R: Michael Ellerman +L: qemu-riscv@nongnu.org +S: Supported +F: docs/system/riscv/tt_*.rst +F: hw/riscv/tt_*.c +F: hw/riscv/aia.[ch] +F: include/hw/riscv/tt_*.h + AMD Microblaze-V Generic Board M: Sai Pavan Boddu S: Maintained diff --git a/docs/system/riscv/tt_atlantis.rst b/docs/system/riscv/tt_atlan= tis.rst new file mode 100644 index 000000000000..640cabf7b046 --- /dev/null +++ b/docs/system/riscv/tt_atlantis.rst @@ -0,0 +1,38 @@ +Tenstorrent Atlantis (``tt-atlantis``) +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The Tenstorrent Atlantis platform is a collaboration between Tenstorrent +and CoreLab Technology. It is based on the Atlantis SoC, which includes +the Ascalon-X CPU and other IP from Tenstorrent and CoreLab Technology. + +The Tenstorrent Ascalon-X is a high performance 64-bit RVA23 compliant +RISC-V CPU. + +Features +-------- + +* 8-core Ascalon-X CPU Cluster +* Dual x32 LPDDR5 @ 6400 MT/s +* RISC-V compliant Advanced Interrupt Architecture +* PCIe Gen4 +* RISC-V compliant IOMMU +* GPU and Video subsystem +* 2x USB3.1 & 2x USB2.0 +* 2x 1GbE Ethernet +* 2x eMMC5.1/SDIO3.0 storage +* Extensive connectivity (SPI, I2C, UART, GPIO, CANFD) + +Note: the QEMU tt-atlantis machine does not model the platform +exactly or all devices, but it is undergoing improvement. + +Supported software +------------------ + +The Tenstorrent Ascalon CPUs avoid proprietary or non-standard +extensions, so compatibility with existing software is generally +good. The QEMU tt-atlantis machine works with upstream OpenSBI +and Linux with default configurations. + +The development board hardware will require some implementation +specific setup in firmware which is being developed and may +become a requirement or option for the tt-atlantis machine. diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst index 3ad5d1ddafbb..a8e6b3342186 100644 --- a/docs/system/target-riscv.rst +++ b/docs/system/target-riscv.rst @@ -71,6 +71,7 @@ undocumented; you can get a complete list by running riscv/mips riscv/shakti-c riscv/sifive_u + riscv/tt_atlantis riscv/virt riscv/xiangshan-kunminghu =20 diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h new file mode 100644 index 000000000000..f7f79e9f2c53 --- /dev/null +++ b/include/hw/riscv/tt_atlantis.h @@ -0,0 +1,77 @@ +/* + * Tenstorrent Atlantis RISC-V System on Chip + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright 2025 Tenstorrent, Joel Stanley + */ + +#ifndef HW_RISCV_TT_ATLANTIS_H +#define HW_RISCV_TT_ATLANTIS_H + +#include "hw/core/boards.h" +#include "hw/core/sysbus.h" +#include "hw/intc/riscv_imsic.h" +#include "hw/riscv/riscv_hart.h" + +#define TYPE_TT_ATLANTIS_MACHINE MACHINE_TYPE_NAME("tt-atlantis") +OBJECT_DECLARE_SIMPLE_TYPE(TTAtlantisState, TT_ATLANTIS_MACHINE) + +struct TTAtlantisState { + /*< private >*/ + MachineState parent; + + /*< public >*/ + Notifier machine_done; + FWCfgState *fw_cfg; + const MemMapEntry *memmap; + + RISCVHartArrayState soc; + DeviceState *irqchip; + + int fdt_size; +}; + +enum { + TT_ATL_SYSCON_IRQ =3D 10, + TT_ATL_UART0_IRQ =3D 38, + TT_ATL_UART1_IRQ =3D 39, + TT_ATL_UART2_IRQ =3D 40, + TT_ATL_UART3_IRQ =3D 41, + TT_ATL_UART4_IRQ =3D 42, +}; + +enum { + TT_ATL_ACLINT, + TT_ATL_BOOTROM, + TT_ATL_DDR_LO, + TT_ATL_DDR_HI, + TT_ATL_FW_CFG, + TT_ATL_I2C0, + TT_ATL_MAPLIC, + TT_ATL_MIMSIC, + TT_ATL_PCIE_ECAM0, + TT_ATL_PCIE_ECAM1, + TT_ATL_PCIE_ECAM2, + TT_ATL_PCIE_MMIO0, + TT_ATL_PCIE_PIO0, + TT_ATL_PCIE_MMIO0_32, + TT_ATL_PCIE_MMIO0_64, + TT_ATL_PCIE_MMIO1, + TT_ATL_PCIE_PIO1, + TT_ATL_PCIE_MMIO1_32, + TT_ATL_PCIE_MMIO1_64, + TT_ATL_PCIE_MMIO2, + TT_ATL_PCIE_PIO2, + TT_ATL_PCIE_MMIO2_32, + TT_ATL_PCIE_MMIO2_64, + TT_ATL_PCI_MMU_CFG, + TT_ATL_SAPLIC, + TT_ATL_SIMSIC, + TT_ATL_SYSCON, + TT_ATL_TIMER, + TT_ATL_UART0, + TT_ATL_WDT0, +}; + +#endif diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c new file mode 100644 index 000000000000..a556ff79c8c8 --- /dev/null +++ b/hw/riscv/tt_atlantis.c @@ -0,0 +1,638 @@ +/* + * Tenstorrent Atlantis RISC-V System on Chip + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright 2025 Tenstorrent, Joel Stanley + */ + +#include "qemu/osdep.h" +#include "qemu/cutils.h" +#include "qemu/error-report.h" +#include "qemu/guest-random.h" +#include "qemu/units.h" + +#include "hw/core/boards.h" +#include "hw/core/loader.h" +#include "hw/core/sysbus.h" + +#include "target/riscv/cpu.h" +#include "target/riscv/pmu.h" + +#include "hw/riscv/boot.h" +#include "hw/riscv/numa.h" +#include "hw/riscv/riscv_hart.h" + +#include "hw/char/serial-mm.h" +#include "hw/intc/riscv_aclint.h" +#include "hw/intc/riscv_aplic.h" +#include "hw/misc/pvpanic.h" + +#include "system/system.h" +#include "system/device_tree.h" + +#include "hw/riscv/tt_atlantis.h" + +#include "aia.h" + +#define TT_IRQCHIP_NUM_MSIS 255 +#define TT_IRQCHIP_NUM_SOURCES 128 +#define TT_IRQCHIP_NUM_PRIO_BITS 3 +#define TT_IRQCHIP_GUESTS 7 /* aia_guests */ + +#define FDT_PCI_ADDR_CELLS 3 +#define FDT_PCI_INT_CELLS 1 +#define FDT_MAX_INT_CELLS 2 +#define FDT_MAX_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \ + 1 + FDT_MAX_INT_CELLS) + +#define TT_ACLINT_MTIME_SIZE 0x8050 +#define TT_ACLINT_MTIME 0x0 +#define TT_ACLINT_MTIMECMP 0x8000 +#define TT_ACLINT_TIMEBASE_FREQ 1000000000 + +static const MemMapEntry tt_atlantis_memmap[] =3D { + /* Keep sorted with :'<,'>!sort -g -k 4 */ + [TT_ATL_DDR_LO] =3D { 0x00000000, 0x80000000 }, + [TT_ATL_BOOTROM] =3D { 0x80000000, 0x2000 }, + [TT_ATL_FW_CFG] =3D { 0x80002000, 0xff }, /* qemu o= nly */ + [TT_ATL_SYSCON] =3D { 0x80004000, 0x1000 }, /* qemu o= nly */ + [TT_ATL_MIMSIC] =3D { 0xa0000000, 0x200000 }, + [TT_ATL_ACLINT] =3D { 0xa2180000, 0x10000 }, + [TT_ATL_SIMSIC] =3D { 0xa4000000, 0x200000 }, + [TT_ATL_TIMER] =3D { 0xa8020000, 0x10000 }, + [TT_ATL_WDT0] =3D { 0xa8030000, 0x10000 }, + [TT_ATL_UART0] =3D { 0xb0100000, 0x10000 }, + [TT_ATL_MAPLIC] =3D { 0xcc000000, 0x4000000 }, + [TT_ATL_SAPLIC] =3D { 0xe8000000, 0x4000000 }, + [TT_ATL_DDR_HI] =3D { 0x100000000, 0x1000000000 }, + [TT_ATL_PCIE_ECAM0] =3D { 0x01110000000, 0x10000000 }, + [TT_ATL_PCIE_ECAM1] =3D { 0x01120000000, 0x10000000 }, + [TT_ATL_PCIE_ECAM2] =3D { 0x01130000000, 0x10000000 }, + [TT_ATL_PCIE_MMIO0] =3D { 0x10000000000, 0x10000000000 }, + [TT_ATL_PCIE_MMIO1] =3D { 0x20000000000, 0x10000000000 }, + [TT_ATL_PCIE_MMIO2] =3D { 0x30000000000, 0x10000000000 }, +}; + +static uint32_t next_phandle(void) +{ + static uint32_t phandle =3D 1; + return phandle++; +} + +static void create_fdt_cpus(TTAtlantisState *s, uint32_t *intc_phandles) +{ + uint32_t cpu_phandle; + void *fdt =3D MACHINE(s)->fdt; + + for (int cpu =3D s->soc.num_harts - 1; cpu >=3D 0; cpu--) { + RISCVCPU *cpu_ptr =3D &s->soc.harts[cpu]; + g_autofree char *cpu_name =3D NULL; + g_autofree char *intc_name =3D NULL; + + cpu_phandle =3D next_phandle(); + + cpu_name =3D g_strdup_printf("/cpus/cpu@%d", s->soc.hartid_base + = cpu); + qemu_fdt_add_subnode(fdt, cpu_name); + + qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv57"); + + riscv_isa_write_fdt(cpu_ptr, fdt, cpu_name); + + qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cbom-block-size", + cpu_ptr->cfg.cbom_blocksize); + + qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cboz-block-size", + cpu_ptr->cfg.cboz_blocksize); + + qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cbop-block-size", + cpu_ptr->cfg.cbop_blocksize); + + qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv"); + qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay"); + qemu_fdt_setprop_cell(fdt, cpu_name, "reg", s->soc.hartid_base + c= pu); + qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu"); + qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle); + + intc_phandles[cpu] =3D next_phandle(); + + intc_name =3D g_strdup_printf("%s/interrupt-controller", cpu_name); + qemu_fdt_add_subnode(fdt, intc_name); + qemu_fdt_setprop_cell(fdt, intc_name, "phandle", + intc_phandles[cpu]); + qemu_fdt_setprop_string(fdt, intc_name, "compatible", + "riscv,cpu-intc"); + qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1); + } +} + +static void create_fdt_memory_node(TTAtlantisState *s, + hwaddr addr, hwaddr size) +{ + void *fdt =3D MACHINE(s)->fdt; + g_autofree char *name =3D g_strdup_printf("/memory@%"HWADDR_PRIX, addr= ); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, addr, 2, size); + qemu_fdt_setprop_string(fdt, name, "device_type", "memory"); +} + +static void create_fdt_memory(TTAtlantisState *s) +{ + hwaddr size_lo =3D MACHINE(s)->ram_size; + hwaddr size_hi =3D 0; + + if (size_lo > s->memmap[TT_ATL_DDR_LO].size) { + size_lo =3D s->memmap[TT_ATL_DDR_LO].size; + size_hi =3D MACHINE(s)->ram_size - size_lo; + } + + create_fdt_memory_node(s, s->memmap[TT_ATL_DDR_LO].base, size_lo); + if (size_hi) { + /* + * The first part of the HI address is aliased at the LO address + * so do not include that as usable memory. Is there any way + * (or good reason) to describe that aliasing 2GB with DT? + */ + create_fdt_memory_node(s, s->memmap[TT_ATL_DDR_HI].base + size_lo, + size_hi); + } +} + +static void create_fdt_aclint(TTAtlantisState *s, uint32_t *intc_phandles) +{ + void *fdt =3D MACHINE(s)->fdt; + g_autofree char *name =3D NULL; + g_autofree uint32_t *aclint_mtimer_cells =3D NULL; + uint32_t aclint_cells_size; + hwaddr addr; + + aclint_mtimer_cells =3D g_new0(uint32_t, s->soc.num_harts * 2); + + for (int cpu =3D 0; cpu < s->soc.num_harts; cpu++) { + aclint_mtimer_cells[cpu * 2 + 0] =3D cpu_to_be32(intc_phandles[cpu= ]); + aclint_mtimer_cells[cpu * 2 + 1] =3D cpu_to_be32(IRQ_M_TIMER); + } + aclint_cells_size =3D s->soc.num_harts * sizeof(uint32_t) * 2; + + addr =3D s->memmap[TT_ATL_ACLINT].base; + + name =3D g_strdup_printf("/soc/mtimer@%"HWADDR_PRIX, addr); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,aclint-mtimer"= ); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", + 2, addr + TT_ACLINT_MTIME, + 2, 0x1000, + 2, addr + TT_ACLINT_MTIMECMP, + 2, 0x1000); + qemu_fdt_setprop(fdt, name, "interrupts-extended", + aclint_mtimer_cells, aclint_cells_size); +} + +static void create_fdt_one_imsic(void *fdt, const MemMapEntry *mem, int cp= us, + uint32_t *intc_phandles, uint32_t msi_pha= ndle, + int irq_line, uint32_t imsic_guest_bits) +{ + g_autofree char *name =3D NULL; + g_autofree uint32_t *imsic_cells =3D g_new0(uint32_t, cpus * 2); + + for (int cpu =3D 0; cpu < cpus; cpu++) { + imsic_cells[cpu * 2 + 0] =3D cpu_to_be32(intc_phandles[cpu]); + imsic_cells[cpu * 2 + 1] =3D cpu_to_be32(irq_line); + } + + name =3D g_strdup_printf("/soc/interrupt-controller@%"HWADDR_PRIX, mem= ->base); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,imsics"); + + qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", 0); + qemu_fdt_setprop(fdt, name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop(fdt, name, "msi-controller", NULL, 0); + qemu_fdt_setprop(fdt, name, "interrupts-extended", + imsic_cells, sizeof(uint32_t) * cpus * 2); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->s= ize); + qemu_fdt_setprop_cell(fdt, name, "riscv,num-ids", TT_IRQCHIP_NUM_MSIS); + + if (imsic_guest_bits) { + qemu_fdt_setprop_cell(fdt, name, "riscv,guest-index-bits", + imsic_guest_bits); + } + qemu_fdt_setprop_cell(fdt, name, "phandle", msi_phandle); +} + +static void create_fdt_one_aplic(void *fdt, + const MemMapEntry *mem, + uint32_t msi_phandle, + uint32_t *intc_phandles, + uint32_t aplic_phandle, + uint32_t aplic_child_phandle, + int irq_line, int num_harts) +{ + g_autofree char *name =3D + g_strdup_printf("/soc/interrupt-controller@%"HWADDR_PRIX, mem->bas= e); + g_autofree uint32_t *aplic_cells =3D g_new0(uint32_t, num_harts * 2); + + for (int cpu =3D 0; cpu < num_harts; cpu++) { + aplic_cells[cpu * 2 + 0] =3D cpu_to_be32(intc_phandles[cpu]); + aplic_cells[cpu * 2 + 1] =3D cpu_to_be32(irq_line); + } + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,aplic"); + qemu_fdt_setprop_cell(fdt, name, "#address-cells", 0); + qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", 2); + qemu_fdt_setprop(fdt, name, "interrupt-controller", NULL, 0); + + qemu_fdt_setprop(fdt, name, "interrupts-extended", + aplic_cells, num_harts * sizeof(uint32_t) * 2); + qemu_fdt_setprop_cell(fdt, name, "msi-parent", msi_phandle); + + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->s= ize); + qemu_fdt_setprop_cell(fdt, name, "riscv,num-sources", + TT_IRQCHIP_NUM_SOURCES); + + if (aplic_child_phandle) { + qemu_fdt_setprop_cell(fdt, name, "riscv,children", + aplic_child_phandle); + qemu_fdt_setprop_cells(fdt, name, "riscv,delegation", + aplic_child_phandle, 1, TT_IRQCHIP_NUM_SOUR= CES); + } + + qemu_fdt_setprop_cell(fdt, name, "phandle", aplic_phandle); +} + +static void create_fdt_pmu(TTAtlantisState *s) +{ + g_autofree char *pmu_name =3D g_strdup_printf("/pmu"); + void *fdt =3D MACHINE(s)->fdt; + RISCVCPU *hart =3D &s->soc.harts[0]; + + qemu_fdt_add_subnode(fdt, pmu_name); + qemu_fdt_setprop_string(fdt, pmu_name, "compatible", "riscv,pmu"); + riscv_pmu_generate_fdt_node(fdt, hart->pmu_avail_ctrs, pmu_name); +} + +static void create_fdt_cpu(TTAtlantisState *s, const MemMapEntry *memmap, + uint32_t aplic_s_phandle, + uint32_t imsic_s_phandle) +{ + MachineState *ms =3D MACHINE(s); + void *fdt =3D MACHINE(s)->fdt; + g_autofree uint32_t *intc_phandles =3D NULL; + + qemu_fdt_add_subnode(fdt, "/cpus"); + qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", + TT_ACLINT_TIMEBASE_FREQ); + qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); + qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); + + intc_phandles =3D g_new0(uint32_t, ms->smp.cpus); + + create_fdt_cpus(s, intc_phandles); + + create_fdt_memory(s); + + create_fdt_aclint(s, intc_phandles); + + /* M-level IMSIC node */ + uint32_t msi_m_phandle =3D next_phandle(); + create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_MIMSIC], ms->smp.cpus, + intc_phandles, msi_m_phandle, + IRQ_M_EXT, 0); + + /* S-level IMSIC node */ + create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_SIMSIC], ms->smp.cpus, + intc_phandles, imsic_s_phandle, + IRQ_S_EXT, imsic_num_bits(TT_IRQCHIP_GUESTS + 1)); + + uint32_t aplic_m_phandle =3D next_phandle(); + + /* M-level APLIC node */ + create_fdt_one_aplic(fdt, &s->memmap[TT_ATL_MAPLIC], + msi_m_phandle, intc_phandles, + aplic_m_phandle, aplic_s_phandle, + IRQ_M_EXT, s->soc.num_harts); + + /* S-level APLIC node */ + create_fdt_one_aplic(fdt, &s->memmap[TT_ATL_SAPLIC], + imsic_s_phandle, intc_phandles, + aplic_s_phandle, 0, + IRQ_S_EXT, s->soc.num_harts); +} + +static void create_fdt_reset(void *fdt, const MemMapEntry *mem) +{ + uint32_t syscon_phandle =3D next_phandle(); + char *name; + + name =3D g_strdup_printf("/soc/syscon@%"HWADDR_PRIX, mem->base); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "syscon"); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->s= ize); + qemu_fdt_setprop_cell(fdt, name, "phandle", syscon_phandle); + g_free(name); + + name =3D g_strdup_printf("/poweroff"); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "syscon-poweroff"); + qemu_fdt_setprop_cell(fdt, name, "regmap", syscon_phandle); + qemu_fdt_setprop_cell(fdt, name, "offset", 0x0); + qemu_fdt_setprop_cell(fdt, name, "value", PVPANIC_SHUTDOWN); + g_free(name); +} + +static void create_fdt_uart(void *fdt, const MemMapEntry *mem, int irq, + int irqchip_phandle) +{ + g_autofree char *name =3D g_strdup_printf("/soc/serial@%"HWADDR_PRIX, + mem->base); + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "ns16550a"); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->s= ize); + qemu_fdt_setprop_cell(fdt, name, "reg-shift", 2); + qemu_fdt_setprop_cell(fdt, name, "reg-io-width", 4); + qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 3686400); + qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", irqchip_phandle); + qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x4); + + qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", name); + qemu_fdt_setprop_string(fdt, "/aliases", "serial0", name); +} + +static void create_fdt_fw_cfg(void *fdt, const MemMapEntry *mem) +{ + g_autofree char *name =3D g_strdup_printf("/fw-cfg@%"HWADDR_PRIX, mem-= >base); + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "qemu,fw-cfg-mmio"); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->s= ize); + qemu_fdt_setprop(fdt, name, "dma-coherent", NULL, 0); +} + +static void finalize_fdt(TTAtlantisState *s) +{ + uint32_t aplic_s_phandle =3D next_phandle(); + uint32_t imsic_s_phandle =3D next_phandle(); + void *fdt =3D MACHINE(s)->fdt; + + create_fdt_cpu(s, s->memmap, aplic_s_phandle, imsic_s_phandle); + + /* + * We want to do this, but the Linux aplic driver was broken before v6= .16 + * + * qemu_fdt_setprop_cell(MACHINE(s)->fdt, "/soc", "interrupt-parent", + * aplic_s_phandle); + */ + + create_fdt_reset(fdt, &s->memmap[TT_ATL_SYSCON]); + + create_fdt_uart(fdt, &s->memmap[TT_ATL_UART0], TT_ATL_UART0_IRQ, + aplic_s_phandle); +} + +static void create_fdt(TTAtlantisState *s) +{ + MachineState *ms =3D MACHINE(s); + uint8_t rng_seed[32]; + g_autofree char *name =3D NULL; + void *fdt; + + fdt =3D create_device_tree(&s->fdt_size); + if (!fdt) { + error_report("create_device_tree() failed"); + exit(1); + } + ms->fdt =3D fdt; + + qemu_fdt_setprop_string(fdt, "/", "model", + "Tenstorrent Atlantis RISC-V Machine"); + qemu_fdt_setprop_string(fdt, "/", "compatible", "tenstorrent,atlantis"= ); + qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2); + qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2); + + qemu_fdt_add_subnode(fdt, "/soc"); + qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0); + qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus"); + qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2); + qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2); + + qemu_fdt_add_subnode(fdt, "/chosen"); + + /* Pass seed to RNG */ + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + qemu_fdt_setprop(fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed= )); + + qemu_fdt_add_subnode(fdt, "/aliases"); + + create_fdt_fw_cfg(fdt, &s->memmap[TT_ATL_FW_CFG]); + create_fdt_pmu(s); +} + +static DeviceState *create_reboot_device(const MemMapEntry *mem) +{ + DeviceState *dev =3D qdev_new(TYPE_PVPANIC_MMIO_DEVICE); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(dev); + + qdev_prop_set_uint32(dev, "events", PVPANIC_SHUTDOWN | PVPANIC_PANICKE= D); + + sysbus_realize_and_unref(sbd, &error_fatal); + sysbus_mmio_map(sbd, 0, mem->base); + + return dev; +} + +static FWCfgState *create_fw_cfg(const MemMapEntry *mem, int num_cpus) +{ + FWCfgState *fw_cfg; + hwaddr base =3D mem->base; + + fw_cfg =3D fw_cfg_init_mem_dma(base + 8, base, 8, base + 16, + &address_space_memory); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, num_cpus); + + return fw_cfg; +} + +static void tt_atlantis_machine_done(Notifier *notifier, void *data) +{ + TTAtlantisState *s =3D container_of(notifier, TTAtlantisState, machine= _done); + MachineState *machine =3D MACHINE(s); + hwaddr start_addr =3D s->memmap[TT_ATL_DDR_LO].base; + hwaddr mem_size; + target_ulong firmware_end_addr, kernel_start_addr; + const char *firmware_name =3D riscv_default_firmware_name(&s->soc); + uint64_t fdt_load_addr; + uint64_t kernel_entry; + RISCVBootInfo boot_info; + + /* + * A user provided dtb must include everything, including + * dynamic sysbus devices. Our FDT needs to be finalized. + */ + if (machine->dtb =3D=3D NULL) { + finalize_fdt(s); + } + + mem_size =3D machine->ram_size; + if (mem_size > s->memmap[TT_ATL_DDR_LO].size) { + mem_size =3D s->memmap[TT_ATL_DDR_LO].size; + } + riscv_boot_info_init_discontig_mem(&boot_info, &s->soc, + s->memmap[TT_ATL_DDR_LO].base, + mem_size); + + firmware_end_addr =3D riscv_find_and_load_firmware(machine, &boot_info, + firmware_name, + &start_addr, NULL); + + kernel_start_addr =3D riscv_calc_kernel_start_addr(&boot_info, + firmware_end_addr); + if (machine->kernel_filename) { + riscv_load_kernel(machine, &boot_info, kernel_start_addr, + true, NULL); + } else { + riscv_setup_halting_payload(&boot_info, kernel_start_addr); + } + kernel_entry =3D boot_info.image_low_addr; + + fdt_load_addr =3D riscv_compute_fdt_addr(s->memmap[TT_ATL_DDR_LO].base, + s->memmap[TT_ATL_DDR_LO].size, + machine, &boot_info); + riscv_load_fdt(fdt_load_addr, machine->fdt); + + /* load the reset vector */ + riscv_setup_rom_reset_vec(machine, &s->soc, start_addr, + s->memmap[TT_ATL_BOOTROM].base, + s->memmap[TT_ATL_BOOTROM].size, + kernel_entry, + fdt_load_addr); + +} + +static void tt_atlantis_machine_init(MachineState *machine) +{ + TTAtlantisState *s =3D TT_ATLANTIS_MACHINE(machine); + + MemoryRegion *system_memory =3D get_system_memory(); + MemoryRegion *ram_hi =3D g_new(MemoryRegion, 1); + MemoryRegion *ram_lo =3D g_new(MemoryRegion, 1); + MemoryRegion *bootrom =3D g_new(MemoryRegion, 1); + ram_addr_t lo_ram_size, hi_ram_size; + int hart_count =3D machine->smp.cpus; + int base_hartid =3D 0; + + s->memmap =3D tt_atlantis_memmap; + + object_initialize_child(OBJECT(machine), "soc", &s->soc, + TYPE_RISCV_HART_ARRAY); + object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type, + &error_abort); + object_property_set_int(OBJECT(&s->soc), "hartid-base", base_hartid, + &error_abort); + object_property_set_int(OBJECT(&s->soc), "num-harts", hart_count, + &error_abort); + object_property_set_int(OBJECT(&s->soc), "resetvec", + s->memmap[TT_ATL_BOOTROM].base, + &error_abort); + sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal); + + s->irqchip =3D riscv_create_aia(true, TT_IRQCHIP_GUESTS, + TT_IRQCHIP_NUM_SOURCES, + &s->memmap[TT_ATL_MAPLIC], + &s->memmap[TT_ATL_SAPLIC], + &s->memmap[TT_ATL_MIMSIC], + &s->memmap[TT_ATL_SIMSIC], + 0, base_hartid, hart_count, + TT_IRQCHIP_NUM_MSIS, + TT_IRQCHIP_NUM_PRIO_BITS); + + riscv_aclint_mtimer_create(s->memmap[TT_ATL_ACLINT].base, + TT_ACLINT_MTIME_SIZE, + base_hartid, hart_count, + TT_ACLINT_MTIMECMP, + TT_ACLINT_MTIME, + TT_ACLINT_TIMEBASE_FREQ, true); + + /* DDR */ + + /* The high address covers all of RAM, the low address just the first = 2GB */ + lo_ram_size =3D s->memmap[TT_ATL_DDR_LO].size; + hi_ram_size =3D s->memmap[TT_ATL_DDR_HI].size; + if (machine->ram_size > hi_ram_size) { + char *sz =3D size_to_str(hi_ram_size); + error_report("RAM size is too large, maximum is %s", sz); + g_free(sz); + exit(EXIT_FAILURE); + } + + memory_region_init_alias(ram_lo, OBJECT(machine), "ram.low", machine->= ram, + 0, lo_ram_size); + memory_region_init_alias(ram_hi, OBJECT(machine), "ram.high", machine-= >ram, + 0, hi_ram_size); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_DDR_LO].base, ram_lo); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_DDR_HI].base, ram_hi); + + /* Boot ROM */ + memory_region_init_rom(bootrom, NULL, "tt-atlantis.bootrom", + s->memmap[TT_ATL_BOOTROM].size, &error_fatal); + memory_region_add_subregion(system_memory, s->memmap[TT_ATL_BOOTROM].b= ase, + bootrom); + + /* + * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the + * device tree cannot be altered and we get FDT_ERR_NOSPACE. + */ + s->fw_cfg =3D create_fw_cfg(&s->memmap[TT_ATL_FW_CFG], machine->smp.cp= us); + rom_set_fw(s->fw_cfg); + + /* Reboot and exit */ + create_reboot_device(&s->memmap[TT_ATL_SYSCON]); + + /* UART */ + serial_mm_init(system_memory, s->memmap[TT_ATL_UART0].base, 2, + qdev_get_gpio_in(s->irqchip, TT_ATL_UART0_IRQ), + 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); + + /* Load or create device tree */ + if (machine->dtb) { + machine->fdt =3D load_device_tree(machine->dtb, &s->fdt_size); + if (!machine->fdt) { + error_report("load_device_tree() failed"); + exit(1); + } + } else { + create_fdt(s); + } + + s->machine_done.notify =3D tt_atlantis_machine_done; + qemu_add_machine_init_done_notifier(&s->machine_done); +} + +static void tt_atlantis_machine_class_init(ObjectClass *oc, const void *da= ta) +{ + MachineClass *mc =3D MACHINE_CLASS(oc); + + mc->desc =3D "Tenstorrent Atlantis RISC-V SoC"; + mc->init =3D tt_atlantis_machine_init; + mc->max_cpus =3D 8; + mc->default_cpus =3D 8; + mc->default_ram_size =3D 2 * GiB; + mc->default_cpu_type =3D TYPE_RISCV_CPU_TT_ASCALON; + mc->block_default_type =3D IF_VIRTIO; + mc->no_cdrom =3D 1; + mc->default_ram_id =3D "tt_atlantis.ram"; +} + +static const TypeInfo tt_atlantis_types[] =3D { + { + .name =3D MACHINE_TYPE_NAME("tt-atlantis"), + .parent =3D TYPE_MACHINE, + .class_init =3D tt_atlantis_machine_class_init, + .instance_size =3D sizeof(TTAtlantisState), + }, +}; + +DEFINE_TYPES(tt_atlantis_types) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 0222c93f878b..0601ae1a7494 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -120,6 +120,21 @@ config SPIKE select RISCV_ACLINT select SIFIVE_PLIC =20 +config TENSTORRENT + bool + default y + depends on RISCV64 + imply PCI_DEVICES + imply TEST_DEVICES + select DEVICE_TREE + select RISCV_NUMA + select PVPANIC_MMIO + select SERIAL_MM + select RISCV_ACLINT + select RISCV_APLIC + select RISCV_IMSIC + select FW_CFG_DMA + config XIANGSHAN_KUNMINGHU bool default y diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build index e53c180d0d10..026e79591f4b 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -9,6 +9,7 @@ riscv_ss.add(when: 'CONFIG_SIFIVE_E', if_true: files('sifiv= e_e.c')) riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: files('sifive_u.c')) riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c')) riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: files('microchip_pfs= oc.c')) +riscv_ss.add(when: 'CONFIG_TENSTORRENT', if_true: files('tt_atlantis.c')) riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c')) riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files( 'riscv-iommu.c', 'riscv-iommu-pci.c', 'riscv-iommu-sys.c', 'riscv-iommu-h= pm.c')) --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749739537355.5128287930245; Mon, 20 Apr 2026 22:35:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3kO-0000lr-EN; Tue, 21 Apr 2026 01:34:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3k8-0000az-QR for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:55 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3k6-0004VA-Kh for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:52 -0400 Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-3567e2b4159so2538939a91.0 for ; Mon, 20 Apr 2026 22:33:50 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749629; x=1777354429; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=SkQdP30uKyUlHIFKW9Uy40Our+7o3vknC9ZwGR+fDis=; b=J3Xox+EpVnJAYsQESEiJFdZcf6EZjUP3QXnpypTQI+l27pMR0/36D+ZhWIEpZMgck0 TWfsTsYHIzCxwdV8ZnWCZ9cnGcLyOcSocpTUysvPJkzJgqrTdcdBPwKjM2UENrSHGhnY ARgsP1QkgEhhERjVUIvDybs1bHqjKfOmMidnf5ab/ugJAdeYGJfet9tN1EgqlyjVnvKV kVhQk/xvEPxMECoSH97irGIbXzwNR/2iyk4jfYmPZC1eUh3E4pBLJPRtstedXC5nr2x3 3vvXDxag2l7r9LJvlBLODSVgWACKTKAx4rS+0zWjXnPbeVNjSxHHiMp/uNs0RikQqhCh Oktg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749629; x=1777354429; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=SkQdP30uKyUlHIFKW9Uy40Our+7o3vknC9ZwGR+fDis=; b=Ttki634iCRRIq/xeX1g0Wjf6YViQnUxUfRqFymgg9HJu+ccZdFH3Ywq5aS3pind0YV UzN99kBJAVjl8BPpfkTxTks2g93FnXagU1QBvThLdl75NA86GapVQVX0nSbAOKgkZAPV VOJQ+ckLvQXZyPFOedUJgYamr+JAqwqDAO1+uRvdTyg4pqmyTtNDm02Vef1DB4Bz+UK8 g9EivVwrgRbpIopWZIrJUvJhi1Y4pNwJP5OyFhuuLtmQYQAzd7OJFGcAlUF8AIIGIvAt 7Zt/F5oIBB14m276k183b0CSLwycuwvrojptsGHRAUGdUPa4feK4s1HKVXfATfB3y8ee nB9g== X-Forwarded-Encrypted: i=1; AFNElJ+LDE3mkKwauJa0Qr9JnBXr69b83J8WUXwRENXN8PlAHIwO18+CfL7PnsO5S1IqcRH2aR4ceNp5Mu0Y@nongnu.org X-Gm-Message-State: AOJu0YyscfJaelG82nhwbZXGfeUo8BDV4DkfygGKWkbEruluSlgcjJ80 NZAKE0v78/obz8xqauD/toRjuxc8aLAmSedX6PmOfIjuio8issCS2U5q X-Gm-Gg: AeBDietgbNNBkjUY1uCj3bql6l88kMDgiEp08R13wzidNO1yOPlo/D7JHRhJY/Brch1 JM0bNFAwRZAcO9vs3GjjjpH6Fd1FqXbr/8QhvS/hH9HzfC+y5C8lffd+AI1rwmR6+SLBD7NKcAP H+r6dByA2nAORiSAM+2Kuo41amUP4gW060WLl1E5vcmla443U+aebz/J5Dso7vYhzX7YoWVV9UG 0UcUK8FaDwlsxLNRnNUpxV4anDqR8yQ7krvQ2DKR85hZx7uftkOytdVVhmqguiD/5H3MD3AF2Vq 0lTI40q3q6tbEMWbScOktiSQXO4fsRjW0tHWLZSJEWZ+LenEEh/CKAk+kjgg2C1ofb+/JjH6NG4 bFKY07HwqhfYgE1ELn9BA4ejlEysBawVr8/IFKIf0vu5GKb7ZQT/WLk9W9xZ2VKn+ZOu0geWuBW RyntetYUKNEp0jDMjjd/QsdLK3NbBY0anXHz+PIpbRUKn6imcCFCGNTy+xLZCNnmieR71OH13f1 LLeiTgM7LS64obL53ra9Y/jKZ4lvt8xdc3jzhAoK+c8KeKH X-Received: by 2002:a17:90a:da8c:b0:35e:3afb:a3ff with SMTP id 98e67ed59e1d1-361403cbd7cmr16548218a91.3.1776749629184; Mon, 20 Apr 2026 22:33:49 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Nicholas Piggin , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 10/13] hw/riscv/atlantis: Add PCIe controller Date: Tue, 21 Apr 2026 15:31:35 +1000 Message-ID: <20260421053140.752059-11-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x102f.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749740409154100 Content-Type: text/plain; charset="utf-8" From: Nicholas Piggin tt-atlantis is likely to use a generic ECAM compatible PCIe memory map, so gpex is not far off the OS programming model Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- v3: Avoid leaks in the dt string allocation --- include/hw/riscv/tt_atlantis.h | 2 + hw/riscv/tt_atlantis.c | 225 ++++++++++++++++++++++++++++++++- hw/riscv/Kconfig | 2 + 3 files changed, 228 insertions(+), 1 deletion(-) diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h index f7f79e9f2c53..c0a0827a5167 100644 --- a/include/hw/riscv/tt_atlantis.h +++ b/include/hw/riscv/tt_atlantis.h @@ -28,6 +28,7 @@ struct TTAtlantisState { =20 RISCVHartArrayState soc; DeviceState *irqchip; + GPEXHost gpex_host; =20 int fdt_size; }; @@ -39,6 +40,7 @@ enum { TT_ATL_UART2_IRQ =3D 40, TT_ATL_UART3_IRQ =3D 41, TT_ATL_UART4_IRQ =3D 42, + TT_ATL_PCIE0_INTA_IRQ =3D 96, }; =20 enum { diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index a556ff79c8c8..e1753d3c1f18 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -27,6 +27,7 @@ #include "hw/intc/riscv_aclint.h" #include "hw/intc/riscv_aplic.h" #include "hw/misc/pvpanic.h" +#include "hw/pci-host/gpex.h" =20 #include "system/system.h" #include "system/device_tree.h" @@ -70,6 +71,9 @@ static const MemMapEntry tt_atlantis_memmap[] =3D { [TT_ATL_PCIE_ECAM1] =3D { 0x01120000000, 0x10000000 }, [TT_ATL_PCIE_ECAM2] =3D { 0x01130000000, 0x10000000 }, [TT_ATL_PCIE_MMIO0] =3D { 0x10000000000, 0x10000000000 }, + [TT_ATL_PCIE_PIO0] =3D { 0x10000000000, 0x10000 }, /* qemu o= nly */ + [TT_ATL_PCIE_MMIO0_32] =3D { 0x10004000000, 0x4000000 }, /* qemu o= nly */ + [TT_ATL_PCIE_MMIO0_64] =3D { 0x10010000000, 0x0fff0000000 }, /* qemu o= nly */ [TT_ATL_PCIE_MMIO1] =3D { 0x20000000000, 0x10000000000 }, [TT_ATL_PCIE_MMIO2] =3D { 0x30000000000, 0x10000000000 }, }; @@ -80,6 +84,59 @@ static uint32_t next_phandle(void) return phandle++; } =20 +static void create_pcie_irq_map(void *fdt, char *nodename, int legacy_irq, + uint32_t irqchip_phandle) +{ + int pin, dev; + uint32_t irq_map_stride =3D 0; + uint32_t full_irq_map[PCI_NUM_PINS * PCI_NUM_PINS * + FDT_MAX_INT_MAP_WIDTH] =3D {}; + uint32_t *irq_map =3D full_irq_map; + + /* + * This code creates a standard swizzle of interrupts such that + * each device's first interrupt is based on it's PCI_SLOT number. + * (See pci_swizzle_map_irq_fn()) + * + * We only need one entry per interrupt in the table (not one per + * possible slot) seeing the interrupt-map-mask will allow the table + * to wrap to any number of devices. + */ + for (dev =3D 0; dev < PCI_NUM_PINS; dev++) { + int devfn =3D dev * 0x8; + + for (pin =3D 0; pin < PCI_NUM_PINS; pin++) { + int irq_nr =3D legacy_irq + ((pin + PCI_SLOT(devfn)) % PCI_NUM= _PINS); + int i =3D 0; + + /* Fill PCI address cells */ + irq_map[i] =3D cpu_to_be32(devfn << 8); + i +=3D FDT_PCI_ADDR_CELLS; + + /* Fill PCI Interrupt cells */ + irq_map[i] =3D cpu_to_be32(pin + 1); + i +=3D FDT_PCI_INT_CELLS; + + /* Fill interrupt controller phandle and cells */ + irq_map[i++] =3D cpu_to_be32(irqchip_phandle); + irq_map[i++] =3D cpu_to_be32(irq_nr); + irq_map[i++] =3D cpu_to_be32(0x4); + + if (!irq_map_stride) { + irq_map_stride =3D i; + } + irq_map +=3D irq_map_stride; + } + } + + qemu_fdt_setprop(fdt, nodename, "interrupt-map", full_irq_map, + PCI_NUM_PINS * PCI_NUM_PINS * + irq_map_stride * sizeof(uint32_t)); + + qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask", + 0x1800, 0, 0, 0x7); +} + static void create_fdt_cpus(TTAtlantisState *s, uint32_t *intc_phandles) { uint32_t cpu_phandle; @@ -320,6 +377,54 @@ static void create_fdt_cpu(TTAtlantisState *s, const M= emMapEntry *memmap, IRQ_S_EXT, s->soc.num_harts); } =20 +static void create_fdt_pcie(void *fdt, + const MemMapEntry *mem_ecam, + const MemMapEntry *mem_pio, + const MemMapEntry *mem_mmio32, + const MemMapEntry *mem_mmio64, + int legacy_irq, + uint32_t aplic_s_phandle, + uint32_t imsic_s_phandle) +{ + g_autofree char *name =3D g_strdup_printf("/soc/pci@%"HWADDR_PRIX, + mem_ecam->base); + + qemu_fdt_setprop_cell(fdt, name, "#address-cells", FDT_PCI_ADDR_CELLS); + qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", FDT_PCI_INT_CELLS= ); + qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0x2); + qemu_fdt_setprop_string(fdt, name, "compatible", "pci-host-ecam-generi= c"); + qemu_fdt_setprop_string(fdt, name, "device_type", "pci"); + qemu_fdt_setprop_cells(fdt, name, "bus-range", 0, + mem_ecam->size / PCIE_MMCFG_SIZE_MIN - 1); + qemu_fdt_setprop(fdt, name, "dma-coherent", NULL, 0); + qemu_fdt_setprop_cell(fdt, name, "msi-parent", imsic_s_phandle); + + qemu_fdt_setprop_sized_cells(fdt, name, "reg", + 2, mem_ecam->base, + 2, mem_ecam->size); + if (!(mem_mmio32->base & 0xffffffffUL)) { + /* XXX: this is a silly hack because it would collide with PIO */ + error_report("mmio32 base must not be 0 mod 2^32"); + exit(1); + } + uint32_t flags =3D FDT_PCI_RANGE_MMIO_64BIT | FDT_PCI_RANGE_PREFETCHAB= LE; + qemu_fdt_setprop_sized_cells(fdt, name, "ranges", + 1, FDT_PCI_RANGE_IOPORT, + 2, 0x0, + 2, mem_pio->base, + 2, mem_pio->size, + 1, FDT_PCI_RANGE_MMIO, + 2, (mem_mmio32->base & 0xffffffffUL), + 2, mem_mmio32->base, + 2, mem_mmio32->size, + 1, flags, + 2, mem_mmio64->base, + 2, mem_mmio64->base, + 2, mem_mmio64->size); + + create_pcie_irq_map(fdt, name, legacy_irq, aplic_s_phandle); +} + static void create_fdt_reset(void *fdt, const MemMapEntry *mem) { uint32_t syscon_phandle =3D next_phandle(); @@ -385,6 +490,14 @@ static void finalize_fdt(TTAtlantisState *s) * aplic_s_phandle); */ =20 + create_fdt_pcie(fdt, + &s->memmap[TT_ATL_PCIE_ECAM0], + &s->memmap[TT_ATL_PCIE_PIO0], + &s->memmap[TT_ATL_PCIE_MMIO0_32], + &s->memmap[TT_ATL_PCIE_MMIO0_64], + TT_ATL_PCIE0_INTA_IRQ, + aplic_s_phandle, imsic_s_phandle); + create_fdt_reset(fdt, &s->memmap[TT_ATL_SYSCON]); =20 create_fdt_uart(fdt, &s->memmap[TT_ATL_UART0], TT_ATL_UART0_IRQ, @@ -395,7 +508,7 @@ static void create_fdt(TTAtlantisState *s) { MachineState *ms =3D MACHINE(s); uint8_t rng_seed[32]; - g_autofree char *name =3D NULL; + char *name; void *fdt; =20 fdt =3D create_device_tree(&s->fdt_size); @@ -417,6 +530,25 @@ static void create_fdt(TTAtlantisState *s) qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2); qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2); =20 + /* + * The "/soc/pci@..." node is needed for PCIE hotplugs + * that might happen before finalize_fdt(). + */ + name =3D g_strdup_printf("/soc/pci@%"HWADDR_PRIX, + s->memmap[TT_ATL_PCIE_ECAM0].base); + qemu_fdt_add_subnode(fdt, name); + g_free(name); + + name =3D g_strdup_printf("/soc/pci@%"HWADDR_PRIX, + s->memmap[TT_ATL_PCIE_ECAM1].base); + qemu_fdt_add_subnode(fdt, name); + g_free(name); + + name =3D g_strdup_printf("/soc/pci@%"HWADDR_PRIX, + s->memmap[TT_ATL_PCIE_ECAM2].base); + qemu_fdt_add_subnode(fdt, name); + g_free(name); + qemu_fdt_add_subnode(fdt, "/chosen"); =20 /* Pass seed to RNG */ @@ -429,6 +561,93 @@ static void create_fdt(TTAtlantisState *s) create_fdt_pmu(s); } =20 +static void gpex_pcie_init_one(TTAtlantisState *s, GPEXHost *gpex_host, + MemoryRegion *mr, + const MemMapEntry *mem_ecam, + const MemMapEntry *mem_pio, + const MemMapEntry *mem_mmio32, + const MemMapEntry *mem_mmio64, + int legacy_irq) +{ + DeviceState *dev; + Object *obj; + MemoryRegion *ecam_alias, *ecam_reg; + MemoryRegion *mmio32_alias, *mmio64_alias, *mmio_reg; + hwaddr ecam_base =3D mem_ecam->base; + hwaddr ecam_size =3D mem_ecam->size; + hwaddr pio_base =3D mem_pio->base; + hwaddr pio_size =3D mem_pio->size; + hwaddr mmio32_base =3D mem_mmio32->base; + hwaddr mmio32_size =3D mem_mmio32->size; + hwaddr mmio64_base =3D mem_mmio64->base; + hwaddr mmio64_size =3D mem_mmio64->size; + qemu_irq irq; + char name[16]; + int i; + + snprintf(name, sizeof(name), "pcie"); + object_initialize_child(OBJECT(s), name, gpex_host, TYPE_GPEX_HOST); + dev =3D DEVICE(gpex_host); + obj =3D OBJECT(dev); + + object_property_set_uint(obj, PCI_HOST_ECAM_BASE, ecam_base, &error_ab= ort); + object_property_set_int(obj, PCI_HOST_ECAM_SIZE, ecam_size, &error_abo= rt); + object_property_set_uint(obj, PCI_HOST_BELOW_4G_MMIO_BASE, mmio32_base, + &error_abort); + object_property_set_int(obj, PCI_HOST_BELOW_4G_MMIO_SIZE, mmio32_size, + &error_abort); + object_property_set_uint(obj, PCI_HOST_ABOVE_4G_MMIO_BASE, mmio64_base, + &error_abort); + object_property_set_int(obj, PCI_HOST_ABOVE_4G_MMIO_SIZE, mmio64_size, + &error_abort); + object_property_set_uint(obj, PCI_HOST_PIO_BASE, pio_base, &error_abor= t); + object_property_set_int(obj, PCI_HOST_PIO_SIZE, pio_size, &error_abort= ); + + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + + ecam_alias =3D g_new0(MemoryRegion, 1); + ecam_reg =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); + snprintf(name, sizeof(name), "pcie.ecam"); + memory_region_init_alias(ecam_alias, obj, name, + ecam_reg, 0, ecam_size); + memory_region_add_subregion(mr, ecam_base, ecam_alias); + + mmio_reg =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); + + mmio32_alias =3D g_new0(MemoryRegion, 1); + snprintf(name, sizeof(name), "pcie.mmio32"); + memory_region_init_alias(mmio32_alias, obj, name, + mmio_reg, mmio32_base & 0xffffffffUL, mmio32_= size); + memory_region_add_subregion(mr, mmio32_base, mmio32_alias); + + mmio64_alias =3D g_new0(MemoryRegion, 1); + snprintf(name, sizeof(name), "pcie.mmio64"); + memory_region_init_alias(mmio64_alias, obj, name, + mmio_reg, mmio64_base, mmio64_size); + memory_region_add_subregion(mr, mmio64_base, mmio64_alias); + + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, pio_base); + + for (i =3D 0; i < PCI_NUM_PINS; i++) { + irq =3D qdev_get_gpio_in(s->irqchip, legacy_irq + i); + + sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq); + gpex_set_irq_num(GPEX_HOST(dev), i, legacy_irq + i); + } + + gpex_host->gpex_cfg.bus =3D PCI_HOST_BRIDGE(dev)->bus; +} + +static void gpex_pcie_init(TTAtlantisState *s, MemoryRegion *mr) +{ + gpex_pcie_init_one(s, &s->gpex_host, mr, + &s->memmap[TT_ATL_PCIE_ECAM0], + &s->memmap[TT_ATL_PCIE_PIO0], + &s->memmap[TT_ATL_PCIE_MMIO0_32], + &s->memmap[TT_ATL_PCIE_MMIO0_64], + TT_ATL_PCIE0_INTA_IRQ); +} + static DeviceState *create_reboot_device(const MemMapEntry *mem) { DeviceState *dev =3D qdev_new(TYPE_PVPANIC_MMIO_DEVICE); @@ -588,6 +807,9 @@ static void tt_atlantis_machine_init(MachineState *mach= ine) s->fw_cfg =3D create_fw_cfg(&s->memmap[TT_ATL_FW_CFG], machine->smp.cp= us); rom_set_fw(s->fw_cfg); =20 + /* PCIe */ + gpex_pcie_init(s, system_memory); + /* Reboot and exit */ create_reboot_device(&s->memmap[TT_ATL_SYSCON]); =20 @@ -623,6 +845,7 @@ static void tt_atlantis_machine_class_init(ObjectClass = *oc, const void *data) mc->default_cpu_type =3D TYPE_RISCV_CPU_TT_ASCALON; mc->block_default_type =3D IF_VIRTIO; mc->no_cdrom =3D 1; + mc->pci_allow_0_address =3D true; mc->default_ram_id =3D "tt_atlantis.ram"; } =20 diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 0601ae1a7494..2ddee591eb90 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -129,6 +129,8 @@ config TENSTORRENT select DEVICE_TREE select RISCV_NUMA select PVPANIC_MMIO + select PCI + select PCI_EXPRESS_GENERIC_BRIDGE select SERIAL_MM select RISCV_ACLINT select RISCV_APLIC --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749741106717.0851049171857; Mon, 20 Apr 2026 22:35:41 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3kQ-00015C-BO; Tue, 21 Apr 2026 01:34:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3kF-0000fv-C9 for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:34:03 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3kA-0004ZW-PB for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:33:56 -0400 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-35da2d35eccso2714258a91.0 for ; Mon, 20 Apr 2026 22:33:54 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749633; x=1777354433; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=tY/qxLv+6MgU0IiIphGv/gCJH4XtLm4qBwv2FYa1ikg=; b=KC9B504NeP7bQ+fPiKMlGkbxnz6hOc9rcyAHg5d8f1VM+8/ikBUt1oDiugBCQtvZwu nV1jWjCowd3/FStva8VbNPB9Vna6kd7oBtykNYcAqaLja7dyTjn6LUUv/1cHTyEvePhF z6lA5Szu6Y+Ecvw7cic9IsDIlcFf3G7VLRb+zIbf1sLdLmoed4VxW5B5sK0Q3AAKnUNF em/+zXNgIk4tiiFYkTTg0ml8mVE6L474u4gf77qSTz7piuA3vEZ9KiCOIlxqLoZiyU4k xbgX+CeOByHkobbpgZeffgMDrw6AbDrMinQeHCZRjClqrwlndwHB5d5Jmyb05yHQ1ocg S9Aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749633; x=1777354433; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tY/qxLv+6MgU0IiIphGv/gCJH4XtLm4qBwv2FYa1ikg=; b=FlaeGbZ/1Wg81hVzpoLAMh8++YO7vRLFoAhc4a7qChE7b8jmARN/NAv29mQ81ttRay M3Jl+EGwB1IbEp3+T/agKFpmUcAXggjqe7wDMsMEgfsMrgqGxjxhaIBtFJffG7CcY+wv 3lTYzqCGBKyqUGLOmtI8MGhB0zbzn0bXFFkuxCYCRN7/hNbcn98IhvaAn9R4rm1fdH4M HnktSn2LZa9WbzBJbWfyBMmxL9s9ljRW1JwR5EVnVwdOG+t53Lhx5LrKrf5OxW1b4hLB vJOpR5a2jYz6BYQi4L6ngSAnmM9gVZLozK2BBrkDi24UKPB+q/Z2C6MU4yNPsKEM9J0O yarw== X-Forwarded-Encrypted: i=1; AFNElJ+lhFL/W4PQiQwhgU3RvcalqoncCuBWtRY69YHk+dVMNHzzPNi81GulRfHeRFF6XFEhgesDcnUog8K4@nongnu.org X-Gm-Message-State: AOJu0Yz9gPNv7oYkPvkW2CBLbF4ss/R+bVlYwHfGxBauegiTaTfiEyyZ gY1y2vHXE7tTDALSurin/92X5O3ZDdfzM6wvwdtn/bAnfiabn2HPAu25 X-Gm-Gg: AeBDietWQf6b0zLQmN0tiY2/X1v4RFK8S/UH6v7QQGEFOZQxIo35GDoPhGZU8CqT6EC 9OMgv12tMgLdeq9hmsD/6d6d75XsUvv8koDMe8KD8Rh8e/lDx900vwERLo2D0zN8Eg7IKOKWt8s 3plkWZGmjwTmbJJdNU+igH53FfuhIXUDmYXNg2SfpYEBe03AM6jgJQO/ZUWYFkU2g3n6A8AR7FJ aOuURuPXAYkxqgt5YubaYKKdWGdshU+64LITnfSFu1LvWd99Q8xqRLzEsPERTZOBzSdj57j5pNR w1WJOSkQ6IEEDjKvisBP/qnLBk0YosKil/qskJ1ii9I1ZLx7vAqFsm3m4mAZLtiYLhbCcI1CQ5a cGSNQK83nd/Eguu4BroT/7/9hIrb9JaGtlKfhjZ62xzGfIY+ZUxb3ydm+jkEV1i8JIrmeCMyMN4 4+UKKHrv1Jp9aMcMtKTSjqsYn+2D0WDdhDN/KGbogo4M98fKTmCMeJyK8sa4v+tuGnLf+sTMfSQ tb5JSmWozfDRCzY72NYr+J1VjMF3I0oFUY3mQ== X-Received: by 2002:a17:90a:f16:b0:361:4521:d311 with SMTP id 98e67ed59e1d1-36145221bbfmr10637957a91.18.1776749633493; Mon, 20 Apr 2026 22:33:53 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Nicholas Piggin , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 11/13] tests/functional/riscv64: Add tt-atlantis tests Date: Tue, 21 Apr 2026 15:31:36 +1000 Message-ID: <20260421053140.752059-12-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x102d.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749742531154100 Content-Type: text/plain; charset="utf-8" From: Nicholas Piggin Add OpenSBI and Linux boot tests for the tt-atlantis machine. Based on tests/functional/riscv64/test_sifive_u.py. Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- v3: - Fix path to test files - Dedupe command line root argument - Remove unused import --- MAINTAINERS | 1 + tests/functional/riscv64/meson.build | 1 + tests/functional/riscv64/test_opensbi.py | 4 ++ tests/functional/riscv64/test_tt_atlantis.py | 63 ++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100755 tests/functional/riscv64/test_tt_atlantis.py diff --git a/MAINTAINERS b/MAINTAINERS index 635a380945fd..9622ffc9edb2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1770,6 +1770,7 @@ F: docs/system/riscv/tt_*.rst F: hw/riscv/tt_*.c F: hw/riscv/aia.[ch] F: include/hw/riscv/tt_*.h +F: tests/functional/riscv64/test_tt_*.py =20 AMD Microblaze-V Generic Board M: Sai Pavan Boddu diff --git a/tests/functional/riscv64/meson.build b/tests/functional/riscv6= 4/meson.build index b996c89d7df9..c4456fabd757 100644 --- a/tests/functional/riscv64/meson.build +++ b/tests/functional/riscv64/meson.build @@ -13,5 +13,6 @@ tests_riscv64_system_quick =3D [ tests_riscv64_system_thorough =3D [ 'boston', 'sifive_u', + 'tt_atlantis', 'tuxrun', ] diff --git a/tests/functional/riscv64/test_opensbi.py b/tests/functional/ri= scv64/test_opensbi.py index d077e40f4278..0f8beb7e7a8c 100755 --- a/tests/functional/riscv64/test_opensbi.py +++ b/tests/functional/riscv64/test_opensbi.py @@ -28,6 +28,10 @@ def test_riscv_sifive_u(self): self.set_machine('sifive_u') self.boot_opensbi() =20 + def test_riscv_tt_atlantis(self): + self.set_machine('tt-atlantis') + self.boot_opensbi() + def test_riscv_virt(self): self.set_machine('virt') self.boot_opensbi() diff --git a/tests/functional/riscv64/test_tt_atlantis.py b/tests/functiona= l/riscv64/test_tt_atlantis.py new file mode 100755 index 000000000000..f6f4b7ceec34 --- /dev/null +++ b/tests/functional/riscv64/test_tt_atlantis.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +# +# Functional test that boots a Linux kernel on a Tenstorrent Atlantis mach= ine +# and checks the console +# +# Copyright (c) Linaro Ltd. +# Copyright 2026 Tenstorrent +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os + +from qemu_test import Asset, LinuxKernelTest + + +class TTAtlantis(LinuxKernelTest): + + ASSET_KERNEL =3D Asset( + 'https://storage.tuxboot.com/kernels/6.11.9/riscv64/Image', + '174f8bb87f08961e54fa3fcd954a8e31f4645f6d6af4dd43983d5e9841490fb0') + ASSET_ROOTFS =3D Asset( + ('https://github.com/groeck/linux-build-test/raw/' + '9819da19e6eef291686fdd7b029ea00e764dc62f/rootfs/riscv64/' + 'rootfs.ext2.gz'), + 'b6ed95610310b7956f9bf20c4c9c0c05fea647900df441da9dfe767d24e8b28b') + + def do_test_riscv64_tt_atlantis(self, connect_disk): + self.set_machine('tt-atlantis') + kernel_path =3D self.ASSET_KERNEL.fetch() + rootfs_path =3D self.uncompress(self.ASSET_ROOTFS) + + self.vm.set_console() + kernel_command_line =3D self.KERNEL_COMMON_COMMAND_LINE + 'earlyco= n=3Dsbi ' + + if connect_disk: + kernel_command_line +=3D 'root=3D/dev/vda panic=3D-1 noreboot = rootwait ' + self.vm.add_args('-device', + 'virtio-blk,drive=3Ddrive0,serial=3D0x1234,bu= s=3Dpcie.0') + self.vm.add_args('-drive', + f'file=3D{rootfs_path},if=3Dnone,id=3Ddrive0,= format=3Draw') + pattern =3D 'Boot successful.' + else: + kernel_command_line +=3D 'panic=3D0 noreboot ' + pattern =3D 'Cannot open root device' + + self.vm.add_args('-kernel', kernel_path, + '-append', kernel_command_line, + '-no-reboot') + + self.vm.launch() + self.wait_for_console_pattern(pattern) + + os.remove(rootfs_path) + + def test_riscv64_tt_atlantis(self): + self.do_test_riscv64_tt_atlantis(False) + + def test_riscv64_tt_atlantis_disk(self): + self.do_test_riscv64_tt_atlantis(True) + + +if __name__ =3D=3D '__main__': + LinuxKernelTest.main() --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749717285723.7985240146982; Mon, 20 Apr 2026 22:35:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3kP-0000wQ-Dr; Tue, 21 Apr 2026 01:34:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3kH-0000g6-SG for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:34:04 -0400 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3kG-0004Zq-3H for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:34:01 -0400 Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-35d99031e4eso2578667a91.1 for ; Mon, 20 Apr 2026 22:33:58 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:33:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749638; x=1777354438; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=hev7AdsgaG3fRb4LKGCXjtOa9s4nvVIm/TmtgrA6C2o=; b=KQCCizHqJfaG2lqwi/01OIXaFLI9Nan0OeewH5YGRyS7gGxvyBVGcz/y5oVLu/wHpk elaakfALJ1Me5JbR86vsM9BiNgDvZ/4zhmmBy8uiF+yVXAbvD1r/lXNXQ0jKZ7ycK2ai /z7VR8q6uXv8EEa2Numfk+GnmKd+4fj2Up0eXMXorvO6lCoVk6YgSHhCt8LHJzD7YlTF igftD0ESipffhyQArWGrW0DB7OQAkCD/MO7oYkfv+rSx5vlRMaQDdd5xl67IcNrGwxF8 j7nRap1zfHrFGdJZa1OsU2gkEhd60jyaPgQWzl80uz3xBpJoIoL0Za5jbwOUO6MKkp6I 56VA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749638; x=1777354438; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=hev7AdsgaG3fRb4LKGCXjtOa9s4nvVIm/TmtgrA6C2o=; b=bHpC8hDU+h7mpuCdRwEE2rlWj+Y6oqyoeKqZ2bQ1KatU6MYiFCluvjdsr2VmePFtQ3 syMlHruKXeuXTMAHJutfHyZFOnkYVZuVMQvYkNbb82rZG780K95Xvyua+It37RYY6tBt O8I1V7Ze0jcpjabde+3ypYQgnD6N/ADPX3bfhbVSQpYND3Bl1626rd/eHAgV1r6GJyZm 6hMp2ARnVfv2g39ubKUOW1G07faFABTIFDaLg0Vpge62bh01RZ/6wJqgJ2XIURXwkuFp sYg+oKjPXtS4TZaN0gg4i8I5tLblHrrpkh475qr72f5vLbZ+oyZxAWqTYnEz+Eq+R32v jQqw== X-Forwarded-Encrypted: i=1; AFNElJ+w69YE9cpJ5NjF4cKYTauS1VkBzb3oww16TE5ciDMpLmOemklvLj9RGN1PLCn0xyYWLuPjr9ddaZfE@nongnu.org X-Gm-Message-State: AOJu0YwAwXfoy1liaB7DE8vnWrUn9FOtntUPT83t6r5hDCqDrSyr44EY nfedhW5KpGgOi5cCaVIYuwrIGXum933g+H2Cka7sFmFJ+OwCfBORgr+y X-Gm-Gg: AeBDieto/B359E+uhfv7E1d6XFomtIpm4/v/JKMzYZTOz/Ljo4cSC0EIXGOdJ7BonlH uOSffR+cnxJBBVH0m1T5CCChmAX/9h6Eji6t1y3GYH9cMCqLoBo8kK29yahJeqI1LeK7SGQNwiL bnHxXVLnYu+kzv7RxR5OVlLB0jC8h22E1m3s+To/nkfqKaNCnq4hqOrnFTN4K9apgp0qoRBxbbt khd4YEG+7DjLj/0YzETh8EndFjbGWC13NyVe6h+fZ5iHILxbiZIbjkIgEfAr+47Tqq+ZKzDWf/1 zczHMmOaXReZvUWaS64ibTbAPRLO9mToh2aptv9h3Y/fGY7A5K6G3xUFkKijD09KIDhasYarmCk MRAHHACdl/xcNgk6IW2sZjc/Dxrr8aFd53ZkjBOgMmliSZIcsNnHrWKZAPe7cRgTh3CL9hBmNgf HVO1xfsunGjElzFIwZC+iHoIYlJa+s9HhI5rXjK/L80FvQfjhwKJfqTsISfApDkTYZyUGZ87gdT cwagAv3qjCrvNRZi2rlbNr/5xLyaCldr9Yk9w== X-Received: by 2002:a17:90b:3808:b0:35f:b572:ece9 with SMTP id 98e67ed59e1d1-361403bdcccmr18220616a91.5.1776749637755; Mon, 20 Apr 2026 22:33:57 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Michael Ellerman , Nicholas Piggin , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 12/13] hw/riscv/atlantis: Integrate i2c buses Date: Tue, 21 Apr 2026 15:31:37 +1000 Message-ID: <20260421053140.752059-13-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x1033.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749717992158500 Content-Type: text/plain; charset="utf-8" Now that we have the DesignWare model we can add buses to the tt-atlantis machine. Provide a fixed clock in the device tree so that the Linux driver probes without WARNing. Signed-off-by: Joel Stanley Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- v3: - Add device tree clock v2: - Correct count from 4 to 5 - Fix headers location - Use HWADDR_PRIX to be consistent --- include/hw/riscv/tt_atlantis.h | 13 +++++++++ hw/riscv/tt_atlantis.c | 53 ++++++++++++++++++++++++++++++++++ hw/riscv/Kconfig | 1 + 3 files changed, 67 insertions(+) diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h index c0a0827a5167..b39c7e090e0b 100644 --- a/include/hw/riscv/tt_atlantis.h +++ b/include/hw/riscv/tt_atlantis.h @@ -11,12 +11,15 @@ =20 #include "hw/core/boards.h" #include "hw/core/sysbus.h" +#include "hw/i2c/designware_i2c.h" #include "hw/intc/riscv_imsic.h" #include "hw/riscv/riscv_hart.h" =20 #define TYPE_TT_ATLANTIS_MACHINE MACHINE_TYPE_NAME("tt-atlantis") OBJECT_DECLARE_SIMPLE_TYPE(TTAtlantisState, TT_ATLANTIS_MACHINE) =20 +#define TT_ATL_NUM_I2C 5 + struct TTAtlantisState { /*< private >*/ MachineState parent; @@ -29,12 +32,18 @@ struct TTAtlantisState { RISCVHartArrayState soc; DeviceState *irqchip; GPEXHost gpex_host; + DesignWareI2CState i2c[TT_ATL_NUM_I2C]; =20 int fdt_size; }; =20 enum { TT_ATL_SYSCON_IRQ =3D 10, + TT_ATL_I2C0_IRQ =3D 33, + TT_ATL_I2C1_IRQ =3D 34, + TT_ATL_I2C2_IRQ =3D 35, + TT_ATL_I2C3_IRQ =3D 36, + TT_ATL_I2C4_IRQ =3D 37, TT_ATL_UART0_IRQ =3D 38, TT_ATL_UART1_IRQ =3D 39, TT_ATL_UART2_IRQ =3D 40, @@ -50,6 +59,10 @@ enum { TT_ATL_DDR_HI, TT_ATL_FW_CFG, TT_ATL_I2C0, + TT_ATL_I2C1, + TT_ATL_I2C2, + TT_ATL_I2C3, + TT_ATL_I2C4, TT_ATL_MAPLIC, TT_ATL_MIMSIC, TT_ATL_PCIE_ECAM0, diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index e1753d3c1f18..bf08b7ed320e 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -64,6 +64,11 @@ static const MemMapEntry tt_atlantis_memmap[] =3D { [TT_ATL_TIMER] =3D { 0xa8020000, 0x10000 }, [TT_ATL_WDT0] =3D { 0xa8030000, 0x10000 }, [TT_ATL_UART0] =3D { 0xb0100000, 0x10000 }, + [TT_ATL_I2C0] =3D { 0xb0400000, 0x10000 }, + [TT_ATL_I2C1] =3D { 0xb0500000, 0x10000 }, + [TT_ATL_I2C2] =3D { 0xb0600000, 0x10000 }, + [TT_ATL_I2C3] =3D { 0xb0700000, 0x10000 }, + [TT_ATL_I2C4] =3D { 0xb0800000, 0x10000 }, [TT_ATL_MAPLIC] =3D { 0xcc000000, 0x4000000 }, [TT_ATL_SAPLIC] =3D { 0xe8000000, 0x4000000 }, [TT_ATL_DDR_HI] =3D { 0x100000000, 0x1000000000 }, @@ -475,10 +480,36 @@ static void create_fdt_fw_cfg(void *fdt, const MemMap= Entry *mem) qemu_fdt_setprop(fdt, name, "dma-coherent", NULL, 0); } =20 +static void create_fdt_clk(void *fdt, const char *name, uint32_t clk_phand= le) +{ + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "fixed-clock"); + qemu_fdt_setprop_cell(fdt, name, "#clock-cells", 0); + qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 100000000); + qemu_fdt_setprop_cell(fdt, name, "phandle", clk_phandle); +} + +static void create_fdt_i2c(void *fdt, const MemMapEntry *mem, uint32_t irq, + uint32_t irqchip_phandle, uint32_t clk_phandle) +{ + g_autofree char *name =3D g_strdup_printf("/soc/i2c@%"HWADDR_PRIX, mem= ->base); + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "snps,designware-i2c"= ); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->s= ize); + qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", irqchip_phandle); + qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x4); + qemu_fdt_setprop_cell(fdt, name, "clocks", clk_phandle); + qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 100000); + qemu_fdt_setprop_cell(fdt, name, "#address-cells", 1); + qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0); +} + static void finalize_fdt(TTAtlantisState *s) { uint32_t aplic_s_phandle =3D next_phandle(); uint32_t imsic_s_phandle =3D next_phandle(); + uint32_t periph_clk_phandle =3D next_phandle(); void *fdt =3D MACHINE(s)->fdt; =20 create_fdt_cpu(s, s->memmap, aplic_s_phandle, imsic_s_phandle); @@ -502,6 +533,15 @@ static void finalize_fdt(TTAtlantisState *s) =20 create_fdt_uart(fdt, &s->memmap[TT_ATL_UART0], TT_ATL_UART0_IRQ, aplic_s_phandle); + + create_fdt_clk(fdt, "/periph-clk", periph_clk_phandle); + + for (int i =3D 0; i < TT_ATL_NUM_I2C; i++) { + create_fdt_i2c(fdt, + &s->memmap[TT_ATL_I2C0 + i], + TT_ATL_I2C0_IRQ + i, + aplic_s_phandle, periph_clk_phandle); + } } =20 static void create_fdt(TTAtlantisState *s) @@ -818,6 +858,19 @@ static void tt_atlantis_machine_init(MachineState *mac= hine) qdev_get_gpio_in(s->irqchip, TT_ATL_UART0_IRQ), 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); =20 + /* I2C */ + for (int i =3D 0; i < TT_ATL_NUM_I2C; i++) { + object_initialize_child(OBJECT(s), "i2c[*]", &s->i2c[i], + TYPE_DESIGNWARE_I2C); + sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_fatal); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(&s->i2c[i]); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_I2C0 + i].base, + sysbus_mmio_get_region(sbd, 0)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, + qdev_get_gpio_in(s->irqchip, TT_ATL_I2C0_IRQ + = i)); + } + /* Load or create device tree */ if (machine->dtb) { machine->fdt =3D load_device_tree(machine->dtb, &s->fdt_size); diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 2ddee591eb90..4c2cf01995e7 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -136,6 +136,7 @@ config TENSTORRENT select RISCV_APLIC select RISCV_IMSIC select FW_CFG_DMA + select DESIGNWARE_I2C =20 config XIANGSHAN_KUNMINGHU bool --=20 2.47.3 From nobody Tue Apr 21 14:38:42 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776749744719107.40279035189644; Mon, 20 Apr 2026 22:35:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wF3kR-0001FO-DO; Tue, 21 Apr 2026 01:34:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wF3kN-0000nJ-6S for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:34:08 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wF3kK-0004bB-3r for qemu-devel@nongnu.org; Tue, 21 Apr 2026 01:34:06 -0400 Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-362bb3260f1so200740a91.2 for ; Mon, 20 Apr 2026 22:34:03 -0700 (PDT) Received: from donnager-debian.. ([203.221.103.1]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36141898ebasm12472308a91.7.2026.04.20.22.33.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Apr 2026 22:34:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776749642; x=1777354442; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=Cb167ruVDMxU0ClBbxjLtNhRudkBM0dnTEahrKy7ou8=; b=msoyVbd2IU9CpF0OzFWAuI73wXxOPwuxCHpeR4ONk/qE0HIJ1QKJbncEwQR6r0qwkJ rV1vsZV0Csrzo+tZhtyNok7kAjLjBifeXjk1k5LDg8J/Zq3o8rKEpSfh1MIo3gawqcXg Ra3NlHwFiDTZLs8y4qXQu68j7J1nn6BuSlPyW3TaVcKuTCJfVO/e8a5ljjEr3NwYFlJF IYOW6nMN1iysO92yS+ySVT6Jh6vytszKmqx0a44ihsiJMO0jBeI6LdSg9xoCfAPe5Mjd rlj/d0ntD46tTHHPJ16kCNwAOODnKyL6QIPl47dnk5G5/czzrlsUMDduAPF/5kQHgjfZ f+PQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776749642; x=1777354442; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Cb167ruVDMxU0ClBbxjLtNhRudkBM0dnTEahrKy7ou8=; b=kRTLqqvBu1Z3o7gMcyNUYoxAImV4JDa+ElRdeOzby41PqGt7xgk62RTlC2k2aRxWJG D0hQN5sa6rqxNrLMzV5vedtt0wv/SoA8xIpGHIOuJwJU4FUDfNypVjvJXvGiP6KdA1vT 08EKfA2yjFsVWQP2/RkneyhTgA9v2zE3ak8l1RAKjc/Empgo1GqOJ+O/c8ub1g5M4saY Viemf2xlNlTsLqDiDJeHlgwyGNxpwku1Rle3YPMJJsLpg+cxjOm3UoYi+ZgVhc7iE4rC 0YeiDu5zlldmIfyfNMLrdkX6oNW/7FBsFkqBAzU3/vaI2CpEtd8qsuRxPsBv52XdX0FA rdqA== X-Forwarded-Encrypted: i=1; AFNElJ+clepY5nYCoNdWvA/GSqTgXkMdwhQtFK54m3j52iiVbfoXFd2rGtQAXWsuOMnXEaf3IzryChpBRmz5@nongnu.org X-Gm-Message-State: AOJu0Yx8gRby+wCNjKMf+bwjAKi+z5JRx3EWasrdlS18jwsRkgIserPh RNQO+/mWwYnkUNF2iJ357JQWsSSx6lN3dNBDGkNuCnJVcBHz6pWeXhMW X-Gm-Gg: AeBDieskP8UFcayhrmRAm+Ta1deMVV4gBy8hxydU9lEXxXvdbnqwK0a9vsadDLLSoM4 7lQRVqxruZsgTL6bBJZyOGoNJk+daqM+f0sWzrJHI9c7oMh5NiVRxt/mAIW8WkO+pJu/w95b2H5 4mgByJ6zj5NOajBAgT3vSzKqu3vWwHMQRWi/CqxMWC9SwpPFdLEgUkaG5oUsXInKJx3nOrkg6Lu 75E4A2NnVKd0ZjODMkU1CrIztbOLCgane8htuhPf/QxaSCb9NbN5VCAoze+OBhACeHYuy7xqawH pOtLKzOfuWnXZ7Ld8S3Km3H4OKybqwdVW1U8YvZRNd6zLL7JJjOH81KGEzhthsyuJBDSOX+9Inr BeTnZAufkxpmEOZM0bMDiSgIW8MYvJfuhY044aMpRb9Z12LgbpNCseXFT/jStr0AmeMuXmWXiq/ 1mtU98C3IatbKRN7jMYUu4y9anOpH9ewVGh/w8Jop0O5RxXwk2hNI2ze1/RiCnXITHtpL3omnNZ a+rJtSocZlSUk3HQMvBb3YSrhe2erPOlQfJjw== X-Received: by 2002:a17:90b:4fcc:b0:35d:8fdb:4f26 with SMTP id 98e67ed59e1d1-361403b7d66mr17266421a91.1.1776749641998; Mon, 20 Apr 2026 22:34:01 -0700 (PDT) From: Joel Stanley To: Alistair Francis , Daniel Henrique Barboza Cc: Michael Ellerman , Nicholas Piggin , Joel Stanley , Anirudh Srinivasan , qemu-riscv@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v3 13/13] hw/riscv/atlantis: Add some i2c peripherals Date: Tue, 21 Apr 2026 15:31:38 +1000 Message-ID: <20260421053140.752059-14-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421053140.752059-1-joel@jms.id.au> References: <20260421053140.752059-1-joel@jms.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=joel.stan@gmail.com; helo=mail-pj1-x102f.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1776749746100158500 Content-Type: text/plain; charset="utf-8" Add an I2C RTC device and a temperature sensor. These are not present on the board but help for testing. Signed-off-by: Joel Stanley Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- v3: Use HWADDR_PRIX in i2c device string consistent --- hw/riscv/tt_atlantis.c | 18 ++++++++++++++++++ hw/riscv/Kconfig | 2 ++ 2 files changed, 20 insertions(+) diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index bf08b7ed320e..5a6149064f1a 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -505,6 +505,19 @@ static void create_fdt_i2c(void *fdt, const MemMapEntr= y *mem, uint32_t irq, qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0); } =20 +static void create_fdt_i2c_device(TTAtlantisState *s, int bus, + const char *compat, int addr) +{ + void *fdt =3D MACHINE(s)->fdt; + hwaddr base =3D s->memmap[TT_ATL_I2C0 + bus].base; + g_autofree char *name =3D g_strdup_printf("/soc/i2c@%"HWADDR_PRIX"/sen= sor@%x", + base, addr); + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", compat); + qemu_fdt_setprop_cell(fdt, name, "reg", addr); +} + static void finalize_fdt(TTAtlantisState *s) { uint32_t aplic_s_phandle =3D next_phandle(); @@ -542,6 +555,9 @@ static void finalize_fdt(TTAtlantisState *s) TT_ATL_I2C0_IRQ + i, aplic_s_phandle, periph_clk_phandle); } + + create_fdt_i2c_device(s, 0, "national,lm75", 0x48); + create_fdt_i2c_device(s, 0, "dallas,ds1338", 0x6f); } =20 static void create_fdt(TTAtlantisState *s) @@ -870,6 +886,8 @@ static void tt_atlantis_machine_init(MachineState *mach= ine) sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, qdev_get_gpio_in(s->irqchip, TT_ATL_I2C0_IRQ + = i)); } + i2c_slave_create_simple(s->i2c[0].bus, "ds1338", 0x6f); + i2c_slave_create_simple(s->i2c[0].bus, "tmp105", 0x48); =20 /* Load or create device tree */ if (machine->dtb) { diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 4c2cf01995e7..a4427ba79807 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -137,6 +137,8 @@ config TENSTORRENT select RISCV_IMSIC select FW_CFG_DMA select DESIGNWARE_I2C + select DS1338 + select TMP105 =20 config XIANGSHAN_KUNMINGHU bool --=20 2.47.3