From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059185; cv=none; d=zohomail.com; s=zohoarc; b=m1vtBj7F89c9ELMjUoxNWCGBtA7yh2uHT+FPJCprAto/CR8xK0YDmpGCl+WuFAGj3FZdzulHCxZOjiDhqStNDeZk3qB5Q0U8JLTF009aBj93HgYF5CFbckMeU5RgCYqD2YweAkIMZ5qClCCKhZUGK5o8l2yf3Ijjo+REvr2BQ0M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059185; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=oBtA1oFudyVY7Vw5dgqM/2NWOChlQXrgG47s0EI8hXU=; b=aLR/Q5Aj/sFcSSvtN+X8xBRxZR/7ahdw6/Tl6xtdbSgHQyvbO/fhLlBWuf1YnelAzFn0NcgWEEdlKtqopE8MMTSWmVyuQ3vTzlob/pjn/W8qch8wWCXcQac8jtvri0XmwxSEZ7+ToJh11eLjhUyotTsJMKuIAtjsENzRvPUTm7I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059185566399.79663408311364; Fri, 29 May 2026 05:53:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwfv-0004lv-4S; Fri, 29 May 2026 08:50:55 -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 1wSwft-0004lX-OM for qemu-devel@nongnu.org; Fri, 29 May 2026 08:50:53 -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 1wSwfq-0006E8-Ug for qemu-devel@nongnu.org; Fri, 29 May 2026 08:50:53 -0400 Received: by mail-pf1-x42c.google.com with SMTP id d2e1a72fcca58-83945063f70so6695108b3a.0 for ; Fri, 29 May 2026 05:50:50 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84214c92fc6sm1791888b3a.36.2026.05.29.05.50.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:50:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059049; x=1780663849; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oBtA1oFudyVY7Vw5dgqM/2NWOChlQXrgG47s0EI8hXU=; b=nNrne3pOxDEnu+yfWVIJN/fxt0G79YgYAZ5D8HkjcWrQDUN+bAy41LUSF7VsEW1yWh nlilq1SPgo9V1HAm+kzoNkhsrL1XknhMv7Zdw+S6MisX7o/c9OTj6S7SxPBZ1J2qin5I lRo7deUxQbJoaO7zE54dJQRK9VWU96+yUNHS2RhDxbZsLUkZzggnYLM7BYDKZgy+w+t2 MriwGxL3aRFaC0PT7J9A7xQokkSNLTNGV+oP6cTFsLXvXzqy3BQf7GFTJw6CKo/7vEEH bELysypz7zzHtKDTOi6DQnuhcTsRuHQolSSYmaQCf8RzjEi0hgeZ8kWDyo5Gj3xdgGXJ pmMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059049; x=1780663849; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=oBtA1oFudyVY7Vw5dgqM/2NWOChlQXrgG47s0EI8hXU=; b=WUOQluqcAjFmK6wfgWLcYd8GeQSqP8bfjPz509kEGvEFiw1uhGurh4WldbN298XIHi 8B2xny+fzLbAarVh3DDL+GEVuUDD9t41n9DSpWZ7TdFwEFEXuppoCYbYNiZa+ZXsLm4P TIOSsPAORI56TP2SUimnYfFzJYFcaniGZlXrUVDK0t2WTXK0l6Lej7kZbhBuw4y4KU06 fyyipfToYCbgI0DUditpuRf9N7suS5uhhYm73lhGlPNqdCf2S+SFlU+y7V/t5q6Dqiyi ba/QTkuE3x2QPX9JNNhMqj1kGPbctuPCeiXA0ZVYfj2iR5yz6HlroFaOWA/D5QHkfwJd 8WMQ== X-Forwarded-Encrypted: i=1; AFNElJ+w/XTgF//F5W0ZYzxa4oz4rvow6fo9JI6ZJDV9XErCY1QPx/qdXEBMh0sVPFzJWyn/go+gzYG4LSUX@nongnu.org X-Gm-Message-State: AOJu0YwKTOJqzNVatDNJmayK+Qq+2g+MAgqnY+EvjqaTi3UfHrk3ugkB /2vPH2jIlO/CrcWgjWIq3l075J+qj+JIuYqJDZk+cjIMUB8m96iSWaZQPG3QHg== X-Gm-Gg: Acq92OEmEE6dIMuk4NiOEnKMxwOsMyH4tXW2Mx70Vjm7WLemEUeeRaJJrIvhKwBqqYQ F2bG7z6LPmzHJlwMQo2GhD6o2H0KDAdD133e9YMjyAKKpBEitk3xB/u79Q59onwW2tfJeF5ge94 GGEod5dT7XY50+N+rg0S1W3tHu/3gZJLRnqdsB/dt7uEb3blaxStAS5TYnhonAXg/l+PLyhEnSs Z/THAfzgvoocObobBO+uRAfN4PRWk5u/pwvDNpwiHNPPEwt07r47U5V/qGyFnZeqhFv9C33n9e9 7UiviNQkERk5GDbpZa7/Syg2Da03ii7/imOZCBDT/kPae1qH6fHWVLf7pvC9Y47HpJwilDugjSA 48ZuO2YL4l6/Ax25AT9AgSK69RdtxoeG27xtK2GYIgeVLDbK5SY0iS11tUW2xmkKxJLJ6O0JSX5 KDzqb/MjYFFRkFCP6o5iBoefXl3oXSP6Smf/ju0HsJhGBsJ7adMIBrwtKpRAdh96C0E2c7fT8lE 3rc/Ep1 X-Received: by 2002:a05:6a00:12c6:b0:7e8:3fcb:9b03 with SMTP id d2e1a72fcca58-84210c9e6d8mr2463722b3a.25.1780059049246; Fri, 29 May 2026 05:50:49 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley Subject: [PATCH v7 01/10] hw/riscv/boot: Describe discontiguous memory in boot_info Date: Fri, 29 May 2026 05:50:26 -0700 Message-ID: <20260529125036.728206-2-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::42c; envelope-from=npiggin@gmail.com; helo=mail-pf1-x42c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059185964158500 Content-Type: text/plain; charset="utf-8" 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: Joel Stanley Signed-off-by: Nicholas Piggin --- hw/riscv/boot.c | 16 ++++++++++++++++ include/hw/riscv/boot.h | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index ae2f86c7ce..b1a020b58a 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -69,11 +69,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) { diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index f00b3ca122..69c99a1496 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, --=20 2.53.0 From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059107; cv=none; d=zohomail.com; s=zohoarc; b=dzG23eg+Ark28QvnR7MH1YbK4zD+I+QoArZf5aD222w7OMVXHA0KemYsGksijOzI6wEwr7B2sceB6Hs+Gv88TbhzzNKP4tOhDYQr7/79c/Su0FmOgo5OQ0rZlx8uScvyKT4CSJx6fJmLgXVBH6++qefVqVu72qLqbtfo91AoLVg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059107; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=SAH7CXKhbJbOYy+X+/fCpfZwl+4JE5GflKjjttJSK4A=; b=K5Q7we67VahIl/NmCqW4O5Tho0TnxdNQgkuZQao+tN1ftT5rJM9xJxMsNPqWQZnJHOhxuheKLKZ/uj6bgRJk8O3hoAaFFJjN2Aj+3aG+AFWG1sj1BOx0LD7SSW7UOGnugoE9Fr/TWQknzhP+lPUQJpn3F2bwHf8zfcyFD8lIjK4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059107206549.8672278381508; Fri, 29 May 2026 05:51:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwfz-0004mw-G0; Fri, 29 May 2026 08:50:59 -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 1wSwfx-0004m3-B3 for qemu-devel@nongnu.org; Fri, 29 May 2026 08:50:57 -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 1wSwfv-0006F3-6g for qemu-devel@nongnu.org; Fri, 29 May 2026 08:50:57 -0400 Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-837dfccd950so6503489b3a.0 for ; Fri, 29 May 2026 05:50:54 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84214b67b8asm1820671b3a.25.2026.05.29.05.50.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:50:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059054; x=1780663854; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SAH7CXKhbJbOYy+X+/fCpfZwl+4JE5GflKjjttJSK4A=; b=hmX3Myx4X251JGxLJR3PdF0y6fGgY/tdtGUhvxMKv4q3Z+/Wkvgalo0ssc4vda4uER pdRUQt4HzueT7RBAr1QtmccoD9Nwwy+Am2I5DE8aJS15tfvgA0RxFuKvysjLt1JbJKMF S7uN83JI+boX4Q+9jVt02OiuRaeoupyRkLkJpZH3lV/KkrCLD9ZdZsNHCJAyRE94TTxk Asr0LoJ0+Y7LNprWw0QixEi/ozY3fTZpOaEUC12zdB0+PrNCMswK9C7QdabG//Ui4HDE gHVbXrVHntmZScGMV/kzOxcpS39JgfjW5VbCK/W/Kw9qqv7YXYFSlSQzALjZZ8PTJqUA wmQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059054; x=1780663854; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=SAH7CXKhbJbOYy+X+/fCpfZwl+4JE5GflKjjttJSK4A=; b=KBIGW+qYBbUSGJ4ixGlUIUDu+SWL9h2+1PMO05FLrNfDRTuA1ckRrWNTO/JNaOWjJY eyd1RtqJYwZ+oARsmaUnzUoZS/92ETnXup8uJysT7RvhZJl2dmj57ZLMz32Q7Y8jjOLu 9S8CySI/bNFcc7qg1yfugqfP5ZyS4ekeDuinzmrkn2OdJZcrw53KYKLiP91mUhvzi5yj +v1froo5vDVXUarIFIuW+2ZMKQfPyh+2NK5pnxFNEOTSNo3azzXIak8YjJKfYjY2TI7N cEvNNcBODKOZ95jcyG2lBDg1N91wIPV6M7PH23ydM7Mx5SRn9kdmwySzA9Tztc6tQMwt 94kA== X-Forwarded-Encrypted: i=1; AFNElJ9yHZtxFICecFJ8OY/x1IaEglEKehJvJCTwiPRpFttPt2gBqOsx4TVU1yAl7XvvOZvRJ1Yz+QgQO5f4@nongnu.org X-Gm-Message-State: AOJu0YyP5MyCY6Zz3lhG5OMM9nwW0FxFF5y+u/IZLj/KNxHXO7Q4Blbm Fj4vUJWWb/A4XREmbJWSrqjYGNnYYX8XB3tYvvN9+O6QeJUpXHazxx5Z X-Gm-Gg: Acq92OFqPTxFYamtJmha7sUGnx+G7OvF9XW3nF205ogpEAsB4Fs0XaQWV5peGZGDwfb evqkr0hHWkhnUq1IDawpxVi87uXbEAfYgQ2LhKlT2KCtEhsJ8L8qAMDx47KldwyDBMUXRkGASWS fuHDT1xLGAjglxv59x4u8s73oH7fJbO/P2cjSIEeYoMeGxaiFjJvMakt5RbCEuDGk7sXITZESZA +IKFbyQYV0hTIv1pECOWoU4dDg9s8+AFJ3OQRbDUFXPkHsKgmt0+c/+6AzrYRm0obt0ORhiYqJ2 8UY8JhkvgWOMCfc04bS9s3mqeJcT2NfWeW34Szo/KcO7mvprx7sIvUIg4Py9T1zsMpV2CnIf97e WBRnhAd+BKCO38AQQo56csEG+UApYd35DGU0clxHxMDS0Syj0n893T3BPIfkHFiELjH2FY3gz97 6EsYK4dcQSDMX0CbLiyoPBFjgNS+MAPFX3sGj4k3UKgl/zhp1sEjxFHtrunzTazHm6Avq3BHQ4/ UeRq/Xq X-Received: by 2002:a05:6a00:130c:b0:839:dd77:3505 with SMTP id d2e1a72fcca58-84212ca221emr3003287b3a.22.1780059053467; Fri, 29 May 2026 05:50:53 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley Subject: [PATCH v7 02/10] hw/riscv/boot: Account for discontiguous memory when loading firmware Date: Fri, 29 May 2026 05:50:27 -0700 Message-ID: <20260529125036.728206-3-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::429; envelope-from=npiggin@gmail.com; helo=mail-pf1-x429.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059108463154100 Content-Type: text/plain; charset="utf-8" This loads firmware into the first (low) memory range, accounting for machines having discontiguous memory regions. Reviewed-by: Daniel Henrique Barboza Signed-off-by: Joel Stanley Signed-off-by: Nicholas Piggin --- hw/riscv/boot.c | 18 ++++++++++++------ 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 +++++- include/hw/riscv/boot.h | 5 ++++- 9 files changed, 48 insertions(+), 20 deletions(-) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index b1a020b58a..b0a2e384b1 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -150,6 +150,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) @@ -162,7 +163,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); } @@ -170,10 +172,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 @@ -202,7 +207,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) { @@ -217,7 +222,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; @@ -263,6 +268,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; @@ -294,7 +300,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; @@ -390,7 +396,7 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwadd= r dram_size, dtb_start =3D QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); =20 if (dtb_start_limit && (dtb_start < dtb_start_limit)) { - error_report("No enough memory to place DTB after kernel/initrd"); + error_report("Not enough memory to place DTB after kernel/initrd"); exit(1); } =20 diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 5e48a29708..4017129c83 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 c8b2f028f2..5b2f33d5ac 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 b1823a3125..835b1f879b 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 6a637e3b86..3b2763de16 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -590,11 +590,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 f9d00e0d5c..8d68b4e235 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -282,9 +282,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); @@ -294,7 +297,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 ce64eaaef7..febf49d5f1 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1458,7 +1458,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]); @@ -1481,8 +1484,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 76417ba7ab..384624d69a 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= */ diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 69c99a1496..4e7bd9a225 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, --=20 2.53.0 From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059185; cv=none; d=zohomail.com; s=zohoarc; b=QYuJ9kP6G2YlQdxxJPeom44uiKg0cAhENH/cYRf0OLCaO6pWyvoJZ++jrN5B6v23QnDNsD3phtCqrXQhIYvhbchfZlFtJe/EF6ISe9Kf7noebyW+cyiQmeG269MQD+fpJ2YcAk5mI0UoriTqM7EeulODZzRT+Sf9vGjIkhSuXyc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059185; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/fV8NgA8t4dq91+ittezQA/lYPgyaIUPJgpS0lQ+V90=; b=DLya0bPwdtwQrLp76/sOCNOr91bLB7yvqOtfxw7ZdrhGjEqxw7J2v+hV+gkvlVvM8LIessNgz4ABFaDRiqn0wK0BKbf3mHn2pn4Q0sbvB/XPUWvgxD9ymg4mzM8w9kbiklwsSK8mUjHnRFAbnWzUKTkCRlKDQ/4mUruljhEGrpw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059185099228.0450600810218; Fri, 29 May 2026 05:53:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwg2-0004nP-O0; Fri, 29 May 2026 08:51:02 -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 1wSwg1-0004mz-FS for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:01 -0400 Received: from mail-pg1-x52c.google.com ([2607:f8b0:4864:20::52c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wSwfz-0006FY-8k for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:01 -0400 Received: by mail-pg1-x52c.google.com with SMTP id 41be03b00d2f7-c8173b2af32so10523790a12.0 for ; Fri, 29 May 2026 05:50:58 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c85771a7cfasm2229114a12.3.2026.05.29.05.50.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:50:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059058; x=1780663858; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/fV8NgA8t4dq91+ittezQA/lYPgyaIUPJgpS0lQ+V90=; b=NQUFr9RN+ZivXE4/I9On0xi9dzX5h4KQ+6hfuIfQAxea1lPhhd30gr8o7ltCsJQhQ8 eiaubdEg3Cmue72egSB+/1FHYds2CUOUHeV/R5hAGcuHZJqmEJSvN1PyvruKpNSg5Up8 llEqmHB5PYUkXrCJ/Vj47954aKQmvaYGQ+g531Sr8/QYrgKNKOd2RWfk7KGHkEaStOEI yD9rLTyFD5C5a0NjHrLzLth/wsJxpz55KTlb1e03SdOGiS0ZOt/qbWx1nVYxGyoKyX8A MfxvZOEPjCJFN33apHBdo1SO/iwmvEVYF25jfbJDGkzY8uwUUa8+jO7U3N2MU7qRkctA 3qlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059058; x=1780663858; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=/fV8NgA8t4dq91+ittezQA/lYPgyaIUPJgpS0lQ+V90=; b=BnU88lKKLG7ZA+NIyDaRXD1kqboD8fcjW2fIJmvHDi83MWbm+82tfsecn9/Xdbq2H5 pjEKh3dgoQDD+O70Cnf5xe7PSab8bZv5oLjauzPUL8rR/W1+WJN3mgnjc12ebOHlsKOV VfgYvxYvMnUtT57f/1NOIY9dPcIwetjvkQCCAL9CWir4OA20KHfA99iJvJ/N0msIHAN3 vL3FyjQisCzh9VCtQwan6pDYz2p04FNtutzr7KrUxKEna4+BpUCJT55VHvyoBmaGoMEI Yubb07uZpPHBGUa0ocb9mckX+kMi3drhz8m7FJJ2NZhALgaFg6in37WFevnkwozKkWwt 7tEQ== X-Forwarded-Encrypted: i=1; AFNElJ/6LFpN+JFCgPm5lpdpcB2QrkuiT5yHM0RHWgZ3lOlw1/GhBIzssfwxvvdhHBi5WS0reoe6eHoTPzIf@nongnu.org X-Gm-Message-State: AOJu0YyZESVJCH9U6a3KmlWRpHZEMy1Wpbckgqd085XEkUCp461iUxY1 944wEHCwlzhhvrC5YI4Qe/omH4LpqwrazZl1/WDLEe0Fee2pQrojMc5S X-Gm-Gg: Acq92OFlykRDDr1Y9LP+Yq2Bvh6kbGdx4QC3FD5xz4p3JlFqiH1v4/EnvOfJrEdYpXP P1RyEYvF2+Hkv+gw6Nmcdwyk4CozyUSmufe0SXVDjbvp1B1loFNxK7/RMW9oeTW1I2wtu3SdUEi 2uCmXWz/m8y4v+U/W2crxjiVDbl2ivZqbb+A048S+U8TFJRRK6YJbchF+vfDLQDsf1L0DljGtWj 8PYUO0JgcyuspRf7j4NlW1A5BE02wvk8lKWYOSBeqezuDfgp+O1Q6yPSgoKMkD+U9BAW/dVILse 84Ubc1LhOZUsaGT3WK7SMhLXBMyDFQGRN9q4xvl82YxjbYyyizGa+2gf/ROPAEVIzJrfiQLa3LI w5wGEU29vIuTwglUGucqHBXt2yY8a9iRixzPB4K8HMRMKA8GIop9q/6M6xuyzWOu3xQEfZLLLR6 GzbOOBauaT80AYqBms7ExC/wKCNkIE6M+x+H52J8MpC5dUkUyU6izy5ewhQ+VO1WNsvjbBcOqVj mAdUzSAV/65bsiiQVI= X-Received: by 2002:a05:6a21:b98:b0:39b:e6af:2d8 with SMTP id adf61e73a8af0-3b411ce21bdmr3628095637.4.1780059057800; Fri, 29 May 2026 05:50:57 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley , Nutty Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v7 03/10] hw/riscv/virt: Move AIA initialisation to helper file Date: Fri, 29 May 2026 05:50:28 -0700 Message-ID: <20260529125036.728206-4-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::52c; envelope-from=npiggin@gmail.com; helo=mail-pg1-x52c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059186074158500 From: Joel Stanley 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 Signed-off-by: Joel Stanley Signed-off-by: Nicholas Piggin --- hw/riscv/aia.c | 89 ++++++++++++++++++++++++++++++++++++++ hw/riscv/aia.h | 26 +++++++++++ hw/riscv/meson.build | 2 +- hw/riscv/virt-acpi-build.c | 2 + hw/riscv/virt.c | 87 +++++-------------------------------- include/hw/riscv/virt.h | 1 - 6 files changed, 129 insertions(+), 78 deletions(-) create mode 100644 hw/riscv/aia.c create mode 100644 hw/riscv/aia.h diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c new file mode 100644 index 0000000000..c724612a50 --- /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/aia.h b/hw/riscv/aia.h new file mode 100644 index 0000000000..dbb8333402 --- /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/hw/riscv/meson.build b/hw/riscv/meson.build index 533472e22a..e53c180d0d 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -1,5 +1,5 @@ riscv_ss =3D ss.source_set() -riscv_ss.add(files('boot.c')) +riscv_ss.add(files('boot.c', 'aia.c')) riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c')) riscv_ss.add(files('riscv_hart.c')) riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c')) diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c index 413d47d70e..e3da874924 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 febf49d5f1..614220a0ce 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -60,6 +60,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) { @@ -510,17 +512,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) @@ -1294,68 +1285,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; @@ -1618,9 +1547,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/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 18a2a323a3..ad858deb76 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 --=20 2.53.0 From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059184; cv=none; d=zohomail.com; s=zohoarc; b=m5rPcs2AECJOmEX510hxU+k0qyfWwFwgo/rjHAIQa7z/KXLc1z7REWeF1ee/mLaLzArwqegxjwOFDnvsvZYYxc5E14QpowqE0m8A3z//B9Q3ufKyzX0RiGbHrecGiHl331eNN+TI5jJRcMLF1uccRJexw7DPDvxD44390zKNIVE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059184; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=s0L4tLl7I6tkMcpsKUvTPNAYZl4B+x0G3/28gkcjtDM=; b=i0kYtbry7ZZrQ6Wc3ExORJQZCbYCPCNOf5qLnuoYn+Wp8iHDdiNt5AeSlhk5sX2oMJrhGWmN3cPayKOBZ1FSOrN3SFvkg9VdYNrXdGC54wyLXQCBTBQSix8s0QVGlsbTpcG5yNwmujryN5Ij5QXLrhaUAT34DchXDUatnEVGD90= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059184522584.8482270454155; Fri, 29 May 2026 05:53:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwg7-0004qT-CE; Fri, 29 May 2026 08:51:07 -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 1wSwg5-0004oL-H0 for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:05 -0400 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wSwg3-0006Ht-H1 for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:05 -0400 Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-36b9ec98144so918645a91.1 for ; Fri, 29 May 2026 05:51:03 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36bc6a34ca9sm1823751a91.9.2026.05.29.05.51.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:51:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059062; x=1780663862; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=s0L4tLl7I6tkMcpsKUvTPNAYZl4B+x0G3/28gkcjtDM=; b=kFc/YFMq6bZ7Gaw6JGpdxJGMk+Od+6lT06RyzU5rgbxm4MIgNoDlPmOPvc5/DoPKFz 2jCQyowbDgH9EVaovjRHhy2Q6EdvgwkBNpheXhYhou97zhylG+idhPLh9MpaEyxgEGf2 73jd5YBYdQOxe8Ub9kkcvY5/jvp2R1371XmS/+7UjWCxuhA9XY9DmVp5dK71yJXsFRmD bkSaqqdm0vgEpvm/THiz4QqD7oZGMCs+Is4dLK6+NEhhvLoJXN0irE3YmsV3GkKwtD21 xE5Rxf6LXH98H+VRuUn5Qyi3jezEqqRqtlLxpSx8l1Rvi57Ti2iEsXTq30luryq8JPap AnIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059062; x=1780663862; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=s0L4tLl7I6tkMcpsKUvTPNAYZl4B+x0G3/28gkcjtDM=; b=gnA9XQTfHHGcQvAZAMxroG4ysWcdZ7G3x/3W8uvmohkLIaSqrrETt9/B2PtZP8RsrA KXtRJJIHsMTyn2iZdeurz2flD+1ixX6LlpG8yBZCr1hLowLgx9h4F60eNqChl4/DNW9Z PaI+V9mytfB+sHOk+3c4pA28Nrj227Q3d+8v/9QWCyCWJEn9YOaMIZz6oaBCOCXW3VCG 1kTCl2Gnv/HEssUtPIewFNBbpyMzgr+UxrEu/dYm6newEciyaJWGEM9ettQ5rFR/aeVw OCkdo3LQ2r7+J7zVTzRPb/YeYTwWurzQgesiW/7gJ0ZypXIfd0ElQo95uxL7TUM9VNae QaJQ== X-Forwarded-Encrypted: i=1; AFNElJ9bpDh6DuoVTRiQ7TCtLg2k99Yf9cn8diBfV1ExELKnC/lIOWAIc1SONSLS9qDFdd9iTywqhKmHl1db@nongnu.org X-Gm-Message-State: AOJu0YwINEkak2iUJtmTgSnaxrx8nYS867QG5ovZF5ukjZcr+DvdcS0T 5lRuI+2otV5jdYyIdqgi9pTtxIaw3mq8aIwWO3Goa3deRCNfDXVxgajh X-Gm-Gg: Acq92OHAH1NVO2zFe4b4hNKuvi2EyeEEyhHT3I6W1O85JRd0VTx70UZ6IpaRCD3ki1e qE7qg/4tQTuc2Fg55qa64Q3rNEXzWfHqr+EIQolcwAJm5DNVVwIDpE2fEeyMkazznPgOi8HqVBK +kNUHfEIr+JAQuQhI5ymX22JWZLOu5wJEn8bVNY6nHZxjFJnrZkn/ofeFRrMKB3vcBzywrwIzbV t0P1c2SN0dOavb3oLEsZqn/T4Z7NVPKMMnZ95Zu9F20ezwZUNf4I5RDQBZn96cmf1n3k5Q9kUKZ tuMHHtrARyn1lZitDfre+7TDb1YTscedp3IGBGSgh0NlA0/2CZ6Kj82Y/UQMTK+WMMfgzFDglmQ 36i0TMHr8uLf8OiaXlF2U49NfQfGBdMRG/tPoB6IdbPW6d2L4iSOr72UA/j3MEDaCcYGS6tyA5r +k6IisoAooprkviIdxVgYRDpYJ4B9DQ7Ja30ArtD5vuMspDXdVecFLl3j3Bt7exR1dJQkGDyzMY 5mZTp0qWOonfOfNjxk= X-Received: by 2002:a17:90b:184b:b0:366:479e:63a5 with SMTP id 98e67ed59e1d1-36bbcc160f0mr3504077a91.2.1780059062043; Fri, 29 May 2026 05:51:02 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley , Nutty Liu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v7 04/10] hw/riscv/aia: Provide number of irq sources Date: Fri, 29 May 2026 05:50:29 -0700 Message-ID: <20260529125036.728206-5-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::1032; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1032.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059187594154100 From: Joel Stanley 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 Signed-off-by: Joel Stanley Signed-off-by: Nicholas Piggin --- hw/riscv/aia.c | 8 ++++++-- hw/riscv/aia.h | 3 +-- hw/riscv/virt-acpi-build.c | 25 ++++++++++++++++--------- hw/riscv/virt.c | 2 ++ include/hw/riscv/virt.h | 1 + 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/hw/riscv/aia.c b/hw/riscv/aia.c index c724612a50..82ea9d48ea 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/aia.h b/hw/riscv/aia.h index dbb8333402..5ad0a902be 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/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c index e3da874924..db3ea4f03a 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 614220a0ce..4cd941a6aa 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1549,6 +1549,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], @@ -1705,6 +1706,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) diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index ad858deb76..36a2def410 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 { --=20 2.53.0 From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059183; cv=none; d=zohomail.com; s=zohoarc; b=UtTJsaTDgCxnAAO8YOyGbPTaxKCVz8KgI2V1i3VJzfD4huaGDdDHH3UEJsa2aIu32uOl2ebTvNxSfmyPIyyp0muBseBypSwkSgqX6gj32zrj0wVdFzNFsO1nyTehMqlUOpiWF3rQ0t1hJvTAAB/gAa5APKrEcAOrk8zZbQm+Cn0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059183; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=x92lbn+dfm1bMNXAWkcVvhDZDWVp9FGF9ZyQOtYbWgc=; b=h2sC6znihLeIXNHwLNlFuOmvKgzLu+sfI+tnJkrPLBPNGejTTt49Gl9sMXlAWkyRzTV8b96erBPaS5OpJ6KRsMXKclD7j+MvY8M8aVaxCM8BDLdw4el6NfA26iA/z9qNthqa6WsJGvVqESeuPNyEqivstHpiI1/E2CBavrO9obk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059183951381.9399887529687; Fri, 29 May 2026 05:53:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwgD-0004sy-0M; Fri, 29 May 2026 08:51: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 1wSwgB-0004sb-E8 for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:11 -0400 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wSwg8-0006Jx-6d for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:11 -0400 Received: by mail-pf1-x435.google.com with SMTP id d2e1a72fcca58-8421f91c07eso49039b3a.1 for ; Fri, 29 May 2026 05:51:07 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84214b31933sm1840875b3a.23.2026.05.29.05.51.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:51:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059067; x=1780663867; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=x92lbn+dfm1bMNXAWkcVvhDZDWVp9FGF9ZyQOtYbWgc=; b=iyllGam/PMM3tYDlYY2TUXrwU6i88rWfxO5GQ50lrXhkPDFzKXGm8zRRbb/2tj55zS 0mc7lg1FIfXlUQvWubIkJWnvmOFuguz4VVFEI30VBogdSN7bL+rQLVlcpfBA6XII7xMb Hzne3dgF0q3A5JjPsUG7J4spO+jmXvgbskIgZZdUtl/cNGAY2FAtUwuTw7s1XqkaLqXG 2sHlsEkptou63bJx0Y90aOFwIQDI3g1HydEqZLtqIXwfgzqCxR2LBKIoTcIfOHrl5owz EQ7CNe1Bs93KdLt/xeVrk0urC0DsL8A+fhdq0N7R1R9pDZC6LZ0fo3FnhisJW2b5e5Tm Wsbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059067; x=1780663867; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=x92lbn+dfm1bMNXAWkcVvhDZDWVp9FGF9ZyQOtYbWgc=; b=KuV7vKXn2SWcSTiTGqKlLUw3zB3YNhpYt03Oy2zdnOGT16egakmShryCqhKTDFZQlk WnniKA/IB9fyoAhWUGQ7/n0aH7DhzUWL1gkys7poxBX/hnNHeMZEFdLKwmx5BKWbQdlc NuFWj23yQep+ruSG07cbMI/MQCRT0D9umUK9k5vnuQL6GsqJ5BetasYTFTMI9kPzMcTP 6IwIZauyVNp3MeBjWIKHF4ATNePAMG6eUQG+y0mpdlHvIxfJu/OiKlQDQP1wO8Y624y5 bgOZg4DxO83buPggvejxg4QAc+Y0tggz4zYg8mNIaVwU/VR2nWn6enmGTLaJkDwJopSF ej8w== X-Forwarded-Encrypted: i=1; AFNElJ8Yds2YUB/6pBOrlpeL1QDldeAlX1QcsA8H+NDjayqVgtw3CYgtc2sIIj7yr6t+EzxhFBRrmBFRs/7O@nongnu.org X-Gm-Message-State: AOJu0YxuSL9tcxoaL7eSRB02ueGLtMmDRGX+5RCD4eorEDPTNecea8bI 93MWl945P8NISavMzIBGWVwp4iBhyLwFBuSgl7AD5HGNtKI24hfKZHvY X-Gm-Gg: Acq92OGP9s+uMvUWrN8B0SkXMTl9WNR6q2IoMRfQVsWuMzN+DvDqRLxn3BspwfMpjY3 LNDOHOZZBQc/xu/LewESJqe4NMSFTY3fAYyBZaljRWi/TYBjx5llFG5f/rhswZNq9vGzYhDWUl9 oHqMd6VGz/s3sDxP2Irtg1oj4lqkg12UR5xZCnEWHn3XjSH2+NwMVRhjU3HQo6jjeN2I6EMTQ3s mD2NOL2hVOLRzHWLhVzRpkDnpJCLwoBTH6MGuRpQg3PVcPahByi7AopvcajEAh8f6VqlJbRXzD0 IibeMRa0q27qs2x0CUXwTtyGylHu/xtP1GGASSD97wnIZETay1H7Pet7Wu9UsdhAlpwMdOC2kIv WtGc8mIMwKiUvhjPRQfN91Wf6dHguSc5aw20l36z/7tKzoJ9rqFInHofQlTIkjpPUFmY3Ea++uB I49BEH+9CUMv5SGy9ub55HWoHTWSVjN2sBqIAjNMOdR6Wrcs3WFTUlVB0EbH9wI/yW09OpA5ER8 0yyZbwAcwILh2mgCHE= X-Received: by 2002:a05:6a00:12cc:b0:837:e9cc:d465 with SMTP id d2e1a72fcca58-84212c8cd39mr2873145b3a.20.1780059066398; Fri, 29 May 2026 05:51:06 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v7 05/10] hw/riscv: Add Tenstorrent Atlantis machine Date: Fri, 29 May 2026 05:50:30 -0700 Message-ID: <20260529125036.728206-6-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::435; envelope-from=npiggin@gmail.com; helo=mail-pf1-x435.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059186138158500 From: Joel Stanley 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: Joel Stanley Signed-off-by: Nicholas Piggin Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Chao Liu --- MAINTAINERS | 10 + docs/system/riscv/tt_atlantis.rst | 32 ++ docs/system/target-riscv.rst | 1 + hw/riscv/Kconfig | 10 + hw/riscv/meson.build | 1 + hw/riscv/tt_atlantis.c | 558 ++++++++++++++++++++++++++++++ include/hw/riscv/tt_atlantis.h | 51 +++ 7 files changed, 663 insertions(+) create mode 100644 docs/system/riscv/tt_atlantis.rst create mode 100644 hw/riscv/tt_atlantis.c create mode 100644 include/hw/riscv/tt_atlantis.h diff --git a/MAINTAINERS b/MAINTAINERS index 7eb5823da6..c5f7a8a6e4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1779,6 +1779,16 @@ F: hw/*/*sifive*.c F: include/hw/*/*sifive*.h F: tests/functional/test_riscv64_sifive_u.py =20 +Tenstorrent Machines +M: Joel Stanley +R: Nicholas Piggin +R: Michael Ellerman +L: qemu-riscv@nongnu.org +S: Supported +F: docs/system/riscv/tt_*.rst +F: hw/riscv/tt_*.c +F: 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 0000000000..e8bc625677 --- /dev/null +++ b/docs/system/riscv/tt_atlantis.rst @@ -0,0 +1,32 @@ +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 + + +Note: the QEMU tt-atlantis machine does not model the platform +exactly or all devices, but it is undergoing improvement. + +Supported software +------------------ + +The Tenstorrent Ascalon CPUs avoid proprietary or non-standard +extensions, so compatibility with existing software is generally +good. The QEMU tt-atlantis machine works with upstream OpenSBI +and Linux with default configurations. + +The development board hardware will require some implementation +specific setup in firmware which is being developed and may +become a requirement or option for the tt-atlantis machine. diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst index 3ad5d1ddaf..a8e6b33421 100644 --- a/docs/system/target-riscv.rst +++ b/docs/system/target-riscv.rst @@ -71,6 +71,7 @@ undocumented; you can get a complete list by running riscv/mips riscv/shakti-c riscv/sifive_u + riscv/tt_atlantis riscv/virt riscv/xiangshan-kunminghu =20 diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 2518b04175..aaf029c9ed 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 e53c180d0d..026e79591f 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -9,6 +9,7 @@ riscv_ss.add(when: 'CONFIG_SIFIVE_E', if_true: files('sifiv= e_e.c')) riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: files('sifive_u.c')) riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c')) riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: files('microchip_pfs= oc.c')) +riscv_ss.add(when: 'CONFIG_TENSTORRENT', if_true: files('tt_atlantis.c')) riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c')) riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files( 'riscv-iommu.c', 'riscv-iommu-pci.c', 'riscv-iommu-sys.c', 'riscv-iommu-h= pm.c')) diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c new file mode 100644 index 0000000000..6f8b882fca --- /dev/null +++ b/hw/riscv/tt_atlantis.c @@ -0,0 +1,558 @@ +/* + * 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/machines-qom.h" +#include "hw/riscv/riscv_hart.h" + +#include "hw/char/serial-mm.h" +#include "hw/intc/riscv_aclint.h" +#include "hw/intc/riscv_aplic.h" + +#include "system/system.h" +#include "system/device_tree.h" + +#include "hw/riscv/tt_atlantis.h" + +#include "aia.h" + +#define TT_IRQCHIP_NUM_MSIS 255 +#define TT_IRQCHIP_NUM_SOURCES 128 +#define TT_IRQCHIP_NUM_PRIO_BITS 3 +#define TT_IRQCHIP_GUESTS 7 /* aia_guests */ + +#define FDT_PCI_ADDR_CELLS 3 +#define FDT_PCI_INT_CELLS 1 +#define FDT_MAX_INT_CELLS 2 +#define FDT_MAX_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \ + 1 + FDT_MAX_INT_CELLS) + +#define TT_ACLINT_MTIME_SIZE 0x8050 +#define TT_ACLINT_MTIME 0x0 +#define TT_ACLINT_MTIMECMP 0x8000 +#define TT_ACLINT_TIMEBASE_FREQ 1000000000 + +static const MemMapEntry tt_atlantis_memmap[] =3D { + /* Keep sorted with :'<,'>!sort -g -k 4 */ + [TT_ATL_DDR_LO] =3D { 0x00000000, 0x80000000 }, + [TT_ATL_BOOTROM] =3D { 0x80000000, 0x2000 }, + [TT_ATL_MIMSIC] =3D { 0xa0000000, 0x200000 }, + [TT_ATL_ACLINT] =3D { 0xa2180000, 0x10000 }, + [TT_ATL_SIMSIC] =3D { 0xa4000000, 0x200000 }, + [TT_ATL_TIMER] =3D { 0xa8020000, 0x10000 }, + [TT_ATL_UART0] =3D { 0xb0100000, 0x10000 }, + [TT_ATL_MAPLIC] =3D { 0xcc000000, 0x4000000 }, + [TT_ATL_SAPLIC] =3D { 0xe8000000, 0x4000000 }, + [TT_ATL_DDR_HI] =3D { 0x100000000, 0x1000000000 }, +}; + +static uint32_t next_phandle(void) +{ + static uint32_t phandle =3D 1; + return phandle++; +} + +static void create_fdt_cpus(TTAtlantisState *s, uint32_t *intc_phandles) +{ + uint32_t cpu_phandle; + void *fdt =3D MACHINE(s)->fdt; + + for (int cpu =3D s->soc.num_harts - 1; cpu >=3D 0; cpu--) { + RISCVCPU *cpu_ptr =3D &s->soc.harts[cpu]; + g_autofree char *cpu_name =3D NULL; + g_autofree char *intc_name =3D NULL; + + cpu_phandle =3D next_phandle(); + + cpu_name =3D g_strdup_printf("/cpus/cpu@%d", s->soc.hartid_base + = cpu); + qemu_fdt_add_subnode(fdt, cpu_name); + + qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv57"); + + riscv_isa_write_fdt(cpu_ptr, fdt, cpu_name); + + qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cbom-block-size", + cpu_ptr->cfg.cbom_blocksize); + + qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cboz-block-size", + cpu_ptr->cfg.cboz_blocksize); + + qemu_fdt_setprop_cell(fdt, cpu_name, "riscv,cbop-block-size", + cpu_ptr->cfg.cbop_blocksize); + + qemu_fdt_setprop_string(fdt, cpu_name, "compatible", "riscv"); + qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay"); + qemu_fdt_setprop_cell(fdt, cpu_name, "reg", s->soc.hartid_base + c= pu); + qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu"); + qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle); + + intc_phandles[cpu] =3D next_phandle(); + + intc_name =3D g_strdup_printf("%s/interrupt-controller", cpu_name); + qemu_fdt_add_subnode(fdt, intc_name); + qemu_fdt_setprop_cell(fdt, intc_name, "phandle", + intc_phandles[cpu]); + qemu_fdt_setprop_string(fdt, intc_name, "compatible", + "riscv,cpu-intc"); + qemu_fdt_setprop(fdt, intc_name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cell(fdt, intc_name, "#interrupt-cells", 1); + } +} + +static void create_fdt_memory_node(TTAtlantisState *s, + hwaddr addr, hwaddr size) +{ + void *fdt =3D MACHINE(s)->fdt; + g_autofree char *name =3D g_strdup_printf("/memory@%"HWADDR_PRIX, addr= ); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, addr, 2, size); + qemu_fdt_setprop_string(fdt, name, "device_type", "memory"); +} + +static void create_fdt_memory(TTAtlantisState *s) +{ + hwaddr size_lo =3D MACHINE(s)->ram_size; + hwaddr size_hi =3D 0; + + if (size_lo > s->memmap[TT_ATL_DDR_LO].size) { + size_lo =3D s->memmap[TT_ATL_DDR_LO].size; + size_hi =3D MACHINE(s)->ram_size - size_lo; + } + + create_fdt_memory_node(s, s->memmap[TT_ATL_DDR_LO].base, size_lo); + if (size_hi) { + /* + * The first part of the HI address is aliased at the LO address + * so do not include that as usable memory. Is there any way + * (or good reason) to describe that aliasing 2GB with DT? + */ + create_fdt_memory_node(s, s->memmap[TT_ATL_DDR_HI].base + size_lo, + size_hi); + } +} + +static void create_fdt_aclint(TTAtlantisState *s, uint32_t *intc_phandles) +{ + void *fdt =3D MACHINE(s)->fdt; + g_autofree char *name =3D NULL; + g_autofree uint32_t *aclint_mtimer_cells =3D NULL; + uint32_t aclint_cells_size; + hwaddr addr; + + aclint_mtimer_cells =3D g_new0(uint32_t, s->soc.num_harts * 2); + + for (int cpu =3D 0; cpu < s->soc.num_harts; cpu++) { + aclint_mtimer_cells[cpu * 2 + 0] =3D cpu_to_be32(intc_phandles[cpu= ]); + aclint_mtimer_cells[cpu * 2 + 1] =3D cpu_to_be32(IRQ_M_TIMER); + } + aclint_cells_size =3D s->soc.num_harts * sizeof(uint32_t) * 2; + + addr =3D s->memmap[TT_ATL_ACLINT].base; + + name =3D g_strdup_printf("/soc/mtimer@%"HWADDR_PRIX, addr); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,aclint-mtimer"= ); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", + 2, addr + TT_ACLINT_MTIME, + 2, 0x1000, + 2, addr + TT_ACLINT_MTIMECMP, + 2, 0x1000); + qemu_fdt_setprop(fdt, name, "interrupts-extended", + aclint_mtimer_cells, aclint_cells_size); +} + +static void create_fdt_one_imsic(void *fdt, const MemMapEntry *mem, int cp= us, + uint32_t *intc_phandles, uint32_t msi_pha= ndle, + int irq_line, uint32_t imsic_guest_bits) +{ + g_autofree char *name =3D NULL; + g_autofree uint32_t *imsic_cells =3D g_new0(uint32_t, cpus * 2); + + for (int cpu =3D 0; cpu < cpus; cpu++) { + imsic_cells[cpu * 2 + 0] =3D cpu_to_be32(intc_phandles[cpu]); + imsic_cells[cpu * 2 + 1] =3D cpu_to_be32(irq_line); + } + + name =3D g_strdup_printf("/soc/interrupt-controller@%"HWADDR_PRIX, mem= ->base); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,imsics"); + + qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", 0); + qemu_fdt_setprop(fdt, name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop(fdt, name, "msi-controller", NULL, 0); + qemu_fdt_setprop(fdt, name, "interrupts-extended", + imsic_cells, sizeof(uint32_t) * cpus * 2); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->s= ize); + qemu_fdt_setprop_cell(fdt, name, "riscv,num-ids", TT_IRQCHIP_NUM_MSIS); + + if (imsic_guest_bits) { + qemu_fdt_setprop_cell(fdt, name, "riscv,guest-index-bits", + imsic_guest_bits); + } + qemu_fdt_setprop_cell(fdt, name, "phandle", msi_phandle); +} + +static void create_fdt_one_aplic(void *fdt, + const MemMapEntry *mem, + uint32_t msi_phandle, + uint32_t *intc_phandles, + uint32_t aplic_phandle, + uint32_t aplic_child_phandle, + int irq_line, int num_harts) +{ + g_autofree char *name =3D + g_strdup_printf("/soc/interrupt-controller@%"HWADDR_PRIX, mem->bas= e); + g_autofree uint32_t *aplic_cells =3D g_new0(uint32_t, num_harts * 2); + + for (int cpu =3D 0; cpu < num_harts; cpu++) { + aplic_cells[cpu * 2 + 0] =3D cpu_to_be32(intc_phandles[cpu]); + aplic_cells[cpu * 2 + 1] =3D cpu_to_be32(irq_line); + } + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,aplic"); + qemu_fdt_setprop_cell(fdt, name, "#address-cells", 0); + qemu_fdt_setprop_cell(fdt, name, "#interrupt-cells", 2); + qemu_fdt_setprop(fdt, name, "interrupt-controller", NULL, 0); + + qemu_fdt_setprop(fdt, name, "interrupts-extended", + aplic_cells, num_harts * sizeof(uint32_t) * 2); + qemu_fdt_setprop_cell(fdt, name, "msi-parent", msi_phandle); + + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->s= ize); + qemu_fdt_setprop_cell(fdt, name, "riscv,num-sources", + TT_IRQCHIP_NUM_SOURCES); + + if (aplic_child_phandle) { + qemu_fdt_setprop_cell(fdt, name, "riscv,children", + aplic_child_phandle); + qemu_fdt_setprop_cells(fdt, name, "riscv,delegation", + aplic_child_phandle, 1, TT_IRQCHIP_NUM_SOUR= CES); + } + + qemu_fdt_setprop_cell(fdt, name, "phandle", aplic_phandle); +} + +static void create_fdt_pmu(TTAtlantisState *s) +{ + g_autofree char *pmu_name =3D g_strdup_printf("/pmu"); + void *fdt =3D MACHINE(s)->fdt; + RISCVCPU *hart =3D &s->soc.harts[0]; + + qemu_fdt_add_subnode(fdt, pmu_name); + qemu_fdt_setprop_string(fdt, pmu_name, "compatible", "riscv,pmu"); + riscv_pmu_generate_fdt_node(fdt, hart->pmu_avail_ctrs, pmu_name); +} + +static void create_fdt_cpu(TTAtlantisState *s, const MemMapEntry *memmap, + uint32_t aplic_s_phandle, + uint32_t imsic_s_phandle) +{ + MachineState *ms =3D MACHINE(s); + void *fdt =3D MACHINE(s)->fdt; + g_autofree uint32_t *intc_phandles =3D NULL; + + qemu_fdt_add_subnode(fdt, "/cpus"); + qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", + TT_ACLINT_TIMEBASE_FREQ); + qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); + qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); + + intc_phandles =3D g_new0(uint32_t, ms->smp.cpus); + + create_fdt_cpus(s, intc_phandles); + + create_fdt_memory(s); + + create_fdt_aclint(s, intc_phandles); + + /* M-level IMSIC node */ + uint32_t msi_m_phandle =3D next_phandle(); + create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_MIMSIC], ms->smp.cpus, + intc_phandles, msi_m_phandle, + IRQ_M_EXT, 0); + + /* S-level IMSIC node */ + create_fdt_one_imsic(fdt, &s->memmap[TT_ATL_SIMSIC], ms->smp.cpus, + intc_phandles, imsic_s_phandle, + IRQ_S_EXT, imsic_num_bits(TT_IRQCHIP_GUESTS + 1)); + + uint32_t aplic_m_phandle =3D next_phandle(); + + /* M-level APLIC node */ + create_fdt_one_aplic(fdt, &s->memmap[TT_ATL_MAPLIC], + msi_m_phandle, intc_phandles, + aplic_m_phandle, aplic_s_phandle, + IRQ_M_EXT, s->soc.num_harts); + + /* S-level APLIC node */ + create_fdt_one_aplic(fdt, &s->memmap[TT_ATL_SAPLIC], + imsic_s_phandle, intc_phandles, + aplic_s_phandle, 0, + IRQ_S_EXT, s->soc.num_harts); +} + +static void create_fdt_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 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_UART0], TT_ATL_UART0_IRQ, + aplic_s_phandle); +} + +static void create_fdt(TTAtlantisState *s) +{ + MachineState *ms =3D MACHINE(s); + uint8_t rng_seed[32]; + g_autofree char *name =3D NULL; + void *fdt; + + fdt =3D create_device_tree(&s->fdt_size); + if (!fdt) { + error_report("create_device_tree() failed"); + exit(1); + } + ms->fdt =3D fdt; + + qemu_fdt_setprop_string(fdt, "/", "model", + "Tenstorrent Atlantis RISC-V Machine"); + qemu_fdt_setprop_string(fdt, "/", "compatible", "tenstorrent,atlantis"= ); + qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2); + qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2); + + qemu_fdt_add_subnode(fdt, "/soc"); + qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0); + qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus"); + qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2); + qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2); + + qemu_fdt_add_subnode(fdt, "/chosen"); + + /* Pass seed to RNG */ + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + qemu_fdt_setprop(fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed= )); + + qemu_fdt_add_subnode(fdt, "/aliases"); + + create_fdt_pmu(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, hi_ram_size; + int hart_count =3D machine->smp.cpus; + int base_hartid =3D 0; + + s->memmap =3D tt_atlantis_memmap; + + object_initialize_child(OBJECT(machine), "soc", &s->soc, + TYPE_RISCV_HART_ARRAY); + object_property_set_str(OBJECT(&s->soc), "cpu-type", machine->cpu_type, + &error_abort); + object_property_set_int(OBJECT(&s->soc), "hartid-base", base_hartid, + &error_abort); + object_property_set_int(OBJECT(&s->soc), "num-harts", hart_count, + &error_abort); + object_property_set_int(OBJECT(&s->soc), "resetvec", + s->memmap[TT_ATL_BOOTROM].base, + &error_abort); + sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal); + + s->irqchip =3D riscv_create_aia(true, TT_IRQCHIP_GUESTS, + TT_IRQCHIP_NUM_SOURCES, + &s->memmap[TT_ATL_MAPLIC], + &s->memmap[TT_ATL_SAPLIC], + &s->memmap[TT_ATL_MIMSIC], + &s->memmap[TT_ATL_SIMSIC], + 0, base_hartid, hart_count, + TT_IRQCHIP_NUM_MSIS, + TT_IRQCHIP_NUM_PRIO_BITS); + + riscv_aclint_mtimer_create(s->memmap[TT_ATL_ACLINT].base, + TT_ACLINT_MTIME_SIZE, + base_hartid, hart_count, + TT_ACLINT_MTIMECMP, + TT_ACLINT_MTIME, + TT_ACLINT_TIMEBASE_FREQ, true); + + /* DDR */ + + /* The high address covers all of RAM, the low address just the first = 2GB */ + lo_ram_size =3D s->memmap[TT_ATL_DDR_LO].size; + hi_ram_size =3D s->memmap[TT_ATL_DDR_HI].size; + if (machine->ram_size > hi_ram_size) { + char *sz =3D size_to_str(hi_ram_size); + error_report("RAM size is too large, maximum is %s", sz); + g_free(sz); + exit(EXIT_FAILURE); + } + + memory_region_init_alias(ram_lo, OBJECT(machine), "ram.low", machine->= ram, + 0, lo_ram_size); + memory_region_init_alias(ram_hi, OBJECT(machine), "ram.high", machine-= >ram, + 0, hi_ram_size); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_DDR_LO].base, ram_lo); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_DDR_HI].base, ram_hi); + + /* Boot ROM */ + memory_region_init_rom(bootrom, NULL, "tt-atlantis.bootrom", + s->memmap[TT_ATL_BOOTROM].size, &error_fatal); + memory_region_add_subregion(system_memory, s->memmap[TT_ATL_BOOTROM].b= ase, + bootrom); + + /* UART */ + serial_mm_init(system_memory, s->memmap[TT_ATL_UART0].base, 2, + qdev_get_gpio_in(s->irqchip, TT_ATL_UART0_IRQ), + 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); + + /* Load or create device tree */ + if (machine->dtb) { + machine->fdt =3D load_device_tree(machine->dtb, &s->fdt_size); + if (!machine->fdt) { + error_report("load_device_tree() failed"); + exit(1); + } + } else { + create_fdt(s); + } + + s->machine_done.notify =3D tt_atlantis_machine_done; + qemu_add_machine_init_done_notifier(&s->machine_done); +} + +static void tt_atlantis_machine_class_init(ObjectClass *oc, const void *da= ta) +{ + MachineClass *mc =3D MACHINE_CLASS(oc); + + mc->desc =3D "Tenstorrent Atlantis RISC-V SoC"; + mc->init =3D tt_atlantis_machine_init; + mc->max_cpus =3D 8; + mc->default_cpus =3D 8; + mc->default_ram_size =3D 2 * GiB; + mc->default_cpu_type =3D TYPE_RISCV_CPU_TT_ASCALON; + mc->block_default_type =3D IF_VIRTIO; + mc->no_cdrom =3D 1; + mc->default_ram_id =3D "tt_atlantis.ram"; +} + +static const TypeInfo tt_atlantis_types[] =3D { + { + .name =3D MACHINE_TYPE_NAME("tt-atlantis"), + .parent =3D TYPE_MACHINE, + .class_init =3D tt_atlantis_machine_class_init, + .instance_size =3D sizeof(TTAtlantisState), + .interfaces =3D riscv64_machine_interfaces, + }, +}; + +DEFINE_TYPES(tt_atlantis_types) diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h new file mode 100644 index 0000000000..960dc07841 --- /dev/null +++ b/include/hw/riscv/tt_atlantis.h @@ -0,0 +1,51 @@ +/* + * 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_UART0_IRQ =3D 38, +}; + +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_TIMER, + TT_ATL_UART0, +}; + +#endif --=20 2.53.0 From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059090; cv=none; d=zohomail.com; s=zohoarc; b=SgEOqzqqR7q8c1hXlaVBxOeSCx8N1infnp1Q+bpxTFtB0fBvr27Ck+hQ6pEOiR7+f2xQODN+yp6aIYbrCQVEV0Cth+aB+kMW3OKAm7INMtiTuBztZrnAa1DUmOen3AFmVqvZ1rPsjuPtcq7pfxwwCFQ8KohJxcagRENYo/lOO5s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059090; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=l7uuhAv5qALLyILQ8blZPaC3DwBK244s0aGHr49256w=; b=gfcVahXfZExEFGmGFWgam+0RFg0kSted1p+8pC5a/bl9D41dbkUHvwjy5SBaXRN0G8Sai2NJd3IKNn+/RBjpnAqZoyGF9K7ihHx9PQliPOowlhUSspOm0Uu593uN1Uzn6NzwpDsGzRXCWA3cXMS3F11z+OVi8PE2VRu6KV2jCuw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059090737607.545553395027; Fri, 29 May 2026 05:51:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwgF-0004uX-Lw; Fri, 29 May 2026 08:51:15 -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 1wSwgE-0004tY-2K for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:14 -0400 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wSwgC-0006Kl-D7 for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:13 -0400 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-2babfd18435so62816775ad.1 for ; Fri, 29 May 2026 05:51:12 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2bf23c26b3bsm19707965ad.64.2026.05.29.05.51.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:51:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059071; x=1780663871; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=l7uuhAv5qALLyILQ8blZPaC3DwBK244s0aGHr49256w=; b=LSYnZnQ4Ut2qpjjeOB9QcqsAeEzcw2gLFt0OrRcudgjtnuHlxS45Lr+G3cIUtV86zL +y3MMAtyKv1lsqJBxKaLCaigP+ZWjIFuJgIp8j/jYdF1MSTScijo9Yg9M+R5NyuiOmtZ CyD6eYKRQWwNLZNCXnjyB8IZmBDFDl3nklgQuicrnOJ1B9Y4lUlB2Opnzg9D7kagwROk WQvK/iy38PrHyC2222M1aN89udhJLhz4E/Jaz6ckrczg43uvZ6ZI9HLVzOyJCWW7k/yk VQyFm5YYreGIrJcskmcwswtQRosTdyKp2MyCS+KoGGtI4rwEJ9G22julxcs/pzyEiQmc vHrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059071; x=1780663871; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=l7uuhAv5qALLyILQ8blZPaC3DwBK244s0aGHr49256w=; b=TPbxlV7ekuCyB82ZLsbg/Wxx/q5sF3AutCn+ofQIWL6W+3l0OMmCfkp+EW8Xuk70bn TnNazKMkoULl4s1tvqWqFrd01eg8w8RTW1irya0/iAlZPfGmtuuHw8SncgwRR1BHmjJw dDodG6u3skKVOdOhz6iOORaBXXFmKBDFa6EvXbFsxz+M9rL1AfE2UFd8w/nMom/Ybaho ImI7NiWC6LUeU5E0ww+X35MluCqjroOszwmLHeoZR0x0UMf7DrbT2pQ8lT0jmy7ifMcp ci5PEkHLkI3BJ6WDQK6OcuG8thAMMP5+7rk27OEG4Zo2uNUZFx0xq5391ZKAW4FEyJ/b 04NA== X-Forwarded-Encrypted: i=1; AFNElJ/hG+cDLdmEz1rfV+q0lG0ZZWtAlBaj1+7QwgZianeU/56J/fMdFJLCruSrxwXDjnD0FRuU4xvIT48F@nongnu.org X-Gm-Message-State: AOJu0YzS0n1j6AAt7ZPf/q27PTmh6ohaxFRuTEJ5qwRrR77mT9p0feTT CYQGRMQZOKp2xh8HRSWua9abokDRNxetWMrreB/5Ow4kwmBuxLzcWqhd X-Gm-Gg: Acq92OE8hm865a0FLbBXh5TuJMpx2pb5qTonF69WyxIWJQEFzOvZ6g0ZiKF5cyqLe1t 9viupMOtWd/AE+/saeY2D6kKcPLUpPiuNA6s1fMKzApFZdq9cyyLI/fmYLOkMQsLqNnZrrSGmMz jJZJ0Aj2M0JPNFs/0cqDuUJcjFkTPwKjTT/D/zY4/MBvc2mLzllJeqMmEwtI7ihbu7fkshtpn5V MTccKfbZdBVYqcDdDcyEeElOkzep44W7jebQSnUlZbfrcnCDvYUihp+dic1dsbROKK4F1G+ZGCU dyKMRz62jHjg1DX/kOE3RpvNqxEQLYktW+T6vp8K+ypPp3bPjkvD1sZmwlk17INtI4SSU8c6mkH 8MYDWH0S8els+uUEV4JPRmdUyIPO+tP1mxDKOUi3xGEN0Ew86kXKue2QGn88rWEx02G6EITImMe mlWXQ1KBcvRLbGCpQKEttVyBtUT6oQ0yNh0cWNlq2N/6pROXvz+JqTd1h4g4PvZQ13ZDxbn/hXv R3Pu2Zy X-Received: by 2002:a17:902:cf0d:b0:2be:956f:144c with SMTP id d9443c01a7336-2bf2052a76dmr39465265ad.2.1780059070902; Fri, 29 May 2026 05:51:10 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v7 06/10] hw/riscv/atlantis: Provide a simple halting payload Date: Fri, 29 May 2026 05:50:31 -0700 Message-ID: <20260529125036.728206-7-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::631; envelope-from=npiggin@gmail.com; helo=mail-pl1-x631.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059091488158500 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 6f8b882fca..20db26f982 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -385,6 +385,30 @@ static void create_fdt(TTAtlantisState *s) create_fdt_pmu(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); @@ -422,6 +446,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.53.0 From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059165; cv=none; d=zohomail.com; s=zohoarc; b=bbvBxPqk4sP7oE8VI6sAOYyEnyXh95H51gyahOBbddTR1Rfbvzsk3rERkBXcG8UioRiZYmLriuVdplU5sOcdqOwWuiYT7PRe/QuR5F9GwQHNG1feXQnhJlA8vnCzDMtqJ8/OR/fymnK1YuHaQRnL90kfnt3L5OXLwQuBLNSXA6g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059165; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Na64UqTsRKpXXVv1acvxDBdZdoKT8LTF8TPzURCFSpY=; b=JWimqXXNtyXeDtEo81AF4yGAioImMpdvAI6FFc+mShLpvKYrDMupp1KttlV4IQ7AdWkslw6nTyY9wdet+wMVaxWEKgyBEZrb6zmH8dZdX1ogAqz2YGbuE0ab6vEXoPPzidkzRQuNqG6aGXRAEcvLhWrtgVmzS5wGAPgmyWppmWs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059165024500.2763064157667; Fri, 29 May 2026 05:52:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwgK-0004wv-GT; Fri, 29 May 2026 08:51:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wSwgI-0004vt-Kj for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:18 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wSwgG-0006LE-LN for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:18 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-2bf125989f2so10416855ad.3 for ; Fri, 29 May 2026 05:51:16 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2bf23b00ea6sm28679005ad.42.2026.05.29.05.51.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:51:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059075; x=1780663875; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Na64UqTsRKpXXVv1acvxDBdZdoKT8LTF8TPzURCFSpY=; b=p3EhO7z/wQQ4OgaKmJkpCYNqsBHhi0l51dfiJ9zQ4xsPXWLgN9j6nKNOD0TE4q5DvL KmA1bXOSi3T/Br4hAWSnlF7KUooVx0EjG/WeZzmWYxy5HF2uB53sD+KPCh0sF7jzJYtR 0DUfOnKVvDFs/x9TzZjcFtFPVX7Hn9o9m0dHh+e+ChaOAF3AKwyAHf/Hj5Hcs9QJ+Yrg +xCvrRC1iozdUgAYuzxa79Uw0mRYA7j/ZxxVSUsN4MWflYCfH65bRVktamjS6Euxru8r ndUukH1jpNwMp+67J4p4pG0PLWKlMIFpBGRcKHq+HbFtG21I9ucam92aZQthZLZfcgjB N30Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059075; x=1780663875; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Na64UqTsRKpXXVv1acvxDBdZdoKT8LTF8TPzURCFSpY=; b=smn6IvodlHlm/BpWcImF5Ufzv3D5YaXRtaIWbiXm/o5adSV6L2Ql1lIapjsy3AokV6 0Vz0VwxvrLHffsZWu+Ln37nnp9Tj7DAKcsfpsUgBrH3coAsgkpkVJaruE8s60VjAcneP DMizc+xmWa+N6uIi7UtBLCbbiSDAjuLQpUcIIossv3FC4U9ZY7iS+hiBcVW1TZPaOCK/ KmvoPPHUt+HtgecCLAGMLSpIJzvTp/j6R7INlyGYzUh/hWPiw/tXdsdNVe+47QstINpz 4G3d9yRx/XCNMh+UKzdg1yZpycFYEchQs01tss/lo9IAqqd2m0j308r0HJngSEkujYuN Du2A== X-Forwarded-Encrypted: i=1; AFNElJ+eIVqu6wEnkfOS/VwGh+TVufbNZZLC5+2lUGw2k6NQJptXEBRGMH/Nc69ih4wVQ+SW9W5tgA8bNOg5@nongnu.org X-Gm-Message-State: AOJu0YxWXGXMoYoVuDQMXzwh+dxhFQTmCuC4t/EhSVqrqTwI46Nv/HqO K4QlSn2wxRNlGd/rn/cq7O70ioL/sqHtO37pjbZ87eVyOTTNFci8uUDh X-Gm-Gg: Acq92OG+0IkFM96jDrsu2k4Do+wfXpJw4isrDSV8S0PfroawrJuOCPl3D2ZJ+/7X5U1 +nohuyQsGAMdB6K1Y7iQAT7PxglGZSeflXfXE8/y2h4vZnhi5FJ+fGazO+9GDrefN7JYS+RWAx/ 4iq0JcTaJM2sFiI/iW4hx/JRGkDtPxEWfeSn0s85AANU8IjvBkBiOwKYAAxgkUOTSn2pkDb/96I 03KxoB6uko+GEoFZkTQrgyWa4rZ5XH+eBkx2MvR9ZlE6nMoe1QUD6zKbcN9G1TSiavDLp/TO08r atUegutemvIwOoYmEn0LHxD7vz82na/Q8MfAAfazcLSLCBd/zHmBUleeTI7Qg2AFWpl16NeXUI3 GnFqQlewv0exsuV3VNTLD2g/lcl6yE7mSlK/k787sAl/LDWW50j8LrbTjEYANcS7BldSzJNknRH gfVAVDfteBp4z+39YTd+8eP9OlnNUMj1RBwk3rp+uTGVUq4CeotbGJQ3M9zcoyKFUxiExBo8M1B b8fqyIpC4BRHyz96z4= X-Received: by 2002:a17:902:f60c:b0:2b4:5f96:184d with SMTP id d9443c01a7336-2bf204e2c80mr37498025ad.5.1780059075207; Fri, 29 May 2026 05:51:15 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v7 07/10] tests/functional/riscv64: Add tt-atlantis tests Date: Fri, 29 May 2026 05:50:32 -0700 Message-ID: <20260529125036.728206-8-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::62b; envelope-from=npiggin@gmail.com; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059167238154100 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 Signed-off-by: Joel Stanley Signed-off-by: Nicholas Piggin --- 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 c5f7a8a6e4..e14d7a9c28 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1788,6 +1788,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 b996c89d7d..c4456fabd7 100644 --- a/tests/functional/riscv64/meson.build +++ b/tests/functional/riscv64/meson.build @@ -13,5 +13,6 @@ tests_riscv64_system_quick =3D [ tests_riscv64_system_thorough =3D [ 'boston', 'sifive_u', + 'tt_atlantis', 'tuxrun', ] diff --git a/tests/functional/riscv64/test_opensbi.py b/tests/functional/ri= scv64/test_opensbi.py index d077e40f42..0f8beb7e7a 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 0000000000..48abd5cd27 --- /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.53.0 From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059136; cv=none; d=zohomail.com; s=zohoarc; b=OLf7tM1hGkkW/Jw5HTjDBo8eBHJuccRQl7GGRUoX0znwHZkHUpB2RKjXlXxEBAouCLrkPbuWQubPFwjzgHf9JzEwoqqG26QPFwyDxeVxJr6M2FRiH/JR2Z4B89vYPzRZYT7xyyA8y2Yua33ObdcGIF3ATpspXvexF6yOO7oNtNA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059136; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=AjvCezPJtbLfSdEOZNKNu95OOn66pglPC9wgYUdr1OI=; b=XIM9itM4lwrbH4K3aoVlwtv2gZ7mzVKp/a9Bahwi7Hc6G7Gy75RpHW+fslTRa4gc5sCd+2sbwbYpc0z6QHgLEHUs6o0hbSk8ZP1j/pS9LhkvWjzFWfDwJhuArV9lc9RjTpvCUe9SvoWvL3l36E+eYEOrBvSXASW+I3Hlao5zvMw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059136915146.14775458014697; Fri, 29 May 2026 05:52:16 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwgR-00054T-RT; Fri, 29 May 2026 08:51:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wSwgP-00051m-II for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:25 -0400 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wSwgL-0006NS-Fq for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:25 -0400 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-36ba706ab46so813055a91.1 for ; Fri, 29 May 2026 05:51:21 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-36bbe19dc07sm1218727a91.5.2026.05.29.05.51.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:51:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059080; x=1780663880; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AjvCezPJtbLfSdEOZNKNu95OOn66pglPC9wgYUdr1OI=; b=NqQiwefl9Sv5hKsECYKSob6vmAF4c7vjs9njOvXguyLXa9NFr6LeVOsl0yw903sFkp GDTzwbqFc9gjNaUrrPddYfiXAQCLc6s0gcY1dhmlp1VNU96KYvJli2furwr0EwAL9vP9 BKIoAID0zrzeaN3+amTifH44ikrDHmYjPo12xq3U1quNYtmRxzJwkUqCJxA+W7Xik4RW xbQTjZkO96nOgtLQg0WwaWPMQj/K9y4tLl7wKtdg/EbpxGh/S3RlXFAoGsNBF+20ItGh u6hsCyX6rkJpXlzwQULC4N4u9FsEE1VKdlbqCwCdW1V+u8dMm1bGkhOmvmrtlcRUdVlD knZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059080; x=1780663880; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=AjvCezPJtbLfSdEOZNKNu95OOn66pglPC9wgYUdr1OI=; b=QJahAME2UTecOIlV8WL0og+N9ymsfzQ32Y0Y7eJ36F8O7WxZDUj/qG0ItlmJi4QtnD FqXNHEwLb9XuDNPAcx7+dnzgxWcjRkoloT1+jP/16nuNRc5zIRl/dOpyyuEf+q8q/EXS DdhRUsdn39VZ1zObGGYzG32Wep4fKG+hTrJgmkmig2UjrocTRuFhklTgzSOp2xkCCYLM 2baGoyINBHDsrKsn9BzGwSxp/Nd6FoN4djvjqNu9zhmE+rg76hceD0lZ/6FIZd/0SUcA PuTTJe2Lb1fZftVRQLU11BKfYPEaX5UeqZ5LKgtqqjtUefrQRDql648VrLH6dH12dc81 jxvA== X-Forwarded-Encrypted: i=1; AFNElJ9A/dFn0v/NWVyI/7etWCTfQtNzw5RXWGxNHr4dyW7h7yexO4b/EjAzUCGNRLNrtUqShxmLS2j4ozzF@nongnu.org X-Gm-Message-State: AOJu0YzoeChRqwa0ZedGBSgOdy2L/fMRF2qBA9SxDNWcs8v5LkFSiJt6 1f+xwDGuRIFl0yoJEG7uF81G5ROoGxXLWkRpXsiGp24d7VwV/4pYX5/n X-Gm-Gg: Acq92OFtgGB5SFIWRXpq2gTEyEsGzsv0to0s3sUTgY4upI7M11w6PFzyg3x4UmHH1yr DTEY2NGyxNsCBQfjRqtl0lEvY6euy6Er8q5tE/D8X1nGOFsEHSUOirt7L9CP8+NP5E25GPs8AMV xFQQJFhdq94Q8cjpzpqU64ZD3EKyFVUvFbFMFXtJnwZjUaC53N1NU+TJgFXKXFAdLGJjZ7D0vnf OWdwWLaCe0z5xn+lfPevJEI0mkxORGa7dl0gI83wLgjAbxYGXRxHg5PSfj5xwgy+wEjG3UwFkHS NaZHDz+39J40172VcjTXOxjFwvevkrjtB+YcN2GTZa81k+GVvFOU8INaSjAkbIc1Xn0jusNX8tL n+YptW6rAZBbDdcseL5leRp7Wh8yyBVBgGxvhDiYiLkAGPwCm/qrInV8E0NNvdmJfKnbkQN1cv/ ksxAfdwzqLXDunx6lZaoFT/qu3wPEW2PO4HVaXVakcBw2mL9bc6KEya37IAnevoKaJOp3pRmCqG UOnWHVC X-Received: by 2002:a17:90b:3c8c:b0:369:e4d4:79c6 with SMTP id 98e67ed59e1d1-36bbceab65cmr3482264a91.20.1780059079585; Fri, 29 May 2026 05:51:19 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley , Chris Rauer , Hao Wu , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Corey Minyard , Alano Song Subject: [PATCH v7 08/10] hw/i2c: Add DesignWare I2C Controller Date: Fri, 29 May 2026 05:50:33 -0700 Message-ID: <20260529125036.728206-9-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::1035; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059138984154100 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. 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] [npiggin: changelog, code cleanups and fixes as-per below link] Link: https://lore.kernel.org/qemu-devel/20260507120524.111056-1-npiggin@gm= ail.com Signed-off-by: Joel Stanley Signed-off-by: Nicholas Piggin Acked-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daud=C3=A9 Acked-by: Corey Minyard Tested-by: Alano Song --- This is a re-submission of the model with Chris' permission, with changes to rebase, update to QEMU register API, several other code improvements, fixes, and cleanups from reviews from Alistair, Phil, and others. Thanks, Nick --- MAINTAINERS | 8 + hw/i2c/Kconfig | 5 + hw/i2c/designware_i2c.c | 739 ++++++++++++++++++++++++++++++++ hw/i2c/meson.build | 1 + hw/i2c/trace-events | 4 + include/hw/i2c/designware_i2c.h | 56 +++ 6 files changed, 813 insertions(+) create mode 100644 hw/i2c/designware_i2c.c create mode 100644 include/hw/i2c/designware_i2c.h diff --git a/MAINTAINERS b/MAINTAINERS index e14d7a9c28..40cc4c4801 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2737,6 +2737,14 @@ S: Orphan F: hw/gpio/pcf8574.c F: include/gpio/pcf8574.h =20 +DesignWare I2C +M: Chris Rauer +R: Alano Song +R: Joel Stanley +S: Maintained +F: hw/i2c/designware_i2c.c +F: include/hw/i2c/designware_i2c.h + Generic Loader M: Alistair Francis S: Maintained diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig index 596a7a3165..0766130b59 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/designware_i2c.c b/hw/i2c/designware_i2c.c new file mode 100644 index 0000000000..67302979e6 --- /dev/null +++ b/hw/i2c/designware_i2c.c @@ -0,0 +1,739 @@ +/* + * DesignWare I2C Module. + * + * Copyright 2021 Google LLC + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" + +#include "hw/i2c/designware_i2c.h" +#include "migration/vmstate.h" +#include "qemu/bitops.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qemu/units.h" +#include "trace.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_M= ASK; + 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->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 threashold of 1. */ + if (value > DESIGNWARE_I2C_RX_FIFO_SIZE - 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid setting to ic_rx_tl %d\n", + DEVICE(s)->canonical_path, (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 threashold of 1. + * However, the tx threshold is not used in the model because commands= are + * always sent out as soon as they are written. + */ + if (value > DESIGNWARE_I2C_TX_FIFO_SIZE - 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid setting to ic_tx_tl %d\n", + DEVICE(s)->canonical_path, (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, + .unimp =3D R_DW_IC_CON_RX_FIFO_FULL_HLD_CTRL_MASK, + .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_smbus_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_smbus_init, + .instance_finalize =3D designware_i2c_finalize, + }, +}; +DEFINE_TYPES(designware_i2c_types); diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build index c459adcb59..88aea35662 100644 --- a/hw/i2c/meson.build +++ b/hw/i2c/meson.build @@ -11,6 +11,7 @@ i2c_ss.add(when: 'CONFIG_MPC_I2C', if_true: files('mpc_i2= c.c')) i2c_ss.add(when: 'CONFIG_ALLWINNER_I2C', if_true: files('allwinner-i2c.c')) i2c_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('microbit_i2c.c')) i2c_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_smbus.c')) +i2c_ss.add(when: 'CONFIG_DESIGNWARE_I2C', if_true: files('designware_i2c.c= ')) i2c_ss.add(when: 'CONFIG_SMBUS_EEPROM', if_true: files('smbus_eeprom.c')) i2c_ss.add(when: 'CONFIG_ARM_SBCON_I2C', if_true: files('arm_sbcon_i2c.c')) i2c_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_i2c.c')) diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events index 1ad0e95c0e..8a78d2d3c8 100644 --- a/hw/i2c/trace-events +++ b/hw/i2c/trace-events @@ -61,3 +61,7 @@ pca954x_read_data(uint8_t value) "PCA954X read data: 0x%0= 2x" =20 imx_i2c_read(const char *id, const char *reg, uint64_t ofs, uint64_t value= ) "%s:[%s (0x%" PRIx64 ")] -> 0x%02" PRIx64 imx_i2c_write(const char *id, const char *reg, uint64_t ofs, uint64_t valu= e) "%s:[%s (0x%" PRIx64 ")] <- 0x%02" PRIx64 + +# designware_i2c.c +dw_i2c_read(const char *id, uint64_t ofs, uint64_t value) "%s: offset 0x%0= 2" PRIx64 " -> value: 0x%02" PRIx64 +dw_i2c_write(const char *id, uint64_t ofs, uint64_t value) "%s: offset: 0x= %02" PRIx64 " <- value: 0x%02" PRIx64 diff --git a/include/hw/i2c/designware_i2c.h b/include/hw/i2c/designware_i2= c.h new file mode 100644 index 0000000000..54112c38e7 --- /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" + +#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; + +/* + * struct DesignWareI2CState - DesignWare I2C device state. + * @bus: The underlying I2C Bus + * @irq: GIC interrupt line to fire on events + * @rx_fifo: The FIFO buffer for receiving in FIFO mode. + */ +typedef 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; +} DesignWareI2CState; + +#define TYPE_DESIGNWARE_I2C "designware-i2c" +#define DESIGNWARE_I2C(obj) OBJECT_CHECK(DesignWareI2CState, (obj), \ + TYPE_DESIGNWARE_I2C) + +#endif /* DESIGNWARE_I2C_H */ --=20 2.53.0 From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059186; cv=none; d=zohomail.com; s=zohoarc; b=CgC4Eub6FChxAyI7Pt9gwrej213yOTxKbjbUQ8oQkEaW5X0rYhsB05h8ipvIJZcozkr/Nb5LG1Fz2G1ixHYlJkXq8nh/0B0XK2b/sxnba4cPnrNGiyp32pgWs/RwgMAaFl3B5I+f+t56DHEUNJfUwh15vWCxjYttZs+i/+VAP2M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059186; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=BsNa9aCVyTTB2LpanIeTZACYZwi0hW4ugdss0KkHJ5Y=; b=HLcyaHXzYAImt/C+9S8i/aH0cwJFbJWo+j8cFCKC77k1MUPLTmSDyPwHU9UF/dW0aBxr8prj9NTWH6rFLM1fypA3YNn2XTu+AXvsXzweTKTmayTkrfOhIHVb/mAGuNKGtd6aqfnuAJ+YPSw65L4D/WKssnEBlhhoxKuFm+V18hI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059185919752.7242598356037; Fri, 29 May 2026 05:53:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwgT-00056S-GA; Fri, 29 May 2026 08:51: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 1wSwgR-00052c-A1 for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:27 -0400 Received: from mail-pg1-x536.google.com ([2607:f8b0:4864:20::536]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wSwgP-0006O7-Gp for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:27 -0400 Received: by mail-pg1-x536.google.com with SMTP id 41be03b00d2f7-c857d04cc99so82887a12.0 for ; Fri, 29 May 2026 05:51:25 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c85772baab6sm2145420a12.24.2026.05.29.05.51.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:51:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059084; x=1780663884; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BsNa9aCVyTTB2LpanIeTZACYZwi0hW4ugdss0KkHJ5Y=; b=oVraCmandQ2l89EHbnO9v1lcr+GfmGz8dvEFs0J/7MQVMeaMFjPc9mzySXMsfho8wm VbziFB6ufXEObU1e0T0H2b9MZxD5IJGyGYbimnwuuenGbTlD1StH29l31d4U87JojqZ1 jQ46wrOXjqYsTn10rXuX2+VnWfkRaDUNnhJZ0ZitCmXsueR0/j8eq4PmWFJ40BN2uiu8 kgx898QJd4m28TDuuBK4ejQRml6XThpO+poBkZqU7XW1vHjUp3jW6f1tDc9/mNL6ejWr ww5d+2qK4nXJkP0ipof7WCErICGhuQ+LRhZ3zEUDap5Q2mlUfQwas5W3VXX8a9RqSGJx Hvew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059084; x=1780663884; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=BsNa9aCVyTTB2LpanIeTZACYZwi0hW4ugdss0KkHJ5Y=; b=dZuwbL8LkZJ65POtWgPI92BqaEYO7j2J5P+nHby2nOxmT3Ls1UOVv1K1ZnQJhT8baI CsKGxIK8lfW2k185eIY+7S/+YN0jKjKVsP/EGwQJXlBG9bUDQ+fb6QPKbCZthx31lvSi wbEbLDOT3a2gOsoWYZflXhxdIMV2rcp5u/uxJaqperjs/mws6D3jYAJW/LnkaRQEdP0/ ATDzUoNWXobdytoQ6OVqJ2U8dHsWoSMeB9J3y6k4jBYlq+vVBJ5W9OFL1ihHRMEVFeSf xOqyHz+QWgpX+djPozrBSm0oghsQkAnyDNdMSKuoCbFCkbZ6CFkN7dEHZkZCut/X+Js3 06QA== X-Forwarded-Encrypted: i=1; AFNElJ9emTaO2aoor6EgrGwANfakOM0LmYBhu8zFbZw8vJwq4RQRA0PwD1qBE0z7vEZZNP3DE3/MUXCEBMjv@nongnu.org X-Gm-Message-State: AOJu0YxgadzEywVEfiNWHOJ6urCN3s5EoRj0CPjhWue7J2UAyrA/uJJX XrTm4PHuKLNHxd14LA7IsmLUFwypVJ1fi7p2oYpoHNeSlN+7HVBDsW8P X-Gm-Gg: Acq92OFYsaoaK9IKfXfDG+Ga9VRqye6W08is+PAIU/ba3xkqmDDFMLr4+pJr55waGai ErUepgs9pyYOyWKT9fJA1Vp6SR/mJeyxMwOTsW1L+T7VjnSf3ez1JfYF3rXPSTJlSn51w5cjjRx FBVxKPsHcBMAfN/dbzr42VaPHPJ2VqrlWkWCmLqds4TFnrePgzLEDGSHUNEHpM2n8aHfw2ixoIs PJtMCR+7KhFuNPpvzn+RLb/U1rFdPD2HV2YouNs99Vr3Fg92wXOgyxQ5Wi7cPLI6haWYFNNwI0N zBGGOpFVor7h68mAN8mpN9jyZXjareh03rtg3Vg11lCId74g7EwYL428xzf2noO0k+7w4MUfd7x 9R/myeENo5J8qufqLT6/AawryI23CpSRGwFP3VKn5EstFE1UQkWOEVWTGxAqWAtfOssa06pY4u6 GLVoaUwPrUodvMeCw1MRb8bszv4NKrzTFFXgo5oHkDlaYrMd3MNESQTxHBzgyc8mbdUabn0DutU iJ72D3CmbmtbSBP8qU= X-Received: by 2002:a05:6a20:1588:b0:3b3:3852:6663 with SMTP id adf61e73a8af0-3b40fcdcdfemr2963580637.24.1780059084030; Fri, 29 May 2026 05:51:24 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v7 09/10] hw/riscv/atlantis: Integrate i2c controllers Date: Fri, 29 May 2026 05:50:34 -0700 Message-ID: <20260529125036.728206-10-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::536; envelope-from=npiggin@gmail.com; helo=mail-pg1-x536.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059187669154100 From: Joel Stanley 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 Signed-off-by: Joel Stanley Signed-off-by: Nicholas Piggin --- hw/riscv/Kconfig | 1 + hw/riscv/tt_atlantis.c | 53 ++++++++++++++++++++++++++++++++++ include/hw/riscv/tt_atlantis.h | 14 +++++++++ 3 files changed, 68 insertions(+) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index aaf029c9ed..38180a903f 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 diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index 20db26f982..39979c662b 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -59,6 +59,11 @@ static const MemMapEntry tt_atlantis_memmap[] =3D { [TT_ATL_SIMSIC] =3D { 0xa4000000, 0x200000 }, [TT_ATL_TIMER] =3D { 0xa8020000, 0x10000 }, [TT_ATL_UART0] =3D { 0xb0100000, 0x10000 }, + [TT_ATL_I2C0] =3D { 0xb0400000, 0x10000 }, + [TT_ATL_I2C1] =3D { 0xb0500000, 0x10000 }, + [TT_ATL_I2C2] =3D { 0xb0600000, 0x10000 }, + [TT_ATL_I2C3] =3D { 0xb0700000, 0x10000 }, + [TT_ATL_I2C4] =3D { 0xb0800000, 0x10000 }, [TT_ATL_MAPLIC] =3D { 0xcc000000, 0x4000000 }, [TT_ATL_SAPLIC] =3D { 0xe8000000, 0x4000000 }, [TT_ATL_DDR_HI] =3D { 0x100000000, 0x1000000000 }, @@ -329,10 +334,36 @@ static void create_fdt_uart(void *fdt, const MemMapEn= try *mem, int irq, qemu_fdt_setprop_string(fdt, "/aliases", "serial0", name); } =20 +static void create_fdt_clk(void *fdt, const char *name, uint32_t clk_phand= le) +{ + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "fixed-clock"); + qemu_fdt_setprop_cell(fdt, name, "#clock-cells", 0); + qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 100000000); + qemu_fdt_setprop_cell(fdt, name, "phandle", clk_phandle); +} + +static void create_fdt_i2c(void *fdt, const MemMapEntry *mem, uint32_t irq, + uint32_t irqchip_phandle, uint32_t clk_phandle) +{ + g_autofree char *name =3D g_strdup_printf("/soc/i2c@%"HWADDR_PRIX, mem= ->base); + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "snps,designware-i2c"= ); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", 2, mem->base, 2, mem->s= ize); + qemu_fdt_setprop_cell(fdt, name, "interrupt-parent", irqchip_phandle); + qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x4); + qemu_fdt_setprop_cell(fdt, name, "clocks", clk_phandle); + qemu_fdt_setprop_cell(fdt, name, "clock-frequency", 100000); + qemu_fdt_setprop_cell(fdt, name, "#address-cells", 1); + qemu_fdt_setprop_cell(fdt, name, "#size-cells", 0); +} + static void finalize_fdt(TTAtlantisState *s) { uint32_t aplic_s_phandle =3D next_phandle(); uint32_t imsic_s_phandle =3D next_phandle(); + uint32_t periph_clk_phandle =3D next_phandle(); void *fdt =3D MACHINE(s)->fdt; =20 create_fdt_cpu(s, s->memmap, aplic_s_phandle, imsic_s_phandle); @@ -346,6 +377,15 @@ static void finalize_fdt(TTAtlantisState *s) =20 create_fdt_uart(fdt, &s->memmap[TT_ATL_UART0], TT_ATL_UART0_IRQ, aplic_s_phandle); + + create_fdt_clk(fdt, "/periph-clk", periph_clk_phandle); + + for (int i =3D 0; i < TT_ATL_NUM_I2C; i++) { + create_fdt_i2c(fdt, + &s->memmap[TT_ATL_I2C0 + i], + TT_ATL_I2C0_IRQ + i, + aplic_s_phandle, periph_clk_phandle); + } } =20 static void create_fdt(TTAtlantisState *s) @@ -542,6 +582,19 @@ static void tt_atlantis_machine_init(MachineState *mac= hine) qdev_get_gpio_in(s->irqchip, TT_ATL_UART0_IRQ), 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); =20 + /* I2C */ + for (int i =3D 0; i < TT_ATL_NUM_I2C; i++) { + object_initialize_child(OBJECT(s), "i2c[*]", &s->i2c[i], + TYPE_DESIGNWARE_I2C); + sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), &error_fatal); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(&s->i2c[i]); + memory_region_add_subregion(system_memory, + s->memmap[TT_ATL_I2C0 + i].base, + sysbus_mmio_get_region(sbd, 0)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, + qdev_get_gpio_in(s->irqchip, TT_ATL_I2C0_IRQ + = i)); + } + /* Load or create device tree */ if (machine->dtb) { machine->fdt =3D load_device_tree(machine->dtb, &s->fdt_size); diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h index 960dc07841..ddea317409 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_UART0_IRQ =3D 38, }; =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, --=20 2.53.0 From nobody Sat May 30 17:17:15 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780059111; cv=none; d=zohomail.com; s=zohoarc; b=hBee8ywjNiNXzY5IlAcxDBoJ2qIvhWwArKFK7rMFZWTEbdvVxaKdAKU3D4PdGEqpiJp0QaLjcgveZe5UxCOUCOoCkaqGZDtjHUqHm7mllNDINAU/kcH/PPVYegk5LoIDfTByWhfr2RqnCHbCdM0JFX5mH+5GVp4qj1zUBZekhv8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780059111; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=j2zfqS8MXtuTTKrwyVtoNZLOJDJV7lQ5nawu6+oWpRg=; b=RH7VG3/kZDgex47V2BfRW+lk1L6553lxuzEA47+9iNLiXtmM/hPamzXUR6CJq3njxgCsmpwkQSgWIqW8tXbX6nDTaPnKLRJU1kud1Lazau8975B5hJJli+rDGoBS757DwhZlKjS1kCcwSSiIS7dy3w1cyEx04maJ20TYxrusnBg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1780059111613997.067861083811; Fri, 29 May 2026 05:51:51 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wSwgX-0005Dr-5H; Fri, 29 May 2026 08:51:33 -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 1wSwgV-0005C2-Bu for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:31 -0400 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wSwgT-0006Oi-LF for qemu-devel@nongnu.org; Fri, 29 May 2026 08:51:31 -0400 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-2bf2247e38eso5740395ad.3 for ; Fri, 29 May 2026 05:51:29 -0700 (PDT) Received: from localhost (124.158.97.178.qld.leaptel.network. [124.158.97.178]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2bf23b00ebcsm19248475ad.51.2026.05.29.05.51.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 May 2026 05:51:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780059088; x=1780663888; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=j2zfqS8MXtuTTKrwyVtoNZLOJDJV7lQ5nawu6+oWpRg=; b=Cn3f3t2uTd0mgQd+cB49g9xmARd5ovjRXTCWNw2MxEoHdxQ9Wh7lkigHzLpA2Jy9v/ LL3zQ9yywGzkjmAJ6BqtGZYrGLcHkqH8VnqiLtpZ0ybZoFeWMoxkbIGmCRU1PHlBbMNU VlMWom7Ci8MbDi7IkuASaauxM+90XsQDwICQe9U0cgKNoPJZO0urG1eJEDHyiIvUN2rY d26qUNXtBXIaPZ/pJM4FIBGcA8AGUDizgan2dJXjpdhhHhrmU250IdoCFI461BN7Ab0d 6puMYRrgIFvyglGhsYOv9B2yLq9hRgaliXCOOMrR7AwG4FCwJrQb4FIK3PSWbLE0kWQR tF2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780059088; x=1780663888; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=j2zfqS8MXtuTTKrwyVtoNZLOJDJV7lQ5nawu6+oWpRg=; b=VLXht+T+NcxclgpEsEoXbf/iG0m+Y2oMLS7s15cv85GeP3XacHIFHjWnu3caH3gmuc FWNRNG1xG2UDiANGxNe0mklEDhOBzO5o0XmleUmBAHAb97+llIYudTup/cHnhS4Z5TGU JGKRuFgOnN3X+YKGHhxMXrC53wdJVSsizT0hX5xeI8aS6DTs2P058lOz+9qJvQs8N04a yswaUZxGCcyyK1GSn+GQ2NhTIhvTVkOyoE5Mx8L74+pO+a9yiNkiEMbyPw9eZdxnASSp F4oeAUuLzaUQOjPT+Xqk0S5NcbsVHEJfemhTQ+9uhwiSTtT27+G+uOpIkF+89kJDf9aM GwLA== X-Forwarded-Encrypted: i=1; AFNElJ8UHi0BcygK8i3iaC1YTxymnSbelhpebUXYbC+TiCx0Bj+CqGDxcul9iFp8Z2UGNkkdRHYMpgdLcupR@nongnu.org X-Gm-Message-State: AOJu0Yy7RDp0NmtNw3BpDZhuWNg7bHt4pYiagKc7rz18B1JDXNAvvIDE s2CUfb8eZYfFOVmc/10Ck+/Amx6vPDCy0F41w9wvD+cHv+yO+tY7LXlO X-Gm-Gg: Acq92OHXd+cRHR9qWLNvNyGx2hlRdQzfB4vyLSdm4WukDBKCAAGtYHfm9Feel9IORNX lNsoki4e8sRFH1jTiu/3uxfh9caEDAKdiW1CYir7npCqH7E1IaZdGO2DeFg0evzPuyjt/RNijdg 63UcVRAX3EmIXKxNhKad3XO+nZ3ZvmaIigjWQeaP3MVP9v1tUilWama+MmYwjyGsdQApahU/7RP u+5V7OF1Bq2wLDv97cKkXqWu9bZEmeNLmkBkQkyBCulnVdx7VQ+PGcRW0/PmJumoUVa1BTDYpp/ +f9YEM4Z3ZtwCzX7fGZtbq2lcHoIQw37W9BN8aLwig1gjdR47Jqd9ZcAPApg8dVLQatGF56jNoV XFiBu9e/8wJMrjHQNCE+fJuTvRoc/PoUhljbkWkhnktyClpAulmVyAdTsXPkFbZQAwcBjhQhYxE ZC6NxsGMNdSFhazLCo5fpbyHAvDcTDWTikCAh0eeHEn4GabwV2+5kx2Y/bZ4cDssTLIBf9EfKHD /WXeei2 X-Received: by 2002:a17:902:fc8f:b0:2b0:4fb6:85ce with SMTP id d9443c01a7336-2bf20977e87mr33743095ad.21.1780059088203; Fri, 29 May 2026 05:51:28 -0700 (PDT) From: Nicholas Piggin To: Alistair Francis Cc: Nicholas Piggin , Andrew Jones , Daniel Henrique Barboza , Chao Liu , Michael Ellerman , Joel Stanley , Anirudh Srinivasan , Portia Stephens , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Joel Stanley , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Subject: [PATCH v7 10/10] hw/riscv/atlantis: Add some i2c peripherals Date: Fri, 29 May 2026 05:50:35 -0700 Message-ID: <20260529125036.728206-11-npiggin@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529125036.728206-1-npiggin@gmail.com> References: <20260529125036.728206-1-npiggin@gmail.com> 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::631; envelope-from=npiggin@gmail.com; helo=mail-pl1-x631.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780059116400154100 From: Joel Stanley 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: Joel Stanley Signed-off-by: Nicholas Piggin --- hw/riscv/Kconfig | 2 ++ hw/riscv/tt_atlantis.c | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 38180a903f..ff2d250ee4 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 diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index 39979c662b..e43b58826a 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -69,6 +69,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 next_phandle(void) { static uint32_t phandle =3D 1; @@ -359,6 +366,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(); @@ -386,6 +406,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) @@ -595,6 +618,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) { machine->fdt =3D load_device_tree(machine->dtb, &s->fdt_size); --=20 2.53.0