From nobody Sat Jun 20 00:37:12 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 1781844597053750.8720958013032; Thu, 18 Jun 2026 21:49:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRAW-0008NO-Dk; Fri, 19 Jun 2026 00:49:29 -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 1waRAF-0008LV-KR for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:14 -0400 Received: from mail-pf1-x432.google.com ([2607:f8b0:4864:20::432]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRAB-0005GC-5V for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:08 -0400 Received: by mail-pf1-x432.google.com with SMTP id d2e1a72fcca58-8454c5a280aso496174b3a.1 for ; Thu, 18 Jun 2026 21:49:05 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.48.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844545; x=1782449345; 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=WsWbPE3Bt2Gd8XbRXKbewV3tBI1M4bc8RRw0T8jY90g=; b=O0EtpxNlhvmyI9WuvjAENATHQe6OwzFtJ0Ewiu/XVV8ly5O28YdS2iIem+GxQlCnRw ZwdYyrndskMvP0L520yUSbDIclX8n6FPjapbLtmXxPcHEQYQvxQSsYKjMBWo41xf52og J7PfRfPDUKlWdjaMa2v0lJAlCcWE7TrylN1u3VCvxi9gPiaQq2F5R2TGKkd7rYIR2HXP Zrcu7VYxfAxW+LD4Urm0Wk6ZxZ+OPG9czsmJjRuoicOyiYvt1bEiomDf94AZPXtwNIE3 CZR94KfQif6ZkqK2uJ8UFeWe5jCvRSgsKDyHXlYgVjxOTaijiwiv5q1+cfHJrMpvd5Pj 2/LQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844545; x=1782449345; 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=WsWbPE3Bt2Gd8XbRXKbewV3tBI1M4bc8RRw0T8jY90g=; b=XipICkEtTpPetRRBJdB2gT6U+d5zfzT317ZbHu/QZdQMlHoEeW1hJEcBnL05tPb985 +f9nCJhjiTS+l+J8emLlA7Z1dbcS2/lc/0nbLEzgMUJ9suP+FutTQN2YNne2pc2Xju/H HNk7HnSwpbAMF26sKcICLBZ2eYSgG05Yq7KeWj4NcXF03HMoltExKtlqbtGrMeMmQch/ GzSzkfTmS2RCO1HGhGLsFeKfyNk6bqYPThox8xeZQBCe/HPrChYSGg4w9x8DM/PXFyYO ZYIYt9qx5XnDcE2d3oRuI6Kd1FlcRUXeyLb8YkN8eeU6mU19T+fdQ4cqJyq24rkCj0bB 9gUQ== X-Forwarded-Encrypted: i=1; AFNElJ/krqhiJymV8hqqOW39IcWnuco4nT0PjKBprbGQOUqMZhfwm7bhDBJWjsaC6lL/jOZakyEIYykpygb0@nongnu.org X-Gm-Message-State: AOJu0Yxo2wV8OJ2sIR8uzGO0YcaypopWEwL4khcYIHl5w2u986WWixiD IklICMlK7xdLYXVMr2JVEMnNMltiEOJnm6L/7C173uc/f7MrF0Wfh0cZ X-Gm-Gg: AfdE7clt5GhZt+SwAa0qX7horBavCUg9YMO0mGOUa+FNFX6wwVN7rdqlsVTp7Wead8w CtNR7HMg6d4TH6icfGObtfbmMXxSSY9Cesx9Iaq8sisfWDwU+HMbmvh5FOotfBGhGDNQzVJ+QHs 5JrO0lLLy1c7aPtvl3zw0oEYkqgE2KGH9I+ZaEXf5IGPHW6DsRpPf/zVuWyMPaUGsfM5Gq5ELWu kpQeylP979vjXf3a1hC0k6SM8PECuE9JO+ODkt0ofJMN5BviWBgc0xNkyAx4uiz+6eAuzCvwoRj LJzuGKkcrUQA8V9FIxwJkYUCZHss/e15kGaE4UPNI3pRovXtCVKGv60T3JAUkzGxC2+F+du/YZZ UztYZB0oFP+6EgFR06nWYPNbqj9wUP8+L6QBTs9FCiinzhs1wOu/co7pCgGVFDeCEpfeVnvUDIS AyztztCoFf+g+tC+00EuRv2mfidibM2DBy3r/JQn7iQI07jFtVTkJOPeccw1iOXzkuTKvaKwVfG Yt1yPdEnHYdV2DPaHe5s7fZJ9Y3hWuYaznLZPXcnA== X-Received: by 2002:a05:6a00:2d82:b0:842:4982:825 with SMTP id d2e1a72fcca58-8455011462fmr1665478b3a.1.1781844544350; Thu, 18 Jun 2026 21:49:04 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Nicholas Piggin , Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org Subject: [PATCH v9 01/12] hw/riscv/boot: Describe discontiguous memory in boot_info Date: Fri, 19 Jun 2026 14:18:25 +0930 Message-ID: <20260619044838.1054677-2-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-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::432; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x432.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.249, 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: 1781844602125158500 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. Reviewed-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- include/hw/riscv/boot.h | 7 +++++++ hw/riscv/boot.c | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index f00b3ca12245..69c99a149613 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 low_start, hwaddr low_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 7c9cd6146815..c8418f83f480 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -70,11 +70,27 @@ 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 +/* + * This can be used instead of riscv_boot_info_init() if the machine has + * discontiguous physical memory. The low memory range specified will be + * used to place firmware images. + */ +void riscv_boot_info_init_discontig_mem(RISCVBootInfo *info, + RISCVHartArrayState *harts, + hwaddr low_start, hwaddr low_size) +{ + riscv_boot_info_init(info, harts); + info->ram_low_start =3D low_start; + info->ram_low_size =3D low_size; +} + vaddr riscv_calc_kernel_start_addr(RISCVBootInfo *info, hwaddr firmware_end_addr) { if (info->is_32bit) { --=20 2.47.3 From nobody Sat Jun 20 00:37:12 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 1781844692878563.0446963051689; Thu, 18 Jun 2026 21:51:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRAY-0008PU-23; Fri, 19 Jun 2026 00:49:30 -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 1waRAK-0008Ld-9r for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:20 -0400 Received: from mail-pf1-x42e.google.com ([2607:f8b0:4864:20::42e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRAF-0005IG-EK for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:14 -0400 Received: by mail-pf1-x42e.google.com with SMTP id d2e1a72fcca58-842307472d4so748341b3a.0 for ; Thu, 18 Jun 2026 21:49:10 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844550; x=1782449350; 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=pofCvfmJXowL3+y4/abJP1laSmSScTxPpd7HSYJEGzg=; b=kaarHmYv9By2mxMuF+DRhxe0xneIvrNjMQa5kAO1vAGupCUXvy3a4EyZWmCo2r183+ xFLqlxLiFE3HrxKDHopo7RovNAVzah1hmo7bkE+8BLp9/NxF9zTw5daWNdzrBgXsPHXt OyWiH7cnVI3N6fNLrNhDKP+J1WdrHrVFqFurVkCzthblofQkvIGVjnOxtpBUVLj1z77Z HYlwbuKgARTHxxw4m8fwISd7GTOHGn5jH8pi+rtFG5wHUvQm0yv5HRg23OrF2j1RUCuN mMNx4efvGoUc2M3kc8BNL5q9M8eNCPDMhPqGQi3xWV8CP3NJBXzhtNtqlUz+8HJMPzJ7 W9xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844550; x=1782449350; 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=pofCvfmJXowL3+y4/abJP1laSmSScTxPpd7HSYJEGzg=; b=ZUowjtod3Cf1uuwKlkQV/m+xY7CQsgJ6wI0fvYXQiu3a+KjiBF99IV6coxV/fxpnTz TXjWOKzmhLax/AmYxNkL9LLAuH9QOAEf3I6ipyYT3GVvyC/x+GuFgyWFq3Jsf+vD2IcY 3qJTbuZP80lqUcrwIU69r45XncaKnP/RA5CyZ7eeJltX3tZW0zinqF50jRivEATaubcE QbbBPDqornfdY+Ygd48Y6Qk/wtKcelF/fwZSo+ozFyHgfBZAEF/L1zUaYmcrfzI7mZHP ShbfkyvxUV7YDWomVQb8dvXkOTmZD37YXpi7/WMA+V1PMlwI4uppSsa8tV+y4TiP1lds GCWw== X-Forwarded-Encrypted: i=1; AFNElJ8jc6vlSSFOGs4t4tGq6BHWtZhsAj2+hG26f0KJkBLsxwTtmPmVvoN7Oc0t7wx5/PVwUClr+r48C+q/@nongnu.org X-Gm-Message-State: AOJu0YyYpXEniEwbW+oifkDSgfqUhdHY2Py7G/Bwg/zp5rf05Hku7vJ2 Y8gYlmHvKthd9qmirFhS+ZdCkV02bxcRAM2xjvM8TdbcSDbs65p6kRuE X-Gm-Gg: AfdE7cmi1eZz9908aIfZcBHL0zSd4sYYIfEpBZYHFnKDdOegaoZ0O11l28kikkJNcsH AX6awOThmE0+b5zjSuOmrQ/JbHaQegXNJSLt/dT3tPQUK4uHI2Lu6w3yYADk/oxLAHj2qafFfAD n1ZToRzq4fBlhP9Y2z9M2UNynhH4/CuD+vh/RxNnfCz0N5w5YboLxfH00tE/xI2hPyceAKnDU/4 sTVZ6/cuZaUuOQHaXMHyOdqHniXDbfwp2I4uSovEfM6mXLEdXG+X0N02Kpj2HJKR2wetF0pG8bl sdzvTezYAYF73XaCykOCNqcnAODi09nfAJ4AnjuiQQct1sXevj6cTvWKWrC0Z7aXpqgkY3mNkud aUAZyEyK/bf/5xkrK0ugEx7uYmxcep24JLlDWEx3CJX7w5tvZfi/2oLp7W9HWUsYEwI8BxCS9n1 zynePmKELCXok76sXV3w6sqsFUI+5G2CoiybGW1PajHp6eZWBVaJWyjHYTQ23vgosc3OR6JCdnF xO8uEX51Aopi94v3EvqhtguCSVLs3vUAlG8hISD2w== X-Received: by 2002:a05:6a00:1d97:b0:842:2cda:7a9c with SMTP id d2e1a72fcca58-84550877479mr2063554b3a.29.1781844549674; Thu, 18 Jun 2026 21:49:09 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Nicholas Piggin , Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org Subject: [PATCH v9 02/12] hw/riscv/boot: Account for discontiguous memory when loading firmware Date: Fri, 19 Jun 2026 14:18:26 +0930 Message-ID: <20260619044838.1054677-3-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-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::42e; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x42e.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.249, 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: 1781844695489158500 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. Reviewed-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- include/hw/riscv/boot.h | 5 ++++- hw/riscv/boot.c | 18 ++++++++++++------ hw/riscv/k230.c | 8 ++++++-- hw/riscv/microchip_pfsoc.c | 8 ++++++-- 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 +++++- 10 files changed, 54 insertions(+), 22 deletions(-) diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 69c99a149613..4e7bd9a225ef 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, + const 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 c8418f83f480..5e2dfa091a13 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -151,6 +151,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) @@ -163,7 +164,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); } @@ -171,10 +173,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, + const 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 @@ -203,7 +208,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) { @@ -218,7 +223,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; @@ -264,6 +269,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; @@ -295,7 +301,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; @@ -391,7 +397,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/k230.c b/hw/riscv/k230.c index 502281c52cff..656f28190cd0 100644 --- a/hw/riscv/k230.c +++ b/hw/riscv/k230.c @@ -424,7 +424,8 @@ static void k230_direct_boot(K230MachineState *s, Machi= neState *machine) =20 riscv_load_fdt(K230_DIRECT_DTB_ADDR, machine->fdt); =20 - 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); if (firmware_end_addr > K230_DIRECT_KERNEL_ADDR) { error_report("K230 firmware overlaps kernel address 0x%x", @@ -442,13 +443,16 @@ static void k230_firmware_boot(K230MachineState *s, M= achineState *machine) { const char *firmware_name =3D riscv_default_firmware_name(&s->soc.c908= _cpu); hwaddr start_addr =3D memmap[K230_DEV_DDRC].base; + RISCVBootInfo boot_info =3D {0}; =20 if (machine->dtb || (machine->kernel_cmdline && *machine->kernel_cmdli= ne)) { error_report("K230 firmware boot does not support -dtb or -append"= ); exit(EXIT_FAILURE); } =20 - riscv_find_and_load_firmware(machine, firmware_name, &start_addr, NULL= ); + riscv_boot_info_init(&boot_info, &s->soc.c908_cpu); + riscv_find_and_load_firmware(machine, &boot_info, firmware_name, + &start_addr, NULL); =20 riscv_setup_rom_reset_vec(machine, &s->soc.c908_cpu, start_addr, memmap[K230_DEV_BOOTROM].base, diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 5e48a2970838..4017129c8304 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -619,18 +619,22 @@ static void microchip_icicle_kit_machine_init(Machine= State *machine) firmware_load_addr =3D RESET_VECTOR; } =20 + riscv_boot_info_init_discontig_mem(&boot_info, &s->soc.u_cpus, + memmap[MICROCHIP_PFSOC_DRAM_LO].bas= e, + mem_low_size); + /* 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 c8b2f028f237..5b2f33d5acac 100644 --- a/hw/riscv/opentitan.c +++ b/hw/riscv/opentitan.c @@ -100,12 +100,14 @@ static void opentitan_machine_init(MachineState *mach= ine) 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 b1823a312508..835b1f879b7f 100644 --- a/hw/riscv/shakti_c.c +++ b/hw/riscv/shakti_c.c @@ -46,6 +46,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 */ @@ -58,8 +59,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 0c6e4204cbfd..ef3cc0ca4612 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -540,11 +540,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 4e60724c147f..9fde0faf39db 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -205,9 +205,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); @@ -217,7 +220,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 33775a61fd95..3b716509c448 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1327,7 +1327,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]); @@ -1350,8 +1353,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 76417ba7aba1..384624d69ad5 100644 --- a/hw/riscv/xiangshan_kmh.c +++ b/hw/riscv/xiangshan_kmh.c @@ -167,6 +167,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, @@ -178,13 +179,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 Sat Jun 20 00:37:12 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 1781844624356418.7040973473546; Thu, 18 Jun 2026 21:50:24 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRAY-0008PV-3r; Fri, 19 Jun 2026 00:49:30 -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 1waRAP-0008MZ-UC for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:22 -0400 Received: from mail-pf1-x42a.google.com ([2607:f8b0:4864:20::42a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRAK-0005LG-Hz for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:19 -0400 Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-8453427d3f4so1018380b3a.3 for ; Thu, 18 Jun 2026 21:49:16 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844555; x=1782449355; 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=ezWe0V+hpQoz0afaQTtTPcXO97/IEavyT3oijSMGGmM=; b=ef/f4pS8NILwBcv9V4lnJKeIXiN9zZ/dduqbvkc126diISak1wyMoEaM0yOSRT3gCI hJgonAsu4RkTXxaiV1MBd4RowWKckm15fln614aXpJ0aF2IP8eyHNiWEpU5eGMwrNvvE zQ4PHPHdeb0CYojvRz5YlpDSKCE5bejOFgJNZIrHDoGlOFd8+8ajtMRd3lSiCPMkfIWC /pA8gpBPlJ11I6vDRGXfWmKL4R0AjvFxpcveNSKZnbTG+FsOOXCOLwhErl3mmkGJwbPe QiqGwa6qqw3uKOoT12VBdq6A5FkUHI1idNNolbmHRHCJ8LGKkiN6RoAlHsccLW255IcP 7kdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844555; x=1782449355; 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=ezWe0V+hpQoz0afaQTtTPcXO97/IEavyT3oijSMGGmM=; b=fZ0nQ+WkTTxryTfMm1f5r7JLSSJBC4op35UMG8/dsXPViVArIxn9baeJYcm146EG1S unWSG7R7ibX4Ztj1fkOx5103BkjfdK67r1KbIVYCxdrBiDeiL+IiwUTvUNGsZKUgq6U5 QzNjikXCg3JHFEtzQNjo2d8nNls8ysF1277SToIQij6KlaXPMEpWHQJ77+CqB+l7F0i0 fHYKnCkHbBaxeO40vGw+2VY+p66qTSOaN0SZIgT0cqcMBMkuX/bpcZyRkjiqv3+Hbf7c 5EY41Wqpi+2QW+0b61Ue/3RX1Q7eH/xdaF4I3d2Zz0nfwgKUHUkPRmyniXfMcUq9P1S/ YN3g== X-Forwarded-Encrypted: i=1; AFNElJ+T/AYHROblLU0enMf4hqq4pLf7kLH3sya4HnTZHYNduRjQtRpFKKi5LB60nB96kPGzD4V5TQGz2DC7@nongnu.org X-Gm-Message-State: AOJu0YxtDKTWWw+o+/RV7EUiAYTjf0fwYjw5BtzG/VnjODYZas6uWGoq QW4ytrQlyx68YxYgWapt59V1YzyBETtm0tC6Y4td/a4y09pUzrFZI2XA X-Gm-Gg: AfdE7cmNbVs2r26tdg+nyA0zcZWfbjuIOEfzty8JaGNoMH+lpbfHlIsVhVfKw1+R48o HsP7kU7owC/LXu1rTi2dWeNPHyKdJ7sDP5YEe/51lL+wNjylIXP4g5f2NGGzisggDLO6+079hqj 8Vbpq+NyQIWFT8k+4qDVEb8rtuGzGuhLdCZjVDffnx83FXL/iIZTe3w/aW9uzTDfEKRwLgwDE6g V8FLxHyOL+EgFAI0wMxHSH9bNqR9fg+Lp0QexLK9HSsfrkkgNizXKa16tnIhRA6chWfFmjVS2Qc d8mIC4DjwTZIi/iA63sahEepkG9ippeKDhmLJzSD/OKEsXXNSQADXfcsib9QV5qh5yB/zp9Jydw GSPQVz859LzHUh4J3KPFKJxuHyue4nKH5OJL1J/sXMopRwE9/orItjTPOhfyvSVPP/SG0lfSmGA 5y/+U94qTITnlp8otTtNYbpG1Rqte++ByPag6jbOl8xAgxutj8Vl9sOiTSCLTSdQfN/uvXsNAXF w5UYPtLbUAtg+3yjywDwaFGXRhuxIAS0AD7gJ/YdA== X-Received: by 2002:a05:6a00:1f11:b0:82f:48e:241c with SMTP id d2e1a72fcca58-845508860d7mr1874925b3a.23.1781844555285; Thu, 18 Jun 2026 21:49:15 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Nick Piggin , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, Nutty Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v9 03/12] hw/riscv/virt: Move AIA initialisation to helper file Date: Fri, 19 Jun 2026 14:18:27 +0930 Message-ID: <20260619044838.1054677-4-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-1-joel@jms.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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::42a; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x42a.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.249, 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: 1781844627121158500 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 Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Alistair Francis Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- 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 | 1 + 6 files changed, 129 insertions(+), 77 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 413d47d70ef1..e3da87492408 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 3b716509c448..84480da2953b 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -61,6 +61,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) { @@ -388,17 +390,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) @@ -1163,68 +1154,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; @@ -1487,9 +1416,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 b70a054579ae..798477b7882a 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -1,4 +1,5 @@ riscv_ss =3D ss.source_set() +riscv_ss.add(files('aia.c')) riscv_ss.add(files('boot.c')) riscv_ss.add(files('fdt-common.c')) riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c')) --=20 2.47.3 From nobody Sat Jun 20 00:37:12 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 1781844767306842.5800995023374; Thu, 18 Jun 2026 21:52:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRAa-0008QN-JX; Fri, 19 Jun 2026 00:49: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 1waRAT-0008NM-Qa for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:26 -0400 Received: from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRAQ-0005MO-JV for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:25 -0400 Received: by mail-pf1-x42d.google.com with SMTP id d2e1a72fcca58-8454c5a280aso496277b3a.1 for ; Thu, 18 Jun 2026 21:49:21 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844561; x=1782449361; 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=kqTO7zQpJ1EAJJdfDeD5+U8h9Uv+pcG9eZ/nvTZxrn0=; b=NNlywXvkZepBjDYARCGrBiN+wi+nuaMkTbWQh6Hr7tWFhExouYO/R0tlm5PcqMPvwN TTR5kIwYLoX2plo8FNCeFLLLcrpbTGHmoG8k4PKzozmfyYuZm5nr0aKqKlLF9RME75xx ucud8rLQ3FG8zynGpmU0pTb69zAl017TJsfkdOjgnOuyNdo4alG0h1jqNbxPRZZrb9C6 FuHLiPGRHfLCPlhdPaMbBcA67V4es4zxQG8KEPPHmF2qQnLnOFHtLug3EkYIrdPfB1SE 9m+Zu4m/w0wMP6G8YLhsTy/mHn0fZKxx4/Q/lO/O2xZFwK4Rq+Iqn/GQPWYxei2sCTw1 Uhyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844561; x=1782449361; 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=kqTO7zQpJ1EAJJdfDeD5+U8h9Uv+pcG9eZ/nvTZxrn0=; b=Y0b3/RBTo6xYoET7O454Cic8X4jBbSXPKlPBLqf/07WnTS37B/1MbaaMAhlcjVJ8V5 jFT4f5vTxcCG/QrnRj7/HuIObpookVUZSxrqNAGrflhzvHKUxyixPnthqz6jYmJumZj8 OfrkzfFilenU/Z0KctGYqnJlkR6hio6lIaQb6YMKkBfJ673Uy7uqPFZWmp5E/ySaRoc2 KyMWR7V7Szi+586NeAt6OGsL5/+UJJPEE/AfWstXDyZ2UZLtyTkIw7cKOMMSSQhpvQGg 7ODW1GnJpUeeyrbX9UqeRAphX/AAHkV1lklMHkwLnZ+YCkrAoDoDlLqCof3balVNjsY0 CKgQ== X-Forwarded-Encrypted: i=1; AFNElJ/i3ukK7/idOPsgAvsq9S8XIJYQmHAM1CirXCm7VAuMYSHHnMO1dQGq0lcZn7u/DzhPC2KmEdctV3HU@nongnu.org X-Gm-Message-State: AOJu0YxqN6vMD56DcEd6yedUfz/tsWvzNSv8AHr8ssVZEeiFKpXHNo1t /TuCP8fa9mXZ1rVapXThO1/tHBMpp61okOtLNEv2CcDq/XOVuv0hDiDJTXPcAg== X-Gm-Gg: AfdE7cl9M9qKDcCLUnDbaec8DzQB7HRHgpfVs+T0+r35dV04nlyL+KH9/JnNnpUpJ0X 88q6kWimTBwKAQTDJOsDn8vqJBFbiLWoirfbApH9/ANRs4Y5CYncfg3hh6TcaITz+UCtKcrlV5x J8JJPf8kK1mpXxRfio63jrhy5Z3KkD/hRVLCJB3vhhcHAFeZgFGUDp+m72wR/6v30ybGg9ACotl z76mwSiGITbWHx3WPvbe+F4QMdnZnqjrhOPVHPivyKWwSTjWqcvZlKDU1/XEw4dONhL5W1+n3wa kmyqvZJySEDhY6CQKJJ9yVE6+RIwkVxfyDtlydr8FJmIKvP6HJeOz8SWJtK/isZobIdPlGda6Q+ vPo7KckUwdRh3uNhZjV168MrqYDX/V5y66qOjrxr5EdI9uI3+w3R0CODwpcGHYQVtu8d6FyfGr/ krd+4yzwHqPnwJynXvUZUWyS55QNfDgcdkvCqnEePEkLLs3t9tgxd1BsXntQnMDgUbLaFkRwUyo C+Uya3dJAFGvuZrPhkswYfbKs2to6a/qLeYXzR09Q== X-Received: by 2002:a05:6a00:853:b0:82c:7420:82bf with SMTP id d2e1a72fcca58-845502f140emr2091342b3a.19.1781844560861; Thu, 18 Jun 2026 21:49:20 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Nick Piggin , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, Nutty Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v9 04/12] hw/riscv/aia: Provide number of irq sources Date: Fri, 19 Jun 2026 14:18:28 +0930 Message-ID: <20260619044838.1054677-5-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-1-joel@jms.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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::42d; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x42d.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.249, 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: 1781844769509158500 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 Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Alistair Francis Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- 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 e3da87492408..db3ea4f03ac3 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 84480da2953b..b62864559f57 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1418,6 +1418,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], @@ -1574,6 +1575,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 Sat Jun 20 00:37:12 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 17818445970812.9907328356383687; Thu, 18 Jun 2026 21:49:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRAc-0008RI-Lv; Fri, 19 Jun 2026 00:49:34 -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 1waRAY-0008Pa-QC for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:31 -0400 Received: from mail-pg1-x533.google.com ([2607:f8b0:4864:20::533]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRAV-0005SV-SE for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:30 -0400 Received: by mail-pg1-x533.google.com with SMTP id 41be03b00d2f7-c8857a27041so798155a12.1 for ; Thu, 18 Jun 2026 21:49:26 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844566; x=1782449366; 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=KUuEtyKtFhfXIoCph6bUYAge9pOaOKkGGobDBDNgwZk=; b=EzXHAZcL4JuGYFfgI7igb1+gN7CARIGHZLpT/EjgDqZTm6tTXNejsWjzEtBPe/HZCh 6i/rF9UHO8fb28RQUTzBncbZjWDrG7POB2gr4fLIS4B2q+wT0MStC2qI3KhO3cd11gOe cnax4VCcEPNSRR8Y4/ukjrP+HBSmxsaA+2L5BXzsIB9UKP9nxMsEUs8Wl2zDJqooCrGU YFhZ4ompQRdL1GP1UpVNFezWKQZXzE4H/k1YVMAIAB6x0cIiul1FwbzGfaFVtANeTcxG dugBaw6UKGrQPfj0HfJkl+b62/1d3wTVSnESaZhZurJEOD3ggMUwOwvk1oS50ObY5ZWT zQTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844566; x=1782449366; 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=KUuEtyKtFhfXIoCph6bUYAge9pOaOKkGGobDBDNgwZk=; b=Xyy1Um7SouGkmoM4i4Pk/zkffMW1U1ZxMgbC8xcQAxm9R+TNIGBL3WIQuc0Xal0R0v x9zZ/LkrLbnbjb9tG4n3z9Pwtu66IpoGOkMqWphtR8Hp+6OFaAo61q5DRyh2h3KILXrG uD30msG4C7HP1YmtKvfHjhgpj8DWPTzSWTiR7k9bjcHQ2P2r2kOkiAZJvxW8US/NNpm8 Sbku8I+CcPZeoiQjN8g64gEKluKEMJxDRQgtbiLN8t+1eEnhJPx3HgfimZ8I9owpxlko D58bB2uUARbgEIOm3RBI+uSLJ39hm4v54952Jg/Fq4Wj4I6Mtn0Bm23m2/ORJV4KHH52 uRXw== X-Forwarded-Encrypted: i=1; AFNElJ9prF2FlqiO9J0p/x8BFeqJWcNhr69pqQGmBd694ud2xBvhAvA/6asyTmuhaRkkqrsIxU8Rot0I9k0L@nongnu.org X-Gm-Message-State: AOJu0Yxw8kJiOp1Es7ydcNvl0NpjLn+d/9JD+h/a5Ht+BItanbyBvEdp TpFdfjwavszOviCH3h35TVnj6i5avMdwq6WeBXyFRiNijpmyldBljAWz X-Gm-Gg: AfdE7claoMPJh94NxfeB1HO2oV/pYpxxqkZbYll2MYAIyX+0TlCq7OWVIu8N2EvbNHD wOAiajkSgFGR73rzTWiTuheO3R9HwVnpbvO8wqxY98a6P1DTqOKwX2/GBcCs8BCMSTPwLU1Zb32 m/Ca+KvncDskQJ643E5XH+8+LRruzM0hz1scrZb770RxOwsiptnvuwILB4VRDsHqkmhfque4kW6 WRKdI66bVqsh5C7HIlAltOw9FZqa9wTUdGvXs1MzNOS9cCKqlzTceq7anaO1eX8ZaoIypkZVXzA hjO4hng1CvwJfnGL2c97qrg/DFz6gOrhME8V45JKjiz3VHapyUmvl7CGzBRT/ERrx6fCi/mmKq5 REXXQ0oi7IDl+/cjVbo0S6EbCauTcn9S/eGo65XbjtlRRiZonjomCB9RmT8gXwy78g76et12XWT ePswZ2NxCmOiRHGvhZMsjLD/l9vmlga3N+J0RUUCk7iJUOXtFcFA0TFmQsds3DgrUJn843VTJ+m V7QRy2JVZijDawlxPXw78iA+IoR0QBi+Aqx2dHhzHowcx32NniZ X-Received: by 2002:a05:6a00:339a:b0:842:83d1:ee6d with SMTP id d2e1a72fcca58-84550aff364mr2034918b3a.45.1781844565863; Thu, 18 Jun 2026 21:49:25 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Nick Piggin , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org Subject: [PATCH v9 05/12] hw/riscv/aia: Configure stride for the M-mode IMSIC Date: Fri, 19 Jun 2026 14:18:29 +0930 Message-ID: <20260619044838.1054677-6-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-1-joel@jms.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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::533; envelope-from=joel.stan@gmail.com; helo=mail-pg1-x533.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.249, 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: 1781844602120158500 riscv_create_aia() currently hard-codes the M-IMSIC at one 4 KiB page per hart and gives callers no way to widen it. Add an m_imsic_stride parameter that supplies the per hart byte stride directly. The virt machine passes IMSIC_HART_SIZE(0) (=3D 4 KiB), preserving its existing compact layout. The parameter only changes how the slots are spaced, with the rest of each slot reserved. This allows future platforms that have different layouts to control the stride. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Alistair Francis Signed-off-by: Joel Stanley --- hw/riscv/aia.h | 1 + hw/riscv/aia.c | 3 ++- hw/riscv/virt.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/riscv/aia.h b/hw/riscv/aia.h index 5ad0a902be0d..565f91accc09 100644 --- a/hw/riscv/aia.h +++ b/hw/riscv/aia.h @@ -14,6 +14,7 @@ uint32_t imsic_num_bits(uint32_t count); =20 DeviceState *riscv_create_aia(bool msimode, int aia_guests, + uint32_t m_imsic_stride, uint16_t num_sources, const MemMapEntry *aplic_m, const MemMapEntry *aplic_s, diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c index 82ea9d48ea75..ed8916002945 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, + uint32_t m_imsic_stride, uint16_t num_sources, const MemMapEntry *aplic_m, const MemMapEntry *aplic_s, @@ -47,7 +48,7 @@ DeviceState *riscv_create_aia(bool msimode, int aia_guest= s, /* 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), + riscv_imsic_create(addr + i * m_imsic_stride, base_hartid + i, true, 1, num_msis); } diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index b62864559f57..b10f347a5cbf 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1418,6 +1418,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, + IMSIC_HART_SIZE(0), s->num_sources, &s->memmap[VIRT_APLIC_M], &s->memmap[VIRT_APLIC_S], --=20 2.47.3 From nobody Sat Jun 20 00:37:12 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 178184462721564.91199983512843; Thu, 18 Jun 2026 21:50:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRAe-0008Sp-ML; Fri, 19 Jun 2026 00:49:36 -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 1waRAc-0008RX-Aa for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:34 -0400 Received: from mail-pf1-x433.google.com ([2607:f8b0:4864:20::433]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRAa-0005Va-JN for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:33 -0400 Received: by mail-pf1-x433.google.com with SMTP id d2e1a72fcca58-842307472d4so748427b3a.0 for ; Thu, 18 Jun 2026 21:49:32 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844571; x=1782449371; 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=PKPKLU7Wp4oiXp2bE1zP5WND+gmgqtQwA9/gdvD+Eus=; b=afeyuAhQ4JeY8wZpquSlbGA1HnBxMsfKQ8Pvl9VxnJkx97JImI1K336/zZMzic65S3 dRDsw3jrSFfLTjxmU7EMDKyO6rSAvzaAbY0tEtu4ELDJFgzfoqC+Of/sFO7heUhOTqUl OMYD8UGPhC/JqnWNGgSqd4ASW1QIR/jjVIjZi1nEfiz5roTFlqu//auQA5Z2chbom8xr txqqIj7m3vh9FrDH5HT55ZB49mygPGGrRym7XHQdbg/ZLo4tTh7Yzw8jxpexp4d6/8mG csF21Q1S+bhU8oZbN6VX5/9BW23gu1aMDaNwA8DaJ5thSsrHtX3HhnN5H1YH9Y4b6UBm Hm5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844571; x=1782449371; 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=PKPKLU7Wp4oiXp2bE1zP5WND+gmgqtQwA9/gdvD+Eus=; b=IDRFEcmQwM6Ke8LcR8O3Wl5WDQYD+XMAh4MU3rbLkMkNh/dfnkue3oHI8WCQWXGhL8 4t4Z/odt80ZQ/Ns4f1u7qRWzx2A4wNCF8UIHYE1XEntYR6WTMVKQx7cSnRjxTJ1zhIyG J7zJ5YPE1PySJmiDyNI2/GKaM3dPzMNjU5RumdyQd6zFZxkijYt1WxM1ktWX+9W94M/K hxyN3OzCgFBrHzgb0bzmktp27StvqbZLp5za3VsYehhYTi5+la2iRCEsbSCLJzfMP1bW 09p8QSvCgdstSxLVwDGus4sdpMFn+NqAAWKJkLDo97WgFEpHvg6bLhrb32yuA6vhpOUY 8d1w== X-Forwarded-Encrypted: i=1; AFNElJ9K/G9XDg9Pi4QJvpNtx4FWya04TzaOdlZL11FwQ78KYu0kp/duTgq39kvolDvvGjIvTjCTQFsLyYqZ@nongnu.org X-Gm-Message-State: AOJu0YyPA7ANQtrswSVxv2anNKVFpGmByNxSyBX8OblwbPN1YwsH8rAg cBDixeRVm/ljBPffqQfSLcN+popsqFOWEUNDDRpMJbUO+WAByaawurM9 X-Gm-Gg: AfdE7ck3h9y58dmyHeEI133jLSRdmlwGFhNHauCfosafu7LP5KAq6Y1mZbRDudPqSMH rt3asXD/wJkHyp6v2ME98XAb4JGv6nZ/br5HrI9gMndHS1x89DeTSwydMZxo0ZTXGkUHyrrl416 nZdhrH57S4O/KYTODZI7St10lualMDmlMcxibwYqWa6BsgoDlo2+9hSPYC+XxBiTW9nIQU6buvW M4znJxnshEy6t100OgZOH3Ynx8woMaff7Pbe3KWbTB0jQcdQXQrFxV3v55FY7JKbuYinhGtU/ya UY3zJm3GzRNPDTCyNQYlSZ2HKauBNj+yoa83Cvs5knHoTic2DO/ATei4bXyS0VF584mZZb5I4/R S/p9ol8rOj3Gd09wge6n6pwFeI8HAi9OKLGLVmsEXFT5w4IXJ7ywdbETiVwWXu7rsVlEkwCGLyp G3b3nzQQUNizag5xH1FSMJXOOLdMDvLhYs6OxPQi1DNDiclnwzPqAvjorFRuduUZLI9RLUJOJlX qZrmmj43M4p+DkJwtt9qLnOX1eqOC4XujKUL+IkiQ== X-Received: by 2002:a05:6a00:1ad2:b0:842:614e:cc97 with SMTP id d2e1a72fcca58-8455087753bmr2113107b3a.23.1781844571187; Thu, 18 Jun 2026 21:49:31 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Nicholas Piggin , Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, Chao Liu Subject: [PATCH v9 06/12] target/riscv: tt-ascalon: Enable Zkr extension Date: Fri, 19 Jun 2026 14:18:30 +0930 Message-ID: <20260619044838.1054677-7-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-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::433; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x433.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.249, 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: 1781844628760158500 Content-Type: text/plain; charset="utf-8" From: Nicholas Piggin Ascalon supports Zkr and the SEED CSR. Reviewed-by: Chao Liu Reviewed-by: Alistair Francis 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 fa497e5e8ab4..6c1b0059980d 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -3211,6 +3211,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 Sat Jun 20 00:37:12 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 1781844617135653.0178698542104; Thu, 18 Jun 2026 21:50:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRAl-0008TI-U2; Fri, 19 Jun 2026 00:49:44 -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 1waRAj-0008T1-Kh for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:42 -0400 Received: from mail-pf1-x430.google.com ([2607:f8b0:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRAg-0005XT-Bu for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:41 -0400 Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-845369f60faso1025989b3a.3 for ; Thu, 18 Jun 2026 21:49:38 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844577; x=1782449377; 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=MWjguvjGqYuYE0o+oX2PxePd4kPTlYRBhBBRlVo+fAI=; b=EfbmlwT6ZQYTrrsiTCbf9KGVOETVReCegcXunMd2ayYWNCaH77TBKCJ/XI0Cm9DvDH OjYXlYqJMzeZN5pv6jfc/jrjLohRSF3z7h7+Ta7Dr2A5qonLOuGmhglbDX63jx1RTR1d YmW1h38D9Fk6S7yIuJ7E/yDJFRG3btR+qgl5/chNMH+o6xF7OU3p218/tEI1E85RFhC1 BMvDUWXbmtbRuhyv8KagW7D9T1Y+HqFrLk7Mfo6QdZ0Mjn4LG2iwXWbs1DnTr2dvgoSo AuZ2x1PPmt3AQG3XmcW0KDSJGBHTlTGbdQNE5sLfDg767ipwMfnzI/Ig6r57b4POn/VD DDWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844577; x=1782449377; 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=MWjguvjGqYuYE0o+oX2PxePd4kPTlYRBhBBRlVo+fAI=; b=WW+Lr7VB5nx+vWvkfvIRaXmsZUcDNW5+HusjwIaWwfU1z1AB2QPGXEaZoD3E2S+jQL oVkPgCsAMW3aZ/ww/SdlqYaEHVNc/S9ywR75l7g0p8HPhnVc/fqSKpA571yRXm76NoCi /IQKsMJ4hHyjWR9Z2OLsqIeUUrFFfT01Cc+ofQsnniPYXN+f1qwSIBMBcqN8SPAFZJMG a568oXrpry32FoLDmObxgmIQzaXHBG2mKMOLredGFG29y9I88KFkyitoUTx4vEdybX43 iIosG5au82T6GIrMramwVrHdNeHzkPuxoBz2KZiEGqgOClJie4yrFg6CedbHPi6MmdPa G8Vg== X-Forwarded-Encrypted: i=1; AFNElJ93KBNYGgyF/5N3LSRHWsdft9iYDBMhhAStvrVmUVuwjYpksciJGqPKJfpMidvvMYfhGAIMPUi+X9QQ@nongnu.org X-Gm-Message-State: AOJu0Yw9NdBG9qW1KcXuzxESoEJZDtCa5CFq8hmPtHTANRRGBo55apgX w1Vq8xNizsfb6+8lCZO7lA0I/wgedUif4qvLUmcFe1QvnVml6+qJmwuY X-Gm-Gg: AfdE7cncAADR6RpgMFkEjFDIqa3Wq1XgGSxIa0GvLa3Cx1HnpBU5rAYJcuY2I7dtRcl KrJeh0qQoxZn+FbebZnV/VBCPYqF2QARUB6XY0Ea8jrbtpCotUk1Wva3BABvsB96sKyI8iMhz0M d0A9OyZxmt0fo2zDyqku9ZmAL9MLJzweoo5lSRXLa7meKawYNxJLFqYvZmQG5b697M0RlKHPw83 OFgmKAYeTvjkGD5q0UZjYx9PYC4y0jFxWio6tjm0dDp+ZHnxltJGCsUuRIX6mPnCXQUY0PvGqg2 yTWVCHqjyCATXAhvsKYI1MrwTTrymtY402OoGM4PlqpX1NLCnhxLQR62q4PBWaaRN8U4qOaI2Eu XNfL/CnJ2jRiW3fH8BjJQjJT3gcQDgldGiNxljGVe6OMhqlz9V6G+KIGBzR0MFrMmHJLrw1rvH5 wjaOsk7RHD1K4IQVoSpG+5MledEJR6lJ25td9ZCNdPrkiEhmzyUiDLx6zOeZygxFVWE32dw9AGE jbRjouUmu2+JSCxY0lRxIv59dXxRQ0Tdu7Mphybn7sWI5N2Kg1i X-Received: by 2002:a05:6a00:984:b0:842:3aee:12c0 with SMTP id d2e1a72fcca58-8455088e054mr2126059b3a.23.1781844577005; Thu, 18 Jun 2026 21:49:37 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Nick Piggin , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chao Liu Subject: [PATCH v9 07/12] hw/riscv: Add Tenstorrent Atlantis machine Date: Fri, 19 Jun 2026 14:18:31 +0930 Message-ID: <20260619044838.1054677-8-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-1-joel@jms.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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::430; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x430.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.249, 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: 1781844619401158500 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. Add the tt-atlantis machine containing serial console, interrupt controllers, and device tree support. The Atlantis boot images loaded from include OpenSBI and an initial DTB that is passed to OpenSBI. This is approximated in the model by having QEMU build the device tree rather than load a DTB image directly. Subsequent stages may use the modified DTB provided by OpenSBI or opt to supply their own. qemu-system-riscv64 -M tt-atlantis -m 512M \ -kernel Image -initrd rootfs.cpio -nographic Co-Developed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Chao Liu Signed-off-by: Joel Stanley --- MAINTAINERS | 12 + docs/system/riscv/tt_atlantis.rst | 41 +++ docs/system/target-riscv.rst | 1 + include/hw/riscv/tt_atlantis.h | 50 +++ hw/riscv/tt_atlantis.c | 523 ++++++++++++++++++++++++++++++ hw/riscv/Kconfig | 10 + hw/riscv/meson.build | 1 + 7 files changed, 638 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 93df53d87f63..09c9a79e04a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1773,6 +1773,18 @@ F: hw/*/*sifive*.c F: include/hw/*/*sifive*.h F: tests/functional/riscv64/test_sifive_u.py =20 +Tenstorrent Machines +M: Joel Stanley +M: Nicholas Piggin +R: Anirudh Srinivasan +R: Michael Ellerman +R: Portia Stephens +L: qemu-riscv@nongnu.org +S: Supported +F: docs/system/riscv/tt_*.rst +F: hw/riscv/tt_*.c +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..1f2880d61773 --- /dev/null +++ b/docs/system/riscv/tt_atlantis.rst @@ -0,0 +1,41 @@ +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. + +tt-atlantis QEMU model features +------------------------------- + +* 8-core Ascalon-X CPU Cluster +* RISC-V compliant Advanced Interrupt Architecture +* 16550A compatible UART + +Known limitations +----------------- + +The QEMU tt-atlantis machine does not yet model every device on the +real platform. Notably: + +* There is no PCI host bridge, so virtio-pci devices cannot be + attached. Boots that need block storage must use ``-initrd`` with + an initramfs. +* The DesignWare UART is modelled with QEMU's ns16550-compatible + ``serial_mm`` device; DesignWare-specific registers beyond that + set return 0. + +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 896f14e78bd0..2639866a3e8a 100644 --- a/docs/system/target-riscv.rst +++ b/docs/system/target-riscv.rst @@ -72,6 +72,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..a17732ce8114 --- /dev/null +++ b/include/hw/riscv/tt_atlantis.h @@ -0,0 +1,50 @@ +/* + * 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; + const MemMapEntry *memmap; + + RISCVHartArrayState soc; + DeviceState *irqchip; + + int fdt_size; +}; + +enum { + TT_ATL_UART1_IRQ =3D 39, +}; + +enum { + TT_ATL_ACLINT, + TT_ATL_BOOTROM, + TT_ATL_DDR_LO, + TT_ATL_DDR_HI, + TT_ATL_MAPLIC, + TT_ATL_MIMSIC, + TT_ATL_SAPLIC, + TT_ATL_SIMSIC, + TT_ATL_UART1, +}; + +#endif diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c new file mode 100644 index 000000000000..1f0cd08ac959 --- /dev/null +++ b/hw/riscv/tt_atlantis.c @@ -0,0 +1,523 @@ +/* + * 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/fdt-common.h" +#include "hw/riscv/machines-qom.h" +#include "hw/riscv/riscv_hart.h" + +#include "hw/char/serial-mm.h" +#include "hw/intc/riscv_aclint.h" +#include "hw/misc/unimp.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 63 /* aia_guests, gives guest_index_bits= =3D6 */ +#define TT_IRQCHIP_MIMSIC_STRIDE 0x40000 + +#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_MIMSIC] =3D { 0xa0000000, 0x200000 }, + [TT_ATL_ACLINT] =3D { 0xa2180000, 0x10000 }, + [TT_ATL_SIMSIC] =3D { 0xa4000000, 0x200000 }, + [TT_ATL_MAPLIC] =3D { 0xcc000000, 0x4000000 }, + [TT_ATL_UART1] =3D { 0xd4110000, 0x10000 }, + [TT_ATL_SAPLIC] =3D { 0xe8000000, 0x4000000 }, + [TT_ATL_DDR_HI] =3D { 0x100000000, 0x1000000000 }, +}; + +static uint32_t fdt_phandle =3D 1; +static uint32_t next_phandle(void) +{ + return fdt_phandle++; +} + +static void create_fdt_memory(TTAtlantisState *s) +{ + void *fdt =3D MACHINE(s)->fdt; + 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_socket_memory(fdt, s->memmap[TT_ATL_DDR_LO].base, size_lo, + 0, false); + 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_socket_memory(fdt, s->memmap[TT_ATL_DDR_HI].base + size= _lo, + size_hi, 0, false); + } +} + +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) +{ + char pmu_name[] =3D "/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 g_new0(uint32_t, ms->smp.cpus); + + fdt_create_cpu_socket_subnode(fdt, TT_ACLINT_TIMEBASE_FREQ); + + create_fdt_socket_cpus(fdt, s->soc.harts, 0, s->soc.num_harts, + s->soc.hartid_base, &fdt_phandle, intc_phandles, + false, false); + + create_fdt_memory(s); + + create_fdt_aclint(s, intc_phandles); + + uint32_t imsic_guest_bits =3D imsic_num_bits(TT_IRQCHIP_GUESTS + 1); + + /* 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, imsic_guest_bits); + + /* 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_guest_bits); + + 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_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_rng(void *fdt) +{ + uint8_t rng_seed[32]; + + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + qemu_fdt_setprop(fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed= )); +} + +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_uart(fdt, &s->memmap[TT_ATL_UART1], TT_ATL_UART1_IRQ, + aplic_s_phandle); +} + +static void create_fdt(TTAtlantisState *s) +{ + MachineState *ms =3D MACHINE(s); + + ms->fdt =3D create_board_device_tree("Tenstorrent Atlantis RISC-V Mach= ine", + "tenstorrent,atlantis", &s->fdt_siz= e); + + qemu_fdt_add_subnode(ms->fdt, "/chosen"); + + create_fdt_rng(ms->fdt); + + qemu_fdt_add_subnode(ms->fdt, "/aliases"); + + create_fdt_pmu(s); +} + +static void load_fdt(TTAtlantisState *s) +{ + MachineState *ms =3D MACHINE(s); + char **node_path; + Error *err =3D NULL; + + ms->fdt =3D load_device_tree(ms->dtb, &s->fdt_size); + if (!ms->fdt) { + error_report("load_device_tree() failed"); + exit(1); + } + + qemu_fdt_add_path(ms->fdt, "/chosen"); + + /* Clear memory nodes and update with the specified RAM size */ + node_path =3D qemu_fdt_node_unit_path(ms->fdt, "memory", &err); + if (err) { + warn_report_err(err); + } else { + for (int i =3D 0; node_path[i]; i++) { + warn_report("Replacing device tree %s with the requested RAM s= ize", + node_path[i]); + qemu_fdt_nop_node(ms->fdt, node_path[i]); + } + g_strfreev(node_path); + } + + create_fdt_memory(s); +} + +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); + } + 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; + int hart_count =3D machine->smp.cpus; + + 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", 0, + &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_MIMSIC_STRIDE, + 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, 0, 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, + 0, hart_count, + TT_ACLINT_MTIMECMP, + TT_ACLINT_MTIME, + TT_ACLINT_TIMEBASE_FREQ, true); + + /* + * DDR + * + * The high address is where RAM lives. It is always present and may be + * up to 64GB. The low address is an alias of the first 2GB of that RA= M. + */ + if (machine->ram_size > s->memmap[TT_ATL_DDR_HI].size) { + char *sz =3D size_to_str(s->memmap[TT_ATL_DDR_HI].size); + error_report("RAM size is too large, maximum is %s", sz); + g_free(sz); + exit(EXIT_FAILURE); + } + + memory_region_init_alias(ram_hi, OBJECT(machine), "ram.high", machine-= >ram, + 0, machine->ram_size); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_DDR_HI].base, ram_hi); + + lo_ram_size =3D MIN(machine->ram_size, s->memmap[TT_ATL_DDR_LO].size); + memory_region_init_alias(ram_lo, OBJECT(machine), "ram.low", machine->= ram, + 0, lo_ram_size); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_DDR_LO].base, ram_lo); + + /* 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); + + /* UART1, the soc console (UART0 is for the boot microcontroller) */ + serial_mm_init(system_memory, s->memmap[TT_ATL_UART1].base, 2, + qdev_get_gpio_in(s->irqchip, TT_ATL_UART1_IRQ), + 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); + /* + * Atlantis contains a DesignWare uart while the QEMU machine + * uses the serial_mm model with the base ns16550 register set. + * Linux's dw driver writes outside of serial_mm's 0x20 sized + * mapping and faults. + * + * Create an unimplemented device region so writes don't fault + * and reads return zero, which keeps Linux happy. + */ + create_unimplemented_device("tt-atlantis.uart0", + s->memmap[TT_ATL_UART1].base, + s->memmap[TT_ATL_UART1].size); + + /* Load or create device tree */ + if (machine->dtb) { + load_fdt(s); + } 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 (Experimental)"; + mc->init =3D tt_atlantis_machine_init; + mc->max_cpus =3D 8; + mc->default_cpus =3D 8; + mc->default_ram_size =3D 4 * 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), + .interfaces =3D riscv64_machine_interfaces, + }, +}; + +DEFINE_TYPES(tt_atlantis_types) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 54e41a6afc90..5033415440d4 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -120,6 +120,16 @@ config SPIKE select RISCV_ACLINT select SIFIVE_PLIC =20 +config TENSTORRENT + bool + default y + depends on RISCV64 + select RISCV_ACLINT + select RISCV_APLIC + select RISCV_IMSIC + select SERIAL_MM + select DEVICE_TREE + config XIANGSHAN_KUNMINGHU bool default y diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build index 798477b7882a..0d82ceacc430 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -11,6 +11,7 @@ riscv_ss.add(when: 'CONFIG_SIFIVE_E', if_true: files('sif= ive_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 Sat Jun 20 00:37:12 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 1781844722669693.5614139650507; Thu, 18 Jun 2026 21:52:02 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRAs-0008Up-Vo; Fri, 19 Jun 2026 00:49:53 -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 1waRAn-0008Tt-2Z for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:45 -0400 Received: from mail-pf1-x434.google.com ([2607:f8b0:4864:20::434]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRAl-0005aA-He for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:44 -0400 Received: by mail-pf1-x434.google.com with SMTP id d2e1a72fcca58-8453f568e84so1556178b3a.0 for ; Thu, 18 Jun 2026 21:49:43 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844582; x=1782449382; 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=h/4gPFTvEOiA6bvBc5b2RKGBkvJS7RvJu6EipcSXEpI=; b=qKxhYi5CxIsmD/2SXjY2yJoJ26ZHx42ZRsE9u6ekLhAfmCQFIWrWxY+hsXkDFyVm+e EbocD+hJT+JKGDrXUIu2hxt8lynVCpm/aT0EgKv5ppHycY4cyX4KTXg1GqRccAiTxFNV TXomXSNbA3UblmyxtIjtUybNl2vQ0EWkaD70OHM8YBSKWdR3SxV0d90bFkRrlwy4juah aK4CKo8Obny4hFn57vW5sBPmbCmpxiMDjIzJHvGoixXIt0sWUbGy+U2GmroZ88C6ca+m ZhUWLoJwLAj8YnSR5NBuZk8T9kRaZESAB9TLqef1O0r+tQZXpQf5VtwhU4LwqRmEykoA x8JQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844582; x=1782449382; 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=h/4gPFTvEOiA6bvBc5b2RKGBkvJS7RvJu6EipcSXEpI=; b=NjD48mI2RNddBOhIMT4dCiB/GOpY4NJNP/gos9N4gQNPJINxf04w0/IWeRpyQoggFc FcAupZtAG5VTmVd2x/C83Zi08k1Ab6Ez47oJoPJPIR2YLWcf76MWxILKW37pii58qmKh HXIfZKZkgldpX3HZDKWsb2+q+sqKF64zmNOTb3AIjGK2RAMEZaUUvVZ8w0a0h4xaU2m1 nnF3iLx/hJ0j9BK7CEVFJR258Zw4Uy/nYtn8pAGtOE2PBVJOKSQecDmIamPSMJzEC7GT uqTIBpSblb5dNvyV82lX+PDZrFEzsWaUmMBSw+9KNyZw5Qo8FOO/M86CqvTAJxC+Vb/m Ek7g== X-Forwarded-Encrypted: i=1; AFNElJ+iPYVdthMTECMTSO9LPIiKsgiTXG1Bb4UgExcx/QpbhpFrWnth58EdmCdhS7M1xAKWJTRvkeHSpCFa@nongnu.org X-Gm-Message-State: AOJu0YyzGqjfs74Z83JrZxUdrmNTmrIqkmwYaOjt4uc4nMK+KOrK3xz4 29CvKtWGwTRzix2VamtqemRwRl4A/LBahXlvKCN5jGP2Cj9r1b6QYv8j X-Gm-Gg: AfdE7cnLOK1Aw+O226v+VqFnPRO0SUhRznA67FIF/DSR8TDJZ7DKL2G1xhU4bckaE5u OODZ96EeKdSi5r6UwvLQxFAe18r9z9pCYEwxpyBzXzK+7pCut+eKlj8hwTHceIblAwTIwPTPUoR xEd6Issinj5XGuxUwWCK1l9oYKIEDXiypYJ2t+uUM88XhXoBPV0PjRWycgYO7XTmJXucBLRXnV7 LDhvZzbcj2zm8wZoQAhnU5nsO/RFLuLKiWUWa0qxbyiuUVQWrPa/WDZIlW5yvfMgP6eyrtuAbVu 9hlvrs7+bZhmBolAmEUa2JcnoDRsEmZwa4GFwKzZl3WSLcDosaE83R+eJWq5wqm/D2kvBa/zl8K CwuQi+xQi9l6ezUUS+89KunEL71C8lCDhgEEzFRvP9l6kM/kfm/fKO8QsRQowtQjZo/edjuz+NB q5b488TKYKqheidUmRC61LB1WZcJJP3lVVl1cp0yKKNetqZNN/XbA3Oq4no48+5kQv08oP/FY4j DwU+Kj49+RazTMTSyudCurIAE91Gj22+/fIuyhQWw== X-Received: by 2002:a05:6a00:18a3:b0:845:4888:74c5 with SMTP id d2e1a72fcca58-8455612ed04mr1166726b3a.23.1781844582268; Thu, 18 Jun 2026 21:49:42 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Nicholas Piggin , Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v9 08/12] hw/riscv/atlantis: Provide a simple halting payload Date: Fri, 19 Jun 2026 14:18:32 +0930 Message-ID: <20260619044838.1054677-9-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-1-joel@jms.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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::434; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x434.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.249, 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: 1781844723565158501 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 Tenstorrent Atlantis machine 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, until OpenSBI can be fixed. Signed-off-by: Nicholas Piggin Reviewed-by: Daniel Henrique Barboza Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Joel Stanley --- hw/riscv/tt_atlantis.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index 1f0cd08ac959..c3016d6d4c9e 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -340,6 +340,30 @@ static void load_fdt(TTAtlantisState *s) create_fdt_memory(s); } =20 +/* + * This works around a problem with OpenSBI hanging with no console output= if + * no payload is provided. By chance, machines with memory at 0x80000000 d= o get + * output, but Atlantis memory begins at 0x0 which takes a different OpenS= BI + * error path. + * + * This can be removed when OpenSBI is fixed in QEMU. + */ +static void tt_atlantis_setup_halting_payload_opensbi_fixup( + RISCVBootInfo *info, hwaddr addr) +{ + /* Store the payload vector in little_endian byte order */ + static const uint32_t payload_vec[] =3D { + const_le32(0x10500073), /* 1: wfi */ + const_le32(0xffdff06f), /* j 1b */ + }; + 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; +} + static void tt_atlantis_machine_done(Notifier *notifier, void *data) { TTAtlantisState *s =3D container_of(notifier, TTAtlantisState, machine= _done); @@ -377,6 +401,9 @@ static void tt_atlantis_machine_done(Notifier *notifier= , void *data) if (machine->kernel_filename) { riscv_load_kernel(machine, &boot_info, kernel_start_addr, true, NULL); + } else { + tt_atlantis_setup_halting_payload_opensbi_fixup(&boot_info, + kernel_start_addr); } kernel_entry =3D boot_info.image_low_addr; =20 --=20 2.47.3 From nobody Sat Jun 20 00:37:12 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 1781844678654416.14203868589755; Thu, 18 Jun 2026 21:51:18 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRBF-0000Ca-3d; Fri, 19 Jun 2026 00:50:13 -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 1waRB7-0000AY-Sb for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:50:06 -0400 Received: from mail-pg1-x52f.google.com ([2607:f8b0:4864:20::52f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRAr-0005ae-2L for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:49:51 -0400 Received: by mail-pg1-x52f.google.com with SMTP id 41be03b00d2f7-c8857a27041so798273a12.1 for ; Thu, 18 Jun 2026 21:49:48 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844587; x=1782449387; 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=Vd3sxRoaOwrRfJ6hdkzafWLf1VuZKQV0n9nVZ9JX8So=; b=ApNdMoevgM7zkH0AotZtqtCTFORSvmGsAS9EOP1Je84jZnV/s9woy884GGJrdALB0g mBOILp/xpK5wHIU7yeifyzAsr4/6BIvb8a+beBXA3IvjBzrrmkNEMix92fDkKJTohUGH epV7ruiQwROE6YHG0VO+kZzd2fUlAS1ryxiTn55AZwb6taxkYJ0PZdzCGYqgnLykqwHa 3uukjiIET4cnpJ5F76bsgsrDAfmaunmJ3184tXhlex93QUvzKtsHQdS4QjhwZrxBSVCr 17Lwtm4HkRKezMdRh5Gdba1nhFIvFOmbHwFYY7PLhZmpAv40gJSrLnJ3c0txhKF9LwJi +wJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844587; x=1782449387; 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=Vd3sxRoaOwrRfJ6hdkzafWLf1VuZKQV0n9nVZ9JX8So=; b=qajMd8UkclKAIzckJV3f+oGOslmMSiOJ/Q8U7RCWVjrJgqRYN2Rno3l0smg78cQsiC VbbxiHQgCwIEBr0im3Ac7FWZ/w6EdepDVaSTNsiU4TFuqUzJ9xjcPzFS7ZErlfxndOP1 XAU7lEFNOp6yyzQF1x+cp8rZNd9xbBR+C3Hkw5DbWF14Qs55YtbIYzMItzf/m68q+9Xw MLfrlNRPHJ6j9wGXomKUkkPTCtiodsnQIbclvdC51h0Zr/y1mWRVEErraNkWp2C+oYqd wxAfO6thZ3d3WyCMZ2C5BxLU+9PEIolGYUq3gVp2/9AJpgQwx9ig5c11Sd8siLrbwuGi ws4A== X-Forwarded-Encrypted: i=1; AFNElJ+57FWT8a37/JhLvMMgBRzJvRBjCtUscZDDcJCNFc11lBudI0YhE+f7ZR5nPd6dP6zAUyAa4r2jsEBX@nongnu.org X-Gm-Message-State: AOJu0Yws46zxvbFS/VOgy5GlmI75tyVc7wLnjJrRZayI1fFYdbRpftlM I1pRFC7utGhK9Ynp65eIrPQmDW7eOVsFqiePxEeHBPZHgZUfIdhP4xHV X-Gm-Gg: AfdE7cmbR60MNzKajxHdGxn+2GiFwBad2fKcds5OFlzMUPupBxEqtPj+jTWhuVnnT/T rniwX75LXKupyvc9F9g5WdDn9Z1s32wHq9NxZJYq27Xf7pXNb/ZPVGNlnCxYtKn17UV+nOl7k4s co4llVxmS6ocan2qRy6Gl8i/NdV24UMmSqYSwzfUc1dzLgE0xTWTi8AitAXYFNSL3YwoNTZ3u64 BLd+nRRipjDHBbYy+xtTUcTzAWs+JFGHcdgVYt3aD0mXTyG0QRyuWqW8XfdV7Hshtw2SQL/w7sz KBvMBeQfxpf+K/cvRaSPPwGMXru34l+ntmkFlBGEI9k3Fwd+WFWfbbefvrQZcnct/R/Uo64TUga YQnPoaxTrEGLzOlNBXoWKIIp14Nca026zK2xgWJ25mhhzX/r8k7jOk4awJ96CJIo2VROjfRUi4b trYHp2KGSqa8PR/56TLPm28HD/B4DNsyud+/ahbB2aeCH1iWWYXgGhHTp3lJEdA+oKVOIiP+uuO wDwrCDLMelz36xrVwDfZr2Y3pw9hAuSnTEI29tJtw== X-Received: by 2002:a05:6a00:1acc:b0:838:127d:a167 with SMTP id d2e1a72fcca58-845507d4da2mr2113111b3a.16.1781844587598; Thu, 18 Jun 2026 21:49:47 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Nicholas Piggin , Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v9 09/12] tests/functional/riscv64: Add tt-atlantis tests Date: Fri, 19 Jun 2026 14:18:33 +0930 Message-ID: <20260619044838.1054677-10-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-1-joel@jms.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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::52f; envelope-from=joel.stan@gmail.com; helo=mail-pg1-x52f.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.249, 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: 1781844679520158500 From: Nicholas Piggin Add OpenSBI and Linux boot tests for the tt-atlantis machine. Based on tests/functional/riscv64/test_sifive_u.py. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Acked-by: Alistair Francis Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- MAINTAINERS | 1 + tests/functional/riscv64/meson.build | 1 + tests/functional/riscv64/test_opensbi.py | 4 ++ tests/functional/riscv64/test_tt_atlantis.py | 57 ++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100755 tests/functional/riscv64/test_tt_atlantis.py diff --git a/MAINTAINERS b/MAINTAINERS index 09c9a79e04a9..fb17511b5725 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1784,6 +1784,7 @@ S: Supported F: docs/system/riscv/tt_*.rst F: hw/riscv/tt_*.c 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 5871211e8998..c9d4c090fb52 100644 --- a/tests/functional/riscv64/meson.build +++ b/tests/functional/riscv64/meson.build @@ -14,5 +14,6 @@ tests_riscv64_system_thorough =3D [ 'endianness', '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..48abd5cd27c2 --- /dev/null +++ b/tests/functional/riscv64/test_tt_atlantis.py @@ -0,0 +1,57 @@ +#!/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 + +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) + + def test_riscv64_tt_atlantis(self): + # tt-atlantis machine has no PCI host yet, so no disk + self.do_test_riscv64_tt_atlantis(False) + + +if __name__ =3D=3D '__main__': + LinuxKernelTest.main() --=20 2.47.3 From nobody Sat Jun 20 00:37:12 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 1781844729351947.507926349274; Thu, 18 Jun 2026 21:52:09 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRBX-0000YO-93; Fri, 19 Jun 2026 00:50:31 -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 1waRBF-0000Fq-3K for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:50:13 -0400 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRB6-0005bA-5u for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:50:12 -0400 Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-8423610ec93so1495803b3a.2 for ; Thu, 18 Jun 2026 21:49:55 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844594; x=1782449394; 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=WAzl79A3Nhe9qMQyZNybzkrJO1jJm3ohmSHmw3yH9f4=; b=joaIP20JaXtjTsQFEDbrsSNSUxhKMhIaKFQGOVW2WTV3QphmV8QxqDvvmFmvIyPpMC 4dLD3WJrUPSYtSGi3kGlxXRHnGetAlYlcIfe4Uur742jSipHIH6dlKz8sRRBCIxT6q24 ZgJk0pXVB1z8sseHz3vGu6B31gRRN8G4RCCahQahr7tnhHHAvAfl4Zmj9EXSwUBlaD3M Pv5zt3MPD+5hXVsgmVCbaRgTbY1TP3ZG2JTPu07ckGYZ500EqdHAf/tyH9p9pqxIhO8/ mcD7XqgAEKVpLf080S8whiw2567tTE0OSogwTsv6gS+IeOzZBXx5iXg76jTg3ak4kt3R m9AA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844594; x=1782449394; 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=WAzl79A3Nhe9qMQyZNybzkrJO1jJm3ohmSHmw3yH9f4=; b=EOd3DndENQKodtjwTH2qe1MIzOLCbXzZHNh/TF6/I7NHWOa2abVX/pWUG4c2LaVKhm yzor1UC4h9KITrJMkfq0V1uWqC1qz4zgBfrmRGGigNVO91/oTZP9wuBzWnpVLweelGyr nySVB5bemt2Jp5y3kH9LfGKV7hzgx4C5jh4PGNtOCTJjh3U+kRwpCD4BZdQQLRLbXHzJ 4/am56bvGwO3dv4ri70lTpnj9UpKgyqTWwMnYbbVoDOP1iJUrDrtfpmSAAO+RLpUSPY1 z91ngDcXTB5ALoeYVx8rhIrf7nTzvF8xNmYVE4E/3qQHwSJuNLlG4nHvJBHPrxhz4XBx qbVA== X-Forwarded-Encrypted: i=1; AFNElJ+qhSZVGqqGL+wHe7PA6goT1YeVhciupPmJT3PjijWi5JLgLV2vg5I4KF6yI1fk3bQsY/if4U9XLFnu@nongnu.org X-Gm-Message-State: AOJu0YxyAn2elwZc6UqcSFO1AkTz5qwdcUHDg1kCdytfOk5JTGFF19MP E1Wc0MNXstctCg4JF4sbNVxJ9JQZfz9pPntlyCmp9AVLeUtlsly64bcp X-Gm-Gg: AfdE7cmcE1WHS0hP+TalxFUz43Zyy8mt7okT6yHWkBaIeqvnXh6Y4OuTv7t3LBtqSOF OoHjKrBdgQcLVkd+w4zFdcRRFWl6eZ90L4ILwhCC0M/+3790a83Xd3Hg7sSErqnUClGwDDz2tmS hkp8eFz6IA8Ndjggz4+1zwf/X/MStg8ad1zVN35e2CLfjotfXSXed2DlwXetmCgeOgUog8mrSzt J29l2XMtUoZ8oTrnGPPjt8TfjP+jL+Z+NuDhUU5cKE3mSAm4bf+mtyYACw3DMkmLgdq9ft+aUWJ j/W++XJtGwFGYayH9s1oCmxQvSOm/9DFN6xBnxFGhiEXVd5lT5B/5JZDpFF1QsM/P55Fj5iDM8h 2k5WRleim+R0HcXiK0bqxjsUixfRM5QDgLzlv6zZCRWJyItad8Zq5zqI8H9tkOKCA6sfjU1CXNj CeRfqPFSMbZpet3t5jR8P8NtVoPDiOdJ7I5D71cT07GmffWfB8DOZNA7rpD+Mma+yNItQb6w2Ft rTHPjfNIIOqDxTnWe41xam+TjpCR3NfIcS3U6kg5g== X-Received: by 2002:a05:6a00:3d4c:b0:82f:6e9:d1c3 with SMTP id d2e1a72fcca58-8455087b229mr2140698b3a.29.1781844593980; Thu, 18 Jun 2026 21:49:53 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Chris Rauer , Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Alano Song , Michael Ellerman , Joel Stanley , Nick Piggin , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, Hao Wu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Corey Minyard , Alano Song Subject: [PATCH v9 10/12] hw/i2c: Add DesignWare I2C Controller Date: Fri, 19 Jun 2026 14:18:34 +0930 Message-ID: <20260619044838.1054677-11-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-1-joel@jms.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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::429; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x429.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.249, 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: 1781844731604158500 From: Chris Rauer Add a model for the Synopsys DesignWare Advanced I2C/SMBus Controller with sufficient functionality to be used by the Linux Designware I2C platform driver. This IP is used in the Tenstorrent Atlantis RISC-V SoC and will be added to the QEMU tt-atlantis machine. [npiggin: changelog, code cleanups and fixes as-per below link] 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] Link: https://lore.kernel.org/qemu-devel/20260507120524.111056-1-npiggin@gm= ail.com Signed-off-by: Nicholas Piggin Acked-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daud=C3=A9 Acked-by: Corey Minyard Tested-by: Alano Song Signed-off-by: Joel Stanley --- MAINTAINERS | 8 + include/hw/i2c/designware_i2c.h | 56 +++ hw/i2c/designware_i2c.c | 745 ++++++++++++++++++++++++++++++++ hw/i2c/Kconfig | 5 + hw/i2c/meson.build | 1 + 5 files changed, 815 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 fb17511b5725..b7887035fda5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2748,6 +2748,14 @@ S: Orphan F: hw/gpio/pcf8574.c F: include/hw/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..4d5ff5d973d8 --- /dev/null +++ b/include/hw/i2c/designware_i2c.h @@ -0,0 +1,56 @@ +/* + * DesignWare I2C Module. + * + * Copyright 2021 Google LLC + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef DESIGNWARE_I2C_H +#define DESIGNWARE_I2C_H + +#include "qemu/fifo8.h" +#include "hw/i2c/i2c.h" +#include "hw/core/irq.h" +#include "hw/core/register.h" +#include "hw/core/sysbus.h" +#include "qom/object.h" + +#define DESIGNWARE_I2C_R_MAX (0x100 / 4) + +#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; + +#define TYPE_DESIGNWARE_I2C "designware-i2c" +OBJECT_DECLARE_SIMPLE_TYPE(DesignWareI2CState, DESIGNWARE_I2C) + +/* + * struct DesignWareI2CState - DesignWare I2C device state. + * @bus: The underlying I2C Bus + * @irq: Interrupt line fired on transaction events. + * @rx_fifo: The FIFO buffer for receiving in FIFO mode. + */ +struct DesignWareI2CState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + + I2CBus *bus; + qemu_irq irq; + + uint32_t regs[DESIGNWARE_I2C_R_MAX]; + RegisterInfo regs_info[DESIGNWARE_I2C_R_MAX]; + + /* fifo8_num_used(rx_fifo) should always equal DW_IC_RXFLR */ + Fifo8 rx_fifo; + + DesignWareI2CStatus status; +}; + +#endif /* DESIGNWARE_I2C_H */ diff --git a/hw/i2c/designware_i2c.c b/hw/i2c/designware_i2c.c new file mode 100644 index 000000000000..daa9714cb7b2 --- /dev/null +++ b/hw/i2c/designware_i2c.c @@ -0,0 +1,745 @@ +/* + * 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/log.h" +#include "qemu/module.h" +#include "qemu/units.h" + +#ifndef DESIGNWARE_I2C_ERR_DEBUG +#define DESIGNWARE_I2C_ERR_DEBUG 0 +#endif + +REG32(DW_IC_CON, 0x00) /* I2C control */ + FIELD(DW_IC_CON, STOP_DET_IF_MASTER_ACTIV, 10, 1) + FIELD(DW_IC_CON, RX_FIFO_FULL_HLD_CTRL, 9, 1) + FIELD(DW_IC_CON, TX_EMPTY_CTRL, 8, 1) + FIELD(DW_IC_CON, STOP_IF_ADDRESSED, 7, 1) + FIELD(DW_IC_CON, SLAVE_DISABLE, 6, 1) + FIELD(DW_IC_CON, IC_RESTART_EN, 5, 1) + FIELD(DW_IC_CON, 10BITADDR_MASTER, 4, 1) + FIELD(DW_IC_CON, 10BITADDR_SLAVE, 3, 1) + FIELD(DW_IC_CON, SPEED, 1, 2) + FIELD(DW_IC_CON, MASTER_MODE, 0, 1) +REG32(DW_IC_TAR, 0x04) /* I2C target address */ + FIELD(DW_IC_TAR, IC_10BITADDR_MASTER, 12, 1) + FIELD(DW_IC_TAR, SPECIAL, 11, 1) + FIELD(DW_IC_TAR, GC_OR_START, 10, 1) + FIELD(DW_IC_TAR, ADDRESS, 0, 10) +REG32(DW_IC_SAR, 0x08) /* I2C slave address */ +REG32(DW_IC_DATA_CMD, 0x10) + FIELD(DW_IC_DATA_CMD, RESTART, 10, 1) + FIELD(DW_IC_DATA_CMD, STOP, 9, 1) + FIELD(DW_IC_DATA_CMD, CMD, 8, 1) + FIELD(DW_IC_DATA_CMD, DAT, 0, 8) +REG32(DW_IC_SS_SCL_HCNT, 0x14) /* Standard speed i2c clock scl high= count */ +REG32(DW_IC_SS_SCL_LCNT, 0x18) /* Standard speed i2c clock scl low = count */ +REG32(DW_IC_FS_SCL_HCNT, 0x1c) /* Fast or fast plus i2c clock scl h= igh count */ +REG32(DW_IC_FS_SCL_LCNT, 0x20) /* Fast or fast plus i2c clock scl l= ow count */ +REG32(DW_IC_INTR_STAT, 0x2c) +REG32(DW_IC_INTR_MASK, 0x30) /* I2C Interrupt Mask */ +REG32(DW_IC_RAW_INTR_STAT, 0x34) /* I2C raw interrupt status */ + /* DW_IC_INTR_STAT/INTR_MASK/RAW_INTR_STAT fields */ + SHARED_FIELD(DW_IC_INTR_RESTART_DET, 12, 1) + SHARED_FIELD(DW_IC_INTR_GEN_CALL, 11, 1) + SHARED_FIELD(DW_IC_INTR_START_DET, 10, 1) + SHARED_FIELD(DW_IC_INTR_STOP_DET, 9, 1) + SHARED_FIELD(DW_IC_INTR_ACTIVITY, 8, 1) + SHARED_FIELD(DW_IC_INTR_RX_DONE, 7, 1) + SHARED_FIELD(DW_IC_INTR_TX_ABRT, 6, 1) + SHARED_FIELD(DW_IC_INTR_RD_REQ, 5, 1) + SHARED_FIELD(DW_IC_INTR_TX_EMPTY, 4, 1) /* Hardware clear only. */ + SHARED_FIELD(DW_IC_INTR_TX_OVER, 3, 1) + SHARED_FIELD(DW_IC_INTR_RX_FULL, 2, 1) /* Hardware clear only. */ + SHARED_FIELD(DW_IC_INTR_RX_OVER, 1, 1) + SHARED_FIELD(DW_IC_INTR_RX_UNDER, 0, 1) + +#define DW_IC_INTR_ANY_MASK \ + (DW_IC_INTR_RESTART_DET_MASK | \ + DW_IC_INTR_GEN_CALL_MASK | \ + DW_IC_INTR_START_DET_MASK | \ + DW_IC_INTR_STOP_DET_MASK | \ + DW_IC_INTR_ACTIVITY_MASK | \ + DW_IC_INTR_RX_DONE_MASK | \ + DW_IC_INTR_TX_ABRT_MASK | \ + DW_IC_INTR_RD_REQ_MASK | \ + DW_IC_INTR_TX_EMPTY_MASK | \ + DW_IC_INTR_TX_OVER_MASK | \ + DW_IC_INTR_RX_FULL_MASK | \ + DW_IC_INTR_RX_OVER_MASK | \ + DW_IC_INTR_RX_UNDER_MASK) + +#define DW_IC_INTR_ANY_SW_CLEAR_MASK \ + (DW_IC_INTR_ANY_MASK & \ + ~(DW_IC_INTR_TX_EMPTY_MASK | \ + DW_IC_INTR_RX_FULL_MASK)) + +REG32(DW_IC_RX_TL, 0x38) /* I2C receive FIFO threshold */ +REG32(DW_IC_TX_TL, 0x3c) /* I2C transmit FIFO threshold */ +REG32(DW_IC_CLR_INTR, 0x40) +REG32(DW_IC_CLR_RX_UNDER, 0x44) +REG32(DW_IC_CLR_RX_OVER, 0x48) +REG32(DW_IC_CLR_TX_OVER, 0x4c) +REG32(DW_IC_CLR_RD_REQ, 0x50) +REG32(DW_IC_CLR_TX_ABRT, 0x54) +REG32(DW_IC_CLR_RX_DONE, 0x58) +REG32(DW_IC_CLR_ACTIVITY, 0x5c) +REG32(DW_IC_CLR_STOP_DET, 0x60) +REG32(DW_IC_CLR_START_DET, 0x64) +REG32(DW_IC_CLR_GEN_CALL, 0x68) +REG32(DW_IC_ENABLE, 0x6c) /* I2C enable */ + FIELD(DW_IC_ENABLE, TX_CMD_BLOCK, 2, 1) + FIELD(DW_IC_ENABLE, ABORT, 1, 1) + FIELD(DW_IC_ENABLE, ENABLE, 0, 1) +REG32(DW_IC_STATUS, 0x70) /* I2C status */ + FIELD(DW_IC_STATUS, SLV_ACTIVITY, 6, 1) + FIELD(DW_IC_STATUS, MST_ACTIVITY, 5, 1) + FIELD(DW_IC_STATUS, RFF, 4, 1) + FIELD(DW_IC_STATUS, RFNE, 3, 1) + FIELD(DW_IC_STATUS, TFE, 2, 1) + FIELD(DW_IC_STATUS, TFNF, 1, 1) + FIELD(DW_IC_STATUS, ACTIVITY, 0, 1) +REG32(DW_IC_TXFLR, 0x74) /* I2C transmit fifo level */ +REG32(DW_IC_RXFLR, 0x78) /* I2C receive fifo level */ +REG32(DW_IC_SDA_HOLD, 0x7c) /* I2C SDA hold time length */ +REG32(DW_IC_TX_ABRT_SOURCE, 0x80) /* The I2C transmit abort source */ + FIELD(DW_IC_TX_ABRT_SOURCE, USER_ABRT, 16, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, SLVRD_INTX, 15, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, SLV_ARBLOST, 14, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, SLVFLUSH_TXFIFO, 13, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, ARB_LOST, 12, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, MASTER_DIS, 11, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, 10B_RD_NORSTRT, 10, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, SBYTE_NORSTRT, 9, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, HS_NORSTRT, 8, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, SBYTE_ACKDET, 7, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, HS_ACKDET, 6, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, GCALL_READ, 5, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, GCALL_NOACK, 4, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, TXDATA_NOACK, 3, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, 10ADDR2_NOACK, 2, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, 10ADDR1_NOACK, 1, 1) + FIELD(DW_IC_TX_ABRT_SOURCE, 7B_ADDR_NOACK, 0, 1) +REG32(DW_IC_SLV_DATA_NACK_ONLY, 0x84) +REG32(DW_IC_DMA_CR, 0x88) +REG32(DW_IC_DMA_TDLR, 0x8c) +REG32(DW_IC_DMA_RDLR, 0x90) +REG32(DW_IC_SDA_SETUP, 0x94) /* I2C SDA setup */ +REG32(DW_IC_ACK_GENERAL_CALL, 0x98) +REG32(DW_IC_ENABLE_STATUS, 0x9c) /* I2C enable status */ + FIELD(DW_IC_ENABLE_STATUS, SLV_RX_DATA_LOST, 2, 1) + FIELD(DW_IC_ENABLE_STATUS, SLV_DISABLED_WHILE_BUSY, 1, 1) + FIELD(DW_IC_ENABLE_STATUS, IC_EN, 0, 1) +REG32(DW_IC_FS_SPKLEN, 0xa0) /* I2C SS, FS or FM+ spike suppressi= on limit */ +REG32(DW_IC_CLR_RESTART_DET, 0xa8) +REG32(DW_IC_SMBUS_INTR_MASK, 0xcc) /* SMBus Interrupt Mask */ +REG32(DW_IC_COMP_PARAM_1, 0xf4) /* Component parameter */ + FIELD(DW_IC_COMP_PARAM_1, TX_FIFO_SIZE, 16, 8) + FIELD(DW_IC_COMP_PARAM_1, RX_FIFO_SIZE, 8, 8) + FIELD(DW_IC_COMP_PARAM_1, HAS_ENCODED_PARAMS, 7, 1) + FIELD(DW_IC_COMP_PARAM_1, HAS_DMA, 6, 1) + FIELD(DW_IC_COMP_PARAM_1, INTR_IO, 5, 1) + FIELD(DW_IC_COMP_PARAM_1, HC_COUNT_VAL, 4, 1) + FIELD(DW_IC_COMP_PARAM_1, HIGH_SPEED_MODE, 2, 2) + FIELD(DW_IC_COMP_PARAM_1, APB_DATA_WIDTH_32, 0, 2) +REG32(DW_IC_COMP_VERSION, 0xf8) /* I2C component version */ +REG32(DW_IC_COMP_TYPE, 0xfc) /* I2C component type */ + +static void dw_i2c_update_irq(DesignWareI2CState *s) +{ + uint32_t intr =3D s->regs[R_DW_IC_RAW_INTR_STAT] & s->regs[R_DW_IC_INT= R_MASK]; + + qemu_set_irq(s->irq, !!(intr & DW_IC_INTR_ANY_MASK)); +} + +static uint64_t dw_ic_data_cmd_reg_post_read(RegisterInfo *reg, uint64_t v= alue) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + g_assert(value =3D=3D 0); + + 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) { + SHARED_ARRAY_FIELD_DP32(s->regs, R_DW_IC_RAW_INTR_STAT, + DW_IC_INTR_RX_UNDER, 1); + dw_i2c_update_irq(s); + } + return 0; + } + + g_assert(s->regs[R_DW_IC_RXFLR] =3D=3D fifo8_num_used(&s->rx_fifo)); + + if (fifo8_is_empty(&s->rx_fifo)) { + SHARED_ARRAY_FIELD_DP32(s->regs, R_DW_IC_RAW_INTR_STAT, DW_IC_INTR= _RX_UNDER, 1); + dw_i2c_update_irq(s); + return 0; + } + + s->regs[R_DW_IC_RXFLR]--; + if (s->regs[R_DW_IC_RXFLR] <=3D s->regs[R_DW_IC_RX_TL]) { + SHARED_ARRAY_FIELD_DP32(s->regs, R_DW_IC_RAW_INTR_STAT, DW_IC_INTR= _RX_FULL, 0); + dw_i2c_update_irq(s); + } + + return fifo8_pop(&s->rx_fifo); +} + +static uint64_t dw_ic_clr_intr_reg_post_read(RegisterInfo *reg, uint64_t v= alue) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + g_assert(value =3D=3D 0); + + switch (reg->access->addr) { + case A_DW_IC_CLR_INTR: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_ANY_SW_CLEAR_MASK; + break; + case A_DW_IC_CLR_RX_UNDER: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_RX_UNDER_MASK; + break; + case A_DW_IC_CLR_RX_OVER: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_RX_OVER_MASK; + break; + case A_DW_IC_CLR_TX_OVER: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_TX_OVER_MASK; + break; + case A_DW_IC_CLR_RD_REQ: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_RD_REQ_MASK; + break; + case A_DW_IC_CLR_TX_ABRT: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_TX_ABRT_MASK; + break; + case A_DW_IC_CLR_RX_DONE: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_RX_DONE_MASK; + break; + case A_DW_IC_CLR_ACTIVITY: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_ACTIVITY_MASK; + break; + case A_DW_IC_CLR_STOP_DET: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_STOP_DET_MASK; + break; + case A_DW_IC_CLR_START_DET: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_START_DET_MASK; + break; + case A_DW_IC_CLR_GEN_CALL: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_GEN_CALL_MASK; + break; + case A_DW_IC_CLR_RESTART_DET: + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_RESTART_DET_MASK; + break; + default: + g_assert_not_reached(); + } + + dw_i2c_update_irq(s); + + return 0; +} + +static uint64_t dw_ic_intr_stat_reg_post_read(RegisterInfo *reg, uint64_t = value) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + g_assert(value =3D=3D 0); + + return s->regs[R_DW_IC_RAW_INTR_STAT] & s->regs[R_DW_IC_INTR_MASK]; +} + +static uint64_t dw_ic_unsupported_reg_post_read(RegisterInfo *reg, uint64_= t value) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + qemu_log_mask(LOG_UNIMP, "%s: unsupported read - %s\n", + DEVICE(s)->canonical_path, reg->access->name); + + return 0; +} + +static uint64_t dw_ic_unsupported_reg_pre_write(RegisterInfo *reg, uint64_= t value) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + qemu_log_mask(LOG_UNIMP, "%s: unsupported write - %s\n", + DEVICE(s)->canonical_path, reg->access->name); + + return 0; +} + +static uint64_t dw_ic_con_reg_pre_write(RegisterInfo *reg, uint64_t value) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + if (s->regs[R_DW_IC_ENABLE] & R_DW_IC_ENABLE_ENABLE_MASK) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid setting to ic_con %d when ic_enable[0]= =3D=3D1\n", + DEVICE(s)->canonical_path, (int)value); + return s->regs[R_DW_IC_CON]; /* keep old value */ + } + + return value; +} + +static void dw_i2c_reset_to_idle(DesignWareI2CState *s) +{ + s->regs[R_DW_IC_ENABLE_STATUS] &=3D ~R_DW_IC_ENABLE_STATUS_IC_EN_MASK; + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_TX_EMPTY_MASK; + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_RX_FULL_MASK; + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_RX_UNDER_MASK; + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_RX_OVER_MASK; + s->regs[R_DW_IC_RXFLR] =3D 0; + fifo8_reset(&s->rx_fifo); + s->regs[R_DW_IC_STATUS] &=3D ~R_DW_IC_STATUS_ACTIVITY_MASK; + s->status =3D DW_I2C_STATUS_IDLE; + dw_i2c_update_irq(s); +} + +static void dw_ic_tx_abort(DesignWareI2CState *s, uint32_t src) +{ + s->regs[R_DW_IC_TX_ABRT_SOURCE] |=3D src; + s->regs[R_DW_IC_RAW_INTR_STAT] |=3D DW_IC_INTR_TX_ABRT_MASK; + dw_i2c_reset_to_idle(s); + dw_i2c_update_irq(s); +} + +static void dw_ic_data_cmd_reg_post_write(RegisterInfo *reg, uint64_t valu= e) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + int recv =3D !!(value & R_DW_IC_DATA_CMD_CMD_MASK); + + s->regs[R_DW_IC_DATA_CMD] =3D 0; /* Register has no storage */ + + if (!(s->regs[R_DW_IC_ENABLE] & R_DW_IC_ENABLE_ENABLE_MASK)) { + /* + * Controller is not enabled. The register_reset() path also lands + * here with value =3D=3D 0, so silently ignore rather than report= ing + * a spurious guest error. + */ + return; + } + + if (s->status =3D=3D DW_I2C_STATUS_IDLE || + s->regs[R_DW_IC_RAW_INTR_STAT] & DW_IC_INTR_TX_ABRT_MASK) { + 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, + ARRAY_FIELD_EX32(s->regs, DW_IC_TAR, ADDRESS), recv); + if (rv) { + dw_ic_tx_abort(s, R_DW_IC_TX_ABRT_SOURCE_7B_ADDR_NOACK_MASK); + 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, FIELD_EX32(value, DW_IC_DATA_CMD, DAT)= ); + if (rv) { + i2c_end_transfer(s->bus); + dw_ic_tx_abort(s, R_DW_IC_TX_ABRT_SOURCE_TXDATA_NOACK_MASK); + return; + } + dw_i2c_update_irq(s); + } + + /* Restart command */ + if (value & R_DW_IC_DATA_CMD_RESTART_MASK && + s->regs[R_DW_IC_CON] & R_DW_IC_CON_IC_RESTART_EN_MASK) { + s->regs[R_DW_IC_RAW_INTR_STAT] |=3D DW_IC_INTR_RESTART_DET_MASK | + DW_IC_INTR_START_DET_MASK | + DW_IC_INTR_ACTIVITY_MASK; + s->regs[R_DW_IC_STATUS] |=3D R_DW_IC_STATUS_ACTIVITY_MASK; + dw_i2c_update_irq(s); + + if (i2c_start_transfer(s->bus, + ARRAY_FIELD_EX32(s->regs, DW_IC_TAR, ADDRESS), recv)) { + dw_ic_tx_abort(s, R_DW_IC_TX_ABRT_SOURCE_7B_ADDR_NOACK_MASK); + return; + } + + s->status =3D recv ? DW_I2C_STATUS_RECEIVING : DW_I2C_STATUS_SENDI= NG; + } + + /* Receive data */ + if (recv) { + g_assert(s->regs[R_DW_IC_RXFLR] =3D=3D fifo8_num_used(&s->rx_fifo)= ); + + if (!fifo8_is_full(&s->rx_fifo)) { + fifo8_push(&s->rx_fifo, i2c_recv(s->bus)); + s->regs[R_DW_IC_RXFLR]++; + } else { + s->regs[R_DW_IC_RAW_INTR_STAT] |=3D DW_IC_INTR_RX_OVER_MASK; + dw_i2c_update_irq(s); + } + + if (s->regs[R_DW_IC_RXFLR] > s->regs[R_DW_IC_RX_TL]) { + s->regs[R_DW_IC_RAW_INTR_STAT] |=3D DW_IC_INTR_RX_FULL_MASK; + dw_i2c_update_irq(s); + } + if (value & R_DW_IC_DATA_CMD_STOP_MASK) { + i2c_nack(s->bus); + } + } + + /* Stop command */ + if (value & R_DW_IC_DATA_CMD_STOP_MASK) { + s->regs[R_DW_IC_RAW_INTR_STAT] |=3D DW_IC_INTR_STOP_DET_MASK; + s->regs[R_DW_IC_STATUS] &=3D ~R_DW_IC_STATUS_ACTIVITY_MASK; + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_TX_EMPTY_MASK; + i2c_end_transfer(s->bus); + dw_i2c_update_irq(s); + } +} + +static void dw_ic_intr_mask_reg_post_write(RegisterInfo *reg, uint64_t val= ue) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + dw_i2c_update_irq(s); +} + +static uint64_t dw_ic_enable_reg_pre_write(RegisterInfo *reg, uint64_t val= ue) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + if (value & R_DW_IC_ENABLE_ENABLE_MASK && + !(s->regs[R_DW_IC_CON] & R_DW_IC_CON_SLAVE_DISABLE_MASK)) { + qemu_log_mask(LOG_UNIMP, + "%s: Designware I2C slave mode is not supported.\n", + DEVICE(s)->canonical_path); + return s->regs[R_DW_IC_ENABLE]; /* keep old value */ + } + + return value; +} + +static void dw_ic_enable_reg_post_write(RegisterInfo *reg, uint64_t value) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + s->regs[R_DW_IC_ENABLE] =3D value & R_DW_IC_ENABLE_ENABLE_MASK; + + if (value & R_DW_IC_ENABLE_ABORT_MASK || value & R_DW_IC_ENABLE_TX_CMD= _BLOCK_MASK) { + dw_ic_tx_abort(s, R_DW_IC_TX_ABRT_SOURCE_USER_ABRT_MASK); + return; + } + + if (value & R_DW_IC_ENABLE_ENABLE_MASK) { + s->regs[R_DW_IC_ENABLE_STATUS] |=3D R_DW_IC_ENABLE_STATUS_IC_EN_MA= SK; + s->regs[R_DW_IC_STATUS] |=3D R_DW_IC_STATUS_ACTIVITY_MASK; + s->regs[R_DW_IC_RAW_INTR_STAT] |=3D DW_IC_INTR_ACTIVITY_MASK | + DW_IC_INTR_START_DET_MASK | + DW_IC_INTR_TX_EMPTY_MASK; + s->status =3D DW_I2C_STATUS_SENDING_ADDRESS; + dw_i2c_update_irq(s); + } else if ((value & R_DW_IC_ENABLE_ENABLE_MASK) =3D=3D 0) { + dw_i2c_reset_to_idle(s); + } +} + +static uint64_t dw_ic_rx_tl_reg_pre_write(RegisterInfo *reg, uint64_t valu= e) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + /* Note that a value of 0 for ic_rx_tl indicates a threshold 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, (int)value); + return DESIGNWARE_I2C_RX_FIFO_SIZE - 1; + } + + return value; +} + +static void dw_ic_rx_tl_reg_post_write(RegisterInfo *reg, uint64_t value) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + if (s->regs[R_DW_IC_RXFLR] > s->regs[R_DW_IC_RX_TL] && + s->regs[R_DW_IC_ENABLE] & R_DW_IC_ENABLE_ENABLE_MASK) { + s->regs[R_DW_IC_RAW_INTR_STAT] |=3D DW_IC_INTR_RX_FULL_MASK; + } else { + s->regs[R_DW_IC_RAW_INTR_STAT] &=3D ~DW_IC_INTR_RX_FULL_MASK; + } + dw_i2c_update_irq(s); +} + +static uint64_t dw_ic_tx_tl_reg_pre_write(RegisterInfo *reg, uint64_t valu= e) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(reg->opaque); + + /* + * Note that a value of 0 for ic_tx_tl indicates a threshold 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, (int)value); + return DESIGNWARE_I2C_TX_FIFO_SIZE - 1; + } + + return value; +} + +static const RegisterAccessInfo designware_i2c_regs_info[] =3D { + { .name =3D "DW_IC_CON", .addr =3D A_DW_IC_CON, + .reset =3D 0x7d, + .unimp =3D 0xfffffc00, + .pre_write =3D dw_ic_con_reg_pre_write, + },{ .name =3D "DW_IC_TAR", .addr =3D A_DW_IC_TAR, + .reset =3D 0x1055, + .unimp =3D 0xfffff000, + },{ .name =3D "DW_IC_SAR", .addr =3D A_DW_IC_SAR, + .reset =3D 0x55, + .unimp =3D 0xfffffc00, + .post_read =3D dw_ic_unsupported_reg_post_read, + .pre_write =3D dw_ic_unsupported_reg_pre_write, + },{ .name =3D "DW_IC_DATA_CMD", .addr =3D A_DW_IC_DATA_CMD, + .post_read =3D dw_ic_data_cmd_reg_post_read, + .post_write =3D dw_ic_data_cmd_reg_post_write, + },{ .name =3D "DW_IC_SS_SCL_HCNT", .addr =3D A_DW_IC_SS_SCL_HCNT, + .reset =3D 0x190, + .unimp =3D 0xffff0000, + },{ .name =3D "DW_IC_SS_SCL_LCNT", .addr =3D A_DW_IC_SS_SCL_LCNT, + .reset =3D 0x1d6, + .unimp =3D 0xffff0000, + },{ .name =3D "DW_IC_FS_SCL_HCNT", .addr =3D A_DW_IC_FS_SCL_HCNT, + .reset =3D 0x3c, + .unimp =3D 0xffff0000, + },{ .name =3D "DW_IC_FS_SCL_LCNT", .addr =3D A_DW_IC_FS_SCL_LCNT, + .reset =3D 0x82, + .unimp =3D 0xffff0000, + },{ .name =3D "DW_IC_INTR_STAT", .addr =3D A_DW_IC_INTR_STAT, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_intr_stat_reg_post_read, + },{ .name =3D "DW_IC_INTR_MASK", .addr =3D A_DW_IC_INTR_MASK, + .reset =3D 0x8ff, + .unimp =3D 0xffff8000, + .post_write =3D dw_ic_intr_mask_reg_post_write, + },{ .name =3D "DW_IC_RAW_INTR_STAT", .addr =3D A_DW_IC_RAW_INTR_STAT, + .ro =3D 0xffffffff, + },{ .name =3D "DW_IC_RX_TL", .addr =3D A_DW_IC_RX_TL, + .pre_write =3D dw_ic_rx_tl_reg_pre_write, + .post_write =3D dw_ic_rx_tl_reg_post_write, + },{ .name =3D "DW_IC_TX_TL", .addr =3D A_DW_IC_TX_TL, + .pre_write =3D dw_ic_tx_tl_reg_pre_write, + },{ .name =3D "DW_IC_CLR_INTR", .addr =3D A_DW_IC_CLR_INTR, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_RX_UNDER", .addr =3D A_DW_IC_CLR_RX_UNDER, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_RX_OVER", .addr =3D A_DW_IC_CLR_RX_OVER, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_TX_OVER", .addr =3D A_DW_IC_CLR_TX_OVER, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_RD_REQ", .addr =3D A_DW_IC_CLR_RD_REQ, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_TX_ABRT", .addr =3D A_DW_IC_CLR_TX_ABRT, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_RX_DONE", .addr =3D A_DW_IC_CLR_RX_DONE, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_ACTIVITY", .addr =3D A_DW_IC_CLR_ACTIVITY, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_STOP_DET", .addr =3D A_DW_IC_CLR_STOP_DET, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_START_DET", .addr =3D A_DW_IC_CLR_START_DET, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_CLR_GEN_CALL", .addr =3D A_DW_IC_CLR_GEN_CALL, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_ENABLE", .addr =3D A_DW_IC_ENABLE, + .unimp =3D 0xfffffff8, + .pre_write =3D dw_ic_enable_reg_pre_write, + .post_write =3D dw_ic_enable_reg_post_write, + },{ .name =3D "DW_IC_STATUS", .addr =3D A_DW_IC_STATUS, + .reset =3D 0x6, + .ro =3D 0xffffffff, + },{ .name =3D "DW_IC_TXFLR", .addr =3D A_DW_IC_TXFLR, + .ro =3D 0xffffffff, + },{ .name =3D "DW_IC_RXFLR", .addr =3D A_DW_IC_RXFLR, + .ro =3D 0xffffffff, + },{ .name =3D "DW_IC_SDA_HOLD", .addr =3D A_DW_IC_SDA_HOLD, + .reset =3D 0x1, + .unimp =3D 0xff000000, + },{ .name =3D "DW_IC_TX_ABRT_SOURCE", .addr =3D A_DW_IC_TX_ABRT_SOURC= E, + .ro =3D 0xffffffff, + },{ .name =3D "DW_IC_SLV_DATA_NACK_ONLY", .addr =3D A_DW_IC_SLV_DATA_= NACK_ONLY, + .post_read =3D dw_ic_unsupported_reg_post_read, + .pre_write =3D dw_ic_unsupported_reg_pre_write, + },{ .name =3D "DW_IC_DMA_CR", .addr =3D A_DW_IC_DMA_CR, + .post_read =3D dw_ic_unsupported_reg_post_read, + .pre_write =3D dw_ic_unsupported_reg_pre_write, + },{ .name =3D "DW_IC_DMA_TDLR", .addr =3D A_DW_IC_DMA_TDLR, + .post_read =3D dw_ic_unsupported_reg_post_read, + .pre_write =3D dw_ic_unsupported_reg_pre_write, + },{ .name =3D "DW_IC_DMA_RDLR", .addr =3D A_DW_IC_DMA_RDLR, + .post_read =3D dw_ic_unsupported_reg_post_read, + .pre_write =3D dw_ic_unsupported_reg_pre_write, + },{ .name =3D "DW_IC_SDA_SETUP", .addr =3D A_DW_IC_SDA_SETUP, + .reset =3D 0x64, + .unimp =3D 0xffffff00, + },{ .name =3D "DW_IC_ACK_GENERAL_CALL", .addr =3D A_DW_IC_ACK_GENERAL= _CALL, + .post_read =3D dw_ic_unsupported_reg_post_read, + .pre_write =3D dw_ic_unsupported_reg_pre_write, + },{ .name =3D "DW_IC_ENABLE_STATUS", .addr =3D A_DW_IC_ENABLE_STATUS, + .ro =3D 0xffffffff, + },{ .name =3D "DW_IC_FS_SPKLEN", .addr =3D A_DW_IC_FS_SPKLEN, + .reset =3D 0x2, + .ro =3D 0xffffff00, + },{ .name =3D "DW_IC_CLR_RESTART_DET", .addr =3D A_DW_IC_CLR_RESTART_= DET, + .ro =3D 0xffffffff, + .post_read =3D dw_ic_clr_intr_reg_post_read, + },{ .name =3D "DW_IC_SMBUS_INTR_MASK", .addr =3D A_DW_IC_SMBUS_INTR_M= ASK, + /* No SMBus interrupts are implemented, Linux updates the mask */ + .reset =3D 0x7ff, + .unimp =3D 0xfffff800, + },{ .name =3D "DW_IC_COMP_PARAM_1", .addr =3D A_DW_IC_COMP_PARAM_1, + .reset =3D /* HAS_DMA and HC_COUNT_VAL are disabled */ + ((2 << R_DW_IC_COMP_PARAM_1_APB_DATA_WIDTH_32_SHIFT) | + R_DW_IC_COMP_PARAM_1_HIGH_SPEED_MODE_MASK | + R_DW_IC_COMP_PARAM_1_INTR_IO_MASK | + R_DW_IC_COMP_PARAM_1_HAS_ENCODED_PARAMS_MASK | + ((DESIGNWARE_I2C_RX_FIFO_SIZE - 1) + << R_DW_IC_COMP_PARAM_1_RX_FIFO_SIZE_SHIFT) | + ((DESIGNWARE_I2C_TX_FIFO_SIZE - 1) + << R_DW_IC_COMP_PARAM_1_TX_FIFO_SIZE_SHIFT)), + .ro =3D 0xffffffff, + },{ .name =3D "DW_IC_COMP_VERSION", .addr =3D A_DW_IC_COMP_VERSION, + .reset =3D 0x3132302a, + .ro =3D 0xffffffff, + },{ .name =3D "DW_IC_COMP_TYPE", .addr =3D A_DW_IC_COMP_TYPE, + .reset =3D 0x44570140, + .ro =3D 0xffffffff, + } +}; + +static const MemoryRegionOps designware_i2c_ops =3D { + .read =3D register_read_memory, + .write =3D register_write_memory, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .impl =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, + .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); + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(s->regs); ++i) { + register_reset(&s->regs_info[i]); + } + + fifo8_reset(&s->rx_fifo); + + 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 (const VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, DesignWareI2CState, DESIGNWARE_I2C_R_MA= X), + VMSTATE_FIFO8(rx_fifo, DesignWareI2CState), + VMSTATE_UINT32(status, DesignWareI2CState), + VMSTATE_END_OF_LIST(), + }, +}; + +static void designware_i2c_instance_init(Object *obj) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(obj); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + RegisterInfoArray *reg_array; + + fifo8_create(&s->rx_fifo, DESIGNWARE_I2C_RX_FIFO_SIZE); + + s->bus =3D i2c_init_bus(DEVICE(s), "i2c-bus"); + + memory_region_init(&s->iomem, obj, TYPE_DESIGNWARE_I2C, 4 * KiB); + reg_array =3D register_init_block32(DEVICE(obj), designware_i2c_regs_i= nfo, + ARRAY_SIZE(designware_i2c_regs_info), + s->regs_info, s->regs, + &designware_i2c_ops, + DESIGNWARE_I2C_ERR_DEBUG, + DESIGNWARE_I2C_R_MAX * 4); + memory_region_add_subregion(&s->iomem, 0, ®_array->mem); + + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->irq); +} + +static void designware_i2c_finalize(Object *obj) +{ + DesignWareI2CState *s =3D DESIGNWARE_I2C(obj); + + fifo8_destroy(&s->rx_fifo); +} + +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; + + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); +} + +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_instance_init, + .instance_finalize =3D designware_i2c_finalize, + }, +}; +DEFINE_TYPES(designware_i2c_types); diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig index 596a7a3165ad..0766130b5963 100644 --- a/hw/i2c/Kconfig +++ b/hw/i2c/Kconfig @@ -18,6 +18,11 @@ config ARM_SBCON_I2C bool select BITBANG_I2C =20 +config DESIGNWARE_I2C + bool + select REGISTER + 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')) --=20 2.47.3 From nobody Sat Jun 20 00:37:12 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 1781844723863489.7703535822544; Thu, 18 Jun 2026 21:52:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRBY-0000dN-4A; Fri, 19 Jun 2026 00:50: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 1waRBI-0000Mo-LM for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:50:23 -0400 Received: from mail-pf1-x430.google.com ([2607:f8b0:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRBE-0005bS-QQ for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:50:15 -0400 Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-8453b56ab74so911844b3a.3 for ; Thu, 18 Jun 2026 21:50:00 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.49.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:49:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844600; x=1782449400; 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=zw4yGax63bC0ox/jGkXgO4IBMTah0WlBIPfyiNjDhBE=; b=iZ0RKETny4jHJSugx7d9HHJvTBJuToZpt+Sgtmti0ahpu7mBK9cvfxP3xygWhWd3KY UQXywVO9jh1z03jDava0vd7H5DMcrGYaTdvBa2wBtFstunD6kxwUDdHkj3plJ98gakH0 9cO35X9j5x9gpnKXIlOjFYdnn/9EeVcXL3xUhh8arZXH1QZevJFhRUfBpjxzbXSKl8h+ b+pqLLnDYBHV3knYSWoKQX4Ir/VQFnOWpNPBM+dVnDgjB0DXVbDTooLENgrH3ivyjpji 8zlaGXkF/eS8YsiTIp6wasoZcEF4rX7g3YNlA4LWtlF+5uejv/BZlSaRV1i8B4D3PrTh +Rpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844600; x=1782449400; 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=zw4yGax63bC0ox/jGkXgO4IBMTah0WlBIPfyiNjDhBE=; b=JqMUKGdQLuCel/588Rs0GF8/ZglMazn2koRU9DzQwFI9AfvBICGI2dz+r/1SO2pSys Btbafo4z4KBrldLAP+/kwDJpLlvoPqA40E1AgxVKH3b+C5HfSwmLow5JOy9HtB2XL4cB MO22NL11n+GBFlFYTTChEYeskT4Kpv2Y8JJ9D800wsBaKuD2ahHiMSaE2SrggEwaop9D AmJ3tr7suIsGC87q2+iPMlQhB0DhEq3tfjx2TJritQAEUpZcabFNNW5inTLHSE3+G1Io fI7z213bwenLEc/EyXdZNWFXzYMrN7r/zv+jN63u6XWoBB9G2znOfsQhEua8zRgQq7uB BkPA== X-Forwarded-Encrypted: i=1; AFNElJ+c7W3Hexca4HVLN9GZCk9X9gtPnx4tOgEQclWIYpbSZsOIX9eiQ9PJeM72d5Zp6NbjhpkCQRyXz/Wt@nongnu.org X-Gm-Message-State: AOJu0Yx3DH4dGBLh+LSC64oaQu52UN05QbxuO0DrgUylKmN9uzJszXc9 U6Rjlt2HoiYkUQT0ZpAGBvOn1IAb94UZO3C+d11f9alB0X1gTVCfW7sb X-Gm-Gg: AfdE7clZ1sF98jldQU8CH3+UllsZEvGumW3HKb47rSHiuXizhLS8zegrh3dvuwJrc1N em+W4CwB2Aarhs0jc6WUZf3T/7AaNXm6XsxSWKwW0iv/ZH4iHY8ngqr+cG8OXRcbrDmzaJ/nW/t kAnscuS2h9dq8gzocO7RmHtgX5rivGIVbU3hwUm6h+FzXUeYxUaFCEJi/84X8MNf569S8DGBAYx NF61iz1opyey8eJpDO1WKPg4eFqhzgO38Jb5Pp11wtC2wn+fNejhk1evg4+NeSOEq+yW+9QJ/np lYXp2YG8Z/Cv6161LP+voPdbNlE5+8Ch2rYNWF2+i5DgTJtGzbij279PmzGSMMsUXq6GXqwJRjq doMQ6JQs2jsH9iSSQ6v9iZ5U9JkVYoxCSvl2SEBG8wB+VUrbMF2pjKtbb3RCR08SF7kqcDRE16B cu3r9fQsza42alL83LacJB8bAFVJyDyQPmKZ6aEmz7dT1e9c/mmk7cSO8F6CVbM3vDReolErII7 AlKEfNHpk0HH9XdGNIWTIh7Ve/Xo8tuldPwbUrVfg== X-Received: by 2002:a05:6a00:1401:b0:842:5b63:610f with SMTP id d2e1a72fcca58-8455603d0e5mr1101311b3a.4.1781844599880; Thu, 18 Jun 2026 21:49:59 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Nick Piggin , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v9 11/12] hw/riscv/atlantis: Integrate i2c controllers Date: Fri, 19 Jun 2026 14:18:35 +0930 Message-ID: <20260619044838.1054677-12-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-1-joel@jms.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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::430; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x430.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.249, 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: 1781844725286158500 Add DesignWare I2C controllers to the tt-atlantis machine. Provide a fixed clock in the device tree so that the Linux driver probes without WARNing. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Acked-by: Alistair Francis Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- include/hw/riscv/tt_atlantis.h | 14 ++++++++ hw/riscv/tt_atlantis.c | 59 ++++++++++++++++++++++++++++++++++ hw/riscv/Kconfig | 1 + 3 files changed, 74 insertions(+) diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h index a17732ce8114..7f7d4a5a5905 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; @@ -27,11 +30,17 @@ struct TTAtlantisState { =20 RISCVHartArrayState soc; DeviceState *irqchip; + DesignWareI2CState i2c[TT_ATL_NUM_I2C]; =20 int fdt_size; }; =20 enum { + 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_UART1_IRQ =3D 39, }; =20 @@ -40,6 +49,11 @@ enum { TT_ATL_BOOTROM, TT_ATL_DDR_LO, TT_ATL_DDR_HI, + TT_ATL_I2C0, + TT_ATL_I2C1, + TT_ATL_I2C2, + TT_ATL_I2C3, + TT_ATL_I2C4, TT_ATL_MAPLIC, TT_ATL_MIMSIC, TT_ATL_SAPLIC, diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index c3016d6d4c9e..e6afd7627da8 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -54,6 +54,11 @@ static const MemMapEntry tt_atlantis_memmap[] =3D { [TT_ATL_ACLINT] =3D { 0xa2180000, 0x10000 }, [TT_ATL_SIMSIC] =3D { 0xa4000000, 0x200000 }, [TT_ATL_MAPLIC] =3D { 0xcc000000, 0x4000000 }, + [TT_ATL_I2C0] =3D { 0xd4040000, 0x10000 }, + [TT_ATL_I2C1] =3D { 0xd4050000, 0x10000 }, + [TT_ATL_I2C2] =3D { 0xd4060000, 0x10000 }, + [TT_ATL_I2C3] =3D { 0xd4070000, 0x10000 }, + [TT_ATL_I2C4] =3D { 0xd4080000, 0x10000 }, [TT_ATL_UART1] =3D { 0xd4110000, 0x10000 }, [TT_ATL_SAPLIC] =3D { 0xe8000000, 0x4000000 }, [TT_ATL_DDR_HI] =3D { 0x100000000, 0x1000000000 }, @@ -275,10 +280,40 @@ static void create_fdt_rng(void *fdt) qemu_fdt_setprop(fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed= )); } =20 +static void create_fdt_clk(void *fdt, const char *clock_name, + uint32_t freq, uint32_t phandle) +{ + g_autofree char *name =3D g_strdup_printf("/clocks/%s", clock_name); + + qemu_fdt_add_path(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "fixed-clock"); + qemu_fdt_setprop_string(fdt, name, "clock-output-names", clock_name); + qemu_fdt_setprop_cell(fdt, name, "#clock-cells", 0); + qemu_fdt_setprop_cell(fdt, name, "clock-frequency", freq); + qemu_fdt_setprop_cell(fdt, name, "phandle", 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); @@ -292,6 +327,15 @@ static void finalize_fdt(TTAtlantisState *s) =20 create_fdt_uart(fdt, &s->memmap[TT_ATL_UART1], TT_ATL_UART1_IRQ, aplic_s_phandle); + + create_fdt_clk(fdt, "periph-clk", 100000000, 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) @@ -511,6 +555,21 @@ static void tt_atlantis_machine_init(MachineState *mac= hine) s->memmap[TT_ATL_UART1].base, s->memmap[TT_ATL_UART1].size); =20 + /* I2C */ + for (int i =3D 0; i < TT_ATL_NUM_I2C; i++) { + SysBusDevice *sbd; + + object_initialize_child(OBJECT(s), "i2c[*]", &s->i2c[i], + TYPE_DESIGNWARE_I2C); + sbd =3D SYS_BUS_DEVICE(&s->i2c[i]); + sysbus_realize(sbd, &error_fatal); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_I2C0 + i].base, + sysbus_mmio_get_region(sbd, 0)); + sysbus_connect_irq(sbd, 0, + qdev_get_gpio_in(s->irqchip, TT_ATL_I2C0_IRQ + = i)); + } + /* Load or create device tree */ if (machine->dtb) { load_fdt(s); diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 5033415440d4..dcce819bf6e9 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -129,6 +129,7 @@ config TENSTORRENT select RISCV_IMSIC select SERIAL_MM select DEVICE_TREE + select DESIGNWARE_I2C =20 config XIANGSHAN_KUNMINGHU bool --=20 2.47.3 From nobody Sat Jun 20 00:37:12 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 1781844721905593.6873345718183; Thu, 18 Jun 2026 21:52:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waRBc-0000kg-Lo; Fri, 19 Jun 2026 00:50:36 -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 1waRBJ-0000N1-J2 for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:50:23 -0400 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1waRBF-0005oM-FR for qemu-devel@nongnu.org; Fri, 19 Jun 2026 00:50:17 -0400 Received: by mail-pf1-x42c.google.com with SMTP id d2e1a72fcca58-8422f395a4aso1147259b3a.0 for ; Thu, 18 Jun 2026 21:50:06 -0700 (PDT) Received: from donnager-debian.. ([144.6.172.18]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8455363da44sm870141b3a.8.2026.06.18.21.50.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 21:50:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781844605; x=1782449405; 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=HO68ROaXgpgmoPhUOGfAjCfRCsOUvV6mmReMnRWPMyg=; b=bEUKqMsioN5HwssxklpxGfJdzCZFjI7l5Gi8burtk2xN4DhgXMVF1xGiFqj3BnAdLf Mlo0mkO5voZRRbkNZ6UHOOs9PKoc/rIdVXtiwhfY+DyHcJnreG9gJEtS03V6lpLncgkZ 3Een9A0TyxGaLPe5Is8jPJPj9FXIyDeFyCx0qe8JO1yUUvCcwp14NojMIKIZCDbKEVrt n0jfZxH9W7P++mU5nMYHHoRf4/KWMxNCtxJf6Z6Tnm8z4ZchQiUv0ECHmq9VOhtBiIQz vrX0lCpR3K+dswQAw3iK7aoM1UEg729nVS1ZaIQ+OnULxWE1Hbsij9lEEP10MiJHBFQH FYgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781844605; x=1782449405; 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=HO68ROaXgpgmoPhUOGfAjCfRCsOUvV6mmReMnRWPMyg=; b=GIm6FSFIwx5Djt1NIoz+n9M/QwJcRZR6BebcAUBLEvD9MJEkbUPXjG/mRQSV9eJx0I T8+r74E99sIlffr6vibfoaCy0sHujuZn6WMujKV3Dn9MHWIVHCZ7pdeHCX50qyP3V2BD D0sn2/fZViCTn0heJ/OtInYrnKRREZWI52KFqZrdK6XEz5uW1BPonyQGsDLEfKKT08yk J+nAzrh5RAbvCRpjlcU2aDtNYlamzAXeqLaC1hrEw6Gw1IW1VL6C+znsJiODW0SM2B9h pUdFIe4qrUH2/MjMx6tc26btw8xbB6iCGrYghcGDIFbdtfHPDs5Auq7ofApeJrWZPOsY rDFw== X-Forwarded-Encrypted: i=1; AFNElJ/CXp3ZrFrNEMSNzfGO6UXNybYCiSBGLvLoBz22Ngny0MmtmiEYyArdce+NgYjHrtIuFW3IoO2pFnqr@nongnu.org X-Gm-Message-State: AOJu0Ywbpr9U1SMIjjXCIeb/fCzsZL/60d5QnXQWHvyc4s3G9ab73qme aREhL1kccuO2aHO0v2srz1Wk9Fn09Y1xwtp3A7CbKZTaKnMOeOv7Ichq X-Gm-Gg: AfdE7cl0zU2oYtAUVg/7qZY9mf+LcX0l1uurWgFdFIe+fiB/6FWoPbVcoirMB/H8+lR DyABECRTRM52rTwD1IcBNO5SZaaNoptohoXMCCkkID/iV16FTIb8KV66osInoKJGlBub+l54Cdw J+ISE9oC6si7paKzQHnvmIA2LJcbWer+1RPRW6O7GE2gjns+bDTUr9C8BLs6RFiMmW3/GDXGfEx 59x5uy7TFfDLm+8R1TPj+rqI77twf+DfMKnfTgUjQD54bLKkzMA5UNiZQOMlvONQh78FwmpUcUU z2k9tdMZQT+gX+nA3aWVMpSWQ3zeSVIzTq8ud+YU51bs4tylkOdKohQa6JVJs+e7/K6GsUUQhha Ocfh0dcwNPQ6rXsGXi/i9mgdGXnKTTIZpqM7WgQ87aPvpRJfFgwUAZS8L341KsdzUF/Lcny6/e2 vd+LlDH09a9qirfG4DpP83RdvOWMFyeb00OS1Wpm7K5DfrCaE1HU0VmVgZ21zCXHbVlXQhj0aoj 7pDxOpR6Jup01MiupMF8NhYaZSkWT2HxH/okML8FQ== X-Received: by 2002:a05:6a00:4fc7:b0:845:3033:6cbb with SMTP id d2e1a72fcca58-8455015fc65mr1591578b3a.11.1781844605133; Thu, 18 Jun 2026 21:50:05 -0700 (PDT) From: Joel Stanley To: Alistair Francis , qemu-devel@nongnu.org Cc: Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Chris Rauer , Alano Song , Michael Ellerman , Joel Stanley , Nick Piggin , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v9 12/12] hw/riscv/atlantis: Add some i2c peripherals Date: Fri, 19 Jun 2026 14:18:36 +0930 Message-ID: <20260619044838.1054677-13-joel@jms.id.au> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260619044838.1054677-1-joel@jms.id.au> References: <20260619044838.1054677-1-joel@jms.id.au> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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::42c; envelope-from=joel.stan@gmail.com; helo=mail-pf1-x42c.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.249, 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: 1781844723565158500 Add an I2C RTC device and a temperature sensor. These are not present on the board but help for testing. The tmp105 is a lm75 compatible temperature sensor used by the SENSORS_LM75 Linux kernel driver. The ds1338 is a RTC device that is used by the RTC_DRV_DS1307 Linux kernel driver. Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Nicholas Piggin Signed-off-by: Joel Stanley --- hw/riscv/tt_atlantis.c | 27 +++++++++++++++++++++++++++ hw/riscv/Kconfig | 2 ++ 2 files changed, 29 insertions(+) diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index e6afd7627da8..9b64f26d2f76 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -64,6 +64,13 @@ static const MemMapEntry tt_atlantis_memmap[] =3D { [TT_ATL_DDR_HI] =3D { 0x100000000, 0x1000000000 }, }; =20 +static I2CBus *i2c_get_bus(TTAtlantisState *s, unsigned busnr) +{ + assert(busnr < TT_ATL_NUM_I2C); + + return s->i2c[busnr].bus; +} + static uint32_t fdt_phandle =3D 1; static uint32_t next_phandle(void) { @@ -309,6 +316,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(); @@ -336,6 +356,9 @@ static void finalize_fdt(TTAtlantisState *s) TT_ATL_I2C0_IRQ + i, aplic_s_phandle, periph_clk_phandle); } + + create_fdt_i2c_device(s, 0, "dallas,ds1338", 0x6f); + create_fdt_i2c_device(s, 4, "ti,tmp105", 0x48); } =20 static void create_fdt(TTAtlantisState *s) @@ -570,6 +593,10 @@ static void tt_atlantis_machine_init(MachineState *mac= hine) qdev_get_gpio_in(s->irqchip, TT_ATL_I2C0_IRQ + = i)); } =20 + /* I2C peripherals: qemu specific */ + i2c_slave_create_simple(i2c_get_bus(s, 0), "ds1338", 0x6f); + i2c_slave_create_simple(i2c_get_bus(s, 4), "tmp105", 0x48); + /* Load or create device tree */ if (machine->dtb) { load_fdt(s); diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index dcce819bf6e9..de37c08caece 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -130,6 +130,8 @@ config TENSTORRENT select SERIAL_MM select DEVICE_TREE select DESIGNWARE_I2C + select DS1338 + select TMP105 =20 config XIANGSHAN_KUNMINGHU bool --=20 2.47.3