From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686383; cv=none; d=zohomail.com; s=zohoarc; b=FeazeYZexuDNGckm5XALntTmwjnPXI1Wm0PPmgxibulocKuvN9qUbLIJN8AtiNNSl7IDkKkIlqBrPfZ4GZmmmEjNUjY2Xzz2b++jjVvfod2wgIKng+OJCBDuQPSHmY5acmScT11jS+sIFOt1aSaqRG2KfIHwqLVtGSU3wZpvmac= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686383; h=Content-Transfer-Encoding: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:Cc; bh=zx5e3hvpLfGgFFqw5DlLZdwsG1nOx/3xyThtl99TTe0=; b=hS3drQ5/GnYXuyhPKMZ1/3g/DQLBhg8uKRGIY8KXUdbkOABi3k2UQof6XZsEv3RHkMgPMQoMzfY22B90WAMtP2P8S9Mtw2xXdotsXnoKWHUIljqjYC0CQfve508FPofIXmh48yI7Of22r+zVNoq9+XNwe3S5UCW0iiWk3UK8YDk= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783686383297458.27783964087337; Fri, 10 Jul 2026 05:26:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEp-0006Xy-Vq; Fri, 10 Jul 2026 08:21:52 -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 1wi3lG-0000Ms-Md for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:26:55 -0400 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lE-000492-Av for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:26:53 -0400 Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3n9k43707758 for ; Fri, 10 Jul 2026 05:26:49 GMT Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4faeg5jvfp-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:26:49 +0000 (GMT) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-37dedbd1cf1so322950a91.3 for ; Thu, 09 Jul 2026 22:26:49 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.26.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:26:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=zx5e3hvpLfG gFFqw5DlLZdwsG1nOx/3xyThtl99TTe0=; b=kpuKGG1crFBDdRVoK00ZOggM2tY AnPQcqfo6+NwIu2l0LKd4YmzyH4WuqVmqfKQnZgmmoa2hhLcTAo9m463B8V4XKqc ewoHMPcOr7k/e8MIiE2J0X8VYhVGUCiqOATav2TA/PJbEoxNM8ZHokzKMLjHZoog vzYl4lN6hjnOTzeEWnQ9ZVwWL/DuCluzruXD7X7clnEyFw/OEvmTVKwzHzIQ/YuH 1P9b0hQfpBJkr7VXGWi/QSwiUXVY635vNM2AD6LKQEKl44kVQdAuAsTL/b8OHCA3 43HxYawm28HWnj2dUZkORfPZmhlZKxxsRNALl8+OLwYRIR04DeQD0ddRNEQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661209; x=1784266009; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=zx5e3hvpLfGgFFqw5DlLZdwsG1nOx/3xyThtl99TTe0=; b=iCTGmp5fsCWWM94k2ngiMoPuiVuHdmtNtoJCg9VnYgYNQAOdDLmQl0DmzgCxi29qeL +GkzH+by6rnn2emXCcQd9hY0ml4M9U3hndL0us8luh+nAUvPk+0tITDM2N+2mdZC4ytr z5YDauK+xL9XvLu5qP+XDgIPHmdkB7r/Z0QGZYWH9yYJh6yMDEq8qxdqMJDdZH8CucyH jXttLq7cHzpawW2ig22jfHgDHqOQI0ogZxwh1TLU/1l9hXiKWy4lGf+Vl0LKyMfzDo93 TEOD8dHMlxDHe5WQu4c7fkI9P7RjkbAHfopFMX10IM9XXtWItrBZ7fEVNxb7/SzAssqD 6a5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661209; x=1784266009; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=zx5e3hvpLfGgFFqw5DlLZdwsG1nOx/3xyThtl99TTe0=; b=PMJxuzDyNXQBMpdSiCr/w0KUPW17pr/83joWLtXrprzATwORHU2mB+VIQj/m6dv6ex ZHa0qDdYUK5BdYoqtkiwyAT6froglAar4OZLLWCvDzVUy43WWmO80oaoH6adHBqHib9A 3BixPGgnceNgDz2AX19nfvoofU0JK63n0nsUA4Jz7lsFkpmdRy+U/LLceeBUxS28Xkl+ u6qZ/6Syw66pU2LpBTq2oF4htLfU5wOAk/yPrZHdTm6eD6rxdcE3pikOzpedgu6oXjkv nQLNbce+jvk1PEGZiIBeHhr+4R3qRjkCQ4Nvqirejz7oS9akvyWU0D4Djq1S/zhDw/eT Wi4g== X-Gm-Message-State: AOJu0YzWVSfpR4SE9MDKzCSVbh9v8PkQeBin2T4f3MYLckVeOlufTpsl j6Bw2sVbIqOlURlQGloxFQOkxjI81hqL2P6qRVuzO6GVulHGHi53EPXYQ/TdUG3zVkCgn3UUI/J fGXS9q4hg4FpvFXoVp/GbH67agvhszAfc/2gAakXv2lpv4sqvYCS7LeeL6fPGkXw84A== X-Gm-Gg: AfdE7ckJYYSgQu2n5BqQGOKOYi4GFCBSbvHWoUxdiUE2Q+5iQSN51va3FLLexA57bHP NiHkz3zL67Chf2y4vcpc1Ha4T/Iq1JvHXs94a3QVFW+QxjfkGj+/b9KUlcr9ynXTZ1paIS5U0Ox Ap/TKZB1yGQ6bz70ejzbBgBrIeAmTWgYKaEDnot8wKb5w+1KtfQlxnxEaFfDmKkRCp7wi7p0Tlb A83Xhwv53LqyKVEGGAx4MJydj5OZN03jMBaMv5vBgObUjlgJVcsaXXv42gLqWgR4ajJF0P9lRxq o98DVHWp4sv+71XJLWK5IMQRj/Vr+HP+FSTBFsCHs3uwL1Lt+18qgGAta9vwu8s/FsPjCNzQBlN jRHTiV6r/d9QyW7HYI/lSjQdwORb3E1wAv5GEv0Sc+w3Mkzp7sSQAVoRquyjA9IJ+nD4SJu5aoh nXbsIqQiwbaMXuJRGaZ8A/Hud0d2p3+MEmc1697C6Reg== X-Received: by 2002:a17:90b:37cc:b0:381:6cf0:d5f5 with SMTP id 98e67ed59e1d1-38a2122afafmr5569047a91.5.1783661208641; Thu, 09 Jul 2026 22:26:48 -0700 (PDT) X-Received: by 2002:a17:90b:37cc:b0:381:6cf0:d5f5 with SMTP id 98e67ed59e1d1-38a2122afafmr5569029a91.5.1783661208044; Thu, 09 Jul 2026 22:26:48 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 01/10] build: add optional librpmi dependency Date: Fri, 10 Jul 2026 10:56:33 +0530 Message-ID: <1f2732b7220280efc1b5f69ae022b318dbbc3827.1783660209.git.subrahmanya.lingappa@qti.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Authority-Analysis: v=2.4 cv=FN8rAeos c=1 sm=1 tr=0 ts=6a508299 cx=c_pps a=RP+M6JBNLl+fLTcSJhASfg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=_6tmRKQHnRYSWcN6IbQA:9 a=iS9zxrgQBfv6-_F4QbHw:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX34t3AZQlWxTA hbQD2tWtK1xRMVOy0g4c4iYRFCStsOQ8S5fiqlQM7Ss92RFMOAEvZzRgWXB5JjJ8r8sIReK9R4V c3a89MMjD8ckhN3J/UKpcrEB5ZcNQ7E= X-Proofpoint-ORIG-GUID: XwXcyZAMabP-59oH6HVX67yyciKGKVFk X-Proofpoint-GUID: XwXcyZAMabP-59oH6HVX67yyciKGKVFk X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX9GPf7Z8btbUk HhG4aQQ/Zx876bKgivsRjkXyISknXqmIUuVDWXXbZfaBwMAnBmb9dA0J5GZwRB/RMmae7lZWSFU Iaf2BkaMrp1OkMX+/tUAY02eN5AEAf1970IK0skdXGsIaEARUqB2KWK0zq4z3k4A3547t5XcTih yInfA3yLEvP7arh77+4Nx4N/vp2fpWSYi6E5c2eyOJ3eJWQWN8T7A4GMdYqgSF9W0hS81pnei/j 1y9YNiMRr1uU8itChQVArW38st1OqmzxzKVzSAGTTaczsqX3BYJUs6Lcgwp5zHTpctmDS69Ngyd UhlKEwCD9DxxdYFaNXx9KboErUxwgTG55Yfxf/+QpvftgasTVYMaVYe0i9+ZRYF+pd/weir3Zpv uDhqjhCcxtl9TYaUyhsLqOYRs4T2ig7+o9w56EvNYFM7rGV1PoplAYdA+SXVaQ7NH6TDpfd81tm cm+XnMx8t4rL6mSBXbQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 suspectscore=0 phishscore=0 clxscore=1011 impostorscore=0 spamscore=0 priorityscore=1501 lowpriorityscore=0 adultscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.168.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686383647158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add a meson option and config probe for librpmi so RISC-V machines can opt into RPMI support when the library is available. Keep the dependency optional so default builds without librpmi continue to work. Signed-off-by: Subrahmanya Lingappa --- Kconfig.host | 3 +++ meson.build | 14 ++++++++++++++ meson_options.txt | 2 ++ scripts/meson-buildoptions.sh | 3 +++ 4 files changed, 22 insertions(+) diff --git a/Kconfig.host b/Kconfig.host index 933425c74b..6f98dadb2e 100644 --- a/Kconfig.host +++ b/Kconfig.host @@ -8,6 +8,9 @@ config LINUX config LIBCBOR bool =20 +config LIBRPMI + bool + config GNUTLS bool =20 diff --git a/meson.build b/meson.build index 19e123423b..103b4649b8 100644 --- a/meson.build +++ b/meson.build @@ -2005,6 +2005,17 @@ if lzo.found() and not cc.links(''' endif endif =20 +librpmi =3D not_found +if not get_option('librpmi').auto() or have_system + librpmi =3D dependency('librpmi', required: get_option('librpmi'), + method: 'pkg-config') + if librpmi.found() and not cc.has_header_symbol('librpmi.h', + 'rpmi_service_group_logg= ing_create', + dependencies: librpmi) + error('librpmi support requires the RPMI logging service group API') + endif +endif + numa =3D not_found if not get_option('numa').auto() or have_system or have_tools numa =3D cc.find_library('numa', has_headers: ['numa.h'], @@ -2427,6 +2438,7 @@ config_host_data.set('CONFIG_LINUX', host_os =3D=3D '= linux') config_host_data.set('CONFIG_POSIX', host_os !=3D 'windows') config_host_data.set('CONFIG_WIN32', host_os =3D=3D 'windows') config_host_data.set('CONFIG_LZO', lzo.found()) +config_host_data.set('CONFIG_LIBRPMI', librpmi.found()) config_host_data.set('CONFIG_MPATH', mpathpersist.found()) config_host_data.set('CONFIG_BLKIO', blkio.found()) if blkio.found() @@ -3258,6 +3270,7 @@ host_kconfig =3D \ (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=3Dy'] : []) + \ (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=3Dy'] : []= ) + \ (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=3Dy'] : []) + \ + (librpmi.found() ? ['CONFIG_LIBRPMI=3Dy'] : []) + \ (have_rust ? ['CONFIG_HAVE_RUST=3Dy'] : []) =20 ignored =3D [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR' ] @@ -4971,6 +4984,7 @@ summary_info +=3D {'TPM support': have_tpm} summary_info +=3D {'IGVM support': igvm} summary_info +=3D {'libssh support': libssh} summary_info +=3D {'lzo support': lzo} +summary_info +=3D {'librpmi support': librpmi} summary_info +=3D {'snappy support': snappy} summary_info +=3D {'bzip2 support': libbzip2} summary_info +=3D {'lzfse support': liblzfse} diff --git a/meson_options.txt b/meson_options.txt index a07cb47d35..9f773a7886 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -204,6 +204,8 @@ option('lzfse', type : 'feature', value : 'auto', description: 'lzfse support for DMG images') option('lzo', type : 'feature', value : 'auto', description: 'lzo compression support') +option('librpmi', type : 'feature', value : 'auto', + description: 'RISC-V RPMI support') option('pvg', type: 'feature', value: 'auto', description: 'macOS paravirtualized graphics support') option('rbd', type : 'feature', value : 'auto', diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index c003985047..e8a20068e7 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -140,6 +140,7 @@ meson_options_help() { printf "%s\n" ' libkeyutils Linux keyutils support' printf "%s\n" ' libnfs libnfs block device driver' printf "%s\n" ' libpmem libpmem support' + printf "%s\n" ' librpmi RISC-V RPMI support' printf "%s\n" ' libssh ssh block device support' printf "%s\n" ' libudev Use libudev to enumerate host devices' printf "%s\n" ' libusb libusb support for USB passthrough' @@ -376,6 +377,8 @@ _meson_option_parse() { --disable-libnfs) printf "%s" -Dlibnfs=3Ddisabled ;; --enable-libpmem) printf "%s" -Dlibpmem=3Denabled ;; --disable-libpmem) printf "%s" -Dlibpmem=3Ddisabled ;; + --enable-librpmi) printf "%s" -Dlibrpmi=3Denabled ;; + --disable-librpmi) printf "%s" -Dlibrpmi=3Ddisabled ;; --enable-libssh) printf "%s" -Dlibssh=3Denabled ;; --disable-libssh) printf "%s" -Dlibssh=3Ddisabled ;; --enable-libudev) printf "%s" -Dlibudev=3Denabled ;; --=20 2.43.0 From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686124; cv=none; d=zohomail.com; s=zohoarc; b=LhDDctIdpuEInp4iNchjkvswiDzfZoQzmHJxPUD/x8IbPwjgwIKue1xkAZPLeLeXj+OsxPhyN5swsAAl0mENopJILWmNNCqCzbNFNaJIRFQ57UTloq8NwDDTeT/FGrY8cI4naaKuJGHEuA6h7nTvMUJYswd+C/ct+j/UM4Qlmac= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686124; h=Content-Transfer-Encoding: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:Cc; bh=KjSwBdcJQe77H5Wc0ouUcojXMswzRh4Qzr4RxAeHtSc=; b=Ij/xJc5XleS2dMWlkkTAZBZ+h9S5AkgS1W08f+Z8Daf+eZO4HhaJ55wPCbLP6vvmiYQycZqDlmJZD2csNDn/HOq1dbMJaBuEaLChuGgp58BDEow9rV0AviNMC0E+F01MYddyjH5fiKZSAozE/W8yUR9jHhCg7rItSTt+JqhO+Gg= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783686124248349.8112029276135; Fri, 10 Jul 2026 05:22:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEw-0006lW-Gh; Fri, 10 Jul 2026 08:21:58 -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 1wi3lI-0000N7-Jx for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:26:57 -0400 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lF-000498-Be for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:26:56 -0400 Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3n59S3802274 for ; Fri, 10 Jul 2026 05:26:52 GMT Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4facqpkdw8-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:26:51 +0000 (GMT) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2c6a72d672aso1303645ad.1 for ; Thu, 09 Jul 2026 22:26:51 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.26.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:26:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=KjSwBdcJQe7 7H5Wc0ouUcojXMswzRh4Qzr4RxAeHtSc=; b=YhB2roeA9yGjsyFUwd4oBJ3wKLS LjXSGBc22oxC99tje+gzBD16OO/yxyx6MX3bt7NKnkDNNDRVQg5x02edBg6kqVjK /r7bxzduPQGJB6zMByE3hGuo7UMPEuP716voKY1Bw+lva31Icg6aajjAif3q6w9A tuL9xCWqOuWY8GpeNi1WW98uVHumZVoRmnhZKNNFJiYmLrEl2sSjk+t4aZ3CwR6W JnCDcbegsPPflyXdddH6+8Mnc+69wUnXe4Zssj/TYmM3HtxkyfdGl/7eHRRzf1yV H6B5sPMIwO3FXe0aSKCL0GmWj+NZzB7s+HiaqD/HyfYmquzEVoNgZyGDAKA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661211; x=1784266011; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=KjSwBdcJQe77H5Wc0ouUcojXMswzRh4Qzr4RxAeHtSc=; b=YB+7eUVw184m3MyDHPO31+cPb4OojxDgoL/UB08LAuEgLh3iF6LCN1G0GAID/pCxMt FIC8K1uXryhLkZTsLWRrHGA1ImU7LVXx5qGsI7Yo4cxTMBjFADqerqi8gVsY247iC1Iv yVBod9PMdWo9lt4B0fu1s+3obm+MIjus/ieZJmFCNgieSqF7m9lcJM+4Fcv5ztCpwjQI vIcwZ3XWTDXzho38HbooJhYv0x0ghyNOt7V5hkLb2dgcdqHCgiZPIcixi916O7O39+PT peb0eFyJ1+oP/A5sWGfPD3m1EyQlQU6TkHIebY1z/z8EcOrfB+d6U5LAX8fPwH9fq2RC oJvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661211; x=1784266011; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=KjSwBdcJQe77H5Wc0ouUcojXMswzRh4Qzr4RxAeHtSc=; b=aER/vSVjgeODHePZVbXTrGMD2jQMShiVSmbM1wFoYtgxYQlU+Ojcgenr6rnGOQPcd+ dzTBD9uDI2xLX17+ZxGAeK8Oy40WeVRsth6Z5nYFvd+k1/mH6WM06aoV0nEpCUHomOTl 8iwqcDqu6YOqxo2vWWyi370Z2wcuS5zRiY9yDlILmKMA6p7Y0STe4L/C8DrQmmYPkv5U SECAfiYblazNLnpi1IN4acGDOIuKnwB+2KhsPSg7RnqWEhih5yQeWvaWcMlUd4NaLd0t cvoLrD1Uvdat33mqRjL/j8g5EYtNswQt173VrZFQBTO4fm7gXSe4/3cPWiLWoq8T6Ksx Jesw== X-Gm-Message-State: AOJu0YziWWQsIrGPFgcHetKtZrsq8wjQyv7+zEDUHnzZwIrUhk+R9FxY nwwyfyb6E35mHpDhhvekENut1P/D976M5YCvz+uY1knekCJsvVpJeopKYm6K7n84kW8IOxjgGMQ /2c7KeBSOEna5xSls/hOh0DQJoirTrBvIKGjoHnm7eloDpsrF2L0FESeuPTPifFpfMg== X-Gm-Gg: AfdE7cleqIdx0V0TwpUD/5pnNhcVUnjX4A0qFTsnPMoZfT9IktzQEbmzIcU/HT7UmUx 7gjJvQRgEyiK/CLtt8cESuIYPIx/sBYAnz/ug/PIwvtQO1MYtf2kT1LEYbkP4csUOC5/L1FdjFJ T9+Ss+9A3rM0ethYP3a9/NRILLtNEMpqB0BlxF7gA52LzlKHIyS+wdlBl9+UPxvp4++MN7DmzdT zS67c4B2CymcfBYRGDF83skrLHqLfKYTfsU/hnu0OSw8CXDfS6lNhBvMEcn/8Ukqacg4+iy+GPU ubLpHlH9bl4CUSCVlbnzfq91dTFtBMJy+GZmgFDB7yV64n2s9VrGV/zfPnxO2wh+C8HdXE3pZXB dJDcqjNNx1Ms9CLiQM9Ah1+d/mVV5Y4yT5D4YVZ/LFv91mq5ScCiiG4J/Fw96rTc9yAmSj80P2C RJp3HucB11Pgs9t672b1GWmEFaCqHxKoO3dwq6CP2HNw== X-Received: by 2002:a17:902:e5d0:b0:2ca:ecf6:9115 with SMTP id d9443c01a7336-2ccfebc7514mr51733495ad.2.1783661210521; Thu, 09 Jul 2026 22:26:50 -0700 (PDT) X-Received: by 2002:a17:902:e5d0:b0:2ca:ecf6:9115 with SMTP id d9443c01a7336-2ccfebc7514mr51733325ad.2.1783661209709; Thu, 09 Jul 2026 22:26:49 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 02/10] hw/misc: add RISC-V RPMI transport and Base support Date: Fri, 10 Jul 2026 10:56:34 +0530 Message-ID: <37eeb3754b10d5310c62169e72211c65114e21bc.1783660209.git.subrahmanya.lingappa@qti.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX7vmqVJ3Ci9H9 uj63bAqU6ABJ/l3QOpmpWuwQslaYuUZRb2INKn5OvhsPCULNy/geLIQgHFezz3/js6/5VsQcUeT h4GPnz7QfIhcg3Cb5GIGNUuH1Gv7xe/zCuRvxMCrw9uraIi9pYI8NQraBbWPOeaS8qB7HAPXl60 rhZ83jwtMFzLDNVGKr+wjAXLsm0gfT9t0xvHPO58DCJn5tv2pa17qYil7jjVbBv4KDt2+BSyDye /u08rLh5aEVMi14+Jp7eE52ajJRcOPHsUqkLtJ2Eky46QgCR/o8Ncm6rmZKpqcahSjqqAbUiqGc 7Go9JqJd5b3rA/rAyca6Sfcs5ykzkarrsoaffi1y/G1uK+dptsl+vMwKJURD/XbgYn7B7jlkaVz Wus3RDEL/FNrIGX+x+cayEseaB3JV60fMj3UlK5IQhqw85MCd616E1lM1loBExFLiwpV623g0gC Ss0RsVvmpPXztlho5Dw== X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfXxsxOdSgPe2Nn SkZq3Gix5fdPyf+Bq2CDTmpboy56zIn/8VZjwl7bnJ0JSsvXyRlM0/FKP/etwT3kDBqcDTzevCS 0utoqVGR1xEuRf8Vl+qQ3sofNfqUSVQ= X-Proofpoint-GUID: H3bOosfEBtlCCxb3gbwhPxiIXiYhnsg7 X-Proofpoint-ORIG-GUID: H3bOosfEBtlCCxb3gbwhPxiIXiYhnsg7 X-Authority-Analysis: v=2.4 cv=GJ441ONK c=1 sm=1 tr=0 ts=6a50829b cx=c_pps a=cmESyDAEBpBGqyK7t0alAg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=V1jnuoLLAAAA:20 a=NEAV23lmAAAA:8 a=EUspDBNiAAAA:8 a=nbwKsA5dBi2aoCUYr7oA:9 a=1OuFwYUASf3TG4hYMiVC:22 a=bA3UWDv6hWIuX7UZL3qL:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 priorityscore=1501 clxscore=1011 suspectscore=0 spamscore=0 phishscore=0 adultscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.180.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0b-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686126950158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa RPMI (RISC-V Platform Management Interface) is the RISC-V non-ISA platform management specification. It defines a shared-memory transport, message protocol, and service groups for platform management. Add the QEMU transport backend and Base service plumbing for virt using librpmi. This implementation targets the RISC-V Platform Management Interface (RPMI) Specification v1.0 Ratified: https://github.com/riscv-non-isa/riscv-rpmi/releases/download/v1.0/riscv-rp= mi.pdf The librpmi backend is maintained at: https://github.com/riscv-software-src/librpmi Signed-off-by: Subrahmanya Lingappa --- MAINTAINERS | 2 + hw/misc/Kconfig | 4 + hw/misc/meson.build | 3 + hw/misc/riscv_rpmi.c | 476 ++++++++++++++++++++++++++++++++++ hw/misc/riscv_rpmi_internal.h | 24 ++ include/hw/misc/riscv_rpmi.h | 90 +++++++ 6 files changed, 599 insertions(+) create mode 100644 hw/misc/riscv_rpmi.c create mode 100644 hw/misc/riscv_rpmi_internal.h create mode 100644 include/hw/misc/riscv_rpmi.h diff --git a/MAINTAINERS b/MAINTAINERS index 93df53d87f..8e91a31757 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -359,6 +359,8 @@ F: target/riscv/ F: hw/char/riscv_htif.c F: hw/riscv/ F: hw/intc/riscv* +F: hw/misc/riscv_rpmi* +F: include/hw/misc/riscv_rpmi.h F: include/hw/char/riscv_htif.h F: include/hw/riscv/ F: common-user/host/riscv* diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 1543ee6653..998944c342 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -258,3 +258,7 @@ config XLNX_ZYNQ_DDRC bool =20 source macio/Kconfig + +config RISCV_RPMI + bool + depends on LIBRPMI diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 23265f6035..e7c2ebe28f 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -168,3 +168,6 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('= sbsa_ec.c')) =20 # HPPA devices system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c')) +system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files( + 'riscv_rpmi.c', +), librpmi]) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c new file mode 100644 index 0000000000..c4b115b659 --- /dev/null +++ b/hw/misc/riscv_rpmi.c @@ -0,0 +1,476 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI transport device. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "exec/cpu-common.h" +#include "hw/core/qdev-properties.h" +#include "hw/misc/riscv_rpmi.h" +#include "hw/misc/riscv_rpmi_internal.h" +#include "migration/vmstate.h" +#include "system/address-spaces.h" +#include "system/runstate.h" +#include "librpmi.h" +#include "librpmi_env.h" + +void *rpmi_env_zalloc(rpmi_size_t size) +{ + return g_malloc0(size); +} + +void rpmi_env_free(void *ptr) +{ + g_free(ptr); +} + +void rpmi_env_writel(rpmi_uint64_t addr, rpmi_uint32_t val) +{ + cpu_physical_memory_write(addr, &val, sizeof(val)); +} + +static bool riscv_rpmi_addr_in_range(uint64_t addr, uint32_t len, + uint64_t base, uint64_t size) +{ + return len && size >=3D len && addr >=3D base && addr - base <=3D size= - len; +} + +static enum rpmi_error shmem_qemu_read(void *priv, rpmi_uint64_t addr, + void *buf, rpmi_uint32_t len) +{ + RiscvRpmiState *s =3D RISCV_RPMI(priv); + + if (!riscv_rpmi_addr_in_range(addr, len, s->shmem_base, s->shmem_size)= || + addr !=3D (rpmi_uint64_t)addr || len !=3D (rpmi_uint32_t)len) { + return RPMI_ERR_INVALID_ADDR; + } + + cpu_physical_memory_read(addr, buf, len); + return RPMI_SUCCESS; +} + +static enum rpmi_error shmem_qemu_write(void *priv, rpmi_uint64_t addr, + const void *buf, rpmi_uint32_t len) +{ + RiscvRpmiState *s =3D RISCV_RPMI(priv); + + if (!riscv_rpmi_addr_in_range(addr, len, s->shmem_base, s->shmem_size)= || + addr !=3D (rpmi_uint64_t)addr || len !=3D (rpmi_uint32_t)len) { + return RPMI_ERR_INVALID_ADDR; + } + + cpu_physical_memory_write(addr, buf, len); + return RPMI_SUCCESS; +} + +static enum rpmi_error shmem_qemu_fill(void *priv, rpmi_uint64_t addr, + char ch, rpmi_uint32_t len) +{ + while (len--) { + shmem_qemu_write(priv, addr++, &ch, sizeof(ch)); + } + + return RPMI_SUCCESS; +} + +const struct rpmi_shmem_platform_ops rpmi_shmem_qemu_ops =3D { + .read =3D shmem_qemu_read, + .write =3D shmem_qemu_write, + .fill =3D shmem_qemu_fill, +}; + +static uint64_t riscv_rpmi_read(void *opaque, hwaddr offset, unsigned int = size) +{ + RiscvRpmiState *s =3D opaque; + + if (offset !=3D 0 || size !=3D 4) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid read at 0x%" HWADDR_PRIx " size %u\n", + __func__, offset, size); + return 0; + } + + return s->doorbell; +} + +static bool riscv_rpmi_transport_indices_valid(RiscvRpmiState *s); + +static void riscv_rpmi_write(void *opaque, hwaddr offset, uint64_t value, + unsigned int size) +{ + RiscvRpmiState *s =3D opaque; + + if (offset !=3D 0 || size !=3D 4) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid write at 0x%" HWADDR_PRIx " size %u\n", + __func__, offset, size); + return; + } + + s->doorbell =3D value; + + if (value =3D=3D 1) { + if (s->context && riscv_rpmi_transport_indices_valid(s)) { + rpmi_context_process_a2p_request(s->context); + rpmi_context_process_all_events(s->context); + } + s->doorbell =3D 0; + } +} + +static const MemoryRegionOps riscv_rpmi_ops =3D { + .read =3D riscv_rpmi_read, + .write =3D riscv_rpmi_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, +}; + +static bool riscv_rpmi_queue_indices_valid(RiscvRpmiState *s, + uint64_t queue_base, + uint32_t queue_size) +{ + uint8_t *shmem =3D memory_region_get_ram_ptr(&s->shmem); + uint32_t data_slots =3D queue_size / RPMI_QUEUE_SLOT_SIZE - 2; + uint32_t head; + uint32_t tail; + + head =3D ldl_le_p(shmem + queue_base); + tail =3D ldl_le_p(shmem + queue_base + RPMI_QUEUE_SLOT_SIZE); + if (head >=3D data_slots || tail >=3D data_slots) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid queue indices head %u tail %u slots %u\= n", + __func__, head, tail, data_slots); + return false; + } + + return true; +} + +static bool riscv_rpmi_transport_indices_valid(RiscvRpmiState *s) +{ + if (!s->has_shmem || !s->a2p_req_size) { + return false; + } + + if (!riscv_rpmi_queue_indices_valid(s, 0, s->a2p_req_size)) { + return false; + } + + return riscv_rpmi_queue_indices_valid(s, s->a2p_req_size, + s->a2p_req_size); +} + +static void riscv_rpmi_configure_base(RiscvRpmiState *s, + const RiscvRpmiConfig *cfg) +{ + s->platform_info =3D g_strdup(cfg->platform_info); + s->services =3D cfg->services; + s->service_count =3D cfg->service_count; + + if (cfg->hart_count) { + s->hart_count =3D cfg->hart_count; + if (cfg->hart_ids) { + s->hart_ids =3D g_memdup2(cfg->hart_ids, + cfg->hart_count * sizeof(*cfg->hart_id= s)); + } + } +} + +static void riscv_rpmi_init(Object *obj) +{ + RiscvRpmiState *s =3D RISCV_RPMI(obj); + + memory_region_init_io(&s->mmio, obj, &riscv_rpmi_ops, s, + TYPE_RISCV_RPMI, RPMI_DBREG_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); +} + +static void riscv_rpmi_reset(DeviceState *dev) +{ + RiscvRpmiState *s =3D RISCV_RPMI(dev); + + s->doorbell =3D 0; + + if (s->has_shmem) { + memset(memory_region_get_ram_ptr(&s->shmem), 0, s->shmem_size); + memory_region_set_dirty(&s->shmem, 0, s->shmem_size); + } + +} + +static void riscv_rpmi_cleanup(RiscvRpmiState *s) +{ + + + if (s->context) { + rpmi_context_destroy(s->context); + s->context =3D NULL; + } + + if (s->transport) { + rpmi_transport_shmem_destroy(s->transport); + s->transport =3D NULL; + } + + if (s->rpmi_shmem) { + rpmi_shmem_destroy(s->rpmi_shmem); + s->rpmi_shmem =3D NULL; + } + + if (s->has_shmem) { + memory_region_del_subregion(get_system_memory(), &s->shmem); + s->has_shmem =3D false; + } +} + +bool riscv_rpmi_service_enabled(RiscvRpmiState *s, RiscvRpmiServiceKind ki= nd) +{ + uint32_t i; + + for (i =3D 0; i < s->service_count; i++) { + if (s->services[i].kind =3D=3D kind) { + return true; + } + } + + return false; +} + +static bool riscv_rpmi_validate_config(RiscvRpmiState *s, Error **errp) +{ + uint64_t queue_bytes; + + if (!s->shmem_size) { + error_setg(errp, "RPMI shared memory size must be non-zero"); + return false; + } + + if (s->shmem_base & (RPMI_QUEUE_SLOT_SIZE - 1)) { + error_setg(errp, "RPMI shared memory base must be %u-byte aligned", + RPMI_QUEUE_SLOT_SIZE); + return false; + } + + if (!s->a2p_req_size) { + error_setg(errp, "RPMI A2P request queue size must be non-zero"); + return false; + } + + if (!s->hart_count || !s->hart_ids) { + error_setg(errp, "RPMI transport requires hart IDs"); + return false; + } + + for (uint32_t i =3D 0; i < s->hart_count; i++) { + for (uint32_t j =3D i + 1; j < s->hart_count; j++) { + if (s->hart_ids[i] =3D=3D s->hart_ids[j]) { + error_setg(errp, "RPMI hart ID %u is duplicated", + s->hart_ids[i]); + return false; + } + } + } + + if (s->service_count && !s->services) { + error_setg(errp, "RPMI service count requires service descriptors"= ); + return false; + } + + if (s->a2p_req_size % RPMI_QUEUE_SLOT_SIZE) { + error_setg(errp, + "RPMI A2P request queue size must be a multiple of %u", + RPMI_QUEUE_SLOT_SIZE); + return false; + } + + if (s->p2a_req_size % RPMI_QUEUE_SLOT_SIZE) { + error_setg(errp, + "RPMI P2A request queue size must be a multiple of %u", + RPMI_QUEUE_SLOT_SIZE); + return false; + } + + queue_bytes =3D 2 * (uint64_t)s->a2p_req_size + + 2 * (uint64_t)s->p2a_req_size; + if (queue_bytes > s->shmem_size) { + error_setg(errp, + "RPMI shared memory size 0x%" PRIx64 + " is too small for queues 0x%" PRIx64, + s->shmem_size, queue_bytes); + return false; + } + + return true; +} + +static bool riscv_rpmi_add_service_group(RiscvRpmiState *s, + const RiscvRpmiServiceConfig *ser= vice, + Error **errp) +{ + switch (service->kind) { + default: + error_setg(errp, "unsupported RPMI service kind %d", service->kind= ); + return false; + } +} + +static bool riscv_rpmi_init_services(RiscvRpmiState *s, Error **errp) +{ + uint32_t i; + + for (i =3D 0; i < s->service_count; i++) { + if (!riscv_rpmi_add_service_group(s, &s->services[i], errp)) { + return false; + } + } + + return true; +} + +static bool riscv_rpmi_init_context(RiscvRpmiState *s, Error **errp) +{ + const char *platform_info =3D s->platform_info ?: RPMI_PLAT_INFO; + + s->rpmi_shmem =3D rpmi_shmem_create("rpmi-shmem", s->shmem_base, + s->shmem_size, + &rpmi_shmem_qemu_ops, s); + if (!s->rpmi_shmem) { + error_setg(errp, "failed to create RPMI shared memory backend"); + return false; + } + + s->transport =3D rpmi_transport_shmem_create("rpmi-shmem-transport", + RPMI_QUEUE_SLOT_SIZE, + s->a2p_req_size, + s->p2a_req_size, + s->rpmi_shmem); + if (!s->transport) { + error_setg(errp, "failed to create RPMI shared memory transport"); + return false; + } + + s->context =3D rpmi_context_create("rpmi-virt", s->transport, + RPMI_SRVGRP_ID_MAX_COUNT, + RPMI_PRIVILEGE_M_MODE, + strlen(platform_info) + 1, + platform_info); + if (!s->context) { + error_setg(errp, "failed to create RPMI context"); + return false; + } + + return riscv_rpmi_init_services(s, errp); +} + +static void riscv_rpmi_realize(DeviceState *dev, Error **errp) +{ + RiscvRpmiState *s =3D RISCV_RPMI(dev); + g_autofree char *name =3D NULL; + + if (!riscv_rpmi_validate_config(s, errp)) { + return; + } + + name =3D g_strdup_printf("rpmi-shmem@%" PRIx64, s->shmem_base); + if (!memory_region_init_ram(&s->shmem, OBJECT(dev), name, s->shmem_siz= e, + errp)) { + return; + } + + memory_region_add_subregion(get_system_memory(), s->shmem_base, &s->sh= mem); + s->has_shmem =3D true; + + if (!riscv_rpmi_init_context(s, errp)) { + riscv_rpmi_cleanup(s); + } +} + +static void riscv_rpmi_unrealize(DeviceState *dev) +{ + riscv_rpmi_cleanup(RISCV_RPMI(dev)); +} + +static const VMStateDescription riscv_rpmi_vmstate =3D { + .name =3D TYPE_RISCV_RPMI, + .unmigratable =3D 1, +}; + +static const Property riscv_rpmi_properties[] =3D { + DEFINE_PROP_UINT64("shmem-base", RiscvRpmiState, shmem_base, 0), + DEFINE_PROP_UINT64("shmem-size", RiscvRpmiState, shmem_size, 0), + DEFINE_PROP_UINT32("a2p-req-size", RiscvRpmiState, a2p_req_size, 0), + DEFINE_PROP_UINT32("p2a-req-size", RiscvRpmiState, p2a_req_size, 0), +}; + +static void riscv_rpmi_finalize(Object *obj) +{ + RiscvRpmiState *s =3D RISCV_RPMI(obj); + + g_free(s->platform_info); + g_free(s->hart_ids); +} + +static void riscv_rpmi_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D riscv_rpmi_realize; + dc->unrealize =3D riscv_rpmi_unrealize; + dc->vmsd =3D &riscv_rpmi_vmstate; + device_class_set_legacy_reset(dc, riscv_rpmi_reset); + device_class_set_props(dc, riscv_rpmi_properties); +} + +static const TypeInfo riscv_rpmi_info =3D { + .name =3D TYPE_RISCV_RPMI, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(RiscvRpmiState), + .instance_init =3D riscv_rpmi_init, + .instance_finalize =3D riscv_rpmi_finalize, + .class_init =3D riscv_rpmi_class_init, +}; + +static void riscv_rpmi_register_types(void) +{ + type_register_static(&riscv_rpmi_info); +} + +type_init(riscv_rpmi_register_types) + +DeviceState *riscv_rpmi_create(const RiscvRpmiConfig *cfg, Error **errp) +{ + DeviceState *dev; + RiscvRpmiState *s; + + if (!cfg) { + error_setg(errp, "missing RPMI configuration"); + return NULL; + } + + dev =3D qdev_new(TYPE_RISCV_RPMI); + qdev_prop_set_uint64(dev, "shmem-base", cfg->shmem_base); + qdev_prop_set_uint64(dev, "shmem-size", cfg->shmem_size); + qdev_prop_set_uint32(dev, "a2p-req-size", cfg->a2p_req_size); + qdev_prop_set_uint32(dev, "p2a-req-size", cfg->p2a_req_size); + + s =3D RISCV_RPMI(dev); + riscv_rpmi_configure_base(s, cfg); + + if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp)) { + return NULL; + } + + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, cfg->doorbell_base); + return dev; +} diff --git a/hw/misc/riscv_rpmi_internal.h b/hw/misc/riscv_rpmi_internal.h new file mode 100644 index 0000000000..447c0acb55 --- /dev/null +++ b/hw/misc/riscv_rpmi_internal.h @@ -0,0 +1,24 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI internal service helpers. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#ifndef HW_MISC_RISCV_RPMI_INTERNAL_H +#define HW_MISC_RISCV_RPMI_INTERNAL_H + +#include "qapi/error.h" +#include "hw/misc/riscv_rpmi.h" +#include "librpmi.h" + +#define RPMI_PLAT_INFO "QEMU RISC-V RPMI" + +extern const struct rpmi_shmem_platform_ops rpmi_shmem_qemu_ops; +bool riscv_rpmi_service_enabled(RiscvRpmiState *s, + RiscvRpmiServiceKind kind); + +#endif diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h new file mode 100644 index 0000000000..cb2658e57e --- /dev/null +++ b/include/hw/misc/riscv_rpmi.h @@ -0,0 +1,90 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI definitions shared by RPMI transport and FDT helpers. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#ifndef HW_MISC_RISCV_RPMI_H +#define HW_MISC_RISCV_RPMI_H + +#include "exec/hwaddr.h" +#include "hw/core/sysbus.h" +#include "qom/object.h" +#include "qemu/notify.h" + +#define RPMI_QUEUE_SLOT_SIZE 64 +#define RPMI_DBREG_SIZE 0x1000 + +#define RPMI_ALL_NUM_QUEUES 4 +#define RPMI_A2P_NUM_QUEUES 2 +#define RPMI_ALL_NUM_REGS (RPMI_ALL_NUM_QUEUES + 1) +#define RPMI_A2P_NUM_REGS (RPMI_A2P_NUM_QUEUES + 1) + +#define VIRT_RPMI_A2P_REQ_SIZE (16 * RPMI_QUEUE_SLOT_SIZE) +#define VIRT_RPMI_P2A_REQ_SIZE 0 + + +#define TYPE_RISCV_RPMI "riscv-rpmi" +OBJECT_DECLARE_SIMPLE_TYPE(RiscvRpmiState, RISCV_RPMI) + +struct rpmi_context; +struct rpmi_service_group; +struct rpmi_shmem; +struct rpmi_transport; + +typedef enum RiscvRpmiServiceKind { + RISCV_RPMI_SERVICE_INVALID =3D 0, +} RiscvRpmiServiceKind; + +typedef struct RiscvRpmiServiceConfig { + RiscvRpmiServiceKind kind; + const char *node_name; + const char *compatible; + uint32_t service_group; + bool has_mpxy_channel; + uint32_t mpxy_channel; +} RiscvRpmiServiceConfig; + +typedef struct RiscvRpmiConfig { + hwaddr doorbell_base; + hwaddr shmem_base; + hwaddr shmem_size; + uint32_t a2p_req_size; + uint32_t p2a_req_size; + const char *platform_info; + + const uint32_t *hart_ids; + uint32_t hart_count; + const RiscvRpmiServiceConfig *services; + uint32_t service_count; +} RiscvRpmiConfig; + +struct RiscvRpmiState { + SysBusDevice parent_obj; + + MemoryRegion mmio; + MemoryRegion shmem; + uint64_t shmem_base; + uint64_t shmem_size; + uint32_t a2p_req_size; + uint32_t p2a_req_size; + char *platform_info; + + uint32_t *hart_ids; + uint32_t hart_count; + const RiscvRpmiServiceConfig *services; + uint32_t service_count; + uint32_t doorbell; + struct rpmi_shmem *rpmi_shmem; + struct rpmi_transport *transport; + struct rpmi_context *context; + bool has_shmem; +}; + +DeviceState *riscv_rpmi_create(const RiscvRpmiConfig *cfg, Error **errp); + +#endif --=20 2.43.0 From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686192; cv=none; d=zohomail.com; s=zohoarc; b=W4NWEiP9cVEkbtAVHb0cfD7z9oq8othdTArwI3SLbdRO57HRsjBP1FTfo3UxPuAB5AYKdPnWwcIyr5ykXCd6B0fhHvd186RIeGYbEKL/7ZvmjvAj6GjWvqSLavwfC+q6CsPKHUkiXvvWxGDM8AalsSK8HRT3nfSUJiT2dgpzaO0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686192; h=Content-Transfer-Encoding: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:Cc; bh=rwYttTklyBmb0/sgxTdmL/5MMEOv8D6OvnpWrhkNgjY=; b=e+MmfIyfR56KQEhjRszMP842T9BXADEAGxch/avh1SD68MksCwAvSMMxUHZDJl/OxkuA/oD4PnXqT9NrXwXGkzMUL8asWaReA/KvQBE+atgTcXX0+yGG8RuZVu9J64Qi+igWyj+AIIpMcP3feeZLo2pEyn9u1Iu+wHcxEad3M3E= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783686192459323.9895927381367; Fri, 10 Jul 2026 05:23:12 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEl-0006Wo-75; Fri, 10 Jul 2026 08:21:47 -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 1wi3lI-0000N6-CZ for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:26:57 -0400 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lG-00049E-Ge for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:26:56 -0400 Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3nTeK3848810 for ; Fri, 10 Jul 2026 05:26:53 GMT Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4faeestu8x-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:26:52 +0000 (GMT) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2ccbdbeffb9so1678505ad.3 for ; Thu, 09 Jul 2026 22:26:52 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.26.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:26:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=rwYttTklyBm b0/sgxTdmL/5MMEOv8D6OvnpWrhkNgjY=; b=CBKwbpIW9sxcFFxBXLAUfRa+9PZ Sdt5B+pR03qOBa4nz5r9nze3+B2qjbf15HB8fO8dh6I/qvHSdc9RIPO3fxEAt36+ Cak55PNZ2LIQkbKYgYjjv6KZXcXryxy+4KC4AFvQkyZINRdKSD/00gXMrEWgFaoy SlGvGKgAr/Xk0ij8mctJIArGUvXXnNg+3WPOjrZu0mHMYes1tkGipqINUVvibNrI fRov7EolNa9b7J2RRx6WaGkOZFsXE15i7jyOiBcCdK3WrO2nuFZKBKJSozJd0ssM KnTe2MjoT1PZ+ZhnlxtRU+ETRD9LlGNWZxhfZByRdV3JRaUz2pxk9gT6CnA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661212; x=1784266012; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=rwYttTklyBmb0/sgxTdmL/5MMEOv8D6OvnpWrhkNgjY=; b=P1Ya1UqYHTfz/quBvSkwIW707r64GE6Ro50baaLz7hyB/5p2Nx4WuWLnZSoGS1E0/G ecVzeukz2KB5+/PxQ5Voxh+q2lQ5J79TQp6d/OMTdB/glE9Hk1CRp3edjjrU9CSCFUQq kRd0cH+PQuepw9jqHCZAxYzzP/DbOgCp0adRd+b2WFxQ1jD1Q/cIoYGmPNoRKbRDJ2l6 AX6aeoQmB01u5HcjcAAD5A66RYQ7jKqcGGuKM85hOx0i+XNaoF1WOYEoCEAjzsIM2tLk UMHMGoBogZtDF73970yAfXY+G3G87r5Yeh0iQCo13orIJk244xoKUcvjpfcYX1+RGV8I lcYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661212; x=1784266012; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=rwYttTklyBmb0/sgxTdmL/5MMEOv8D6OvnpWrhkNgjY=; b=CshYZzgJ7beQ5552jpHNHfxI2B/5FhtgQrhu9+6MCuyV7z4IC/9DQcwWcjKUZfr5Lq +/ZLRrX2g016ofrlY0p+ibICQTFcCfZ1EWITnk2FGYfg0cHLw5AG+4l56xEHiqXyxUtS aCeDhV9rXcuADUPJ9zqd0a8/ohe4PWs6q6rTWhwxtmhohDxYtACQm4yNjHUTTZ8c2RhH FkO4PPGiK0ftz7l9x9XJj01r9i2eb8+gK078+8fLfxlGgMuOK2bs7UrT8cBkRp2jMaJx Glo1Fqabs1mjmzOGCWTYNXhs7UZndegseXZ99qqBZE3sYPweqCjImR8Um/Sm1DIdx60n 2ZgQ== X-Gm-Message-State: AOJu0YxSqtr6FH9rKAtz0QzDGBhrmOhBDkOxchvC0RvuBLj/Z+oyIHIL QJrPZVqvJtDd9rdAb9B7HVkIhXyAt7nMOHftX3Ss148i2TmemkjlSWrSWhgDb8hZBRkkTHba7O0 H+m5ENtp8cwhfS11CU5m0iAknC2jQZo3sEdcnHV75svCRav9tf9nnm5VDBgFI3XlYAA== X-Gm-Gg: AfdE7ckCcE9nnX4+hxzJ14TAJfW8r7Gi3+fsohL1dAgi2+OtnNvPN/+f6WwFp2ZZjv4 0glDwXw/t8ReGLhO4iWPjh46KZlPFOLMuGv5uTtvmBTuPebPnIwkcXp3ghcGbUFrriWzs2B13iv ZAP6FdAf/QM+4E0OeQvxRVasYpvW83YBzR+BhjOD2gOVZGFcppclJOe5JuteJ0+PCqolubbpg6G uurVRi+BW43mhVqHiGjuxWKrfpxWX1Fl5c1B9WDIyDmY9+MyiMRooBJXZ4cKAkV1spthCjNmUOu rSs5Icwl8p7k+DtwSvQ3DShfNQeqfNptZwupyrIZZz6d7zheY9TsVNtrBOGa+pHeGV4Elg9csLV /302kFrfv/nk5uVwvPIy7wVGhiEGy/ccZnmboRPdqygIBnq7RTpeOxxaTMU2v2ld0s1dHvRwh4P oQv6pkXZdqK5wEgT1NtM7aLSf/9d20LRBQuft0tKoTzQ== X-Received: by 2002:a17:902:ce85:b0:2c7:ef84:c58e with SMTP id d9443c01a7336-2ccfebc6ddbmr56537385ad.1.1783661211901; Thu, 09 Jul 2026 22:26:51 -0700 (PDT) X-Received: by 2002:a17:902:ce85:b0:2c7:ef84:c58e with SMTP id d9443c01a7336-2ccfebc6ddbmr56537105ad.1.1783661211235; Thu, 09 Jul 2026 22:26:51 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 03/10] hw/riscv: add RPMI FDT helpers Date: Fri, 10 Jul 2026 10:56:35 +0530 Message-ID: <0028254f03ea55c578dc6e79b7a8d9cbabaa201d.1783660209.git.subrahmanya.lingappa@qti.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: u0rvnVlHe-5qlzYGjZ227vIN-dLtgJq5 X-Authority-Analysis: v=2.4 cv=bbpbluPB c=1 sm=1 tr=0 ts=6a50829c cx=c_pps a=cmESyDAEBpBGqyK7t0alAg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=jHWy4UxqgUe44QwoGJQA:9 a=1OuFwYUASf3TG4hYMiVC:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX3abQvYxpBrcd qAH85l2EU6yyQZFkbJDOrsKsRtGLlbSHZ/QFqc4Wd+TfYqxxJNRViiZYMDYUIO5glPQJz8cIu0W MN4Gz30J0daZ1xo+IgjH+BmjpUrQL7s= X-Proofpoint-ORIG-GUID: u0rvnVlHe-5qlzYGjZ227vIN-dLtgJq5 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX9nEG/h4mijKo VtOPDfe0Bn2DzhrChUdJyFlIY6pBID8SrjRBkglqLSoZjJlSI4bFUDFzo/bd/hqPhKaF/iPNzRD NjxODa6XGh2h+5Yed7eDpC1/WCqEhatrfO0d7ySVsQAZ7XRI1Q4qvxuaQ7ROUXMAVcLrCPS04uy hc9ONn6+LoeV4owW0WabSaj1v56vq0t1VWBB7lrX6Qy7LI9Fh6aFX1OwPej8EnGydM6jzMym5bE HQxTyYd35yheBaPdD0Z0wGh6Kt3rLZWaSnYz5VhIlhTXNoz+mVulqIPlmV5WxdLI1+aLQD6+OEh 33TIemBOAxEoUy24Cg1f4f/xdoGOoh50B9zJlEJWcN4CXBBoj8K1u71W7ssFlKEXjjgIsS3dae8 YGunnQXsyMwCLFOiGRK7K8dvuYJuBTw8nYYYWEvyCVzwk26KmKXB2CZXsF2o3OQxixtxmSTUbiC 7bKc/0PtBooZoV+DjEQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 priorityscore=1501 malwarescore=0 bulkscore=0 suspectscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.180.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0b-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686194377158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add helper routines for describing RPMI shared-memory mailbox transports and service child nodes in the RISC-V virt device tree. The helpers keep RPMI node construction in one place so the virt machine can add service groups without open-coding compatible strings, channel IDs, interrupts, and shared-memory references at each call site. Signed-off-by: Subrahmanya Lingappa --- hw/riscv/meson.build | 1 + hw/riscv/rpmi-fdt.c | 103 ++++++++++++++++++++++++++++++++++++ include/hw/riscv/rpmi-fdt.h | 30 +++++++++++ 3 files changed, 134 insertions(+) create mode 100644 hw/riscv/rpmi-fdt.c create mode 100644 include/hw/riscv/rpmi-fdt.h diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build index b70a054579..529ec273fd 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -3,6 +3,7 @@ riscv_ss.add(files('boot.c')) riscv_ss.add(files('fdt-common.c')) riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c')) riscv_ss.add(files('riscv_hart.c')) +riscv_ss.add(files('rpmi-fdt.c')) riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c')) riscv_ss.add(when: 'CONFIG_RISCV_VIRT', if_true: files('virt.c')) riscv_ss.add(when: 'CONFIG_SHAKTI_C', if_true: files('shakti_c.c')) diff --git a/hw/riscv/rpmi-fdt.c b/hw/riscv/rpmi-fdt.c new file mode 100644 index 0000000000..b2b3daea1c --- /dev/null +++ b/hw/riscv/rpmi-fdt.c @@ -0,0 +1,103 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI device-tree helpers + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "qemu/bswap.h" +#include "hw/riscv/rpmi-fdt.h" +#include "hw/misc/riscv_rpmi.h" +#include "system/device_tree.h" + +void riscv_rpmi_fdt_add_mbox(void *fdt, + const RiscvRpmiFdtMboxConfig *cfg, + uint32_t *phandle, + uint32_t *mbox_handle) +{ + g_autofree char *name =3D NULL; + hwaddr a2p_req_base, p2a_ack_base, p2a_req_base, a2p_ack_base; + static const char * const regnames_all[RPMI_ALL_NUM_REGS] =3D { + "a2p-req", "p2a-ack", "p2a-req", "a2p-ack", "a2p-doorbell" + }; + static const char * const regnames_a2p[RPMI_A2P_NUM_REGS] =3D { + "a2p-req", "p2a-ack", "a2p-doorbell" + }; + + a2p_req_base =3D cfg->shmem_base; + p2a_ack_base =3D a2p_req_base + cfg->a2p_req_size; + p2a_req_base =3D p2a_ack_base + cfg->a2p_req_size; + a2p_ack_base =3D p2a_req_base + cfg->p2a_req_size; + + *mbox_handle =3D (*phandle)++; + name =3D g_strdup_printf("/soc/mailbox@%" HWADDR_PRIx, cfg->shmem_base= ); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,rpmi-shmem-mbo= x"); + qemu_fdt_setprop_cell(fdt, name, "riscv,slot-size", RPMI_QUEUE_SLOT_SI= ZE); + qemu_fdt_setprop_cell(fdt, name, "#mbox-cells", 1); + + if (cfg->p2a_req_size) { + qemu_fdt_setprop_string_array(fdt, name, "reg-names", + (char **)®names_all, + ARRAY_SIZE(regnames_all)); + qemu_fdt_setprop_cells(fdt, name, "reg", + (uint32_t)(a2p_req_base >> 32), (uint32_t)a2p_req_base, + 0x0, cfg->a2p_req_size, + (uint32_t)(p2a_ack_base >> 32), (uint32_t)p2a_ack_base, + 0x0, cfg->a2p_req_size, + (uint32_t)(p2a_req_base >> 32), (uint32_t)p2a_req_base, + 0x0, cfg->p2a_req_size, + (uint32_t)(a2p_ack_base >> 32), (uint32_t)a2p_ack_base, + 0x0, cfg->p2a_req_size, + (uint32_t)(cfg->doorbell_base >> 32), (uint32_t)cfg->doorbell_= base, + 0x0, cfg->doorbell_size); + } else { + qemu_fdt_setprop_string_array(fdt, name, "reg-names", + (char **)®names_a2p, + ARRAY_SIZE(regnames_a2p)); + qemu_fdt_setprop_cells(fdt, name, "reg", + (uint32_t)(a2p_req_base >> 32), (uint32_t)a2p_req_base, + 0x0, cfg->a2p_req_size, + (uint32_t)(p2a_ack_base >> 32), (uint32_t)p2a_ack_base, + 0x0, cfg->a2p_req_size, + (uint32_t)(cfg->doorbell_base >> 32), (uint32_t)cfg->doorbell_= base, + 0x0, cfg->doorbell_size); + } + + qemu_fdt_setprop_cells(fdt, name, "phandle", *mbox_handle); +} + +void riscv_rpmi_fdt_add_service(void *fdt, hwaddr shmem_base, + const char *node_name, + const char *compatible, + uint32_t mbox_handle, + uint32_t service_group, + bool has_mpxy_channel, + uint32_t mpxy_channel) +{ + g_autofree char *name =3D g_strdup_printf("/soc/mailbox@%" HWADDR_PRIx= "/%s", + shmem_base, node_name); + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", compatible); + qemu_fdt_setprop_cells(fdt, name, "mboxes", mbox_handle, service_group= ); + if (has_mpxy_channel) { + qemu_fdt_setprop_cell(fdt, name, "riscv,sbi-mpxy-channel-id", + mpxy_channel); + } +} + +void riscv_rpmi_fdt_add_service_node(void *fdt, hwaddr shmem_base, + const RiscvRpmiServiceConfig *service, + uint32_t mbox_handle) +{ + riscv_rpmi_fdt_add_service(fdt, shmem_base, service->node_name, + service->compatible, mbox_handle, + service->service_group, + service->has_mpxy_channel, + service->mpxy_channel); +} diff --git a/include/hw/riscv/rpmi-fdt.h b/include/hw/riscv/rpmi-fdt.h new file mode 100644 index 0000000000..f053ae5d57 --- /dev/null +++ b/include/hw/riscv/rpmi-fdt.h @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI device-tree helpers + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#ifndef HW_RISCV_RPMI_FDT_H +#define HW_RISCV_RPMI_FDT_H + +#include "exec/hwaddr.h" +#include "hw/misc/riscv_rpmi.h" + +typedef struct RiscvRpmiFdtMboxConfig { + hwaddr shmem_base; + hwaddr doorbell_base; + uint32_t a2p_req_size; + uint32_t p2a_req_size; + uint32_t doorbell_size; +} RiscvRpmiFdtMboxConfig; + +void riscv_rpmi_fdt_add_mbox(void *fdt, + const RiscvRpmiFdtMboxConfig *cfg, + uint32_t *phandle, + uint32_t *mbox_handle); + +#endif --=20 2.43.0 From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686251; cv=none; d=zohomail.com; s=zohoarc; b=L7FUKtdEx7FUPOyUJ13qKh19KnVTTDTJWDhRoHFOk0BokWstgXd6Zucpgr1ZXySLG9Bb6N8XsMod+1PNKIjKJkZFgzOM08POBu4Ec5UUmCg4MSnw0Zq+3BhiKnuI1Uur6If5G594lA8Z6gR/U0WG6TTu+ME5+an1H9C6fDHwekg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686251; h=Content-Transfer-Encoding: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:Cc; bh=jZZ4niVrLmn2GO/pDHbdvlka4uQ0QskiTf3YDgvds3c=; b=OM8Z4Qw8tzn9GNb9L2O0mqPJ/hXraeD1PZn5tJAZ89EJ16XQeOE3g5LtO1+hXApOpHJSBNdbLRPPEqBj/LNuMUs36GVd8ob+U58VAPCHS7kqErKJhAqnrBt4yq/YoM/3nCqLYnOKASTG55unYj/ORQSBXy2FHjpc6Buc64ZbVeY= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783686251444156.45402470975; Fri, 10 Jul 2026 05:24:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEc-0006VX-NJ; Fri, 10 Jul 2026 08:21:38 -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 1wi3lK-0000NT-GQ for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:00 -0400 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lI-00049a-3Q for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:26:57 -0400 Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3n4rY3898996 for ; Fri, 10 Jul 2026 05:26:54 GMT Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4faeg3jvu0-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:26:54 +0000 (GMT) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-37dedbd1cf1so322961a91.3 for ; Thu, 09 Jul 2026 22:26:54 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.26.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:26:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=jZZ4niVrLmn 2GO/pDHbdvlka4uQ0QskiTf3YDgvds3c=; b=jHPGEFtyCAVgHfGaixDssB1kv6u 14YxahSO5ZRToe3Idn54eI/DaY2od3f7OzfKdAMFn0mh+m/yiYovu4z8wxtgGpGJ Haxgta9H/E8oP5uBS4m5qG8F5Q6qlOPJD8kDdtQDlvoG0d4xpjHHVGNYKciyBO0u Wy+oQj1fv3WNr/lhXgFYOKuLhiKCTx8twklAvmG8DW/8Gby/HbQK98hKjWzha1G1 NjuJNTbGRSiGMCBuiCzVjzzvzzBejEoez5B0tBPa8lel+iLzNvclgDk6RM1FX2Bv YiEod7wTJ0IP6FSJE82TPTOh+19PbEbquCE6YBkhjrfxcQ4/C6OdkFTJ66w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661214; x=1784266014; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=jZZ4niVrLmn2GO/pDHbdvlka4uQ0QskiTf3YDgvds3c=; b=DF6FknS2650QbUG/SsacwFAjzI/BczPsheUJk8ezr+LLU7aLebrzsTad2SeKv5PUyo +TcynLZzU0y8pgZJMbrrDfZAMW8Mqg6H43MmoothaignhGRlCBYeg5oK4m9ZV4mggLm3 F3WcGf0a+UhZKu/LmfEkdEwfTtimmfSe4hBroAbwXfMl9WyqRUBoDCn6R/ktYBqNcFm5 cQvOrOwiGJKY2TP/7EsidU+6ulVgUoiikQ69uDjeyKDPpy3+kKykFP0rnu+jF/HpEewf tkx3pJFPdLTdmmLJzt9YBq0rErV22QlEyyhIuSsZyHmp8LStUtJiU41mpUziLRTxnoOM DvfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661214; x=1784266014; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=jZZ4niVrLmn2GO/pDHbdvlka4uQ0QskiTf3YDgvds3c=; b=Kn28qq+QC5ln7Te5SHO2eJPlNaRGVQ0C2DL3BCHrr2MbLQVJcp4Qvdh2KphcyGS5Qu ugBbCOK4u0D4sBs9mbENz9xGO5W9Avno6bg6rPg/GWsq8muxqaie843dhavoesIcA8bw M7zl16xXECyaSIdK44tmffQ9QRPIj70bqyMMvKWbIqnsrfoMmqP/UnXt8sCmtSjOaiTo gRLHwMyfA7nV3hCXCgTtnnb8fA36fiQ9wsi8B5JXey+8ZVy+bqNYwaiwzvpYjp57iXUg 0LvdMF9JJkqciRDorpwyVp0TtcKHNmS5w9OlxIi4oBs+kd84cVJ01x6YA/Do1/q9HlBb nOJw== X-Gm-Message-State: AOJu0Yw11f1I14D2pcXLt5oGNaSw81l8JzQwbPy7LWTRmRQTY2k+nOcJ LkSgvyPrSCbwDO2YD/yEp4jNuvjdhsdNEyY1GchLTvdyBlD5Or7tsI0XgtgkXI0wpUnW7rNO/dL V9xp838APO2MwxF+oD4X/kVLkbCugnr8OK1JUZ/aFd0F0aRnrQTlMah19trRC5i+OPA== X-Gm-Gg: AfdE7cklFCIpBE8s70aJCFrxL405ngKrqlMKAefdPLeILkXdOLmlUA/aaNqHBs2i6IH qC+QzjZeZ3YBssG3B1XasUurWYahl6WC8lwZAZ8H9fYG/oFk9oPoIRBE+T9Wz3yb2boi1zu8Kjr N+h56yeWkGOkRiTFUwJ0DktfxfwEbaktCjyU53Whur8L6FE7jbROfN62MyryStTih2h0bdN7kNT VZTNQW5dRyeleeSyVA4Xh+vDKXbiASUeJptwWCSoDOjtsi3F914jWEHWU9fdQrrnEMNVXdnCgQK QEcx1CqASyo8oxomD0baGBSIbFJxtB3m1ipS2Yds8onqZwQDzqcnlAPjgpZuVTdeL3mcYY9G3ac lKFJKJ1e5ELlTEkyT0VEMAIjTHDrK3f82vScso6/t2LqWGRwIPrlRYKBP4T2kCOx4G+ueMIISoJ UGgM9WEiN1O7Rz4pf0BaN07Ah4KFPZAzuu7fgzrxTRvw== X-Received: by 2002:a17:90b:2f0c:b0:381:abcc:c8d8 with SMTP id 98e67ed59e1d1-38a1f1de21emr5907692a91.1.1783661213639; Thu, 09 Jul 2026 22:26:53 -0700 (PDT) X-Received: by 2002:a17:90b:2f0c:b0:381:abcc:c8d8 with SMTP id 98e67ed59e1d1-38a1f1de21emr5907664a91.1.1783661213043; Thu, 09 Jul 2026 22:26:53 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 04/10] hw/riscv/virt: add opt-in RPMI base support Date: Fri, 10 Jul 2026 10:56:36 +0530 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX02ojr9mBrmFm oBtU+jA7bv0F7iXYX7Gt6Cy7G2dph7plaMZ9wER3DOqSSylHQuDZONk6h5IDABILSm3Uo00bsrm zmUHqsUkMl22y4GNVACsJVxbAgN3taChC7og8HdhaY4rgaUolDp0ahX9eMvHjXNMYHB9PDW7joV qLncekRpTXJLBsuI/JRS2EdTIG0pRWYa1JJWv5Vshi5gpPRkoB7w4anQcRZ5taHS3lRZtYIz12Z bEmhwNZqkVYypZknac9OcGZAyMDqGqZp4tEYjgPhJYrLomqIrkJcS0+0qLMIHVu4p6+TO2QSRhR biq5pouLOz//0+m9laQSfnC/9yGUokQdSBI0KSwabxLMH7ExeeV0nUQfwikg9i2fuFYDaefk0Qt E0FrIQjfL+JXv4nNhFAB0O9STZomb9XRsPG8kZQO5hq1CpHLN7hRGJmXzWbnUmN1leTQWnL3qX5 maW+JhifWVh6d3W450w== X-Authority-Analysis: v=2.4 cv=ZcMt8MVA c=1 sm=1 tr=0 ts=6a50829e cx=c_pps a=RP+M6JBNLl+fLTcSJhASfg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=EUspDBNiAAAA:8 a=g5JW_UTvCJDKiRHPheAA:9 a=iS9zxrgQBfv6-_F4QbHw:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX8tKjCcTfApeQ KqrXdYuyuSQp0cazfc0DK5GX+5GF2yiqXmPUA4SoaYLy6OwAZMZmiIYmTn6kzLsUUuOFHmI8NfB 1AEU9J4l3nGzFxvREPunaU55RJxF/Eg= X-Proofpoint-GUID: rhT9i9k-w5qoSxOj0jZSnXYGIDtXO-jf X-Proofpoint-ORIG-GUID: rhT9i9k-w5qoSxOj0jZSnXYGIDtXO-jf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 clxscore=1015 lowpriorityscore=0 malwarescore=0 bulkscore=0 suspectscore=0 priorityscore=1501 impostorscore=0 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.168.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686252828158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add the virt machine rpmi=3Don/off option and wire the initial RPMI Base transport into machine realization. The option remains disabled by default and requires TCG plus librpmi. Invalid accelerator/build combinations fail during machine initialization. When enabled, virt allocates the RPMI shared-memory transport, creates the RPMI device, configures Base service metadata, and emits the corresponding device-tree nodes for firmware discovery. Signed-off-by: Subrahmanya Lingappa --- hw/riscv/Kconfig | 1 + hw/riscv/virt.c | 96 ++++++++++++++++++++++++++++++++++++ include/hw/misc/riscv_rpmi.h | 10 ++++ include/hw/riscv/virt.h | 3 ++ 4 files changed, 110 insertions(+) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 54e41a6afc..4e25be113a 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -49,6 +49,7 @@ config RISCV_VIRT imply VIRTIO_VGA imply TEST_DEVICES imply TPM_TIS_SYSBUS + imply RISCV_RPMI select DEVICE_TREE select RISCV_NUMA select GOLDFISH_RTC diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 33775a61fd..e52ccfae1f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -45,6 +45,8 @@ #include "hw/intc/riscv_aplic.h" #include "hw/intc/sifive_plic.h" #include "hw/misc/sifive_test.h" +#include "hw/misc/riscv_rpmi.h" +#include "hw/riscv/rpmi-fdt.h" #include "hw/core/platform-bus.h" #include "chardev/char.h" #include "system/device_tree.h" @@ -97,6 +99,8 @@ static const MemMapEntry virt_memmap[] =3D { [VIRT_UART0] =3D { 0x10000000, 0x100 }, [VIRT_VIRTIO] =3D { 0x10001000, 0x1000 }, [VIRT_FW_CFG] =3D { 0x10100000, 0x18 }, + [VIRT_RPMI_SHMEM] =3D { 0x10200000, 0x20000 }, + [VIRT_RPMI_DOORBELL] =3D { 0x10230000, 0x1000 }, [VIRT_FLASH] =3D { 0x20000000, 0x4000000 }, [VIRT_IMSIC_M] =3D { 0x24000000, VIRT_IMSIC_MAX_SIZE }, [VIRT_IMSIC_S] =3D { 0x28000000, VIRT_IMSIC_MAX_SIZE }, @@ -1002,6 +1006,40 @@ static void create_fdt_iommu(RISCVVirtState *s, uint= 16_t bdf) s->pci_iommu_bdf =3D bdf; } =20 + +static RiscvRpmiConfig virt_rpmi_config(RISCVVirtState *s, + const uint32_t *hart_ids, + uint32_t hart_count) +{ + return (RiscvRpmiConfig) { + .doorbell_base =3D s->memmap[VIRT_RPMI_DOORBELL].base, + .shmem_base =3D s->memmap[VIRT_RPMI_SHMEM].base, + .shmem_size =3D s->memmap[VIRT_RPMI_SHMEM].size, + .a2p_req_size =3D VIRT_RPMI_A2P_REQ_SIZE, + .p2a_req_size =3D VIRT_RPMI_P2A_REQ_SIZE, + .platform_info =3D "QEMU RISC-V virt RPMI", + .hart_ids =3D hart_ids, + .hart_count =3D hart_count, + }; +} + +static void create_fdt_rpmi(RISCVVirtState *s, uint32_t *phandle, + uint32_t msi_phandle) +{ + RiscvRpmiConfig rpmi_cfg =3D virt_rpmi_config(s, NULL, 0); + uint32_t rpmi_mbox_handle; + RiscvRpmiFdtMboxConfig cfg =3D { + .shmem_base =3D rpmi_cfg.shmem_base, + .doorbell_base =3D rpmi_cfg.doorbell_base, + .a2p_req_size =3D rpmi_cfg.a2p_req_size, + .p2a_req_size =3D rpmi_cfg.p2a_req_size, + .doorbell_size =3D s->memmap[VIRT_RPMI_DOORBELL].size, + }; + + riscv_rpmi_fdt_add_mbox(MACHINE(s)->fdt, &cfg, phandle, + &rpmi_mbox_handle); +} + static void finalize_fdt(RISCVVirtState *s) { uint32_t phandle =3D 1, irq_mmio_phandle =3D 1, msi_pcie_phandle =3D 1; @@ -1021,6 +1059,10 @@ static void finalize_fdt(RISCVVirtState *s) create_fdt_pcie(s, irq_pcie_phandle, msi_pcie_phandle, iommu_sys_phandle); =20 + if (s->have_rpmi) { + create_fdt_rpmi(s, &phandle, msi_pcie_phandle); + } + create_fdt_reset(s, &phandle); =20 create_fdt_uart(s, irq_mmio_phandle); @@ -1410,6 +1452,18 @@ static void virt_machine_init(MachineState *machine) exit(1); } =20 + + if (s->have_rpmi) { +#ifndef CONFIG_LIBRPMI + error_report("RISC-V RPMI support is not compiled in"); + exit(1); +#else + if (kvm_enabled()) { + error_report("RISC-V RPMI support is not available with KVM"); + exit(1); + } +#endif + } /* Initialize sockets */ mmio_irqchip =3D virtio_irqchip =3D pcie_irqchip =3D NULL; for (i =3D 0; i < socket_count; i++) { @@ -1552,6 +1606,25 @@ static void virt_machine_init(MachineState *machine) /* SiFive Test MMIO device */ sifive_test_create(s->memmap[VIRT_TEST].base); =20 + if (s->have_rpmi) { + MachineClass *mc =3D MACHINE_GET_CLASS(machine); + const CPUArchIdList *possible_cpus =3D mc->possible_cpu_arch_ids(m= achine); + g_autofree uint32_t *rpmi_hart_ids =3D + g_new0(uint32_t, machine->smp.cpus); + RiscvRpmiConfig rpmi_cfg; + Error *local_err =3D NULL; + + for (i =3D 0; i < machine->smp.cpus; i++) { + rpmi_hart_ids[i] =3D possible_cpus->cpus[i].arch_id; + } + + rpmi_cfg =3D virt_rpmi_config(s, rpmi_hart_ids, machine->smp.cpus); + if (!riscv_rpmi_create(&rpmi_cfg, &local_err)) { + error_report_err(local_err); + exit(1); + } + } + /* VirtIO MMIO devices */ for (i =3D 0; i < VIRTIO_COUNT; i++) { sysbus_create_simple("virtio-mmio", @@ -1636,6 +1709,7 @@ static void virt_machine_instance_init(Object *obj) =20 s->oem_id =3D g_strndup(ACPI_BUILD_APPNAME6, 6); s->oem_table_id =3D g_strndup(ACPI_BUILD_APPNAME8, 8); + s->have_rpmi =3D false; s->acpi =3D ON_OFF_AUTO_AUTO; s->iommu_sys =3D ON_OFF_AUTO_AUTO; } @@ -1710,6 +1784,21 @@ static void virt_set_aclint(Object *obj, bool value,= Error **errp) s->have_aclint =3D value; } =20 + +static bool virt_get_rpmi(Object *obj, Error **errp) +{ + RISCVVirtState *s =3D RISCV_VIRT_MACHINE(obj); + + return s->have_rpmi; +} + +static void virt_set_rpmi(Object *obj, bool value, Error **errp) +{ + RISCVVirtState *s =3D RISCV_VIRT_MACHINE(obj); + + s->have_rpmi =3D value; +} + bool virt_is_iommu_sys_enabled(RISCVVirtState *s) { return s->iommu_sys =3D=3D ON_OFF_AUTO_ON; @@ -1831,6 +1920,13 @@ static void virt_machine_class_init(ObjectClass *oc,= const void *data) "enable/disable emulating " "ACLINT devices"); =20 + + object_class_property_add_bool(oc, "rpmi", virt_get_rpmi, + virt_set_rpmi); + object_class_property_set_description(oc, "rpmi", + "Set on/off to enable/disable " + "RISC-V RPMI devices"); + object_class_property_add_str(oc, "aia", virt_get_aia, virt_set_aia); object_class_property_set_description(oc, "aia", diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h index cb2658e57e..b5d8a32f9b 100644 --- a/include/hw/misc/riscv_rpmi.h +++ b/include/hw/misc/riscv_rpmi.h @@ -85,6 +85,16 @@ struct RiscvRpmiState { bool has_shmem; }; =20 +#ifdef CONFIG_LIBRPMI DeviceState *riscv_rpmi_create(const RiscvRpmiConfig *cfg, Error **errp); +#else +static inline DeviceState *riscv_rpmi_create(const RiscvRpmiConfig *cfg, + Error **errp) +{ + (void)cfg; + (void)errp; + return NULL; +} +#endif =20 #endif diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 18a2a323a3..f7c48613bf 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -55,6 +55,7 @@ struct RISCVVirtState { =20 int fdt_size; bool have_aclint; + bool have_rpmi; RISCVVirtAIAType aia_type; int aia_guests; char *oem_id; @@ -79,6 +80,8 @@ enum { VIRT_UART0, VIRT_VIRTIO, VIRT_FW_CFG, + VIRT_RPMI_SHMEM, + VIRT_RPMI_DOORBELL, VIRT_IMSIC_M, VIRT_IMSIC_S, VIRT_FLASH, --=20 2.43.0 From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686188; cv=none; d=zohomail.com; s=zohoarc; b=ezTsHMFfe74UF6x1Z92C6ARZ41e8G/G/08dxOtNuCHa0jWh+8SGXTgdbiJv28s8jcpp8t9j0bvfSb2ECzhHuBqe2AOR1Qq6w/FhuNHajJGU+n7Rj/Bx+evixqa+m8s43WKFfUCsIZ5RK5ZehLZtTgJ4AS+2OKgvCZFCQjnJQ96c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686188; h=Content-Transfer-Encoding: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:Cc; bh=iicBHwDC6ZKEx55TqmOMP0bLP6MIfmn8Fv+QWMV91Ug=; b=dtGzkMh0hlp7nZvBuXK55x3FBxqN5nG3vL7gOdRqPWwTeZrhUaK+i4TbXLunce3ZU4IQn+QFZ30zbgWsy4qA+rGtl08HAI8ZRFSwNdRvSxtY72Lv+vPYSpZVTbWq6FJwnD3fIr5X/LvYdbt0KFuAbFlLhThzu4upABNxivKc2Mk= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178368618844698.38320671360873; Fri, 10 Jul 2026 05:23:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEl-0006Wu-Dr; Fri, 10 Jul 2026 08:21:47 -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 1wi3lM-0000Ne-Na for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:02 -0400 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lJ-00049v-P7 for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:00 -0400 Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3nSrX3803809 for ; Fri, 10 Jul 2026 05:26:56 GMT Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4faf5mtm1a-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:26:56 +0000 (GMT) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-2cc620652bfso1557525ad.2 for ; Thu, 09 Jul 2026 22:26:56 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.26.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:26:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=iicBHwDC6ZK Ex55TqmOMP0bLP6MIfmn8Fv+QWMV91Ug=; b=ingt5gMOyGlmG2HwYZ18P4KLFcv FMd0RIil0UbUwnBg2xyHJeBGOHjB4iTevbSSq3c+3Yho2ueeCiMHrEsrvZ7julGB 1AUR2MZCSLoo4hCOAwrGtLUkAUt37VdAPovCnc3geWekMLPyAMU+1YBcESgqZHvy BGPINztVspDQg2l6UvfOmk/OIByu/gyvwu3RqMgBYhDGDxt8s15vEVtlBmB5zLIL J+36RmRwDnL+ivuaetacNkc2d5KLVsXK7WMChHvm7WAmLHxjK3XdyyPZGB4gJ6Z4 vYhp9mv9XAnRNrloDNPsYPtLD+H6Me8tnc0KLwj4fFnwQdaSwfiHCdmopjw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661215; x=1784266015; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=iicBHwDC6ZKEx55TqmOMP0bLP6MIfmn8Fv+QWMV91Ug=; b=N5sAS0RAXFwQSu/KHGuYEQEz/XskUmj7VkmPAEFOhaDc1brNyrmHRM5BsbbonFUj8w llp5r1sJjBVZ/ZaHmPkQkBnULIxyfIx4AdApc+xDQynr6rnHyTeq5Jy4kwofLI2mECmv yVPz0W5WzNgeN5PvxuMNhpq3qMhxmP87+s0YgESKFzOvXBk6yADBeEs42fKKI4w46oJc OZ7QQvQK35Y8ngFTgU7sy+o+TIiFCC7roLCVK81/bmVf5xA4Gn7SsDpcwt5HUBqKdvju vv7aI9YGWt3jD9wF/bbv3KJbqa+8YlaXt5QaAcMSAdVbn4dtMEiJVzyNPC6faVvR3NrY IE0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661215; x=1784266015; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=iicBHwDC6ZKEx55TqmOMP0bLP6MIfmn8Fv+QWMV91Ug=; b=WNC7iX/xZNncAIs7xhO4/rcZdOJLj2sy+DWm1Cn0zpw0bToGw6zGMHxhlh1DNBBBCM swweqsUvCx2KmSVE0ZzG53L2+Mq6QBE/NfbQGYGRAdyhM5qlu40JYavJg3a1J6YJUr8Z Zn2TaYHRsyW/mZCN3JMYrqlrWD/taLpaBbDufD1+7SCoziabLRgThOaP8Su1n7FFoVY8 MEWrdhfz4LSOSpbd7dK485Zh8SL7/8yDOkN1wsAdC9pGrW5alyo5+fcFnIDbGt+yF6// +xxWdKml0BEl0bM3ffcKearMfoep+Ejo4laceOmCMeyCWGc4ER3+SbiMc3eaa1k7eIKr bo6A== X-Gm-Message-State: AOJu0Yzx5c4vwC/nm4YjzXdyY5d7jt7Sf4G0nFtYRW9bMGzNfc8tNmNK bRyX2G44or+AEUJuXIQHL/+xCwYW9ECGkpRwGr7S9m1bxACvhFa2uqOOQ8w+rDxf2vTfazXPpbn 0K1HmOEB8cPTTlABpYoE8ohFs+n7m8MQePO2VR2reyKycqr1J484vz1fXke1Ndn0u6Q== X-Gm-Gg: AfdE7clwd4hVWwqHYb+PEpcPcHo1Jwcpl2VKqJZEF+/7stBUV9tZzpOoB4ss1VDaUDD 8wMm2OrQKTFxMTVcQRpVxZd+Hxt2HATQB5M1PuhYXaLWZ4Qmc30AaawkYl8PzMxtBx64r35aIt6 Fm8AvJaTNDw7ZDzrQonvqTvPSP3HRz3Yo5fUTs1wS6xECfgYF4mk+M0aDRqDHss7dKSHsxHDI/w NbKZUtJW99yXMuu8bWnM4SK660fac189iBV8Bi54+rByktX8MB81LXBHylYe9kENoJ5IjBot8IK t8LSc2Bl1gcBIoV4CklP2y/Rqk+arebymVCjhj+RyrwMmAQvFgskQfjVkyY00WU2gTQWnhlEyVb itt6My6Lyk0Cr7O4mvP2wRyqhJYnHjbT/RsaQ4m57AVtdH1Pw6vxVhAnd88o5KqX527I+lpF9tH iTiotOC+wcL96gakGczi9uy76pM+Eiaknramcskmx0yw== X-Received: by 2002:a17:902:e94d:b0:2cc:9d9:b8df with SMTP id d9443c01a7336-2ccff2d2fb5mr56383075ad.5.1783661215426; Thu, 09 Jul 2026 22:26:55 -0700 (PDT) X-Received: by 2002:a17:902:e94d:b0:2cc:9d9:b8df with SMTP id d9443c01a7336-2ccff2d2fb5mr56382815ad.5.1783661214738; Thu, 09 Jul 2026 22:26:54 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 05/10] riscv: add RPMI system reset service Date: Fri, 10 Jul 2026 10:56:37 +0530 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-ORIG-GUID: w0DuEgEZG304tfZDV0ZxtwDMaRXKB5jY X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX69GTvsmKhgTF r7lW/ZBIjKIhJGYw2Ms05iN2AvosrJw1E9cVFqquRcF/HBw/dgp0fdbRborEQrnhtdo7XlBvZSq GBj0DphM23/7c4Zj/pDKB0K1f8i0Dak= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX7Y/hM7XzbONH V0r9fS7uNLJzkb3scnsPzS6V9/y08pR6VBdIi9cnlD5+5jjbi9CpeBNDi2hbrYNNZNfUz5micG0 dZMAlaKQmFOzd7pqXWPFw+3qjYTPIuzgiKFjzjCVO6vJAPoDd+AKkd/gIzh8R0Qm1uns67c5H1Y sx4nDKdCtsB82/9dueo3IbsYWKmA8yu27m4Ajx9CI8z9V9HG0FiUuLRsNL8oxANOXXh3Ky+SNJl uPSqsWOQiApR+3zV37hidKpCva97Qxgz3DiKHPNiB0BfCAfKKOxf/DN1U18QXaLLg7XARkbFgWg M9cogBYPJAdiT8xb2Yd8LyKAavxf5Z97TzbCExndXvqFDVRJwUGgd2ub57v9RlfFMc592TZOmAp RTohJ/Psp5nkgnm4rTEAsug3WCggcj0MSd2P3uFhXtHTgrFtx5/pQg3ARnpGTji3iohtNHDYwVW Ez7WKl6T2DqLSDaR3lw== X-Proofpoint-GUID: w0DuEgEZG304tfZDV0ZxtwDMaRXKB5jY X-Authority-Analysis: v=2.4 cv=N+QZ0W9B c=1 sm=1 tr=0 ts=6a5082a0 cx=c_pps a=IZJwPbhc+fLeJZngyXXI0A==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=blQ9iIGB7deKtsPWDqUA:9 a=uG9DUKGECoFWVXl0Dc02:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 suspectscore=0 impostorscore=0 spamscore=0 lowpriorityscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.180.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0b-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686190411158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add a QEMU implementation of the RPMI System Reset service group. The service advertises shutdown and cold reboot reset types, validates guest requests, and dispatches accepted requests through the machine reset and shutdown callbacks. This lets firmware use RPMI reset commands while keeping the board-specific reset policy in the RISC-V virt machine. Signed-off-by: Subrahmanya Lingappa --- hw/misc/meson.build | 1 + hw/misc/riscv_rpmi.c | 38 ++++++- hw/misc/riscv_rpmi_internal.h | 9 ++ hw/misc/riscv_rpmi_sysreset.c | 206 ++++++++++++++++++++++++++++++++++ hw/riscv/virt.c | 40 +++++++ include/hw/misc/riscv_rpmi.h | 13 ++- include/hw/riscv/rpmi-fdt.h | 11 ++ 7 files changed, 313 insertions(+), 5 deletions(-) create mode 100644 hw/misc/riscv_rpmi_sysreset.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index e7c2ebe28f..bca7819ee0 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -170,4 +170,5 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('= sbsa_ec.c')) system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c')) system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files( 'riscv_rpmi.c', + 'riscv_rpmi_sysreset.c', ), librpmi]) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c index c4b115b659..7a3f570ee7 100644 --- a/hw/misc/riscv_rpmi.c +++ b/hw/misc/riscv_rpmi.c @@ -175,6 +175,8 @@ static void riscv_rpmi_configure_base(RiscvRpmiState *s, const RiscvRpmiConfig *cfg) { s->platform_info =3D g_strdup(cfg->platform_info); + s->machine_ops =3D cfg->machine_ops; + s->machine_opaque =3D cfg->machine_opaque; s->services =3D cfg->services; s->service_count =3D cfg->service_count; =20 @@ -211,7 +213,9 @@ static void riscv_rpmi_reset(DeviceState *dev) =20 static void riscv_rpmi_cleanup(RiscvRpmiState *s) { - + for (uint32_t i =3D ARRAY_SIZE(riscv_rpmi_service_ops); i > 0; i--) { + riscv_rpmi_service_ops[i - 1].remove(s); + } =20 if (s->context) { rpmi_context_destroy(s->context); @@ -247,6 +251,30 @@ bool riscv_rpmi_service_enabled(RiscvRpmiState *s, Ris= cvRpmiServiceKind kind) return false; } =20 +bool riscv_rpmi_context_add_group(RiscvRpmiState *s, + struct rpmi_service_group *group, + const char *name, + Error **errp) +{ + enum rpmi_error rc; + + rc =3D rpmi_context_add_group(s->context, group); + if (rc !=3D RPMI_SUCCESS) { + error_setg(errp, "failed to add RPMI %s service group: %d", name, = rc); + return false; + } + + return true; +} + +void riscv_rpmi_context_remove_group(RiscvRpmiState *s, + struct rpmi_service_group *group) +{ + if (s->context && group) { + rpmi_context_remove_group(s->context, group); + } +} + static bool riscv_rpmi_validate_config(RiscvRpmiState *s, Error **errp) { uint64_t queue_bytes; @@ -318,11 +346,15 @@ static bool riscv_rpmi_add_service_group(RiscvRpmiSta= te *s, const RiscvRpmiServiceConfig *ser= vice, Error **errp) { - switch (service->kind) { - default: + const RiscvRpmiServiceOps *ops; + + ops =3D riscv_rpmi_service_ops_by_kind(service->kind); + if (!ops) { error_setg(errp, "unsupported RPMI service kind %d", service->kind= ); return false; } + + return ops->add(s, errp); } =20 static bool riscv_rpmi_init_services(RiscvRpmiState *s, Error **errp) diff --git a/hw/misc/riscv_rpmi_internal.h b/hw/misc/riscv_rpmi_internal.h index 447c0acb55..fe09804e69 100644 --- a/hw/misc/riscv_rpmi_internal.h +++ b/hw/misc/riscv_rpmi_internal.h @@ -20,5 +20,14 @@ extern const struct rpmi_shmem_platform_ops rpmi_shmem_qemu_ops; bool riscv_rpmi_service_enabled(RiscvRpmiState *s, RiscvRpmiServiceKind kind); +bool riscv_rpmi_context_add_group(RiscvRpmiState *s, + struct rpmi_service_group *group, + const char *name, + Error **errp); +void riscv_rpmi_context_remove_group(RiscvRpmiState *s, + struct rpmi_service_group *group); + +bool riscv_rpmi_sysreset_add(RiscvRpmiState *s, Error **errp); +void riscv_rpmi_sysreset_remove(RiscvRpmiState *s); =20 #endif diff --git a/hw/misc/riscv_rpmi_sysreset.c b/hw/misc/riscv_rpmi_sysreset.c new file mode 100644 index 0000000000..da6ef4c566 --- /dev/null +++ b/hw/misc/riscv_rpmi_sysreset.c @@ -0,0 +1,206 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI System Reset service. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "riscv_rpmi_internal.h" +#include "qemu/log.h" +#include "librpmi_env.h" + +typedef struct RiscvRpmiSysresetType { + uint32_t type; + void (*action)(RiscvRpmiState *s); +} RiscvRpmiSysresetType; + +typedef struct RiscvRpmiSysresetGroup { + struct rpmi_service_group group; + struct rpmi_service services[RPMI_SYSRST_SRV_ID_MAX]; + RiscvRpmiState *rpmi; +} RiscvRpmiSysresetGroup; + +static void riscv_rpmi_sysreset_reboot(RiscvRpmiState *s) +{ + const RiscvRpmiMachineOps *ops =3D s->machine_ops; + + if (ops && ops->system_reset) { + ops->system_reset(s->machine_opaque); + } +} + +static void riscv_rpmi_sysreset_shutdown(RiscvRpmiState *s) +{ + const RiscvRpmiMachineOps *ops =3D s->machine_ops; + + if (ops && ops->system_shutdown) { + ops->system_shutdown(s->machine_opaque); + } +} + +static const RiscvRpmiSysresetType riscv_rpmi_sysreset_types[] =3D { + { + .type =3D RPMI_SYSRST_TYPE_SHUTDOWN, + .action =3D riscv_rpmi_sysreset_shutdown, + }, { + .type =3D RPMI_SYSRST_TYPE_COLD_REBOOT, + .action =3D riscv_rpmi_sysreset_reboot, + }, +}; + +static const RiscvRpmiSysresetType *riscv_rpmi_sysreset_type_by_id( + uint32_t reset_type) +{ + for (uint32_t index =3D 0; index < ARRAY_SIZE(riscv_rpmi_sysreset_type= s); + index++) { + if (riscv_rpmi_sysreset_types[index].type =3D=3D reset_type) { + return &riscv_rpmi_sysreset_types[index]; + } + } + + return NULL; +} + +static void riscv_rpmi_do_system_reset(RiscvRpmiState *s, + rpmi_uint32_t reset_type) +{ + const RiscvRpmiSysresetType *type; + + type =3D riscv_rpmi_sysreset_type_by_id(reset_type); + if (type) { + type->action(s); + return; + } + + qemu_log_mask(LOG_GUEST_ERROR, "%s: unsupported reset type %u\n", + __func__, reset_type); +} + +static enum rpmi_error riscv_rpmi_sysreset_get_attributes( + struct rpmi_service_group *group, struct rpmi_service *service, + struct rpmi_transport *trans, rpmi_uint16_t request_data_len, + const rpmi_uint8_t *request_data, rpmi_uint16_t *response_data_len, + rpmi_uint8_t *response_data) +{ + uint32_t reset_type =3D ldl_le_p(request_data); + uint32_t *resp =3D (uint32_t *)response_data; + + *response_data_len =3D 2 * sizeof(*resp); + stl_le_p(&resp[0], RPMI_SUCCESS); + stl_le_p(&resp[1], riscv_rpmi_sysreset_type_by_id(reset_type) ? + RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE : 0); + + return RPMI_SUCCESS; +} + +static enum rpmi_error riscv_rpmi_sysreset_do_reset( + struct rpmi_service_group *group, struct rpmi_service *service, + struct rpmi_transport *trans, rpmi_uint16_t request_data_len, + const rpmi_uint8_t *request_data, rpmi_uint16_t *response_data_len, + rpmi_uint8_t *response_data) +{ + RiscvRpmiSysresetGroup *sysreset =3D group->priv; + uint32_t reset_type =3D ldl_le_p(request_data); + uint32_t *resp =3D (uint32_t *)response_data; + + *response_data_len =3D sizeof(*resp); + + if (!riscv_rpmi_sysreset_type_by_id(reset_type)) { + stl_le_p(resp, (uint32_t)RPMI_ERR_INVALID_PARAM); + return RPMI_SUCCESS; + } + + stl_le_p(resp, RPMI_SUCCESS); + riscv_rpmi_do_system_reset(sysreset->rpmi, reset_type); + return RPMI_SUCCESS; +} + +static const struct rpmi_service riscv_rpmi_sysreset_services[] =3D { + [RPMI_SYSRST_SRV_ENABLE_NOTIFICATION] =3D { + .service_id =3D RPMI_SYSRST_SRV_ENABLE_NOTIFICATION, + .min_a2p_request_datalen =3D 8, + }, + [RPMI_SYSRST_SRV_GET_ATTRIBUTES] =3D { + .service_id =3D RPMI_SYSRST_SRV_GET_ATTRIBUTES, + .min_a2p_request_datalen =3D 4, + .process_a2p_request =3D riscv_rpmi_sysreset_get_attributes, + }, + [RPMI_SYSRST_SRV_SYSTEM_RESET] =3D { + .service_id =3D RPMI_SYSRST_SRV_SYSTEM_RESET, + .min_a2p_request_datalen =3D 4, + .process_a2p_request =3D riscv_rpmi_sysreset_do_reset, + }, +}; + +static struct rpmi_service_group *riscv_rpmi_sysreset_create(RiscvRpmiStat= e *s) +{ + RiscvRpmiSysresetGroup *sysreset; + struct rpmi_service_group *group; + + sysreset =3D g_new0(RiscvRpmiSysresetGroup, 1); + sysreset->rpmi =3D s; + memcpy(sysreset->services, riscv_rpmi_sysreset_services, + sizeof(riscv_rpmi_sysreset_services)); + + group =3D &sysreset->group; + group->name =3D "sysreset"; + group->servicegroup_id =3D RPMI_SRVGRP_SYSTEM_RESET; + group->max_service_id =3D RPMI_SYSRST_SRV_ID_MAX; + group->servicegroup_version =3D + RPMI_BASE_VERSION(RPMI_SPEC_VERSION_MAJOR, RPMI_SPEC_VERSION_MINOR= ); + group->privilege_level_bitmap =3D RPMI_PRIVILEGE_M_MODE_MASK; + group->services =3D sysreset->services; + group->lock =3D rpmi_env_alloc_lock(); + group->priv =3D sysreset; + + return group; +} + +static void riscv_rpmi_sysreset_destroy(struct rpmi_service_group *group) +{ + if (!group) { + return; + } + + rpmi_env_free_lock(group->lock); + g_free(group->priv); +} + +bool riscv_rpmi_sysreset_add(RiscvRpmiState *s, Error **errp) +{ + struct rpmi_service_group *group; + + if (s->sysreset_group) { + error_setg(errp, "duplicate RPMI sysreset service descriptor"); + return false; + } + + group =3D riscv_rpmi_sysreset_create(s); + if (!group) { + error_setg(errp, "failed to create RPMI sysreset service group"); + return false; + } + + if (!riscv_rpmi_context_add_group(s, group, "sysreset", errp)) { + riscv_rpmi_sysreset_destroy(group); + return false; + } + + s->sysreset_group =3D group; + return true; +} + +void riscv_rpmi_sysreset_remove(RiscvRpmiState *s) +{ + if (!s->sysreset_group) { + return; + } + + riscv_rpmi_context_remove_group(s, s->sysreset_group); + riscv_rpmi_sysreset_destroy(s->sysreset_group); + s->sysreset_group =3D NULL; +} diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index e52ccfae1f..273a9aa04f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1007,6 +1007,35 @@ static void create_fdt_iommu(RISCVVirtState *s, uint= 16_t bdf) } =20 =20 +static const RiscvRpmiServiceConfig virt_rpmi_services[] =3D { + { + .kind =3D RISCV_RPMI_SERVICE_SYSRESET, + .node_name =3D "sysreset", + .compatible =3D "riscv,rpmi-system-reset", + .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_RESET, + }, +}; + +static uint32_t virt_rpmi_service_count(RISCVVirtState *s) +{ + return ARRAY_SIZE(virt_rpmi_services); +} + +static void virt_rpmi_system_reset(void *opaque) +{ + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); +} + +static void virt_rpmi_system_shutdown(void *opaque) +{ + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); +} + +static const RiscvRpmiMachineOps virt_rpmi_machine_ops =3D { + .system_reset =3D virt_rpmi_system_reset, + .system_shutdown =3D virt_rpmi_system_shutdown, +}; + static RiscvRpmiConfig virt_rpmi_config(RISCVVirtState *s, const uint32_t *hart_ids, uint32_t hart_count) @@ -1018,8 +1047,12 @@ static RiscvRpmiConfig virt_rpmi_config(RISCVVirtSta= te *s, .a2p_req_size =3D VIRT_RPMI_A2P_REQ_SIZE, .p2a_req_size =3D VIRT_RPMI_P2A_REQ_SIZE, .platform_info =3D "QEMU RISC-V virt RPMI", + .machine_ops =3D &virt_rpmi_machine_ops, + .machine_opaque =3D s, .hart_ids =3D hart_ids, .hart_count =3D hart_count, + .services =3D virt_rpmi_services, + .service_count =3D virt_rpmi_service_count(s), }; } =20 @@ -1028,6 +1061,7 @@ static void create_fdt_rpmi(RISCVVirtState *s, uint32= _t *phandle, { RiscvRpmiConfig rpmi_cfg =3D virt_rpmi_config(s, NULL, 0); uint32_t rpmi_mbox_handle; + uint32_t i; RiscvRpmiFdtMboxConfig cfg =3D { .shmem_base =3D rpmi_cfg.shmem_base, .doorbell_base =3D rpmi_cfg.doorbell_base, @@ -1038,6 +1072,12 @@ static void create_fdt_rpmi(RISCVVirtState *s, uint3= 2_t *phandle, =20 riscv_rpmi_fdt_add_mbox(MACHINE(s)->fdt, &cfg, phandle, &rpmi_mbox_handle); + + for (i =3D 0; i < rpmi_cfg.service_count; i++) { + riscv_rpmi_fdt_add_service_node(MACHINE(s)->fdt, rpmi_cfg.shmem_ba= se, + &rpmi_cfg.services[i], + rpmi_mbox_handle); + } } =20 static void finalize_fdt(RISCVVirtState *s) diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h index b5d8a32f9b..d11db87731 100644 --- a/include/hw/misc/riscv_rpmi.h +++ b/include/hw/misc/riscv_rpmi.h @@ -27,6 +27,7 @@ #define VIRT_RPMI_A2P_REQ_SIZE (16 * RPMI_QUEUE_SLOT_SIZE) #define VIRT_RPMI_P2A_REQ_SIZE 0 =20 +#define RISCV_RPMI_SRVGRP_SYSTEM_RESET 3 =20 #define TYPE_RISCV_RPMI "riscv-rpmi" OBJECT_DECLARE_SIMPLE_TYPE(RiscvRpmiState, RISCV_RPMI) @@ -38,8 +39,13 @@ struct rpmi_transport; =20 typedef enum RiscvRpmiServiceKind { RISCV_RPMI_SERVICE_INVALID =3D 0, + RISCV_RPMI_SERVICE_SYSRESET, } RiscvRpmiServiceKind; =20 +typedef struct RiscvRpmiMachineOps { + void (*system_reset)(void *opaque); + void (*system_shutdown)(void *opaque); +} RiscvRpmiMachineOps; typedef struct RiscvRpmiServiceConfig { RiscvRpmiServiceKind kind; const char *node_name; @@ -56,7 +62,8 @@ typedef struct RiscvRpmiConfig { uint32_t a2p_req_size; uint32_t p2a_req_size; const char *platform_info; - + const RiscvRpmiMachineOps *machine_ops; + void *machine_opaque; const uint32_t *hart_ids; uint32_t hart_count; const RiscvRpmiServiceConfig *services; @@ -73,7 +80,9 @@ struct RiscvRpmiState { uint32_t a2p_req_size; uint32_t p2a_req_size; char *platform_info; - + const RiscvRpmiMachineOps *machine_ops; + void *machine_opaque; + struct rpmi_service_group *sysreset_group; uint32_t *hart_ids; uint32_t hart_count; const RiscvRpmiServiceConfig *services; diff --git a/include/hw/riscv/rpmi-fdt.h b/include/hw/riscv/rpmi-fdt.h index f053ae5d57..af0e8a65ab 100644 --- a/include/hw/riscv/rpmi-fdt.h +++ b/include/hw/riscv/rpmi-fdt.h @@ -26,5 +26,16 @@ void riscv_rpmi_fdt_add_mbox(void *fdt, const RiscvRpmiFdtMboxConfig *cfg, uint32_t *phandle, uint32_t *mbox_handle); +void riscv_rpmi_fdt_add_service(void *fdt, hwaddr shmem_base, + const char *node_name, + const char *compatible, + uint32_t mbox_handle, + uint32_t service_group, + bool has_mpxy_channel, + uint32_t mpxy_channel); + +void riscv_rpmi_fdt_add_service_node(void *fdt, hwaddr shmem_base, + const RiscvRpmiServiceConfig *service, + uint32_t mbox_handle); =20 #endif --=20 2.43.0 From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686130; cv=none; d=zohomail.com; s=zohoarc; b=cZTK62eq0ZgWCKHj8vNrGiGBdGjieIC9871AYPoTEhRQaYcCv3pWN9fORhabX1fQAXT92fPKLPkPIWvzKCbcXD5fGgZoRfv8fSvJWV7A1SLezAZC7ksi96DnsSGe1mnqgG0SkIjbwSxZ8YF7mQdcXENSIVu1kKJ/1UVU1ZzrT+M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686130; h=Content-Transfer-Encoding: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:Cc; bh=t08bHJKjaddmUlHmz3nOuNBudB8m1WTA58X3xHCAAMw=; b=EOqa4mrMeYif1L3RYgkkWOron4FBCIECwq42vgPo9Z/h30CAYS+2NsyZArGqx9nFZoYZCFVtrLmlYKo8clISSJvH5DXOfBN0R4IlxfJRxsOkH4VOyEbFzEm4wqS78FCdraAww2rilPkP9hDxgjMnJ76X1hSUEJHxIY+xe0Ae1/U= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783686130365113.85920247832962; Fri, 10 Jul 2026 05:22:10 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEZ-0006SD-Nl; Fri, 10 Jul 2026 08:21:35 -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 1wi3lO-0000Nm-Nl for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:02 -0400 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lM-0004A8-3V for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:02 -0400 Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3mZtG3838057 for ; Fri, 10 Jul 2026 05:26:58 GMT Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fanwe8wa2-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:26:57 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-384cb1637c2so125220a91.2 for ; Thu, 09 Jul 2026 22:26:57 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.26.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:26:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=t08bHJKjadd mUlHmz3nOuNBudB8m1WTA58X3xHCAAMw=; b=WZ1lqL7ExsIc0pnHcGHYEo/Phac w0RDsXiaNuK2m4PgzLdv2v43nMsvi0COxZN0k0bKmSp/WkcqqJNVDhgmDdswmo7x kIMc3oOlzyROsftUASZbIkC4gKILorBRm8Q8Xq2NidB0fZdxPHsPoSw14pJRT2jQ XprI8ViBx0oTM9pz8FnyMqbqXtZlLYSZHsE2A9a+AepYfHwmVt4oyU22N9JKIKKo JH/0jPotsnsA9Py5tjDsdsukTpY5h8JqUpayLXkg44ZYOa8Vg064ExwLxM0KC57W wwn3ijv0H91WIlX7SlKtQcFVHZ1j5kdl1+Ld6yJ8RQGQ+kO0F7i6SImYtKw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661217; x=1784266017; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=t08bHJKjaddmUlHmz3nOuNBudB8m1WTA58X3xHCAAMw=; b=LRNksg7kD1sof8uXuMCAFNsCRX8PxoCkIV7ta5y64J42pqT49xwqPTVn3qRQBc6mrX cYX7AvL874+EaeHcY7buLOG8N8vgv/umZ6LXwzy/6vHwhtmlCPW6JiCW5bo35JjUCauL qdBduleS43qFAFO/doarOdMC4rXa6hHCWe8oSdgcsX2y0GDWQSzVkcsYLjvZHpV5tW// H54S69mxllskM5+RB/HIDcjwMs0cytcU6hetUSD/heyuATV8iQrBQsEUlavMbxgywy1j B1cbug4yZYz1rcQuThM1xdVNbQYkGC1zhrxutlpvYjaaSKe5X8wBUPQQccIr2gwBAyns m9Xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661217; x=1784266017; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=t08bHJKjaddmUlHmz3nOuNBudB8m1WTA58X3xHCAAMw=; b=SgEJ69f2pJ6RZyZtCYwKCd3sukoYKQXQXUB1ohGS9o/Cc17LU8zCvs46GMB5Cr0pX0 TVR8LKbzdb4eVHifZ4Ocf49aUHsqroqrPnSsxS9+UiL2zeSsyg2pB1Mtloqct9IlMLew Nl1xPyrWhs0e6grVKG69iX9YkCpusxBKcGItx7+PkCkGNGxTstnuSTcy+nHmtf8gq7fK k7KffgYTQM4BaLrzfd5JkbabETTDTQErBoenjNWAbafO/C4ZXjIj+olguyNziC2XbmMi R2zMcsCrU03ON/gLPxxCtleBPAi/Jvb+A4bECi3RYQgivabIk0IOIII8aForb7pAOp1G qOvw== X-Gm-Message-State: AOJu0YyYsPlcwja3krmnDknIiovjigPqrKfxhxWr6JLTihB0OJshnBHY 4rf6MM6TMAbyOcGC+l0JPTOYaIYJp4QAdnVwggQRIZs6TvCdvGbLrN08Hzu/NfdAWn9Xci5xwta oVxJ6R92rMlMPO/zvcvPb//JNKAigi4sgnY/FKEdiyItjYb/ZGakVAPt7hkVf29WEHg== X-Gm-Gg: AfdE7cmTK1Wx9gfRDFv/z8c2Yst4yVlrypUcQTSc4+YuzfTgsMDR6rcgR6cgwkX9oL7 /I5V/Chqg8/XD3WKrRXSQMkwApl1YHm76Ub9utqd1G474KQkPmmowTwHEUXdVDQDVaal1Ngqrdv wKBaq73fsqzuSeDbR/MYM5kVZVc7sFkJgR9f2eO39WlCF1rMOJjoxU83Q4hFj1nUNXw7TqAb6rW +k9n4iNmxAJD3S34H0w6Cak6B4qY6Jzj3TBHUTrWlh5alys6JzaUJtYtVS8lZmJPz8oTd/z0rlG 3LccV8woqvSa3DYuOk08PYZ3akpKgUYHksJj3nF5us3K6Tii7ISmZUphKp7xPUr46w6cDhXuH8d lMZmu/WOvBAabbvKo7uxdIGIxp4pUdK6MihgJOrR3cx9JgkzJvO2LSuy3I425LvW65tQkDfOUlZ J9EPkbzpun7HxSSGqWgDn8e2+VDMkCvxviT8m0rMSeHw== X-Received: by 2002:a17:90b:5287:b0:381:2788:a437 with SMTP id 98e67ed59e1d1-38a1f1dbefamr5155216a91.1.1783661217104; Thu, 09 Jul 2026 22:26:57 -0700 (PDT) X-Received: by 2002:a17:90b:5287:b0:381:2788:a437 with SMTP id 98e67ed59e1d1-38a1f1dbefamr5155193a91.1.1783661216541; Thu, 09 Jul 2026 22:26:56 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 06/10] riscv: add RPMI HSM service Date: Fri, 10 Jul 2026 10:56:38 +0530 Message-ID: <21b8264726d7d4a2dfc2c4446e980ffc18f9829e.1783660209.git.subrahmanya.lingappa@qti.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a5082a1 cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=hCKTHIyopvcgo9YcQkoA:9 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfXxfaKnjXv5Ddj IvNpJkdzefKGqmeO6dnmeKYP2TwRZTdWjbrXH1L9RkPloPeNNxE2l6oyAC8FYNfsIZzejH/Mw9p ej5o1ZSTZo1y1gFeneX+jmJ459Khyo5jp4pMKr6uYwo2QOfaCAuXj4NAWGRiwZmiPXjhp3qi+EN ZW0D+Ib/tL2ykz9X5tMWMSTy9z/IthABsw1ZBPqdHWMJ5yofuED/bQENmjk6oKYELSfUf4RIIAY 2cNM5ofcJKLM7YPZpeLKOFHlJvr1xCI/wORYA/VPVZ6i9XuHH/+fJ+hNQDwhVqnVAoLXaGfXWhO bTs+fWbi4TaIvfv+jb8uKVjX+nhrDAV1+HPPh5YndnLYZJoXv4Yf9sUl4SlSP4cIh0R3krwcpX9 rydWTGAWW6raTjD2GkpzSuKGyfCmK7wb9yoC/KKacjGj+yBfjYPbkhI09EEb77KjkVRkx7oX6xA 0Mq5PUNCW9NX+UkW5pQ== X-Proofpoint-ORIG-GUID: 3jMSaQinCqBRBAoZwkEnSxfotA0pOLJ5 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX8Q30yx7FkA41 ul2SjzArjfIQnzIEc+0Jgt+aqqjQwxNAL5q2QeiFwDhTcH2ue2k4P+kEHd4C2dKYILC2DmqgpBh vIG70lo5uMEvbUd8ycVSmM8WPBKgmfw= X-Proofpoint-GUID: 3jMSaQinCqBRBAoZwkEnSxfotA0pOLJ5 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 suspectscore=0 lowpriorityscore=0 bulkscore=0 clxscore=1011 impostorscore=0 priorityscore=1501 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.168.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686132203158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add the RPMI Hart State Management service group for RISC-V virt. The service exposes the configured virt hart IDs to librpmi and keeps per-hart RPMI hardware state in the RPMI device. Start, stop, and suspend requests update QEMU CPU halted state and resume/kick vCPUs as needed so firmware can exercise RPMI HSM operations against the emulated topology. Signed-off-by: Subrahmanya Lingappa --- hw/misc/meson.build | 1 + hw/misc/riscv_rpmi.c | 46 ++++++ hw/misc/riscv_rpmi_hsm.c | 280 ++++++++++++++++++++++++++++++++++ hw/misc/riscv_rpmi_internal.h | 4 + hw/riscv/virt.c | 6 + include/hw/misc/riscv_rpmi.h | 6 + 6 files changed, 343 insertions(+) create mode 100644 hw/misc/riscv_rpmi_hsm.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index bca7819ee0..fc5b11ed57 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -171,4 +171,5 @@ system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi= .c')) system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files( 'riscv_rpmi.c', 'riscv_rpmi_sysreset.c', + 'riscv_rpmi_hsm.c', ), librpmi]) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c index 7a3f570ee7..820b1d5d63 100644 --- a/hw/misc/riscv_rpmi.c +++ b/hw/misc/riscv_rpmi.c @@ -171,6 +171,49 @@ static bool riscv_rpmi_transport_indices_valid(RiscvRp= miState *s) s->a2p_req_size); } =20 +typedef struct RiscvRpmiServiceOps { + RiscvRpmiServiceKind kind; + void (*configure)(RiscvRpmiState *s, const RiscvRpmiConfig *cfg); + bool (*add)(RiscvRpmiState *s, Error **errp); + void (*remove)(RiscvRpmiState *s); +} RiscvRpmiServiceOps; + +static const RiscvRpmiServiceOps riscv_rpmi_service_ops[] =3D { + { + .kind =3D RISCV_RPMI_SERVICE_SYSRESET, + .add =3D riscv_rpmi_sysreset_add, + .remove =3D riscv_rpmi_sysreset_remove, + }, { + .kind =3D RISCV_RPMI_SERVICE_HSM, + .add =3D riscv_rpmi_hsm_add, + .remove =3D riscv_rpmi_hsm_remove, + }, +}; + +static const RiscvRpmiServiceOps *riscv_rpmi_service_ops_by_kind( + RiscvRpmiServiceKind kind) +{ + for (uint32_t i =3D 0; i < ARRAY_SIZE(riscv_rpmi_service_ops); i++) { + if (riscv_rpmi_service_ops[i].kind =3D=3D kind) { + return &riscv_rpmi_service_ops[i]; + } + } + + return NULL; +} + +static void riscv_rpmi_configure_services(RiscvRpmiState *s, + const RiscvRpmiConfig *cfg) +{ + for (uint32_t i =3D 0; i < ARRAY_SIZE(riscv_rpmi_service_ops); i++) { + const RiscvRpmiServiceOps *ops =3D &riscv_rpmi_service_ops[i]; + + if (ops->configure && riscv_rpmi_service_enabled(s, ops->kind)) { + ops->configure(s, cfg); + } + } +} + static void riscv_rpmi_configure_base(RiscvRpmiState *s, const RiscvRpmiConfig *cfg) { @@ -187,6 +230,8 @@ static void riscv_rpmi_configure_base(RiscvRpmiState *s, cfg->hart_count * sizeof(*cfg->hart_id= s)); } } + + riscv_rpmi_configure_services(s, cfg); } =20 static void riscv_rpmi_init(Object *obj) @@ -209,6 +254,7 @@ static void riscv_rpmi_reset(DeviceState *dev) memory_region_set_dirty(&s->shmem, 0, s->shmem_size); } =20 + riscv_rpmi_hsm_reset(s); } =20 static void riscv_rpmi_cleanup(RiscvRpmiState *s) diff --git a/hw/misc/riscv_rpmi_hsm.c b/hw/misc/riscv_rpmi_hsm.c new file mode 100644 index 0000000000..9a9859b10c --- /dev/null +++ b/hw/misc/riscv_rpmi_hsm.c @@ -0,0 +1,280 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI HSM service. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "riscv_rpmi_internal.h" +#include "hw/core/cpu.h" +#include "librpmi_env.h" + +static const struct rpmi_hsm_suspend_type riscv_rpmi_hsm_suspend_types[] = =3D { + { + .type =3D 0, + .info =3D { + .flags =3D 0, + .entry_latency_us =3D 0, + .exit_latency_us =3D 0, + .wakeup_latency_us =3D 0, + .min_residency_us =3D 0, + }, + }, +}; + +typedef struct RiscvRpmiHsmStateTransition { + enum rpmi_hart_hw_state state; + bool halted; + bool resume; +} RiscvRpmiHsmStateTransition; + +static const RiscvRpmiHsmStateTransition riscv_rpmi_hsm_state_transitions[= ] =3D { + { + .state =3D RPMI_HART_HW_STATE_STARTED, + .halted =3D false, + .resume =3D true, + }, { + .state =3D RPMI_HART_HW_STATE_STOPPED, + .halted =3D true, + .resume =3D false, + }, { + .state =3D RPMI_HART_HW_STATE_SUSPENDED, + .halted =3D true, + .resume =3D false, + }, +}; + +static const RiscvRpmiHsmStateTransition *riscv_rpmi_hsm_state_transition( + enum rpmi_hart_hw_state state) +{ + for (uint32_t index =3D 0; + index < ARRAY_SIZE(riscv_rpmi_hsm_state_transitions); index++) { + if (riscv_rpmi_hsm_state_transitions[index].state =3D=3D state) { + return &riscv_rpmi_hsm_state_transitions[index]; + } + } + + return NULL; +} + +static CPUState *riscv_rpmi_hart_cpu(RiscvRpmiState *s, uint32_t hart_inde= x) +{ + if (hart_index >=3D s->hart_count || !s->hart_ids) { + return NULL; + } + + return cpu_by_arch_id(s->hart_ids[hart_index]); +} + +static void riscv_rpmi_hsm_set_hw_state(RiscvRpmiState *s, + uint32_t hart_index, + enum rpmi_hart_hw_state state) +{ + CPUState *cpu =3D riscv_rpmi_hart_cpu(s, hart_index); + const RiscvRpmiHsmStateTransition *transition; + + if (hart_index >=3D s->hart_count || !s->hsm_hw_states) { + return; + } + + s->hsm_hw_states[hart_index] =3D state; + if (!cpu) { + return; + } + + transition =3D riscv_rpmi_hsm_state_transition(state); + if (!transition) { + return; + } + + cpu->halted =3D transition->halted; + if (transition->resume) { + cpu_resume(cpu); + } else { + qemu_cpu_kick(cpu); + } +} + +static enum rpmi_error riscv_rpmi_hsm_start_prepare( + void *priv, rpmi_uint32_t hart_index, rpmi_uint64_t start_addr) +{ + RiscvRpmiState *s =3D priv; + CPUState *cpu =3D riscv_rpmi_hart_cpu(s, hart_index); + + if (!cpu) { + return RPMI_ERR_INVALID_PARAM; + } + + riscv_rpmi_hsm_set_hw_state(s, hart_index, RPMI_HART_HW_STATE_STARTED); + return RPMI_SUCCESS; +} + +static void riscv_rpmi_hsm_start_finalize(void *priv, + rpmi_uint32_t hart_index, + rpmi_uint64_t start_addr) +{ +} + +static enum rpmi_error riscv_rpmi_hsm_stop_prepare(void *priv, + rpmi_uint32_t hart_inde= x) +{ + RiscvRpmiState *s =3D priv; + + if (!riscv_rpmi_hart_cpu(s, hart_index)) { + return RPMI_ERR_INVALID_PARAM; + } + + riscv_rpmi_hsm_set_hw_state(s, hart_index, RPMI_HART_HW_STATE_STOPPED); + return RPMI_SUCCESS; +} + +static void riscv_rpmi_hsm_stop_finalize(void *priv, rpmi_uint32_t hart_in= dex) +{ +} + +static enum rpmi_error riscv_rpmi_hsm_suspend_prepare( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_hsm_suspend_type *suspend_type, + rpmi_uint64_t resume_addr) +{ + RiscvRpmiState *s =3D priv; + + if (!suspend_type || !riscv_rpmi_hart_cpu(s, hart_index)) { + return RPMI_ERR_INVALID_PARAM; + } + + riscv_rpmi_hsm_set_hw_state(s, hart_index, RPMI_HART_HW_STATE_SUSPENDE= D); + return RPMI_SUCCESS; +} + +static void riscv_rpmi_hsm_suspend_finalize( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_hsm_suspend_type *suspend_type, + rpmi_uint64_t resume_addr) +{ +} + +static enum rpmi_hart_hw_state riscv_rpmi_hsm_get_hw_state( + void *priv, rpmi_uint32_t hart_index) +{ + RiscvRpmiState *s =3D priv; + + if (hart_index >=3D s->hart_count || !s->hsm_hw_states) { + return RPMI_HART_HW_STATE_STOPPED; + } + + return s->hsm_hw_states[hart_index]; +} + +static const struct rpmi_hsm_platform_ops riscv_rpmi_hsm_ops =3D { + .hart_get_hw_state =3D riscv_rpmi_hsm_get_hw_state, + .hart_start_prepare =3D riscv_rpmi_hsm_start_prepare, + .hart_start_finalize =3D riscv_rpmi_hsm_start_finalize, + .hart_stop_prepare =3D riscv_rpmi_hsm_stop_prepare, + .hart_stop_finalize =3D riscv_rpmi_hsm_stop_finalize, + .hart_suspend_prepare =3D riscv_rpmi_hsm_suspend_prepare, + .hart_suspend_finalize =3D riscv_rpmi_hsm_suspend_finalize, +}; + +static bool riscv_rpmi_hsm_create(RiscvRpmiState *s, + struct rpmi_service_group **group, + Error **errp) +{ + struct rpmi_hsm *hsm; + + if (!s->hart_count || !s->hart_ids) { + error_setg(errp, "RPMI HSM service requires hart IDs"); + return false; + } + + s->hsm_hw_states =3D g_new0(uint32_t, s->hart_count); + for (uint32_t i =3D 0; i < s->hart_count; i++) { + s->hsm_hw_states[i] =3D RPMI_HART_HW_STATE_STARTED; + } + + hsm =3D rpmi_hsm_create(s->hart_count, s->hart_ids, + ARRAY_SIZE(riscv_rpmi_hsm_suspend_types), + riscv_rpmi_hsm_suspend_types, + &riscv_rpmi_hsm_ops, s); + if (!hsm) { + g_clear_pointer(&s->hsm_hw_states, g_free); + error_setg(errp, "failed to create RPMI HSM context"); + return false; + } + + *group =3D rpmi_service_group_hsm_create(hsm); + if (!*group) { + rpmi_hsm_destroy(hsm); + g_clear_pointer(&s->hsm_hw_states, g_free); + error_setg(errp, "failed to create RPMI HSM service group"); + return false; + } + + s->hsm =3D hsm; + return true; +} + +static void riscv_rpmi_hsm_destroy(RiscvRpmiState *s) +{ + if (s->hsm_group) { + rpmi_env_free_lock(s->hsm_group->lock); + s->hsm_group->lock =3D NULL; + rpmi_service_group_hsm_destroy(s->hsm_group); + s->hsm_group =3D NULL; + } + + if (s->hsm) { + rpmi_hsm_destroy(s->hsm); + s->hsm =3D NULL; + } + + g_clear_pointer(&s->hsm_hw_states, g_free); +} + + +bool riscv_rpmi_hsm_add(RiscvRpmiState *s, Error **errp) +{ + struct rpmi_service_group *group; + + if (s->hsm_group) { + error_setg(errp, "duplicate RPMI HSM service descriptor"); + return false; + } + + if (!riscv_rpmi_hsm_create(s, &group, errp)) { + return false; + } + + if (!riscv_rpmi_context_add_group(s, group, "HSM", errp)) { + s->hsm_group =3D group; + riscv_rpmi_hsm_destroy(s); + return false; + } + + s->hsm_group =3D group; + return true; +} + +void riscv_rpmi_hsm_remove(RiscvRpmiState *s) +{ + riscv_rpmi_context_remove_group(s, s->hsm_group); + riscv_rpmi_hsm_destroy(s); +} + +void riscv_rpmi_hsm_reset(RiscvRpmiState *s) +{ + if (!s->hsm_hw_states) { + return; + } + + for (uint32_t i =3D 0; i < s->hart_count; i++) { + s->hsm_hw_states[i] =3D RPMI_HART_HW_STATE_STARTED; + } + if (s->hsm) { + rpmi_hsm_process_state_changes(s->hsm); + } +} diff --git a/hw/misc/riscv_rpmi_internal.h b/hw/misc/riscv_rpmi_internal.h index fe09804e69..42a6708907 100644 --- a/hw/misc/riscv_rpmi_internal.h +++ b/hw/misc/riscv_rpmi_internal.h @@ -30,4 +30,8 @@ void riscv_rpmi_context_remove_group(RiscvRpmiState *s, bool riscv_rpmi_sysreset_add(RiscvRpmiState *s, Error **errp); void riscv_rpmi_sysreset_remove(RiscvRpmiState *s); =20 +bool riscv_rpmi_hsm_add(RiscvRpmiState *s, Error **errp); +void riscv_rpmi_hsm_remove(RiscvRpmiState *s); +void riscv_rpmi_hsm_reset(RiscvRpmiState *s); + #endif diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 273a9aa04f..2b5f367bdb 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1014,6 +1014,12 @@ static const RiscvRpmiServiceConfig virt_rpmi_servic= es[] =3D { .compatible =3D "riscv,rpmi-system-reset", .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_RESET, }, + { + .kind =3D RISCV_RPMI_SERVICE_HSM, + .node_name =3D "hsm", + .compatible =3D "riscv,rpmi-hsm", + .service_group =3D RISCV_RPMI_SRVGRP_HSM, + }, }; =20 static uint32_t virt_rpmi_service_count(RISCVVirtState *s) diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h index d11db87731..37c56ea2e8 100644 --- a/include/hw/misc/riscv_rpmi.h +++ b/include/hw/misc/riscv_rpmi.h @@ -28,6 +28,7 @@ #define VIRT_RPMI_P2A_REQ_SIZE 0 =20 #define RISCV_RPMI_SRVGRP_SYSTEM_RESET 3 +#define RISCV_RPMI_SRVGRP_HSM 5 =20 #define TYPE_RISCV_RPMI "riscv-rpmi" OBJECT_DECLARE_SIMPLE_TYPE(RiscvRpmiState, RISCV_RPMI) @@ -36,10 +37,12 @@ struct rpmi_context; struct rpmi_service_group; struct rpmi_shmem; struct rpmi_transport; +struct rpmi_hsm; =20 typedef enum RiscvRpmiServiceKind { RISCV_RPMI_SERVICE_INVALID =3D 0, RISCV_RPMI_SERVICE_SYSRESET, + RISCV_RPMI_SERVICE_HSM, } RiscvRpmiServiceKind; =20 typedef struct RiscvRpmiMachineOps { @@ -83,6 +86,9 @@ struct RiscvRpmiState { const RiscvRpmiMachineOps *machine_ops; void *machine_opaque; struct rpmi_service_group *sysreset_group; + struct rpmi_hsm *hsm; + struct rpmi_service_group *hsm_group; + uint32_t *hsm_hw_states; uint32_t *hart_ids; uint32_t hart_count; const RiscvRpmiServiceConfig *services; --=20 2.43.0 From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686303; cv=none; d=zohomail.com; s=zohoarc; b=iixBYJTY/v5aPUgigvKJDD4K44qlMlTc0sX2CD8zET5E+wJlo0gMEZUNlilzU0D16V337SGA+jJx5O61Kklcuurbvl0wAJJ8F48AXOZ2XxR3Hb8HLXZgoZvZ0WHTtUv9NyI00p5MY0acEyOAoB9S7DCzHH3bCz5o9cdkyoCqiMM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686303; h=Content-Transfer-Encoding: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:Cc; bh=qqexeTU5rC0F3XG2W/BVlfxGTL9faWmCVU3vE/quGCk=; b=jMaqCz/RgEM4W3XuIkobu4TqxnvoCpSvydC1fly5fm11EM4otSAUxEEx6+5izI7dWYC1cEJx0FZeCuicl8gJ2yRjJHEwLURSG0sKWBh0N+8lz3TIXpKz/TyDg+2lDusiUxFvdwITAH5S3Guyq14MqWaA0jepqskERFPr6ojM3fw= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783686303467397.42187297734097; Fri, 10 Jul 2026 05:25:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEp-0006XY-Mg; Fri, 10 Jul 2026 08:21:51 -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 1wi3lP-0000O4-3o for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:03 -0400 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lM-0004AS-TF for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:02 -0400 Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3nSD23848797 for ; Fri, 10 Jul 2026 05:27:00 GMT Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4faeestu9w-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:26:59 +0000 (GMT) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-2cc98d6a88bso1721275ad.0 for ; Thu, 09 Jul 2026 22:26:59 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.26.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:26:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=qqexeTU5rC0 F3XG2W/BVlfxGTL9faWmCVU3vE/quGCk=; b=ixksy8bzLJx14SFhgK/BvjzDvxo FIvU+am0aCG0i7XxnxmxJK677gMyVo5huMvW3m0dMGmAZ2FQTpz1sRNH+hBvQhFi Q8ms0XJdtljuuiEKnpFIQPoPYZASbehKBbzQQMcxueRvZK0qGaIWP8T/pwh/HoXt qJKb2MpP2lps/QU38jG9H4mCN8hsDtG4OOE1Cvj1BQQzAiN7KjMFxQasSje0tzK/ 1yiJgeoRGOYluNqZxgcq2fj+G2p68nTryQOVqQImcOFUBRGdZ/POMhedziBJLoQ3 IDo7EzEBA7e7a+UsOcC7DPxQLe1pj2TDXQ+6vRRimOxMiXzgTmbdvEpakEg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661219; x=1784266019; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=qqexeTU5rC0F3XG2W/BVlfxGTL9faWmCVU3vE/quGCk=; b=jv5+ZtkxbNzC4K9tl+IQFT9RyzLGmC/kxMauQyT6seC9Ulq2Qv+o+lV7JtucTFikMg gFqi07NWaAQZjmKbrLldM8kDGwHR/VgCq4xCx8PTFggQyO6XWqlojmTx/QMPO6k0Gd7q 4OmKwZMfXvoFWrbTyn2HD2K5zTgb0IZW/Kr8zRRsqzOkElswPRXxgdwjRVoDVDzL06um DXmOij5Upr2dXnLB2eYhcm379m/NhlNnC6xksDtha6r9g16MQQgaxQjaSYxdaN1QJWe9 KXm7/SxB5ZB+UUC32pOIrUvIZomQ9J9n1l2k330HmCv430A63kOvy4E55GF9jhEIObFw vmgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661219; x=1784266019; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=qqexeTU5rC0F3XG2W/BVlfxGTL9faWmCVU3vE/quGCk=; b=XXr5x1uuTrlquB7l+0ynn9gkVp4UfplN2H0+ux3rpEtFQhNrLAMTPGYyp5+rNoMy+P FYrmXSWy/OBGKt6T+ds8+J0XbNuABWsHcjIKKmA542FyuH47uhH6GmiI92666YWS3cF1 8aVZV+iObl10A5OxLz74LKz18jPQKvBYoQziflY1AYbMRWBHnMShGeb+tpqcTktdBd+0 g3SnEF3eYM8FlKM3YWTqTqK5h474S1n0eF7MWKzhJNYR9csy/voUYLiMjPWy3HgJLM+n iifmYx3nibzN6DwCpQQxvuvhmFrmBp5VQ1SXs9EBZDCCp0ZzIb/QbHOIB6c8kmVEkonL aixg== X-Gm-Message-State: AOJu0YwD0J7iV+4XIwLSoEAc4csGw4tZ/2kNtUF47sH2WQbIXJ7a9wFm PX4nYmlZHJp8ZwvMdrqseAbpwZTnHC2GGcUvw4ucWcJWO++9wfQz2IPZ90lkTWKjP3dmt8/h9fc HkboJ2x+4lYxd2ZTdT2nTLQfVLPMfwSRFRHWWusj2+y5+zztjmxKIWxAS+uUgMcaj7g== X-Gm-Gg: AfdE7cmoGSOV8/vRHUfFKxX3K017MQqlk7WGGHpan66OhGWy4CjpJgXLVTWrav9PyyT ozqGO+WazxJrfQUknf41q7s8gztfxNCnCyOchwM6Zy/05HpIpbagrDdhadqF3JY18GEtsnVDzKg ptbUFMrj0eHFSvLt69P1kGxauUsmCRo4mnbp2GuzlOFQSLiLDQmRYXgjFU01fwypMXeHak3r2dU nOHDbK0xEPme9w7kvs29L55d/o7zkMl6KkuAK+Q2v7qFwlme8X2CYSahyDO4GOdriyDcVHmWaUn A/wwcadJYmKxUE969isnIP/DCJreoJfsKnIGUfTte4oMfq7xu9LDSDMheKuttaJcnNF8Ja1Yhiv QPBMnukpSG8yFDqcVcIS5zU/FWcQITUOy4P/U1LfCF6d8HhPq7SEt2KboSej/XQ1/WIXR4GSR4h s165S1/I0QRa+9Ir042vFIoF3+AC+0NjsuclAWnqefbQ== X-Received: by 2002:a17:903:244a:b0:2ca:d9ec:3217 with SMTP id d9443c01a7336-2ccff1b9995mr56856475ad.7.1783661218791; Thu, 09 Jul 2026 22:26:58 -0700 (PDT) X-Received: by 2002:a17:903:244a:b0:2ca:d9ec:3217 with SMTP id d9443c01a7336-2ccff1b9995mr56856215ad.7.1783661218156; Thu, 09 Jul 2026 22:26:58 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 07/10] riscv: add RPMI system suspend service Date: Fri, 10 Jul 2026 10:56:39 +0530 Message-ID: <1362f2b24fc65169cf916bd3be4ef107f8d0c000.1783660209.git.subrahmanya.lingappa@qti.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: xNr_pmgtaYh72RqHOZzsTdySP9uEdPJA X-Authority-Analysis: v=2.4 cv=bbpbluPB c=1 sm=1 tr=0 ts=6a5082a4 cx=c_pps a=JL+w9abYAAE89/QcEU+0QA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=YpNgDGc-obDsCk2VH-MA:9 a=324X-CrmTo6CU4MGRt3R:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX/cUwcd4DDkfV 93FojbTAcBf61EXOF3ST4VPpK4dohzkEq8aApWblj+VrbbFrBQReuntvz+UvDrMFjFnLdRbqDtr uJbu2qKt+7PJyzCMXHjQp4T3mbrL7sc= X-Proofpoint-ORIG-GUID: xNr_pmgtaYh72RqHOZzsTdySP9uEdPJA X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX4CsUJZRjK0Tc APyZd2sAcUk6sshsnSlrf6lHmyrANPf5qN2vfkYNHzIApg71aE/v1qgZTTnYpadY8Ccn03uyK3s 1mdDCnD2zM+2OuulidZgoeitn52FOXGaXmpMKCOzzqQdxa7BkIxRvgHQm+64vRyjg9PLVOfJKkU xueliYVwchNfCc6kpNEEk7/4u/ErgGRe8YYdmNEiZosEgvBptL0z+bfcvAw1t9zgW5QOYBdKPbA xMd0ISLBcxmJsJ/Qc7fDrrHnG/Epbs59IS/WvIQv8xN+8xCyKofKFNZPlPCGgC7PjHxrrNHQolG NTVuiuN8X5MtN7AQtfd2aZIedMGIh5qMl96JyqTYxAZvuPbwwWyY4dCagUK86I3Q1Tt30L8SkGP I82fn2cK+vhbgUycCWMwuOy2XHSrMnKR3OPCGKBERiQsrCU7yhutDfR+RmzBNA6sBDCQziY8bGY Fs74cvBwcNLehZLhZzA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 priorityscore=1501 malwarescore=0 bulkscore=0 suspectscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.180.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0b-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686305067158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add the RPMI System Suspend service group for RISC-V virt. The service advertises suspend-to-RAM support through librpmi, registers QEMU wakeup support, and routes the suspend finalize callback to the machine suspend path. On wakeup it processes RPMI group events and defers the HSM hart resume until vCPUs are ready to run again. Signed-off-by: Subrahmanya Lingappa --- hw/misc/meson.build | 1 + hw/misc/riscv_rpmi.c | 4 + hw/misc/riscv_rpmi_hsm.c | 9 +- hw/misc/riscv_rpmi_internal.h | 5 + hw/misc/riscv_rpmi_syssusp.c | 191 ++++++++++++++++++++++++++++++++++ hw/riscv/virt.c | 25 +++++ include/hw/misc/riscv_rpmi.h | 11 ++ 7 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 hw/misc/riscv_rpmi_syssusp.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index fc5b11ed57..cb093a8642 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -172,4 +172,5 @@ system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [file= s( 'riscv_rpmi.c', 'riscv_rpmi_sysreset.c', 'riscv_rpmi_hsm.c', + 'riscv_rpmi_syssusp.c', ), librpmi]) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c index 820b1d5d63..08691861b0 100644 --- a/hw/misc/riscv_rpmi.c +++ b/hw/misc/riscv_rpmi.c @@ -187,6 +187,10 @@ static const RiscvRpmiServiceOps riscv_rpmi_service_op= s[] =3D { .kind =3D RISCV_RPMI_SERVICE_HSM, .add =3D riscv_rpmi_hsm_add, .remove =3D riscv_rpmi_hsm_remove, + }, { + .kind =3D RISCV_RPMI_SERVICE_SYSSUSP, + .add =3D riscv_rpmi_syssusp_add, + .remove =3D riscv_rpmi_syssusp_remove, }, }; =20 diff --git a/hw/misc/riscv_rpmi_hsm.c b/hw/misc/riscv_rpmi_hsm.c index 9a9859b10c..bacdabcac6 100644 --- a/hw/misc/riscv_rpmi_hsm.c +++ b/hw/misc/riscv_rpmi_hsm.c @@ -235,7 +235,6 @@ static void riscv_rpmi_hsm_destroy(RiscvRpmiState *s) g_clear_pointer(&s->hsm_hw_states, g_free); } =20 - bool riscv_rpmi_hsm_add(RiscvRpmiState *s, Error **errp) { struct rpmi_service_group *group; @@ -278,3 +277,11 @@ void riscv_rpmi_hsm_reset(RiscvRpmiState *s) rpmi_hsm_process_state_changes(s->hsm); } } + +void riscv_rpmi_hsm_resume(RiscvRpmiState *s, uint32_t hart_index) +{ + riscv_rpmi_hsm_set_hw_state(s, hart_index, RPMI_HART_HW_STATE_STARTED); + if (s->hsm) { + rpmi_hsm_process_state_changes(s->hsm); + } +} diff --git a/hw/misc/riscv_rpmi_internal.h b/hw/misc/riscv_rpmi_internal.h index 42a6708907..34cab35c32 100644 --- a/hw/misc/riscv_rpmi_internal.h +++ b/hw/misc/riscv_rpmi_internal.h @@ -33,5 +33,10 @@ void riscv_rpmi_sysreset_remove(RiscvRpmiState *s); bool riscv_rpmi_hsm_add(RiscvRpmiState *s, Error **errp); void riscv_rpmi_hsm_remove(RiscvRpmiState *s); void riscv_rpmi_hsm_reset(RiscvRpmiState *s); +void riscv_rpmi_hsm_resume(RiscvRpmiState *s, uint32_t hart_index); + +bool riscv_rpmi_syssusp_add(RiscvRpmiState *s, Error **errp); +void riscv_rpmi_syssusp_remove(RiscvRpmiState *s); + =20 #endif diff --git a/hw/misc/riscv_rpmi_syssusp.c b/hw/misc/riscv_rpmi_syssusp.c new file mode 100644 index 0000000000..d455e08163 --- /dev/null +++ b/hw/misc/riscv_rpmi_syssusp.c @@ -0,0 +1,191 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI System Suspend service. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "riscv_rpmi_internal.h" +#include "qemu/timer.h" +#include "system/runstate.h" + +static const struct rpmi_system_suspend_type riscv_rpmi_syssusp_types[] = =3D { + { + .type =3D RPMI_SYSSUSP_TYPE_SUSPEND_TO_RAM, + .attr =3D RPMI_SYSSUSP_ATTRS_FLAGS_RESUMEADDR, + }, +}; + +static enum rpmi_error riscv_rpmi_syssusp_prepare( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_system_suspend_type *syssusp_type, + rpmi_uint64_t resume_addr) +{ + RiscvRpmiState *s =3D priv; + + if (s->machine_ops && s->machine_ops->register_wakeup_support) { + s->machine_ops->register_wakeup_support(s->machine_opaque); + } + return RPMI_SUCCESS; +} + +static rpmi_bool_t riscv_rpmi_syssusp_ready(void *priv, + rpmi_uint32_t hart_index) +{ + return true; +} + +static void riscv_rpmi_syssusp_finalize( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_system_suspend_type *syssusp_type, + rpmi_uint64_t resume_addr) +{ + RiscvRpmiState *s =3D priv; + + if (s->machine_ops && s->machine_ops->system_suspend) { + s->machine_ops->system_suspend(s->machine_opaque); + } +} + +static rpmi_bool_t riscv_rpmi_syssusp_can_resume(void *priv, + rpmi_uint32_t hart_index) +{ + RiscvRpmiState *s =3D priv; + + if (s->machine_ops && s->machine_ops->system_can_resume) { + return s->machine_ops->system_can_resume(s->machine_opaque); + } + + return true; +} + +static enum rpmi_error riscv_rpmi_syssusp_resume( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_system_suspend_type *syssusp_type, + rpmi_uint64_t resume_addr) +{ + RiscvRpmiState *s =3D priv; + + s->syssusp_resume_hart_index =3D hart_index; + s->syssusp_resume_pending =3D true; + return RPMI_SUCCESS; +} + +static const struct rpmi_syssusp_platform_ops riscv_rpmi_syssusp_ops =3D { + .system_suspend_prepare =3D riscv_rpmi_syssusp_prepare, + .system_suspend_ready =3D riscv_rpmi_syssusp_ready, + .system_suspend_finalize =3D riscv_rpmi_syssusp_finalize, + .system_suspend_can_resume =3D riscv_rpmi_syssusp_can_resume, + .system_suspend_resume =3D riscv_rpmi_syssusp_resume, +}; + +static void riscv_rpmi_wakeup_timer(void *opaque) +{ + RiscvRpmiState *s =3D opaque; + + if (s->syssusp_resume_pending) { + riscv_rpmi_hsm_resume(s, s->syssusp_resume_hart_index); + s->syssusp_resume_pending =3D false; + } +} + +static void riscv_rpmi_wakeup_notify(Notifier *notifier, void *data) +{ + RiscvRpmiState *s =3D container_of(notifier, RiscvRpmiState, + wakeup_notifier); + + if (s->context) { + rpmi_context_process_group_events(s->context, + RPMI_SRVGRP_SYSTEM_SUSPEND); + } + if (s->wakeup_timer) { + /* + * Wakeup notifiers run before vCPUs resume. Defer the HSM + * kick so OpenSBI can leave WFI after QEMU restarts execution. + */ + timer_mod(s->wakeup_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) = + 10); + } +} + +static bool riscv_rpmi_syssusp_create(RiscvRpmiState *s, + struct rpmi_service_group **group, + Error **errp) +{ + if (!s->hsm) { + error_setg(errp, "RPMI system suspend service requires HSM service= "); + return false; + } + + if (s->machine_ops && s->machine_ops->register_wakeup_support) { + s->machine_ops->register_wakeup_support(s->machine_opaque); + } + if (!s->wakeup_timer) { + s->wakeup_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, + riscv_rpmi_wakeup_timer, s); + } + if (!s->wakeup_notifier_registered) { + s->wakeup_notifier.notify =3D riscv_rpmi_wakeup_notify; + qemu_register_wakeup_notifier(&s->wakeup_notifier); + s->wakeup_notifier_registered =3D true; + } + + *group =3D rpmi_service_group_syssusp_create( + s->hsm, ARRAY_SIZE(riscv_rpmi_syssusp_types), + riscv_rpmi_syssusp_types, &riscv_rpmi_syssusp_ops, s); + if (!*group) { + error_setg(errp, "failed to create RPMI system suspend service gro= up"); + return false; + } + + return true; +} + +static void riscv_rpmi_syssusp_destroy(RiscvRpmiState *s) +{ + if (s->wakeup_notifier_registered) { + notifier_remove(&s->wakeup_notifier); + s->wakeup_notifier_registered =3D false; + } + if (s->wakeup_timer) { + timer_free(s->wakeup_timer); + s->wakeup_timer =3D NULL; + } + + if (s->syssusp_group) { + rpmi_service_group_syssusp_destroy(s->syssusp_group); + s->syssusp_group =3D NULL; + } +} + +bool riscv_rpmi_syssusp_add(RiscvRpmiState *s, Error **errp) +{ + struct rpmi_service_group *group; + + if (s->syssusp_group) { + error_setg(errp, "duplicate RPMI system suspend descriptor"); + return false; + } + + if (!riscv_rpmi_syssusp_create(s, &group, errp)) { + return false; + } + + if (!riscv_rpmi_context_add_group(s, group, "system suspend", errp)) { + s->syssusp_group =3D group; + riscv_rpmi_syssusp_destroy(s); + return false; + } + + s->syssusp_group =3D group; + return true; +} + +void riscv_rpmi_syssusp_remove(RiscvRpmiState *s) +{ + riscv_rpmi_context_remove_group(s, s->syssusp_group); + riscv_rpmi_syssusp_destroy(s); +} diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 2b5f367bdb..21c218a78d 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -51,6 +51,7 @@ #include "chardev/char.h" #include "system/device_tree.h" #include "system/system.h" +#include "system/runstate.h" #include "system/tcg.h" #include "system/kvm.h" #include "system/tpm.h" @@ -1020,6 +1021,12 @@ static const RiscvRpmiServiceConfig virt_rpmi_servic= es[] =3D { .compatible =3D "riscv,rpmi-hsm", .service_group =3D RISCV_RPMI_SRVGRP_HSM, }, + { + .kind =3D RISCV_RPMI_SERVICE_SYSSUSP, + .node_name =3D "suspend", + .compatible =3D "riscv,rpmi-system-suspend", + .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_SUSPEND, + }, }; =20 static uint32_t virt_rpmi_service_count(RISCVVirtState *s) @@ -1037,9 +1044,27 @@ static void virt_rpmi_system_shutdown(void *opaque) qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } =20 +static void virt_rpmi_system_suspend(void *opaque) +{ + qemu_system_suspend_request(); +} + +static void virt_rpmi_register_wakeup_support(void *opaque) +{ + qemu_register_wakeup_support(); +} + +static bool virt_rpmi_system_can_resume(void *opaque) +{ + return runstate_check(RUN_STATE_RUNNING); +} + static const RiscvRpmiMachineOps virt_rpmi_machine_ops =3D { .system_reset =3D virt_rpmi_system_reset, .system_shutdown =3D virt_rpmi_system_shutdown, + .system_suspend =3D virt_rpmi_system_suspend, + .register_wakeup_support =3D virt_rpmi_register_wakeup_support, + .system_can_resume =3D virt_rpmi_system_can_resume, }; =20 static RiscvRpmiConfig virt_rpmi_config(RISCVVirtState *s, diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h index 37c56ea2e8..a4fe2aac63 100644 --- a/include/hw/misc/riscv_rpmi.h +++ b/include/hw/misc/riscv_rpmi.h @@ -29,6 +29,7 @@ =20 #define RISCV_RPMI_SRVGRP_SYSTEM_RESET 3 #define RISCV_RPMI_SRVGRP_HSM 5 +#define RISCV_RPMI_SRVGRP_SYSTEM_SUSPEND 4 =20 #define TYPE_RISCV_RPMI "riscv-rpmi" OBJECT_DECLARE_SIMPLE_TYPE(RiscvRpmiState, RISCV_RPMI) @@ -43,11 +44,15 @@ typedef enum RiscvRpmiServiceKind { RISCV_RPMI_SERVICE_INVALID =3D 0, RISCV_RPMI_SERVICE_SYSRESET, RISCV_RPMI_SERVICE_HSM, + RISCV_RPMI_SERVICE_SYSSUSP, } RiscvRpmiServiceKind; =20 typedef struct RiscvRpmiMachineOps { void (*system_reset)(void *opaque); void (*system_shutdown)(void *opaque); + void (*system_suspend)(void *opaque); + void (*register_wakeup_support)(void *opaque); + bool (*system_can_resume)(void *opaque); } RiscvRpmiMachineOps; typedef struct RiscvRpmiServiceConfig { RiscvRpmiServiceKind kind; @@ -86,9 +91,15 @@ struct RiscvRpmiState { const RiscvRpmiMachineOps *machine_ops; void *machine_opaque; struct rpmi_service_group *sysreset_group; + struct rpmi_service_group *syssusp_group; struct rpmi_hsm *hsm; struct rpmi_service_group *hsm_group; uint32_t *hsm_hw_states; + Notifier wakeup_notifier; + bool wakeup_notifier_registered; + QEMUTimer *wakeup_timer; + bool syssusp_resume_pending; + uint32_t syssusp_resume_hart_index; uint32_t *hart_ids; uint32_t hart_count; const RiscvRpmiServiceConfig *services; --=20 2.43.0 From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686369; cv=none; d=zohomail.com; s=zohoarc; b=IkfKjh/fxRwqk3s3IARQ+aZRgkbwbxEIpmi3H/fztLk0T7fwgmSdLsu66yqaoGRn2abdCWEx+trQNcUIHGos4njzCGydZIgzDxRQTgTZWRnQGYaRAvM+WL68hhCkBv0e8j9V6iNDrDbSPf4UOtja7/TbA4lGNvglFDMhrkeDpTM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686369; h=Content-Transfer-Encoding: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:Cc; bh=Reyq+Bfk7gr9bLQ5GSqP4nU1exjoe62siU0U9X/2MjE=; b=fKBLa8UCzim1umSnPshlvMdqisSl33evmQ6YxkEmCcLd1p4WhT7M84JXf4CUtoML+at1DZ7vuDQsugsJ0pZ+EzZxd3QV76pQ1svv8mNxs0Qoy8y5Ztb1JLk41A4jGauf3rA3jlQmoWwWviBW47yA8etR3PRt6Hh5NYrhPwq9iBk= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783686368987739.4236312866701; Fri, 10 Jul 2026 05:26:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEd-0006Vf-4y; Fri, 10 Jul 2026 08:21:39 -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 1wi3lR-0000OC-62 for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:05 -0400 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lO-0004BO-HO for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:04 -0400 Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3mbbW3838073 for ; Fri, 10 Jul 2026 05:27:01 GMT Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fanwe8wac-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:27:01 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-382befb9555so161275a91.1 for ; Thu, 09 Jul 2026 22:27:01 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.26.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:26:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=Reyq+Bfk7gr 9bLQ5GSqP4nU1exjoe62siU0U9X/2MjE=; b=NylzNL0S/HTOjdjfURU+fGJuqb0 8BBYLYAx6hn+bsq3QTbvajCiW4C+fPff6WvDYlc/Ynz+shZZrFB8LubFyLltr4mb QteRiTIcR/dfamkkTG9NcuZb4dWhcyA2WAnxZEjlPg0/SPUp5GMiGjy75xUNv8ps HNIYZ6WuX9vKE08BT2XR8CDi+0a7hYl6/g3worQqyfHG0pPbZ92MfEwzqJ4d38S1 VQZXQ7wo8DCP5U6tx+cSmWpc8zqRg4vdxD/qtFbC3UH5eCnaOC5JyifMdDiulqAv 0A0w97fpv2kGwAPu5Jq17aI5jziAcVeNGpgfP+gYqMvQ7Agmud5LCGkpkSA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661220; x=1784266020; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=Reyq+Bfk7gr9bLQ5GSqP4nU1exjoe62siU0U9X/2MjE=; b=HcUWlxTvOBNl+BziiYEjPq5rk3JowqvLQ4w9KU+0ybjCuMfn2BLm4aKDgYAqjpHEVC 9R/hcY4k2giimxqmoo8jTvowh1y5n+a+eBL2DpimKZE7JCae6hPGBaw8MpuzjjMKTXii zJasmCh701xk9BIDdERzCN7WgPhej+IqwDDhmLBkkLPSNX0XzvkZehqXORDOgSgypMat l14gejhH7ezs03GLL5x6BPy/mTo7oeR0ECzdAjpFIaJw0aUti+ln+eHcRsPz4S99s1tv HJVGFK/9GQlJEbF9qlBAjT0rsqXhY2LEP/Pq2SbK+mVZBUJVi4TVHLmV6Sckr2ySuU24 sTKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661220; x=1784266020; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=Reyq+Bfk7gr9bLQ5GSqP4nU1exjoe62siU0U9X/2MjE=; b=fZIIIQWlL9qFVStiCo11UooxXxQZlZT77/q817s3i+werD7EhxkKWQzdKFCQE8h4IE UriZK1xvA5afJZMKcD8T1Y7Fowvzx9190sXTFsnNAZIP7tZh6w8IPOoLZylY6etJzhdy aJCyLkALR6rWhJpXGrM2At3s5qRO3BdGytEGrJ/96aM0fkMsdzyW7G9Lyf5BnyhbpJMf xELWhGG11OWbNd2yJS7ZO2yFtabTjm9P309WUxNqN+VMjmWIKBrnoiJK1pIOVSNxYi6k 4mpNP/AuyX1/RWTncpuZLuiYb5kxmxt7obXvZpPWSRYz+iQl9GDHDjh1+pv/mjFqJU8s XscA== X-Gm-Message-State: AOJu0YxmSgaE9ZHrMOQ2TKcByOzX5ng5iOEmTDa1bfAPrpUjdmcj80Kq saMwLpnWg/909ZQZALhGZuT3WM7y08Ik2XpIseJTvEiPfd9yO5O1QlA0yIhd7rwiVmEkkx0kMmH Dwp+D6dHj1TogkPi80CMzKPSb7sT/eLRjNxJjc/MnCDWth7E8fPFSvFcXtRRAfuT4Vg== X-Gm-Gg: AfdE7cnwr8Uwv+yYatRxh7kTI2+mL//M1udUHsIesmA4xTvvdzl1O3ZxzaBKEWmAtDb sRvFQf1s6UfmuiUNHKG/Kr3ti/c0zvwNNxDiKgwFYctPOjCzuZ4OaAKgkUFod4lAioeiz2IwPxb amU87t3A8+zu8/0/kbbtCnpZD+mTUyfvR4PC2ID9rMl4LF6Q9lbmYmYFbQetOknhuqaWayP2Eqm OggTJSt8Vclh29G1MknQ2gVlWH7YLKN8Twm0uaELvZmanJIfyntIffeKftGT+ifUJUyUDne0Nl2 ZQsyEvys1EhwjmIPtPaVKZZWae8yjiDOn4vRXatYmsGIj6VgmjVgc9PgKkdOZ/Iyl4/wJvNAxWa Pax9X7IQOb6aQ1MtQekcsR4c+/dRcbm7GTAhNjpNXSzSyY7dInRKKkVdG18e0uuqcrPwApvf8S0 sR0jA1G8LL+RIe3Oov/AJ308sAvuKPoAVSMX1WD4OGPA== X-Received: by 2002:a17:90b:4d12:b0:380:9cd1:d985 with SMTP id 98e67ed59e1d1-38a2160e57emr6423841a91.6.1783661220326; Thu, 09 Jul 2026 22:27:00 -0700 (PDT) X-Received: by 2002:a17:90b:4d12:b0:380:9cd1:d985 with SMTP id 98e67ed59e1d1-38a2160e57emr6423817a91.6.1783661219730; Thu, 09 Jul 2026 22:26:59 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 08/10] docs/system/riscv: document initial virt RPMI support Date: Fri, 10 Jul 2026 10:56:40 +0530 Message-ID: <10f13dfad6528556a3bb4aa077aca8c38e34bc24.1783660209.git.subrahmanya.lingappa@qti.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a5082a5 cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=V1jnuoLLAAAA:20 a=NEAV23lmAAAA:8 a=EUspDBNiAAAA:8 a=RyhCfiGMEKD-kOZgqhYA:9 a=uKXjsCUrEbL0IQVhDsJ9:22 a=bA3UWDv6hWIuX7UZL3qL:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX0qk3kBf3t7Bz ho2aVUSrmZBN5NLzbUdlYfi/hERI0jEY+dU2VusGNoLy+zsnYS7NHoM2v+LeL7Wt+dRLPzrPMk/ +DxusujH8WRgp6SyIHCfhUXMAnf35IsV5zJ9wYdwPSyUhSwGVvyA9OqgTkmdw97QyybXxdU3t2X ZPohyBWSjYAzGigoszNaRs/eoFf8Kl9AR0r5wBIxOk4u+HBpV5h5bdas1+vKvh74dJ0mlyTizmO OqInm2onSJBwNu7TZRlUGfMsudozo8GJRlHq9X7M6HAt4Q4Z+WYqc7icONQeHwReiuwMYdHzv3k fyLGzzm4DFbHpiV+PZFS2R8sjQZMtW4go8DoHHRqfvd/J3Xsm26mV7Ivo9hHXskLufeyiBOtYw2 lNnqpgY8W9FIrwuAT+x8Fkrw3h9F7YcXD2iqvQGEcmO1OZhKd5ne6TLrZOAQEvM6g2leEgFVMQU 94AscevCFSmT13wQ0Fw== X-Proofpoint-ORIG-GUID: lKnOc_esYAkQpCl2MyrWY9XCodyJWfEM X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX3pkzbtitc9Te AN3TqqvgNyIKrVEj5SON83DlObcQk23FlMyos2vAWyxhePpDdjBku06sJcq7Nebh0nQqWGtdoTi 54g/O87EQzNCTZn/eS6zFyq4VFGNkPA= X-Proofpoint-GUID: lKnOc_esYAkQpCl2MyrWY9XCodyJWfEM X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 suspectscore=0 lowpriorityscore=0 bulkscore=0 clxscore=1015 impostorscore=0 priorityscore=1501 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.168.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686369553158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Document the opt-in virt RPMI transport and the initial HSM, system reset, and system suspend service groups. Signed-off-by: Subrahmanya Lingappa --- docs/system/riscv/virt.rst | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst index 60850970ce..8e88f780e1 100644 --- a/docs/system/riscv/virt.rst +++ b/docs/system/riscv/virt.rst @@ -146,6 +146,56 @@ The following machine-specific options are supported: =20 Enables the riscv-iommu-sys platform device. Defaults to 'off'. =20 +- rpmi=3D[on|off] + + Enables the RISC-V RPMI shared-memory transport. This option defaults to + "off", is TCG-only, and is available only when QEMU is built with librpmi + support. This support targets the RISC-V Platform Management Interface + (RPMI) Specification v1.0 Ratified (`RPMI v1.0 specification`_). The ini= tial + ``virt`` implementation exposes RPMI system reset, system suspend, and H= SM + service groups. System reset can request shutdown or cold reboot through + RPMI. HSM uses the ``virt`` hart IDs and supports hart discovery, status, + start, stop, and suspend commands. System suspend uses QEMU's suspend and + wakeup path. Migration is currently blocked while RPMI transport and ser= vice + VMState support is being designed. + + The build dependency is provided by `librpmi`_. Install librpmi so that + ``pkg-config`` can find ``librpmi.pc``, then configure QEMU with + ``--enable-librpmi`` or ``-Dlibrpmi=3Denabled``. + +.. _RPMI v1.0 specification: https://github.com/riscv-non-isa/riscv-rpmi/r= eleases/download/v1.0/riscv-rpmi.pdf +.. _librpmi: https://github.com/riscv-software-src/librpmi + +RPMI firmware and guest smoke +----------------------------- + +A firmware-level RPMI smoke test can be run with OpenSBI, a Linux kernel, = and a +RISC-V disk image: + +.. code-block:: bash + + $ qemu-system-riscv64 \ + -machine virt,rpmi=3Don \ + -cpu rv64 -smp 4 -m 4G -nographic \ + -bios /path/to/fw_jump.bin \ + -kernel /path/to/Image \ + -append "root=3D/dev/vda rw console=3DttyS0 earlycon=3Dsbi" \ + -drive file=3D/path/to/rootfs.img,format=3Draw,if=3Dvirtio,snapshot= =3Don + +The OpenSBI banner should report RPMI-backed HSM and system suspend suppor= t. +After the guest reaches a shell, normal guest reboot/poweroff commands exe= rcise +the RPMI system reset path. + +RPMI device tree policy +----------------------- + +RPMI is currently described through FDT only; no ACPI representation is em= itted +for the RPMI transport or service groups. The ``virt`` machine uses the +``riscv,rpmi-shmem-mbox`` shared-memory mailbox node plus child service no= des +with ``riscv,rpmi-*`` compatible strings. These binding names are part of = the +RPMI RFC surface and may be revised if the RISC-V RPMI bindings change dur= ing +review. + Running Linux kernel -------------------- =20 --=20 2.43.0 From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686147; cv=none; d=zohomail.com; s=zohoarc; b=O3d+dqQi4AkP7EO2wy6vzuJUteFIyOq/ffxiaB8eVqxAyRqyYg9DxdlnGYLp1bEG+Ssmu0lxLqNNGiKkYk/cttWy4WLpeiJS05Lda2ujjpEBsVVgDWpnfqT81hGObWuZKMf5OSXI7QUhcFNU6pDI9/QkRXQPG3F+t/IdEo+dXbo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686147; h=Content-Transfer-Encoding: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:Cc; bh=xljqCi1LtqvoxwLHoydu294Ph4jNzL+usHTeM3Olgac=; b=NmHnrQc78zmJD7B3wrKojZD4EHSNMNzgfUbtv83/C0SNoxCzue7JRIkWLrCgj+Ya2X+ffP+hu1St3GqlbZNOzmtjWhQQ1pe/fhntPuh+DNjRgyvrioEaT6jcvAouXgmsFbevSHdU1aDqzQIzY7FPWvyMc4yi1PqKg12EFdQrqhc= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783686147521685.2678701794715; Fri, 10 Jul 2026 05:22:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEz-00072k-Cj; Fri, 10 Jul 2026 08:22:01 -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 1wi3lU-0000OT-J3 for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:09 -0400 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lQ-0004Bj-U7 for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:08 -0400 Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3moJR3629762 for ; Fri, 10 Jul 2026 05:27:03 GMT Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fahv8hq57-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:27:03 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-388277fd89aso157661a91.2 for ; Thu, 09 Jul 2026 22:27:03 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.27.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:27:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=xljqCi1Ltqv oxwLHoydu294Ph4jNzL+usHTeM3Olgac=; b=TZrjjPtTOG2VverLUh7N0zE0YWV tYtYQyexBU0Q6smcrMnJAWqj1jSjtVgAqSPhJu+NLm4tK0hf4Qe096FTdJIv8Fwv Sgx6yjaVQQKIY2Hr/S7eLHGrHeqxkQC8WEFf6KoepylO9MuNlVQkyZz+exHv5Unq 2WZ1n3QafCn/215StHZDo3Ye1VFuHYGlyHHSC2DdLwwB9xzH9izLfwF0YFGDdOQH bQ38fFLhOTMf0jgnNosebaADhTZdguuqeVmHopNRK69ZIvCrUw5u2RotO8KZx6q/ hr82fn79PqA5nJcK+N3cHLIc4sVqtU9dx7OHmm+TUghBnbxYQezSG72oAng== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661222; x=1784266022; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=xljqCi1LtqvoxwLHoydu294Ph4jNzL+usHTeM3Olgac=; b=bA9iNVtpREXxVN5oG587N4OzulzoECtp6e8ZZ5fsZEPN3mZ5aS+x42G5+z7x5miULT JU1yreKsINBf5Ci+xuNkK2vxOOf8tHomoSnr0Hku8GHUv1HUFnCTT1yTJESLvP/2EDEX 0NnjhnC9w3m9hIvpeME8a8kHsAEilzJacRenfokId34qpjddQrmNzBkaqvJQnXH2bm4H wbj1+qH7Wnoen2vjdtJkgEpihMb1O/C5ufYYkz0bfvPIbC1LlX+79I9ZAjo2N+Zed+0Q ABP6rnkAZVMbg9e2UO95phCG9FQ/+6PTbbhAQEXeWTeIZ7v3DYbfygYCb2Da3reNrBR8 xI4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661222; x=1784266022; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=xljqCi1LtqvoxwLHoydu294Ph4jNzL+usHTeM3Olgac=; b=ZubggRrqKfG+/Pqr48KqWSYAxySH7F2c1Rsj5MADOx3joT8tL+xeYkorm1HOg/8qRP ZTyBVXnRuQ21x/7jR5znjwEhJfLD10j75K73uCSTmILQ/Olw0wqjnRfQ6mUnH+EL+YeS 9jLKP7Jv+JfotWgLKk8J1MJu5y6nkHXtmFNwr3yFHmX1/NAyH/3U5lo8qRNwqHvMZwY+ eB4VGd/AHGHWVdMG8NU/KyLn/h/fFOYnY2xXBY14reUMUQVuz4xQuqMWznogqk1kbN60 1GSZB+n4bggQkuBIWMrT49C8mI5wTfj8LuVSCFxeBbcrnxesMgHgUD45VF7nrH/gfvH2 pFTw== X-Gm-Message-State: AOJu0YzeV9rSE9nFAMMD5eCSyuYZCczUJaTi5ug1ItR7eG5S0Youaaj3 hNEjsp9cmNVIcYuaZPb55q9H/ROquDs+xPyvs7gkiYTo9uSP56gidTu1AQlkIDkP5/tn3pbBu0b Vk6CyHdyTXP+oQjqHjd16jQSNq46e1Dn1h3F/wkDij0pKiCQ3MRZVxoJOLgGowTi0WQ== X-Gm-Gg: AfdE7cnt0QBXkwchlHRZKXPL849v0x459pLR2Xyj4cEPrqk2ltvIlByZXvt8nZT0JBT FoAQGlfMVfOcpfQQtFXQC7vQCFx5r5zYV3Zvk15KVz5/JsAkhboKYNOlSDQ1Tjz8P2BzOSAsFIl Zk7FGGFy4HIWL6fE+qMgnTMveR4M8qIX8Ty8PwG4JSzEYcvjdSraTwFEVz+4UKLGeOSPLNvEwCE bzF/f0YSU5JSgMU+Ve0RdIdlIvtRPcMTXvaISt6CIAAKV5GA+Xm3HocLsKefN0Sn1T9kPySJWVP wG5irA4ZwGhZiBlmTVBtwPDN+xOvRtee4r+Dc309p18apqPZM2MNUip46s1WoYyKLAPSbjDQsz5 YptRBBin2a9CjCxlxDbi5qyZ38Zae+x/Myj/KQu49LHSrXO81NNReK9y9qH803d4tiFOCIAGy1s vJzfs/VPzHU8pIU/h3LAW29NA+wmrUwnlAhW39CnYqMg== X-Received: by 2002:a17:90b:3fc8:b0:37f:df57:2ddf with SMTP id 98e67ed59e1d1-3893f97f9acmr8505985a91.1.1783661222189; Thu, 09 Jul 2026 22:27:02 -0700 (PDT) X-Received: by 2002:a17:90b:3fc8:b0:37f:df57:2ddf with SMTP id 98e67ed59e1d1-3893f97f9acmr8505964a91.1.1783661221451; Thu, 09 Jul 2026 22:27:01 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 09/10] tests/qtest: cover initial RISC-V RPMI services Date: Fri, 10 Jul 2026 10:56:41 +0530 Message-ID: <3ce559db08a853001115da730be724f76f95b802.1783660209.git.subrahmanya.lingappa@qti.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: puRnKJ77TkdDILkonqlV8Fa3E6EdYEoe X-Proofpoint-ORIG-GUID: puRnKJ77TkdDILkonqlV8Fa3E6EdYEoe X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfXxyPuiqkF3Z9F bWrgqnZvAodyVmt/YGijXL/oDjJSQJeCBM3yblJEnRrFPBhPg/UFe59oyxMtVbI67t2upY76K11 y1+sexT1/2x9Dr/zey1zNgMGPVH5KxY= X-Authority-Analysis: v=2.4 cv=funsol4f c=1 sm=1 tr=0 ts=6a5082a7 cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=cXInsyxJmRBO8JMYNpUA:9 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX9qBlzqOJPybr ufTuVDQeaSpAh64VGqJ+MYLPRewrDVoaKo80GRa4Qv0uBDBVTIsiJVQBgKSFeMqYC5kSzDbzUwI AWgZCe9V9apaDRg5hsrUJAh6AAXhG6UGHpdyIFy7I2sWZ1uh6iLYRUD/oWAgfhhZQjaF7rDuwzD WDEMTXT409sJD4ZQw+XMRaig0vypY1sJu+JZX3rN85rzaZuXw0bL0SGDtRMc3vRWEub+kl1lGwz wvRSyD4rDeK3oLUK061dYd0Pbv9pLdJ+Og/cr10NK4woBRoOr+j0HPNm9lUNNO6peSiR0/2ESMZ UIJGg8Bnk63oEIXms1DX5XVOMUDmj2GNPNL0hcdv+San4jCrS8vZ9+oNzGLlKey7gImXxj9aUPq smY/fSUXv3F5XP4W685Vgt8SMJuZkJeCNPLfC6SiU85YwPLFgLInGun9klLuA3yLuFTdW+CsHaK gYI8dji7syAgozG+oag== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 phishscore=0 clxscore=1015 lowpriorityscore=0 adultscore=0 bulkscore=0 suspectscore=0 malwarescore=0 priorityscore=1501 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.168.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686147959158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add qtests for the RPMI transport plus Base, system reset, HSM, and system suspend service groups. Signed-off-by: Subrahmanya Lingappa --- MAINTAINERS | 1 + tests/qtest/meson.build | 2 + tests/qtest/riscv-rpmi-test.c | 684 ++++++++++++++++++++++++++++++++++ 3 files changed, 687 insertions(+) create mode 100644 tests/qtest/riscv-rpmi-test.c diff --git a/MAINTAINERS b/MAINTAINERS index 8e91a31757..6dd71c5a82 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -361,6 +361,7 @@ F: hw/riscv/ F: hw/intc/riscv* F: hw/misc/riscv_rpmi* F: include/hw/misc/riscv_rpmi.h +F: tests/qtest/riscv-rpmi-test.c F: include/hw/char/riscv_htif.h F: include/hw/riscv/ F: common-user/host/riscv* diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 4897325d84..d54b79cbcf 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -290,6 +290,8 @@ qtests_riscv32 =3D \ =20 qtests_riscv64 =3D ['riscv-csr-test'] + \ (unpack_edk2_blobs ? ['bios-tables-test'] : []) + \ + (config_all_devices.has_key('CONFIG_RISCV_RPMI') ? + ['riscv-rpmi-test'] : []) + \ (config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and config_all_devices.has_key('CONFIG_RISCV_IOMMU') ? ['iommu-riscv-test'] : []) + \ diff --git a/tests/qtest/riscv-rpmi-test.c b/tests/qtest/riscv-rpmi-test.c new file mode 100644 index 0000000000..ecd5b910c7 --- /dev/null +++ b/tests/qtest/riscv-rpmi-test.c @@ -0,0 +1,684 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * QTests for RISC-V RPMI devices. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include +#include "libqtest.h" +#include "qobject/qdict.h" + +#define RPMI_SHMEM_BASE 0x10200000ULL +#define RPMI_DOORBELL_BASE 0x10230000ULL +#define RPMI_IMSIC_S_BASE 0x28000000ULL +#define RPMI_CPPC_FASTCHAN_BASE 0x10240000ULL +#define RPMI_CPPC_FASTCHAN_SIZE 0x4000 +#define RPMI_CPPC_FASTCHAN_FEEDBACK_OFFSET 0x2000 +#define RPMI_SLOT_SIZE 64 + +#define RPMI_A2P_HEAD RPMI_SHMEM_BASE +#define RPMI_A2P_TAIL (RPMI_SHMEM_BASE + RPMI_SLOT_SIZE) +#define RPMI_A2P_SLOT0 (RPMI_SHMEM_BASE + 2 * RPMI_SLOT_SIZE) + +#define RPMI_SRVGRP_BASE 0x0001 +#define RPMI_SRVGRP_SYSTEM_MSI 0x0002 +#define RPMI_SRVGRP_SYSTEM_RESET 0x0003 +#define RPMI_SRVGRP_SYSTEM_SUSPEND 0x0004 +#define RPMI_SRVGRP_HSM 0x0005 +#define RPMI_SRVGRP_CPPC 0x0006 +#define RPMI_SRVGRP_CLOCK 0x0008 +#define RPMI_SRVGRP_MANAGEMENT_MODE 0x000b +#define RPMI_SRVGRP_LOGGING 0x000e +#define RPMI_BASE_SRV_GET_PLATFORM_INFO 0x05 +#define RPMI_BASE_SRV_PROBE_SERVICE_GROUP 0x06 +#define RPMI_SYSMSI_SRV_GET_ATTRIBUTES 0x02 +#define RPMI_SYSMSI_SRV_GET_MSI_ATTRIBUTES 0x03 +#define RPMI_SYSMSI_SRV_SET_MSI_STATE 0x04 +#define RPMI_SYSMSI_SRV_GET_MSI_STATE 0x05 +#define RPMI_SYSMSI_SRV_SET_MSI_TARGET 0x06 +#define RPMI_SYSMSI_SRV_GET_MSI_TARGET 0x07 +#define RPMI_SYSRST_SRV_GET_ATTRIBUTES 0x02 +#define RPMI_SYSRST_SRV_SYSTEM_RESET 0x03 +#define RPMI_HSM_SRV_GET_HART_STATUS 0x02 +#define RPMI_HSM_SRV_GET_HART_LIST 0x03 +#define RPMI_HSM_SRV_GET_SUSPEND_TYPES 0x04 +#define RPMI_HSM_SRV_GET_SUSPEND_INFO 0x05 +#define RPMI_HSM_SRV_HART_START 0x06 +#define RPMI_HSM_SRV_HART_STOP 0x07 +#define RPMI_HSM_SRV_HART_SUSPEND 0x08 +#define RPMI_SYSSUSP_SRV_GET_ATTRIBUTES 0x02 +#define RPMI_SYSSUSP_SRV_SYSTEM_SUSPEND 0x03 +#define RPMI_CPPC_SRV_PROBE_REG 0x02 +#define RPMI_CPPC_SRV_READ_REG 0x03 +#define RPMI_CPPC_SRV_WRITE_REG 0x04 +#define RPMI_CPPC_SRV_GET_FAST_CHANNEL_REGION 0x05 +#define RPMI_CPPC_SRV_GET_FAST_CHANNEL_OFFSET 0x06 +#define RPMI_CPPC_SRV_GET_HART_LIST 0x07 +#define RPMI_CPPC_NOMINAL_PERF 0x01 +#define RPMI_CPPC_DESIRED_PERF 0x05 +#define RPMI_CPPC_COUNTER_WRAPAROUND_TIME 0x0a +#define RPMI_CPPC_REFERENCE_PERF_COUNTER 0x0b +#define RPMI_CPPC_DELIVERED_PERF_COUNTER 0x0c +#define RPMI_CPPC_REG_LEN_64 64 +#define RPMI_CLK_SRV_GET_NUM_CLOCKS 0x02 +#define RPMI_CLK_SRV_GET_ATTRIBUTES 0x03 +#define RPMI_CLK_SRV_GET_SUPPORTED_RATES 0x04 +#define RPMI_CLK_SRV_SET_CONFIG 0x05 +#define RPMI_CLK_SRV_GET_CONFIG 0x06 +#define RPMI_CLK_SRV_SET_RATE 0x07 +#define RPMI_CLK_SRV_GET_RATE 0x08 +#define RPMI_MM_SRV_GET_ATTRIBUTES 0x02 +#define RPMI_MM_SRV_COMMUNICATE 0x03 +#define RPMI_LOGGING_SRV_SET_CONFIG 0x02 +#define RPMI_MSG_NORMAL_REQUEST 0x00 +#define RPMI_MSG_POSTED_REQUEST 0x01 +#define RPMI_MSG_ACKNOWLEDGEMENT 0x02 +#define RPMI_SYSRST_TYPE_SHUTDOWN 0x00 +#define RPMI_SYSRST_TYPE_COLD_REBOOT 0x01 +#define RPMI_SYSRST_TYPE_INVALID 0x03 +#define RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE 1 +#define RPMI_SYS_MSI_SHUTDOWN_INDEX 0 +#define RPMI_SYS_MSI_REBOOT_INDEX 1 +#define RPMI_SYS_MSI_SUSPEND_INDEX 2 +#define RPMI_SYS_NUM_MSI 4 +#define RPMI_SYSMSI_MSI_STATE_ENABLE 1 +#define RPMI_SYSMSI_MSI_STATE_PENDING 2 +#define RPMI_TOKEN 0x55aa +#define RPMI_ERR_NOTSUPP 0xfffffffeU +#define RPMI_ERR_INVALID_PARAM 0xfffffffdU +#define RPMI_ERR_INVALID_ADDR 0xfffffffbU +#define RPMI_ERR_DENIED 0xfffffffcU +#define RPMI_HSM_HART_STATE_STARTED 0x00 +#define RPMI_HSM_HART_STATE_STOPPED 0x01 +#define RPMI_HSM_HART_STATE_SUSPENDED 0x04 +#define VIRT_RPMI_CPPC_NOMINAL_PERF 30 +#define VIRT_RPMI_CLOCK_COUNT 6 +#define VIRT_RPMI_MM_VERSION 0x10000 +#define VIRT_RPMI_SHMEM_SIZE 0x20000 +#define RPMI_MM_INPUT_OFFSET 0x3000 +#define RPMI_MM_OUTPUT_OFFSET 0x3800 +#define RPMI_MM_BUFFER_SIZE 0x400 +#define RPMI_MM_INPUT_BASE (RPMI_SHMEM_BASE + RPMI_MM_INPUT_OFFSET) +#define RPMI_MM_OUTPUT_BASE (RPMI_SHMEM_BASE + RPMI_MM_OUTPUT_OFFSET) +#define MM_EFI_COMM_HEADER_SIZE 24 +#define EFI_VAR_COMM_HEADER_SIZE 16 +#define EFI_VAR_ACCESS_NAME_OFFSET 36 +#define EFI_VAR_NEXT_NAME_OFFSET 24 +#define EFI_VAR_FN_GET_VARIABLE 1 +#define EFI_VAR_FN_GET_NEXT_VARIABLE_NAME 2 +#define EFI_VAR_FN_SET_VARIABLE 3 +#define EFI_SUCCESS 0ULL +#define EFI_INVALID_PARAMETER 0x8000000000000002ULL +#define EFI_BUFFER_TOO_SMALL 0x8000000000000005ULL +#define EFI_NOT_FOUND 0x800000000000000eULL +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 + +#define RPMI_P2A_ACK_BASE (RPMI_SHMEM_BASE + 16 * RPMI_SLOT_SIZE) +#define RPMI_P2A_ACK_HEAD RPMI_P2A_ACK_BASE +#define RPMI_P2A_ACK_TAIL (RPMI_P2A_ACK_BASE + RPMI_SLOT_SIZE) +#define RPMI_P2A_ACK_SLOT0 (RPMI_P2A_ACK_BASE + 2 * RPMI_SLOT_SIZE) + +static uint64_t rpmi_response_base; + +static uint64_t rpmi_queue_slot(uint64_t queue_base, uint32_t index) +{ + return queue_base + (index + 2) * RPMI_SLOT_SIZE; +} + +static void rpmi_send_request(QTestState *qts, uint16_t service_group, + uint8_t service_id, uint8_t request_type, + const uint32_t *data, size_t data_words) +{ + uint32_t tail =3D qtest_readl(qts, RPMI_A2P_TAIL); + uint64_t slot =3D rpmi_queue_slot(RPMI_SHMEM_BASE, tail); + size_t i; + + qtest_writew(qts, slot, service_group); + qtest_writeb(qts, slot + 2, service_id); + qtest_writeb(qts, slot + 3, request_type); + qtest_writew(qts, slot + 4, data_words * sizeof(*data)); + qtest_writew(qts, slot + 6, RPMI_TOKEN); + + for (i =3D 0; i < data_words; i++) { + qtest_writel(qts, slot + 8 + i * sizeof(*data), data[i]); + } + + g_test_message( + "RPMI_A2P_REQ shmem=3D0x%016" PRIx64 " doorbell=3D0x%016" PRIx64 + " group=3D0x%04x service=3D0x%02x type=3D0x%02x data_len=3D%zu" + " token=3D0x%04x a2p_tail=3D%u slot=3D0x%016" PRIx64, + (uint64_t)RPMI_SHMEM_BASE, (uint64_t)RPMI_DOORBELL_BASE, + service_group, service_id, request_type, data_words * sizeof(*data= ), + RPMI_TOKEN, tail, slot); + + qtest_writel(qts, RPMI_A2P_TAIL, (tail + 1) % 16); + qtest_writel(qts, RPMI_DOORBELL_BASE, 1); +} + +static uint32_t rpmi_response_word(QTestState *qts, unsigned int word) +{ + return qtest_readl(qts, rpmi_response_base + 8 + word * sizeof(uint32_= t)); +} + +static void rpmi_expect_ack(QTestState *qts, uint16_t service_group, + uint8_t service_id, uint16_t data_len) +{ + uint32_t head =3D qtest_readl(qts, RPMI_P2A_ACK_HEAD); + uint32_t tail =3D qtest_readl(qts, RPMI_P2A_ACK_TAIL); + + g_assert_cmphex(tail, !=3D, head); + rpmi_response_base =3D rpmi_queue_slot(RPMI_P2A_ACK_BASE, head); + g_assert_cmphex(qtest_readw(qts, rpmi_response_base), =3D=3D, service_= group); + g_assert_cmphex(qtest_readb(qts, rpmi_response_base + 2), =3D=3D, + service_id); + g_assert_cmphex(qtest_readb(qts, rpmi_response_base + 3), =3D=3D, + RPMI_MSG_ACKNOWLEDGEMENT); + g_assert_cmphex(qtest_readw(qts, rpmi_response_base + 4), =3D=3D, data= _len); + g_assert_cmphex(qtest_readw(qts, rpmi_response_base + 6), =3D=3D, + RPMI_TOKEN); + g_test_message( + "RPMI_P2A_ACK shmem=3D0x%016" PRIx64 + " group=3D0x%04x service=3D0x%02x type=3D0x%02x data_len=3D%u" + " token=3D0x%04x p2a_head=3D%u slot=3D0x%016" PRIx64 + " status=3D0x%08x", + (uint64_t)RPMI_SHMEM_BASE, service_group, service_id, + RPMI_MSG_ACKNOWLEDGEMENT, data_len, RPMI_TOKEN, head, + rpmi_response_base, + data_len >=3D sizeof(uint32_t) ? rpmi_response_word(qts, 0) : 0); + qtest_writel(qts, RPMI_P2A_ACK_HEAD, (head + 1) % 16); +} + +static void rpmi_send_sysreset(QTestState *qts, uint32_t reset_type, + uint8_t request_type) +{ + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_SYSTEM_RESET, request_type, + &reset_type, 1); +} + +static void rpmi_expect_qemu_failure(const char *extra_args, + const char *stderr_needle) +{ + g_autoptr(GError) error =3D NULL; + g_auto(GStrv) split_args =3D NULL; + g_autoptr(GPtrArray) argv =3D g_ptr_array_new(); + g_autofree char *stderr_data =3D NULL; + gint wait_status; + gboolean spawned; + + g_assert_true(g_shell_parse_argv(extra_args, NULL, &split_args, &error= )); + g_assert_no_error(error); + + g_ptr_array_add(argv, (gpointer)qtest_qemu_binary(NULL)); + for (char **arg =3D split_args; *arg; arg++) { + g_ptr_array_add(argv, *arg); + } + g_ptr_array_add(argv, NULL); + + spawned =3D g_spawn_sync(NULL, (char **)argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL, + NULL, NULL, NULL, &stderr_data, + &wait_status, &error); + g_assert_true(spawned); + g_assert_no_error(error); + g_assert_false(g_spawn_check_exit_status(wait_status, NULL)); + g_assert_nonnull(stderr_data); + g_assert_nonnull(strstr(stderr_data, stderr_needle)); +} + +static void test_rpmi_machine_realize_off(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Doff"); + qtest_quit(qts); +} + +static void test_rpmi_machine_rejects_too_many_harts(void) +{ + rpmi_expect_qemu_failure( + "-machine virt,rpmi=3Don -smp 513 -display none -S", + "max CPUs supported by machine 'virt' is 512"); +} + +static void test_rpmi_base_platform_info(void) +{ + static const char expected[] =3D "QEMU RISC-V virt RPMI"; + QTestState *qts; + size_t i; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_request(qts, RPMI_SRVGRP_BASE, + RPMI_BASE_SRV_GET_PLATFORM_INFO, + RPMI_MSG_NORMAL_REQUEST, NULL, 0); + + rpmi_expect_ack(qts, RPMI_SRVGRP_BASE, + RPMI_BASE_SRV_GET_PLATFORM_INFO, + 2 * sizeof(uint32_t) + sizeof(expected)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, sizeof(expected)); + for (i =3D 0; i < sizeof(expected); i++) { + g_assert_cmphex(qtest_readb(qts, RPMI_P2A_ACK_SLOT0 + 16 + i), =3D= =3D, + expected[i]); + } + + qtest_quit(qts); +} + +static void rpmi_probe_group(QTestState *qts, uint32_t service_group, + bool present) +{ + rpmi_send_request(qts, RPMI_SRVGRP_BASE, + RPMI_BASE_SRV_PROBE_SERVICE_GROUP, + RPMI_MSG_NORMAL_REQUEST, &service_group, 1); + + rpmi_expect_ack(qts, RPMI_SRVGRP_BASE, + RPMI_BASE_SRV_PROBE_SERVICE_GROUP, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + if (present) { + g_assert_cmphex(rpmi_response_word(qts, 1), !=3D, 0); + } else { + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + } +} + +static void test_rpmi_base_probe_service_groups(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don,aia=3Daplic-imsic"); + rpmi_probe_group(qts, RPMI_SRVGRP_BASE, true); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_SYSTEM_RESET, true); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_HSM, true); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, true); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_CPPC, false); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_SYSTEM_MSI, false); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_CLOCK, false); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_MANAGEMENT_MODE, false); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_LOGGING, false); + + qtest_quit(qts); +} + +static void test_rpmi_sysreset_attrs(void) +{ + QTestState *qts; + uint32_t reset_type =3D RPMI_SYSRST_TYPE_SHUTDOWN; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, &reset_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, + RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE); + + qtest_system_reset(qts); + reset_type =3D RPMI_SYSRST_TYPE_COLD_REBOOT; + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, &reset_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, + RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE); + + qtest_system_reset(qts); + reset_type =3D RPMI_SYSRST_TYPE_INVALID; + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, &reset_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + + qtest_quit(qts); +} + +static void test_rpmi_sysreset_shutdown(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_sysreset(qts, RPMI_SYSRST_TYPE_SHUTDOWN, + RPMI_MSG_POSTED_REQUEST); + qtest_qmp_eventwait(qts, "SHUTDOWN"); + qtest_quit(qts); +} + +static void test_rpmi_sysreset_cold_reboot(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don -no-reboot"); + rpmi_send_sysreset(qts, RPMI_SYSRST_TYPE_COLD_REBOOT, + RPMI_MSG_POSTED_REQUEST); + qtest_qmp_eventwait(qts, "SHUTDOWN"); + qtest_quit(qts); +} + +static void test_rpmi_sysreset_invalid_type(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_sysreset(qts, RPMI_SYSRST_TYPE_INVALID, + RPMI_MSG_NORMAL_REQUEST); + + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_SYSTEM_RESET, sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, + RPMI_ERR_INVALID_PARAM); + + qtest_quit(qts); +} + +static void test_rpmi_repeated_reset_after_traffic(void) +{ + QTestState *qts; + uint32_t reset_type =3D RPMI_SYSRST_TYPE_SHUTDOWN; + + qts =3D qtest_init("-machine virt,rpmi=3Don,aia=3Daplic-imsic"); + for (uint32_t i =3D 0; i < 5; i++) { + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, + &reset_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + qtest_system_reset(qts); + } + qtest_quit(qts); +} + +static void test_rpmi_reset_clears_transport(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_sysreset(qts, RPMI_SYSRST_TYPE_INVALID, + RPMI_MSG_NORMAL_REQUEST); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_SYSTEM_RESET, sizeof(uint32_t)); + + qtest_system_reset(qts); + + g_assert_cmphex(qtest_readl(qts, RPMI_A2P_TAIL), =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, RPMI_P2A_ACK_TAIL), =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, RPMI_DOORBELL_BASE), =3D=3D, 0); + + qtest_quit(qts); +} + +static void test_rpmi_doorbell_invalid_access(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + qtest_writeb(qts, RPMI_DOORBELL_BASE, 1); + qtest_writel(qts, RPMI_DOORBELL_BASE + 4, 1); + g_assert_cmphex(qtest_readl(qts, RPMI_DOORBELL_BASE), =3D=3D, 0); + + qtest_quit(qts); +} + +static void test_rpmi_queue_bounds(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + qtest_writel(qts, RPMI_A2P_TAIL, 0x1000); + qtest_writel(qts, RPMI_DOORBELL_BASE, 1); + g_assert_cmphex(qtest_readl(qts, RPMI_A2P_HEAD), =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, RPMI_P2A_ACK_TAIL), =3D=3D, 0); + + qtest_quit(qts); +} + +static void test_rpmi_migration_blocked(void) +{ + QTestState *qts; + QDict *error; + const char *desc; + + qts =3D qtest_init("-machine virt,rpmi=3Don -S"); + error =3D qtest_qmp_assert_failure_ref(qts, + "{ 'execute': 'migrate'," + " 'arguments': { 'uri': 'exec:cat > /dev/null' } }"); + desc =3D qdict_get_try_str(error, "desc"); + + g_assert_nonnull(desc); + g_assert_nonnull(strstr(desc, "non-migratable device")); + g_assert_nonnull(strstr(desc, "riscv-rpmi")); + + qobject_unref(error); + qtest_quit(qts); +} + +static void test_rpmi_hsm_hart_list(void) +{ + QTestState *qts; + uint32_t start_index =3D 0; + + qts =3D qtest_init("-machine virt,rpmi=3Don -smp 4"); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_LIST, + RPMI_MSG_NORMAL_REQUEST, &start_index, 1); + + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_LIST, + 7 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 2), =3D=3D, 4); + g_assert_cmphex(rpmi_response_word(qts, 3), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 4), =3D=3D, 1); + g_assert_cmphex(rpmi_response_word(qts, 5), =3D=3D, 2); + g_assert_cmphex(rpmi_response_word(qts, 6), =3D=3D, 3); + + qtest_quit(qts); +} + +static void test_rpmi_hsm_multi_socket_hart_list(void) +{ + QTestState *qts; + uint32_t start_index =3D 0; + + qts =3D qtest_init("-machine virt,rpmi=3Don " + "-smp 4,sockets=3D2,cores=3D2,threads=3D1"); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_LIST, + RPMI_MSG_NORMAL_REQUEST, &start_index, 1); + + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_LIST, + 7 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 2), =3D=3D, 4); + g_assert_cmphex(rpmi_response_word(qts, 3), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 4), =3D=3D, 1); + g_assert_cmphex(rpmi_response_word(qts, 5), =3D=3D, 2); + g_assert_cmphex(rpmi_response_word(qts, 6), =3D=3D, 3); + + qtest_quit(qts); +} + +static void test_rpmi_hsm_hart_status(void) +{ + QTestState *qts; + uint32_t hart_id =3D 3; + + qts =3D qtest_init("-machine virt,rpmi=3Don -smp 4"); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_STATUS, + RPMI_MSG_NORMAL_REQUEST, &hart_id, 1); + + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_STATUS, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, + RPMI_HSM_HART_STATE_STARTED); + + qtest_quit(qts); +} + +static void rpmi_expect_hsm_status(QTestState *qts, uint32_t hart_id, + uint32_t expected_state) +{ + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_STATUS, + RPMI_MSG_NORMAL_REQUEST, &hart_id, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_STATUS, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, expected_state); +} + +static void test_rpmi_hsm_hart_control(void) +{ + QTestState *qts; + uint32_t hart_id =3D 1; + uint32_t stop_request[] =3D { hart_id }; + uint32_t start_request[] =3D { hart_id, 0x80000000, 0 }; + uint32_t suspend_request[] =3D { hart_id, 0, 0x80001000, 0 }; + uint32_t start_index =3D 0; + uint32_t suspend_type =3D 0; + + qts =3D qtest_init("-machine virt,rpmi=3Don -smp 2"); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_SUSPEND_TYPES, + RPMI_MSG_NORMAL_REQUEST, &start_index, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_SUSPEND_TYPES, + 4 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 2), =3D=3D, 1); + g_assert_cmphex(rpmi_response_word(qts, 3), =3D=3D, 0); + + qtest_system_reset(qts); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_SUSPEND_INFO, + RPMI_MSG_NORMAL_REQUEST, &suspend_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_SUSPEND_INFO, + 6 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + + qtest_system_reset(qts); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_STOP, + RPMI_MSG_NORMAL_REQUEST, stop_request, + ARRAY_SIZE(stop_request)); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_STOP, + sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + rpmi_expect_hsm_status(qts, hart_id, RPMI_HSM_HART_STATE_STOPPED); + + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_START, + RPMI_MSG_NORMAL_REQUEST, start_request, + ARRAY_SIZE(start_request)); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_START, + sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + rpmi_expect_hsm_status(qts, hart_id, RPMI_HSM_HART_STATE_STARTED); + + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_SUSPEND, + RPMI_MSG_NORMAL_REQUEST, suspend_request, + ARRAY_SIZE(suspend_request)); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_SUSPEND, + sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + rpmi_expect_hsm_status(qts, hart_id, RPMI_HSM_HART_STATE_SUSPENDED); + + qtest_quit(qts); +} + +static void test_rpmi_syssusp_attrs_and_suspend(void) +{ + QTestState *qts; + uint32_t suspend_type =3D 0; + uint32_t suspend_request[] =3D { 0, 0, 0x80000000, 0 }; + + qts =3D qtest_init("-machine virt,rpmi=3Don -smp 1"); + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, + RPMI_SYSSUSP_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, &suspend_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, + RPMI_SYSSUSP_SRV_GET_ATTRIBUTES, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 3); + + qtest_system_reset(qts); + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, + RPMI_SYSSUSP_SRV_SYSTEM_SUSPEND, + RPMI_MSG_NORMAL_REQUEST, suspend_request, + ARRAY_SIZE(suspend_request)); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, + RPMI_SYSSUSP_SRV_SYSTEM_SUSPEND, sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + qtest_qmp_eventwait(qts, "SUSPEND"); + qtest_qmp_assert_success(qts, "{ 'execute': 'system_wakeup' }"); + qtest_qmp_eventwait(qts, "WAKEUP"); + + qtest_quit(qts); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + if (qtest_has_machine("virt")) { + qtest_add_func("/riscv/rpmi/machine/realize-off", + test_rpmi_machine_realize_off); + qtest_add_func("/riscv/rpmi/machine/rejects-too-many-harts", + test_rpmi_machine_rejects_too_many_harts); + qtest_add_func("/riscv/rpmi/base/platform-info", + test_rpmi_base_platform_info); + qtest_add_func("/riscv/rpmi/base/probe-service-groups", + test_rpmi_base_probe_service_groups); + qtest_add_func("/riscv/rpmi/sysreset/attrs", + test_rpmi_sysreset_attrs); + qtest_add_func("/riscv/rpmi/sysreset/shutdown", + test_rpmi_sysreset_shutdown); + qtest_add_func("/riscv/rpmi/sysreset/cold-reboot", + test_rpmi_sysreset_cold_reboot); + qtest_add_func("/riscv/rpmi/sysreset/invalid-type", + test_rpmi_sysreset_invalid_type); + qtest_add_func("/riscv/rpmi/reset/clears-transport", + test_rpmi_reset_clears_transport); + qtest_add_func("/riscv/rpmi/negative/doorbell-invalid-access", + test_rpmi_doorbell_invalid_access); + qtest_add_func("/riscv/rpmi/negative/queue-bounds", + test_rpmi_queue_bounds); + qtest_add_func("/riscv/rpmi/reset/repeated-after-traffic", + test_rpmi_repeated_reset_after_traffic); + qtest_add_func("/riscv/rpmi/migration/blocked", + test_rpmi_migration_blocked); + qtest_add_func("/riscv/rpmi/hsm/hart-list", + test_rpmi_hsm_hart_list); + qtest_add_func("/riscv/rpmi/hsm/multi-socket-hart-list", + test_rpmi_hsm_multi_socket_hart_list); + qtest_add_func("/riscv/rpmi/hsm/hart-status", + test_rpmi_hsm_hart_status); + qtest_add_func("/riscv/rpmi/hsm/hart-control", + test_rpmi_hsm_hart_control); + qtest_add_func("/riscv/rpmi/syssusp/attrs-and-suspend", + test_rpmi_syssusp_attrs_and_suspend); + } + + return g_test_run(); +} --=20 2.43.0 From nobody Sun Jul 12 00:34:17 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=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686149; cv=none; d=zohomail.com; s=zohoarc; b=bU/Lda8Mde6lHLHdUYSuTgVm9YgY0lbG/LcXcAfXPeuSWQR6QIJCczvtdpTKJn5PsejNtfOAvZMHS1/dHMB1eGyz+D2SNmG/k8ElOfvQt+g4Wf7H7AM9sxub/yPdfolyfjUvgd0ShhFr5QxVmiqSG6xsjUMwqPo7SYklyPs6+Vw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686149; h=Content-Transfer-Encoding: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:Cc; bh=UWnqngjifChP51DpkO3ronTqKQpkH0m2237QEE2Dlhg=; b=NGbq8nbaXALYmywMU3n2H1PIIA1t6sFxsZjLtRRpo7sf6wEZIPlg3ci4F1Bemkh4v2gf1AAVdutggRVfDBpqljcKJkRmwAavuKMrigSgA4NpWm1dY85NcaLtf49p3XbenEzou/SogZMoUodam4U7EeJuHn31htTbTnqR8oJwO7I= 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=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783686149319254.36065963294834; Fri, 10 Jul 2026 05:22:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAFF-0007V2-6Y; Fri, 10 Jul 2026 08:22:19 -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 1wi3lU-0000OS-IJ for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:09 -0400 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi3lS-0004Bp-0w for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:27:08 -0400 Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3mh1B3847273 for ; Fri, 10 Jul 2026 05:27:04 GMT Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fajte1fws-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:27:04 +0000 (GMT) Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-38459087607so274199a91.2 for ; Thu, 09 Jul 2026 22:27:04 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659d8da9sm62476707c88.14.2026.07.09.22.27.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:27:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=UWnqngjifCh P51DpkO3ronTqKQpkH0m2237QEE2Dlhg=; b=GkYfm7FrZLmjphEkw+KD08Hgrrc Vlk4NF6Sihy/s813z2d6FZ8EbNN1BjE5/ZyNbXUJhsW/btdSS1FW7B1b5Dhpf9Ia 2UES4tdlDnNmj0e9Hnme0WX48ABN9IkvShLhyHCZX+G3ZOkbhIbcPkKIff75Mshe iapoq6LERLVA/9cuNDy6GwWj6Qs7GUh6iziQx8CCg51JSA+QhGJL1YHPEKDNXyd4 wUrfrUAcsw+mqAom3uKBxNabH97Dn9IdSOhOZVi7WMGexuR7bUWnspjg0I2CAqVD PwiJ4zWqo1Mk+3qZkqfZMtCL88Ny4hEV4lk91E/r690VPGHEpjBd/yMBuJw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783661224; x=1784266024; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=UWnqngjifChP51DpkO3ronTqKQpkH0m2237QEE2Dlhg=; b=UyEUX8twrO4erNXZ16Su+rZZb21wrKWOd+9P7zteR4PivqEs+z1+ct1D4kOF3FvoPX PjNsmx1i4FNYW+xRWVlc7yhUtogeSyASLwpHj0xmKJFZtZV1ZKI0sgAM0+zuLz5TnpLg M5isWkRA3hV+kMJA5uXM6m4+liZgYULV2C7vtVvNYWMHAetiYJtNHAUbUuvTQMKXKTzk PRjT/BjCGQqk6ZzTcwSmwe+JYoQ7/0eJf5bHnh8ORmOnMKASBkQ5SC25rq9mJTqBSIFH +hXa3XtIyyo5y46jKIwonBEEPLDcVPwoZoHQBN2zUuBAEQU2yDTIzPB8eX5MhlN0O3WH dqZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783661224; x=1784266024; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=UWnqngjifChP51DpkO3ronTqKQpkH0m2237QEE2Dlhg=; b=XLHXO3JTJTukVp/mJbYQ29ekju6GlCJQ0Ia613vBbWxo8qru8ula+EdDADwbylkRxA aMC28kT23J8vPyH5lmwzf7Xj9mofHYS6HPz877tEzthyfbay+JqAbfGGj9x+SlczI3Gg ECPpl0U8kvFEsc5le2diwf7bPbN3BSTlfQgH0HihmDaLoohAiQDAd/Ir24/hAqBt4eyd +01+ILm0GTSX/L7LX9erz/9oOE2TidIlG8NM5VpZsKEc94hHpTsMr4ZpmYhg+JCrHMIt oyIxPYZ6CFeuXp5Aw65w7D/wwexshywCHwyrz5936p+ToQ2EletUxs3f+ER5xtd8lQZJ IdOg== X-Gm-Message-State: AOJu0Yzss/cuzlmF4GSxoKo8Wlw3nvfw7DqVMNMgOgmYEIT094WcxLWV cFrcVUaWET0abKGtvJ4ORJpaALLn1DyXJSIc6TvPLdG9NBvoH+rGaDG/7gRcrn4Tk6UWEwCJKlY dfulgJW2M6NAzpZypJHleyvHZDnPrq+R7F+yeX1hXI+l3z9rp6mELZyiJSCkuyANrPQ== X-Gm-Gg: AfdE7cn9r/IQsu2VnrX+nSU77ERY2hqeCP20/zTwYNCWo0xMlGCYE8S2y04rUaBL5tH k3Ysm4K2gWJXN8kkaENZw8DBa6BSugiJBYrnUEKv0sqgkuk83tcGlWecBRblMqg58PveziMyZY1 hH2Q/lLyrwHWj9/PS3bQtRG/3xd3dCMGb+cogdzJQMI0dqV/Ez+FxPWmZhULaXuSiDNd4X12W80 p0cLs3QTWTYi+wbMgWLQeTqCZWtdmRz6jmf2GeRrBEfN/HqOfr0Q6BGFEabRi27CauoKHtBbdAc 0UYrY0bMCPmA/jr5ggAlnyfOl5jDSiafcNGlSO/S/mHp/k2fYm5MB1x7adbLzRdmIKeewhZOr42 rTZBtev+a9vkR1cTidbu6UHcdzdGx3sMGbZFfi/mQBTAblwrLuSVN5WvdHLTOz1hRTrS5yV47Ro luo6F5cs21dVIaYIAE1zC5Fokd+3AIwJ7M936EdPwLwA== X-Received: by 2002:a17:90b:5886:b0:381:bcfb:e710 with SMTP id 98e67ed59e1d1-38a20e414e7mr6163470a91.3.1783661223654; Thu, 09 Jul 2026 22:27:03 -0700 (PDT) X-Received: by 2002:a17:90b:5886:b0:381:bcfb:e710 with SMTP id 98e67ed59e1d1-38a20e414e7mr6163439a91.3.1783661223069; Thu, 09 Jul 2026 22:27:03 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH 10/10] tests/functional: add initial RPMI virt guest smoke Date: Fri, 10 Jul 2026 10:56:42 +0530 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: QtWTQOQ4WPFlhY2D1q0QQJRPbMyHRsR7 X-Proofpoint-ORIG-GUID: QtWTQOQ4WPFlhY2D1q0QQJRPbMyHRsR7 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX8IlGK9eQlzR5 aWHu46pICjh+LhRi/eapZA0dQNekiG8dyS/dGW1i+JzuWEMI/2VDoktgiWWE0OtXbjoh/rIMX7J vOXPtd60a46AaKNGnBAs8E7EjcBT6q8peG36nO5cVXGvkha4Gmp8e53HJvZXRJyO6s5FGjUMIzn Yrr4RGX3rxOuLKO03tNllHFYFw7HLjjeOOJMY5tEgbVPvviuJGAEqw/P4oxC7s7B8ukHcg6IdCE YVNmczV0ohDyaC8fkJuyVsDmgC2pbNDrt7vkgJim1RV2l3ONAAcmm+Tv8uO9MF7ZV4AxquWBDLI W2W33dmZk1r4m7ZdzNiW90aJ3xSOCdvzauivUmOs2HA8GncFyCMUX5rHZfj/VZDN5pZMSIB54Zb 3tEXaXfTc1XX4wmwqkarXbdqThVNwTTxuOkJsKCmTdjYpv4m9ul7zvDShXy+8PR1PHR/zFjkwyA EdzljrW99uBpBSKzrUA== X-Authority-Analysis: v=2.4 cv=N7MZ0W9B c=1 sm=1 tr=0 ts=6a5082a8 cx=c_pps a=vVfyC5vLCtgYJKYeQD43oA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=EUspDBNiAAAA:8 a=Cnp7e1vNUpDCZbjFkkcA:9 a=rl5im9kqc5Lf4LNbBjHf:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA0OCBTYWx0ZWRfX91j+Vxfaz3v4 PHAyhjdpIUUEDF6mPQ5bGYmcoZYF1phySVDVKZWH+HPaxECcUKXn0P5DoOmW2FkfZkJFP2wibSC LW2LXy5g27cPxoss3bLfzZo0bWIwE6k= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1011 spamscore=0 impostorscore=0 suspectscore=0 adultscore=0 malwarescore=0 phishscore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100048 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=205.220.168.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:33 -0400 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 @qualcomm.com) X-ZM-MESSAGEID: 1783686150104158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Boot an RPMI-enabled RISC-V virt guest and exercise the initial HSM, system suspend, and system reset paths. Signed-off-by: Subrahmanya Lingappa --- tests/functional/riscv64/meson.build | 2 + tests/functional/riscv64/test_rpmi_virt.py | 172 +++++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 tests/functional/riscv64/test_rpmi_virt.py diff --git a/tests/functional/riscv64/meson.build b/tests/functional/riscv6= 4/meson.build index 5871211e89..619a0735fa 100644 --- a/tests/functional/riscv64/meson.build +++ b/tests/functional/riscv64/meson.build @@ -3,6 +3,7 @@ test_riscv64_timeouts =3D { 'boston' : 120, 'tuxrun' : 120, + 'rpmi_virt' : 300, } =20 tests_riscv64_system_quick =3D [ @@ -15,4 +16,5 @@ tests_riscv64_system_thorough =3D [ 'boston', 'sifive_u', 'tuxrun', + 'rpmi_virt', ] diff --git a/tests/functional/riscv64/test_rpmi_virt.py b/tests/functional/= riscv64/test_rpmi_virt.py new file mode 100644 index 0000000000..c0f96f7d8d --- /dev/null +++ b/tests/functional/riscv64/test_rpmi_virt.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 +# +# RISC-V virt RPMI Linux guest integration tests +# +# Copyright (c) 2026 Ventana Micro Systems Inc. +# Copyright (c) 2026 Qualcomm Technologies, Inc. +# +# Author: +# Subrahmanya Lingappa +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +from pathlib import Path +import subprocess +import time + +from qemu_test import QemuSystemTest +from qemu_test import exec_command +from qemu_test import exec_command_and_wait_for_pattern +from qemu_test import get_qemu_img +from qemu_test import wait_for_console_pattern + + +class RiscvVirtRpmiGuestTest(QemuSystemTest): + """Boot Linux and exercise RPMI-backed services through guest APIs. + + This test intentionally keeps guest artifacts external. Set: + + QEMU_TEST_RPMI_OPENSBI=3D/path/to/fw_jump.bin + QEMU_TEST_RPMI_KERNEL=3D/path/to/Image + QEMU_TEST_RPMI_ROOTFS=3D/path/to/rootfs.ext4 + + Exact RPMI packet command-ID coverage remains in riscv-rpmi qtests. Th= is + functional test verifies Linux/OpenSBI integration paths visible from a + real guest without adding probe hooks to production RPMI sources. + """ + + timeout =3D 360 + PROMPT =3D 'root@tuxtest:~#' + + def _require_path(self, env_name): + value =3D os.getenv(env_name) + if not value: + self.skipTest(f'{env_name} is required') + path =3D Path(value) + if not path.exists(): + self.skipTest(f'{env_name} does not exist: {path}') + return path + + def setUp(self): + super().setUp() + self.opensbi =3D self._require_path('QEMU_TEST_RPMI_OPENSBI') + self.kernel =3D self._require_path('QEMU_TEST_RPMI_KERNEL') + self.rootfs =3D self._require_path('QEMU_TEST_RPMI_ROOTFS') + self.qemu_img =3D get_qemu_img(self) + + def _create_rootfs_overlay(self): + overlay =3D Path(self.scratch_file('rootfs.qcow2')) + subprocess.run([ + self.qemu_img, 'create', '-q', '-f', 'qcow2', '-F', 'raw', + '-b', str(self.rootfs), str(overlay), + ], check=3DTrue) + return overlay + + def _boot_guest(self, smp=3D4): + self.set_machine('virt') + self.machine =3D 'virt,rpmi=3Don,aia=3Daplic-imsic' + rootfs_overlay =3D self._create_rootfs_overlay() + + self.vm.set_console() + self.vm.add_args( + '-cpu', 'rv64', + '-smp', str(smp), + '-m', '1G', + '-bios', str(self.opensbi), + '-kernel', str(self.kernel), + '-append', 'printk.time=3D0 root=3D/dev/vda rw console=3DttyS0= ' + 'earlycon=3Dsbi loglevel=3D8 no_console_suspend', + '-blockdev', 'driver=3Dqcow2,file.driver=3Dfile,' + f'file.filename=3D{rootfs_overlay},node-name=3Dhd= 0', + '-device', 'virtio-blk-device,drive=3Dhd0', + ) + self.vm.launch() + + def _expect_rpmi_firmware_and_linux(self): + patterns =3D [ + 'Platform HSM Device : rpmi-hsm', + 'Platform Suspend Device : rpmi-system-suspend', + 'Standard SBI Extensions', + 'susp', + 'tuxtest login:', + ] + for pattern in patterns: + wait_for_console_pattern(self, pattern) + exec_command_and_wait_for_pattern(self, 'root', self.PROMPT) + + def _run_marker_command(self, command, marker, failure_marker=3DNone): + out =3D exec_command_and_wait_for_pattern(self, command, marker, + failure_message=3Dfailure_= marker) + self.assertIn(marker.encode(), out) + return out + + def _validate_hsm_boot_start(self, online_cpus): + self._run_marker_command( + 'echo RPMI_LINUX_HSM_START_BEGIN; ' + 'cat /sys/devices/system/cpu/present; ' + 'online=3D$(cat /sys/devices/system/cpu/online); ' + 'echo "$online"; ' + f'if [ "$online" =3D "{online_cpus}" ]; ' + 'then echo RPMI_LINUX_HSM_START_PASS; ' + 'else echo RPMI_LINUX_HSM_START_FAIL; fi', + 'RPMI_LINUX_HSM_START_PASS', 'RPMI_LINUX_HSM_START_FAIL') + + def _validate_hsm_stop(self): + self._run_marker_command( + 'echo RPMI_LINUX_HSM_STOP_BEGIN; ' + 'if [ -w /sys/devices/system/cpu/cpu1/online ]; then ' + 'echo 0 > /sys/devices/system/cpu/cpu1/online && ' + '[ "$(cat /sys/devices/system/cpu/online)" =3D 0 ] && ' + 'echo RPMI_LINUX_HSM_STOP_PASS || echo RPMI_LINUX_HSM_STOP_FAI= L; ' + 'else echo RPMI_LINUX_HSM_STOP_FAIL; fi', + 'RPMI_LINUX_HSM_STOP_PASS', 'RPMI_LINUX_HSM_STOP_FAIL') + + def _validate_system_suspend(self): + exec_command( + self, + 'echo RPMI_LINUX_SUSPEND_BEGIN; ' + 'if grep -qw mem /sys/power/state; then ' + 'echo mem > /sys/power/state; ' + 'else echo RPMI_LINUX_SUSPEND_FAIL; fi') + wait_for_console_pattern(self, 'RPMI_LINUX_SUSPEND_BEGIN') + wait_for_console_pattern(self, 'PM: suspend entry') + self.vm.event_wait('SUSPEND', 10) + self.vm.qmp('system_wakeup') + self.vm.event_wait('WAKEUP', 10) + wait_for_console_pattern(self, 'PM: suspend exit') + wait_for_console_pattern(self, self.PROMPT) + self._run_marker_command( + 'marker=3DRPMI_LINUX_WAKEUP; echo ${marker}_PASS', + 'RPMI_LINUX_WAKEUP_PASS') + + def _validate_reset_poweroff(self): + exec_command(self, 'echo RPMI_LINUX_RESET_POWEROFF_BEGIN; poweroff= -f') + wait_for_console_pattern(self, 'RPMI_LINUX_RESET_POWEROFF_BEGIN') + wait_for_console_pattern(self, 'reboot: Power down') + self.vm.wait() + + def test_linux_guest_service_enumeration(self): + self._boot_guest(smp=3D4) + self._expect_rpmi_firmware_and_linux() + self._validate_hsm_boot_start('0-3') + + def test_linux_guest_hsm_stop(self): + self._boot_guest(smp=3D2) + self._expect_rpmi_firmware_and_linux() + self._validate_hsm_boot_start('0-1') + self._validate_hsm_stop() + + def test_linux_guest_suspend(self): + self._boot_guest(smp=3D1) + self._expect_rpmi_firmware_and_linux() + self._validate_system_suspend() + + def test_linux_guest_reset_poweroff(self): + self._boot_guest(smp=3D1) + self._expect_rpmi_firmware_and_linux() + self._validate_reset_poweroff() + + +if __name__ =3D=3D '__main__': + QemuSystemTest.main() --=20 2.43.0