From nobody Mon Sep 28 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=1786964171; cv=none; d=zohomail.com; s=zohoarc; b=g9N5M3l53m29XGT4N48Z6BZdobGuQ7iKDiizm3PM5xvOR47BvofgIIZ/ljlp1zx00soUUake4uNO9Rp/oZKs1XZcWYze8WoDOe5aAbljMyh7ZGg/vjQHfJVeSvE+N7DwjeGhMYM6Uvb1a/HgxThDjQfqNWlF++jpH+6FIwQ1jQY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964171; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=a/5p61xQaYVPkAjYS8CsqPTMi8Z+ZbCfOetNwPWaI3c=; b=TW1tejcvpPPtBeMl5QRsBM7+OuGNjbEKRNRCtW6KfLBjEvzseLTDU43/3Qyz13aVMAlHEGnYinFfjYwA3fh1a/myDtRD15cAIQl+uhvVvzNZlWq3Yurnsvs37Ec1d7WATV1GQntPtSH888mzdrbInEdhcUXyGFJOcB43Mi8XPgk= 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 1786964171706745.8703442082344; Mon, 17 Aug 2026 03:56:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0d-0003Oc-J6; Mon, 17 Aug 2026 06:56:03 -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 1wvv0E-00038k-OB for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55:41 -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 1wvv0D-00066s-1F for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55:38 -0400 Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67H9djs81861295 for ; Mon, 17 Aug 2026 10:55:35 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 4g3vghs8an-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:55:35 +0000 (GMT) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-2cfd13d6d50so7031565ad.1 for ; Mon, 17 Aug 2026 03:55:35 -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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.55.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:55:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= a/5p61xQaYVPkAjYS8CsqPTMi8Z+ZbCfOetNwPWaI3c=; b=B9F/OhaFBfGe8gvJ ZsC4KCYKv6dcQVWxQkUrAz1rGgx4hZQ700TWbhlup+QaEHuvZZDYYPPlCL2ur996 RGl/sztmu51qJHzI9dP7wBa4s9ooyRwcMLVx0GoalJowwcrp7kBbljlE+meHqGOR XJZV3Z5zrG6vmRuaAmiuVGsnFDgEDxozxNIT71Ug/TaBKTtl/P3rma1gYHq827Rx Rp6Qbe1qw9umRTrZlHxvNjGOyIj8LJlU5VNlCvOEhhmBd/Hs6otI/7039MJ36pKy VOBhzqLzm99+063nFaq9U2EVMqG8yaQhTQdtxX2I8GZsgLWaZax+eSlgHcmbnnED iJLfIw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964135; x=1787568935; darn=nongnu.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=a/5p61xQaYVPkAjYS8CsqPTMi8Z+ZbCfOetNwPWaI3c=; b=NAdEptMtQ7CysKREvjCN+zAp53MfTnBsoogeqZmh85mLlVOqwOPMoYievWhvZcV7yD vhfQS2AFevT2D+vC7osc5gU7M3Ms8RN7Khaz9dtRESfn8M04En7GOOb9yeeq8n+ac0zS Lm9TzDiw11XLli7aFpjM6juWGe6IxV4uwnq3yNXdMhvxIE+mtGGZ+esXIONgYc9SYHPv wauce+YhjJ4Cm+nt7emj7JJnQIDmQhBdd+yRQTaztCRxT0qdB457blZfWLcrdGmct1gk JwuzwJOtEvbWn3gFDLqtac35ohQord8LmHNu3OqbbC+ZaklqUjbUQIpbRXFHkleqstOY svHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964135; x=1787568935; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=a/5p61xQaYVPkAjYS8CsqPTMi8Z+ZbCfOetNwPWaI3c=; b=ZQPDoCTiJ5JTnlF/PqXWtvaUfc32EdV8cYmobKSYGE4xM+n/Zgz4AAJ7v7SY6P3MgA 6OdQbMW334FuIQTEg2bxOrVcyk3vXlWdsslJB4OtxnoQ2qciFFfxKSXZO9pynJVvViVj Zzxg9CaG/oK/vta0quTozydqir20Ni3TsXDaiKLRVAUzIJBYT4NJmjlScgAePRqnSsvu ZZ64Ih0ww7RmCj2rPVaBtKPMaJDL5dTWPPR8SQjXtsJB6zE4T/02iRW8x/xn6DDnjfU9 ox6wsRH+XqSjMkrd7Bzd1VQ2+Gip1et3f5sg3gZntKV0tgWsz//9yXbtYqeVbyCNLqMz 0jbg== X-Gm-Message-State: AOJu0YxJBrnJBGUqd/1RyrS6ssPM0vhRn0wbRTD5ymWkzyJS63Tad/Hp sGTIPkb01idQ1y+G8OOZ/zpBl2phsG4NEJP9x3cwutiGnX6JPvRmV+/0fClJdItCU3BU8LqJ7DW alytBcVF43WYyrxgN49Xb/EyMOUU+hybaLI1TZFam8JHPF9UZ5Rm+cCdVLxcOfWuDoHVa X-Gm-Gg: AR+sD13XoyNmT/7HLsHS3WEj46mNM3nPLSoDKwFs+9RzgDcgxEPmlsHdwCNbx6T62lv eQsC7VOdQkYsF3MHs9yfS/AMviBcF+OwoCnzn2yez/N3LAIhHgz6RVybv6Kv0n91ETmzVHNdFWh ItHCGMB24Hj0sF3y5/o7Q+Z+pdGObIUJ6PEUB6peM1N8xClv3MFy4wjF0j0Wh7ZWyF3gG/M72jw e/fmjrsE+2dsydwu6uXVGg5D0ZyqKurTFRE+3HzwTbURlwPjbyksuCMeQ5p1hUKpv3s5bNYS55o pRmxd/KymJgVCQreLoENtgu+E9xPL5jO2yVcL9zpsfICR7zaONHa6ZWKAVAiXFu7yQrYkBNAL1Z CYh87jObSb+qYUbsQdp2x5MX4xDoQ27L3oZT3F7l40iBYbTqCIrL/QfybHMy2aqa6KnC4FT6FGD 6lfMe0tiIMDtu8Z4Oa0i98B8K3Fxgfd8U= X-Received: by 2002:a17:902:c944:b0:2c9:e846:a582 with SMTP id d9443c01a7336-2d3b04fdcb2mr192995325ad.0.1786964134609; Mon, 17 Aug 2026 03:55:34 -0700 (PDT) X-Received: by 2002:a17:902:c944:b0:2c9:e846:a582 with SMTP id d9443c01a7336-2d3b04fdcb2mr192994865ad.0.1786964134165; Mon, 17 Aug 2026 03:55:34 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Daniel Henrique Barboza , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Paolo Bonzini , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v9 01/10] build: add optional librpmi dependency Date: Mon, 17 Aug 2026 16:24:55 +0530 Message-ID: <20260817105505.2607506-2-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Authority-Analysis: v=2.4 cv=P9gKQCAu c=1 sm=1 tr=0 ts=6a82e8a7 cx=c_pps a=JL+w9abYAAE89/QcEU+0QA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=EUspDBNiAAAA:8 a=2ZSorBgdJM4krTjbFk8A:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=324X-CrmTo6CU4MGRt3R:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX2/J5eD9cdCys oo59noh60t6TFqpmm7lVLprpjf5eHnwIsTOd16XsIQge4M/bijg6N+IfDLk3VV/9SGLkNoaUmFT IycZ6EduWDbsy995FJ+auaSaOeZDQRw= X-Proofpoint-ORIG-GUID: H_HgwJcnfRsDj8wlnLQvj2XLthyW8gB0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX0jKHazOMaFRm RgM2CAh40cNQAAMRfECueVV6RhpzPdaM7sG5BocfFGoYnio1AqiqIGRuq8jw9TSBM3zlXa8OD3s 2uUydk1Xz/VarUWs/bXmvldqk7qyEuRemae+gyGDddp0cZAqReMxUVk286DYRFUkQjKx5j+Hzlb mvjDG28F1Jfoi3cG4HZWnUHF3V570V6XH6QHHx+uzaoego7ecR77L2mAnEYDLl5O0q15vfM84CX YfvwdoVhPx0CDGBm8D0V0LmH51SV5oeajcv/qWz1bq1yxkzTbC11rqFfbuQDc6c8yybBxj8A84f FqugUpRvkrgq8TKYzeF377VJd/TwHijavpkw0JAO2zdgxTHkg/OgEhNErS0AogvyNg3en5v5PWG 0B5N88x2hXbYyXmhGMH/dkAyOANFV2nObzfn44wj9NK81w/yDEzYLmS1mD3tYmLEm1Suvt710r4 fDAOg3nNqrBDix7aQSQ== X-Proofpoint-GUID: H_HgwJcnfRsDj8wlnLQvj2XLthyW8gB0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 impostorscore=0 malwarescore=0 lowpriorityscore=0 priorityscore=1501 adultscore=0 spamscore=0 phishscore=0 bulkscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1786964172249158500 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 Reviewed-by: Daniel Henrique Barboza Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- 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 49a5baf5b5..99219dffad 100644 --- a/meson.build +++ b/meson.build @@ -2017,6 +2017,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_syss= usp_create', + dependencies: librpmi) + error('librpmi support requires the RPMI system suspend 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'], @@ -2439,6 +2450,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() @@ -3271,6 +3283,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' ] @@ -4987,6 +5000,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 {'RPMI 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..a65af0e633 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: '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..12179f6024 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 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 ;; base-commit: 539bc315538afe036a4b99088659aa82e3b489f2 --=20 2.43.0 From nobody Mon Sep 28 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=1786964171; cv=none; d=zohomail.com; s=zohoarc; b=PFhQ+b0v6lZGmlTr35FtMO8pyKuJhhxJO6iHl2AknyY1FcTqnQmMc0+mvxrG3PV39+GuFhJ9yzZS9yg0F41rxEBNN89TOpBlLwKnPuan4Dm0FHMZbSmv/GOpOAd+vd8ZuerI5WI0a/SDCbH7qQKUVhaH7k5wmC8Wso2xq+xJ9lw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964171; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=FMTKFazjVrEwkbtcHeZPUAz0wxDGcSPg1sRjvG78XMI=; b=jDXfZvfuIyqvAUYJ2avx2LTRwMcI18VGUnCyZj0lGRROYUwmGV5VgBDkk1VAiQHQLvffmn185r07XxswcBbCOnPK29qBwF2lGxlDlubwKkc2ps+0chFp3jfrmE7VOI6xlR0JND4gKz/211SAoMwjUQcckY8DZPoeTSIMzvXD7Z4= 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 1786964171762235.52365067557776; Mon, 17 Aug 2026 03:56:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0d-0003QV-Vu; Mon, 17 Aug 2026 06:56:04 -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 1wvv0L-0003F3-91 for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55:48 -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 1wvv0I-00067k-0F for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55:44 -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 67H9dePB2470460 for ; Mon, 17 Aug 2026 10:55:39 GMT Received: from mail-pl1-f198.google.com (mail-pl1-f198.google.com [209.85.214.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g3wm7ruh6-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:55:39 +0000 (GMT) Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-2cfd13d6d50so7031665ad.1 for ; Mon, 17 Aug 2026 03:55:39 -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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.55.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:55:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=FMTKFazjVrE wkbtcHeZPUAz0wxDGcSPg1sRjvG78XMI=; b=Uw3RoNfhk0w2CfZ8EZc1+kgd1OF x0FsBsInzPa+0g3/G8VN4BnNRcBeqS3HU4csiAaQ+U1n+YDIKYD/4lpcUGFxLmjX XHgXj+9f7Kznry+aGB8MIzZp9/ntN06RkBUkmCkKp+Dz0g6yqRl0xi+3c1DAhuMi pvAIH9Qg5wgXI36Ec4u2aCYbpMC5ZdSKHErUz1fMVP0wdhg6D0mJngGgdKjrAEJr VcP+NJF4mKgO8+15c+Gp2YTGORBT64W4nAunv5/lty+8rKaIAbvPNAku76cEGdiB BXF2ZsKOUCp8KypZQ1FdeL9tICG9ev3HCFnjdva2cU+8hhxa3jeIwmsZz6w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964139; x=1787568939; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=FMTKFazjVrEwkbtcHeZPUAz0wxDGcSPg1sRjvG78XMI=; b=Yq27Pg+J2Q+BhPSzVrUTYUMlJUVptfgtYTPyawsJUDDgWY3Dm7BxMDuPBr5DzRnhLh QlgRa/e+7BkzUhmRsyxEOYxUYwtDV3kUtoVR9Zp4cvw5pOxhPrR/iOQDfgypZ9aR5yG1 tQaNEikvuNvDzjqm6k8/orMciBPp2Bcz9GXyMoFHLb++FxbSIsQtNm6GF9gKIfJU86kB teYPLc9NTFeNWPRtrfTO0cCJdnY+WpyPBJRgypKWeIOrlM+ZW9eU/9evWO0oUQ+JoZM1 sq9Y6++DeAdyuTeWpykv1BDb5GTJGISdhr6MkBsOsRqTuG3u4tCscFKZ8ZJV0DsyXvkJ hg1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964139; x=1787568939; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=FMTKFazjVrEwkbtcHeZPUAz0wxDGcSPg1sRjvG78XMI=; b=lWShJkBqa7p5iE1HUeLTk7qjtFw86bihxmujDTXNT8FobPw8hfBSk3IOw6JZEid37O FjDgjaOZ1X55mF5iw32a0Csp6BQZLbqCxdzkOZDq1SdBiu8OMf/xfjhV8oft2C9E+s4F HCNDACBn2Xx4FVTXc+D5vW3sttP4CCItbMOxwBG8t0oURDG4NicHPx5aUmhXmVGLt6Bx IkLBATqBdMxnInrFPtHR6pc8H+/iuykHg9NDSewLZuhjhUA4rhXtXFluHH+SJFPpfSu4 nDaO1ku7sf6DhX+FwH9Ka+3XhMXVrqLKqbjg+XWD/yfQ7NQBnPg1a9ptAcEnJorMvXmS 2jXQ== X-Gm-Message-State: AOJu0YyOuiPRARBOWYjY8wviKF3aEHXfwyX1zTmmYsXm1YtBqRtD0mF2 SGnzUe0JOD79OiHRTPVmuDPNm8ZgdHCtDeW3hRA3eUyMdPOmX+Aw69l4ivo6Z0gOStkeaMILbRn ndWt8sN1GVdXHLjq+HwVhdhfMaQ0v4uO+6ioWEMY39iLATTYocW9f1rA6p+dBEA4gDIwD X-Gm-Gg: AR+sD102nvlB1gNDihZmymsgFJ//fD9tISpkxLg+2hhFB+UQ/An14tT2dglPFgjJzXw UxfNAyN/RR6uls3DMwoVgtX6pNpDEVGygFq8JgiCEw5b2Oxnslni0nRCZD6q4Nhf6T3QYzd8Ckp GvuyG5IJUF0HCMoIUt+zzfwOO364CH9gJWVDbLw4shH2/rqSnAZ1EFXxqsoDuCrEOVEen97gpds 45F+ps0cyjv7YwR5cBqaBRxdAxFvwTieiHMLS9i+WeKdBd1g/KVNXHVM+LMThfH1eH+8vJfBa1q 1HuOvkLH446DAMdV/JdGxvl7v4L9l4VP82fg6tFJUgYu1NQUpSpat9g4PUyaiPz0pqoSLPHao1P 2j2u3F96GdRlzeU4Wcnnn91nXzB6RSD9mznvs0FPRxuYSa8L5KTR93fHhECitn6gl11rSNsx7O5 D5U9Q/YY2p3En59EyHWSW2K2rSQQp6qEQ= X-Received: by 2002:a17:902:854c:b0:2d5:3f09:4126 with SMTP id d9443c01a7336-2d53f094341mr95985345ad.4.1786964138815; Mon, 17 Aug 2026 03:55:38 -0700 (PDT) X-Received: by 2002:a17:902:854c:b0:2d5:3f09:4126 with SMTP id d9443c01a7336-2d53f094341mr95984835ad.4.1786964138155; Mon, 17 Aug 2026 03:55:38 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu Subject: [PATCH v9 02/10] hw/misc: add RISC-V RPMI transport and Base support Date: Mon, 17 Aug 2026 16:24:56 +0530 Message-ID: <20260817105505.2607506-3-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: 2-sQyWeMEe3xhZMwM8sBvxEPECG0DrpO X-Proofpoint-ORIG-GUID: 2-sQyWeMEe3xhZMwM8sBvxEPECG0DrpO X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX58DYK60w1C8X sYvhZain/7jjMNo7AUpr7coe+DlVwsk1sEZWuMLXExxTdf1VhF3qYoMx7LZsqoszMKhzf/S4XpI YVzld2ApcbEN7KxPK0vJ5J39oEm5L/JBBgPH5HT9fiMelc0z1LPcTyHKjhndxCe1wcNQ3KdJRtN O2vjp1MC/E5lbAX3yz+mAd+kDq0O/7+YHJWKwYTgrCmwW/v9R9EDRdJY2+FfwEQpvBmbwaeb6Q6 lbs2HGpeyGL9NCMgeRBHt2f9z5Rv7vDu7tRUsPO3qga7dEg3WDw4GU7P5hjMsmrGgK0lYJC/Yf1 QtTYB9986IDz3uLVTtyL34LUoHgp7BM8MJvlVTJuN6ISu9u2IlbB8wp5QKR2C+KTbTuNsvdY2jn UHsDMdHg0l/kXreBZDx/B+ckNtBZ9VuK8PDGHr8wScrcKy4nrX/F5FdNICPairBesBKZ80FxLXO VjpXHD1xCphz3ZnTlhQ== X-Authority-Analysis: v=2.4 cv=YqM/gYYX c=1 sm=1 tr=0 ts=6a82e8ab cx=c_pps a=MTSHoo12Qbhz2p7MsH1ifg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=V1jnuoLLAAAA:20 a=NEAV23lmAAAA:8 a=EUspDBNiAAAA:8 a=DmI9vCv-aQFBvt5XpaMA:9 a=GvdueXVYPmCkWapjIL-Q:22 a=bA3UWDv6hWIuX7UZL3qL:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfXwzUbhkaPuh6i BgKtaLeZ4fIttY4WMhR4cQy2LXuZbiIRp4ERuS7Fn4ZtpJ2FAshL4drTn1oI2Z+oQVGa7J7r95L GDrH5NV+61y5gXRDZtiHUy2c1cmbuTc= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 impostorscore=0 suspectscore=0 adultscore=0 clxscore=1015 bulkscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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-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: 1786964174019158500 Content-Type: text/plain; charset="utf-8" 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 | 477 ++++++++++++++++++++++++++++++++++ hw/misc/riscv_rpmi_internal.h | 24 ++ include/hw/misc/riscv_rpmi.h | 90 +++++++ 6 files changed, 600 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 f249be744e..c742a71ee6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -372,6 +372,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 b8860dd3e7..dd2e876ba5 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -261,3 +261,7 @@ config AXIADO_CLK 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 e86d9ad6b3..6a19fe443c 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -171,3 +171,6 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('= sbsa_ec.c')) system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c')) =20 system_ss.add(when: 'CONFIG_AXIADO_CLK', if_true: files('axiado_clk.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..8598a3f133 --- /dev/null +++ b/hw/misc/riscv_rpmi.c @@ -0,0 +1,477 @@ +/* + * 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 "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/physmem.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) +{ + 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; + } + + 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; + } + + 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_hold(Object *obj, ResetType type) +{ + RiscvRpmiState *s =3D RISCV_RPMI(obj); + + 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); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + dc->realize =3D riscv_rpmi_realize; + dc->unrealize =3D riscv_rpmi_unrealize; + dc->vmsd =3D &riscv_rpmi_vmstate; + rc->phases.hold =3D riscv_rpmi_reset_hold; + 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..c263033634 --- /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..f5fd1ee8c7 --- /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 Mon Sep 28 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=1786964212; cv=none; d=zohomail.com; s=zohoarc; b=HEo/RrXlCe+0GiPW98+y5rlrce8jYBVoHtsuQWgWoE21e8nwvOfjhYzAOAUfdRUQcqZahoevZ+Qn32tFZInd2bBW5YLybWwkaBwYn/LJ70fTW5g3lOIFKsDerGwaTugUIzuZ9j/TJOBaIB7Cr1WZu9P30PqooU8/qRc5LhPczz8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964212; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=d5xFcJI+/UHEitLjRFs9Ilg/TXnyZDJq7fykLRCnwoc=; b=JediwDi9YWBYnkst0TCtQWWEep3kVJwg7g8u4fLgBjnV7g0Kv7AklzpB0xO33n1kif3e9F5mIf45DvLpMQ4LaPM6sCFX6VLbjMMsJhrEgG/85hJ+AUW23w5+QjZKSGFfaEMVkulOgKMoiV6PGWifPYg7o+84jRdtjDUbsdEsXko= 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 1786964212389482.0520028885535; Mon, 17 Aug 2026 03:56:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0g-0003fs-8Z; Mon, 17 Aug 2026 06:56:06 -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 1wvv0N-0003FR-Kg for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55:50 -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 1wvv0K-00068E-Dq for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55:46 -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 67H9dfKn1466631 for ; Mon, 17 Aug 2026 10:55:43 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 4g3xx7ggk4-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:55:42 +0000 (GMT) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-2d0e306c7d0so8558335ad.1 for ; Mon, 17 Aug 2026 03:55:42 -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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.55.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:55:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=d5xFcJI+/UH EitLjRFs9Ilg/TXnyZDJq7fykLRCnwoc=; b=LJricQxtvTru291aosLRao36S9D Tf1wTEr2gL/jMFbvd3AyjxvnM37DBXrieOL1hfdGbE9YzAmQJ1YpKR65vyav0bDq Pe6VN5Cp/Q7gx+U2+BxJLz847iGNCKIy419os8JE4EYqQCoMa3mcIZtUroDfJJJ/ Km3VIhvDZOZdlndqxOeqYJ52XlludF4EI7ej31Oz25LbMwOXaqY0ab8hQUYlj9gN cu+T57kApMEYbrbJc/ileagTulcwGoE1qgUO+Gipiv5vOAN5xvgbltuQLRAO4Kbc nhQD4YtG/ofOCUem+5iho06iadhRELA0dwvL8qdC1EbAr1HM/yY/cXw/b8w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964142; x=1787568942; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=d5xFcJI+/UHEitLjRFs9Ilg/TXnyZDJq7fykLRCnwoc=; b=OeZAlcG7FaJCr5CRvt1lKHnYeD7Nz1+qFrj+3j3cXH9dwzjzxt9QBaHnf8DIkjQQvi s/46Tts/mmOdhhVmjIQ+xRrGtlMBMaat0sd3A62Jo8+APE1j5aYmDLOOq9TpihmtOi4k yYquJYH/m4SN/0HsM66i3mHmkepPjtxJArIXucPHXBml8joRPj9UaB6eyuLJld718qiU MUs8HoRo9p/2NcT1RhnsV2z7NaQoOxxUHYYDQXlz9fDUlmHAUIHV7tPeyzKjePqXZ/fk IEJZYNlc+v+/EjQyhpv8V7hnzWsjsaKNUIj2UqQgMBu4QDV6v/3c7ibUhmjuC7yOP7Vs qECA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964142; x=1787568942; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=d5xFcJI+/UHEitLjRFs9Ilg/TXnyZDJq7fykLRCnwoc=; b=LLoOeyGa1XPmp+wjFhGiR04P91VVM5Ou6ZrNNQboLbosOsmx5xH8JL2ZlLtu99SS6G I2d5i6R+jH63mierwmn4jJmACQQIctpfDOeB09pTI+QfB34fqoxiiCCb1QgQaXt86a4V EMtpDVfdo5v7uVmAxIZMQ8JclNfIeYDflQcMfcT08VkHRe/KKdGlJ8K9IiAUY/pVZ1/B CWEuH2xQgswvt1Fe3yre7MADTLcaGl+RRiAphLGAbEQBrtSFyElYS8R2cXzG98Ug1MOD 9KZzPqzI6QaKWOqve0UllvMPldm1GqE4hM6qk3HlxxP6hMauclkF1xyjeVUGuzHM5fFi O1Ug== X-Gm-Message-State: AOJu0Yzc3wgsoiqDS6gbjeVzpMM3WmxYZZ4Zd9FHVIUxiEckAqIF9bMe HP5mm//4X+3Ym/JsIa1LmKZoWzgNpHdzFdO1dwQ/ybTw7pmrQo4HCefGklBEP2Mr/ktGKPj5D4/ VtoCNv7wvBd1tB2WTCSHzVSv+tU33V31Dgopm9s6tOt/57qJWRiuX15ANWwvszKRI0nDV X-Gm-Gg: AR+sD12k1bzVLaN1VUaHObXVQgSvWxhZB7wPqTI/aG5+JztwDUnhw4Gk81VuQLB1bE1 esPJQVeIlPK8iWNmK7iiALBlWQFWaMJ8fYAyGKvMeJuAyS0KJnZHaUPiIRy9bAnDwPLbepz4qMv OlTS91WdCNQpjvtooEUV5zDoQPO7EnQPpYOJSDdswh9PcK/y8FpLykebzTuioC5G+7iBIECflqA g33trLIUZ9QhjvAjY82aCHwvOi9cgp9GUujcmrEnl9++mp3jPgvWJL4sDxuv1/j+fAeFqVcygEx LPUQCc2tPpbhgMEJwc0YozRSpCOvu6aeI5Va0LNrk0FeQzayECSzOw9DdUux302TkVu2RvDcBvt yK4kWABMYT51ogzVNDtJqcDlo8kqRsFClRWlWdDV3Hlb7yINOnFvDXR3UcjMYtQ9NJchRsINQOl WIPXMqCUH4M649g/p34dO3/XM9t+2jljw= X-Received: by 2002:a17:902:e54c:b0:2c9:ed4a:c3a4 with SMTP id d9443c01a7336-2d3b0503575mr173620775ad.0.1786964142270; Mon, 17 Aug 2026 03:55:42 -0700 (PDT) X-Received: by 2002:a17:902:e54c:b0:2c9:ed4a:c3a4 with SMTP id d9443c01a7336-2d3b0503575mr173620395ad.0.1786964141766; Mon, 17 Aug 2026 03:55:41 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Daniel Henrique Barboza , Palmer Dabbelt , Alistair Francis , Weiwei Li , Liu Zhiwei , Chao Liu Subject: [PATCH v9 03/10] hw/riscv: add RPMI FDT helpers Date: Mon, 17 Aug 2026 16:24:57 +0530 Message-ID: <20260817105505.2607506-4-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX6/cHDGN4kx+L DJ4XBWtUc4u68Na5b3lU8gwMqwl6dyX3H4DEJA3dOU0sWQr40wc81Hriqg0ry/oRYr1iQpZLi+H DgaTJkPsVV3Mb1lrmGyPoKHSapXDX/M= X-Authority-Analysis: v=2.4 cv=TK91jVla c=1 sm=1 tr=0 ts=6a82e8ae cx=c_pps a=JL+w9abYAAE89/QcEU+0QA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=jHWy4UxqgUe44QwoGJQA:9 a=324X-CrmTo6CU4MGRt3R:22 X-Proofpoint-GUID: ocfsbN5essc32acZmgnmcl20AWvTwYeL X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfXxomfKsCxFNFa OJ9rVRe6eAnHjOLa81/fbSC0Uqd1v7vC8nhLKYIT6RO8KRTrylW1fluplLz8pCDuRzeo244grHX 1X51d/vorQRVuOj9pDsQjzfKZExditMm0LGDYk0rSoBexvCdrVFPy2upGwyE/fj+a3xxMe4b1Bg ocv5b1zQ3S6rCKc37AGf+OXPHxNYbsjEnUb5qUvrNE2antnIYEZrlEFAOzfMhBKj3BsrXPmGl/1 QzpSOfEJLfg3PVZHPhWh9SlqpB4DPLX2+OFZUKD2ThIWV6LBL6JK29TNtCCPxK6/8u7Zbpx8JZV AifOihEgQMoBew8Yyw/X4FCpZXUsKOk3UAv2G5DReF2nT9ZGIXzNAa39qkpLzQV449DxZGPNPmJ CqoaKrNsK2vxCVqrBedrVot2K8CxpnlTJPK5nzhRqqk+QqP7LsCVrdnbH8eQ4grjHHkjaaTkMni JSJfEdjxPMVULQpU3ng== X-Proofpoint-ORIG-GUID: ocfsbN5essc32acZmgnmcl20AWvTwYeL X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 phishscore=0 lowpriorityscore=0 spamscore=0 bulkscore=0 impostorscore=0 adultscore=0 suspectscore=0 clxscore=1015 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1786964214215158500 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Daniel Henrique Barboza --- 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 0d82ceacc4..17e23265f8 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -4,6 +4,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(when: 'CONFIG_RISCV_RPMI', if_true: 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..439c91c894 --- /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..b157bda1d1 --- /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 Mon Sep 28 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=1786964199; cv=none; d=zohomail.com; s=zohoarc; b=VgQrGBFPcLmZ3/Tr/GoECJjrFKzfre/NZwjWwUfpSzEKl4IccNqqiwi1/7L4tXzeZglXtY0BYAPYcSO/bxjhwuG6F47SIUS531SlMmYXgoPkySLaepQBFRibtilBvjmeiKGrkilaSjqrPDi7CCbDWXFpYuIbagXA+H+teTAkY4E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964199; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kuq6dyKmFOsXnzCMTB2OBBBgFZOt/NOp0TsaA/J3L6k=; b=OybSEtLKvAx42ZCb8UqlEh4npzYS8KMPNIOJHQgmZ2gAvXKievibtsz5Hvjq7OLMv0mxcsgtP96DDGIxTbUoFE52P//P5WYwHNozougjk+qHCRYdjQHzWp9uYhNdTeb2xQP9aO3jMrMrQmqeObKIqsje1rOfCoxKLt3WaKYDpGc= 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 1786964199226816.2338813558985; Mon, 17 Aug 2026 03:56:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0i-0003nE-Ea; Mon, 17 Aug 2026 06:56:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wvv0T-0003Ie-9F for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55: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 1wvv0P-00069S-BQ for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55:52 -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 67H9dqrL1771645 for ; Mon, 17 Aug 2026 10:55:47 GMT Received: from mail-pg1-f199.google.com (mail-pg1-f199.google.com [209.85.215.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g3xyk8guj-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:55:47 +0000 (GMT) Received: by mail-pg1-f199.google.com with SMTP id 41be03b00d2f7-cbef10aac86so530524a12.2 for ; Mon, 17 Aug 2026 03:55:47 -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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.55.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:55:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=kuq6dyKmFOs XnzCMTB2OBBBgFZOt/NOp0TsaA/J3L6k=; b=BJqFYxOjHtl6tBrs8SNiom4Ap2G wvDul45Zw18wh8KM96I4qvSDVCGrUlHNG+DH5TWnUUjeUFXbU7lNJJl2basw8N8Q PPOPIfQh91EsFoPhZUdriVJtPZYo1eOgeZgQ4GoU9CPDcUnxvUiz639m2Xc2P8Mu 6xVFci+FMKcUgMHGCaXXp9J6vdMkiSJJq4KOrq0r/gEUht4tDvOPTuujxFdjXlwk 3KM6GaS/Iiv7Cl6uxNGdkkCi548kmVhNdI6hyXY0F0ACwSd/EJtpy8rZRvqblUhL OqcfHXA7oxpElGUyMV44KxBUGszDw52McmS/webTa3PspMDy+Zf2TzPTONQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964146; x=1787568946; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=kuq6dyKmFOsXnzCMTB2OBBBgFZOt/NOp0TsaA/J3L6k=; b=iNjVIJPU3V1rcyao4MswbMGOnI5H+hM0hx9HVoD2uekik0SteJzCOhUpuf/3PWsD4D 3bJODmkIdIBhyMG7M2uSzIK12n70wcnj56ianlhpqFSiUWaaCtUeMfZcKgnLp8Uv3TLu 69nFTob1cYuzoLbJDYvWmgKXno3ovXmy5Rkh5vOT5mAXcXgtjulKFwJIUzO1syysIBNY H55Cc+ZRjgtuWOP0ZMj8F5SRheMcQDaymkTwGABMYMN0hWVfDE4jSLwR7OiCBc0s+sj7 /6pPhtR47BM/ghuvGLvumYSJoiiYWh0BMgYvNzTGDKoA+S8lPujCjJwNmyUqg/egLq6c 82Bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964146; x=1787568946; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=kuq6dyKmFOsXnzCMTB2OBBBgFZOt/NOp0TsaA/J3L6k=; b=b6LvlPTuy8FgBzH1HFlRnGmOKzcE/nsPKlTFgwhLgSeQbkZYd98JLeVI+LvcykYcVc GE4moOc37Gpz+mLLoqAmFMEKsaLxxMLZZX301B6x6tHm2SFHKrj5Y8a0nKELXia65g1a 51y4eDqoGOHqkPHUA2TemW9iGENryIpuuTCf9or7myF77QkQ7X5gAhpaOXKE9DA9slaj mQv/s63YhSV0BMacjqOjUrO4y4uYbgQwxC3xfNGdVcFrqbC2DqvmsSLtl3qf9uk5RAbR fnFs4KK1kuMxOn4Zmxz1k85lk6nHnjnuS4ZF2Twn4YI9z41s8ObrfIPMr+bydju/83t6 0ojg== X-Gm-Message-State: AOJu0Yzv2F+p7P4TS0L28xvjlQrfBiFbPnuPTKQO4NbgVHBA/7s3rckQ 1ucUGgYOg4/8CabzbtttL2fEdBzOUEaFmdm8SNV8NslInW1NnIu6INzVuB06Uhi5nnOJiwmAnTf s+Qfxbr3Dbqf6x+M6PYr+tFQwtD5XfxPh0yTEBXD3BYgkH0UOhZpZTv2n8NPPSHkl6RpC X-Gm-Gg: AR+sD10P/LhVKIJSK62P/MfJAFCMTPPN31b3Dpvx501sdzWhD1bi8WLjqoJ+WAHISn6 FK6UuqZi3RMUm5frfd8rLXx0KuGtR0z7JgIcCRNKalUdIpK717NMppHpR2ORHn3Zq0kGOg83VpA Xa6nWmIRZwvtOyvXjJWe8owRju0+GBD2hQ6LqqRp/k/+A9wU7VNRlQ3ye45XlZUdwCqIFibhFYy g07GV52tkNq9XHe8u8zumrXP6QEJELIRb2u0/fs+ug0ME8Gdg4gG3Ehi+Daoaq5g9YNcvi+aNs6 4bP4TpIxjcmz4fUF/RHICQA0C9Do+Q1SK8bXg9as0QbWuy+p3muZNSXFNYnq4Kpt4GU89+HpArN orgayXMUDdneCQUpV3jJ55UfKBH9WPekXPUskx5I51DYD7WmRT7IC+beiw7qpzFnRlf3W4IOtGC q6D8YNxHnmRlzCua1tTAPkbxSRMz0NFo8= X-Received: by 2002:a17:903:1b46:b0:2d3:aecd:51f7 with SMTP id d9443c01a7336-2d3b0ce9999mr199821945ad.1.1786964146214; Mon, 17 Aug 2026 03:55:46 -0700 (PDT) X-Received: by 2002:a17:903:1b46:b0:2d3:aecd:51f7 with SMTP id d9443c01a7336-2d3b0ce9999mr199821505ad.1.1786964145661; Mon, 17 Aug 2026 03:55:45 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu , Paolo Bonzini Subject: [PATCH v9 04/10] hw/riscv/virt: add opt-in RPMI base support Date: Mon, 17 Aug 2026 16:24:58 +0530 Message-ID: <20260817105505.2607506-5-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: 4hKC6U2pPmp5MLcuraIITarRqqKyUSAr X-Proofpoint-ORIG-GUID: 4hKC6U2pPmp5MLcuraIITarRqqKyUSAr X-Authority-Analysis: v=2.4 cv=dLaWXuZb c=1 sm=1 tr=0 ts=6a82e8b3 cx=c_pps a=Oh5Dbbf/trHjhBongsHeRQ==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=HJcZEfycbju_5WdDyrcA:9 a=_Vgx9l1VpLgwpw_dHYaR:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX3/2WNxULteLK X2VdBvUNYeTFOUaG9GfUTTmFZ179atH3YkJZBtXElyQfV9HPditTMmAXXf2z8qZFjPAFXA2Odvk Fxzuk0ZKDu62jQHVpWjDlKj+ewK/ZF89LGX0yLMS7aXfAN9NcSZGhbrKKJ/dggDQcB0fq3DO5qm AMjZAyJnPQpPpC7+ty+yvxdMZnGtmXIyRHKke8IJp0YAo8nWzBhGEDFqd0mn5T56bLwEcYyLJQO h0JW0GvO2gHnWRakB99b2YCfiDBUmKkV1TcZPfqg0r6Yk1toG4FC68kxYcXLEFPZpl1ovSrgvoi 9ZA5LFMoGkWgEvBJRjtZIHy68eDP8pDWc6XWKSdhN44LF+4KrvTb4LyuQJ0RsjcXBzKgkl/V9qR zQSr9I04Dxaks6u/AwzXQ+C7VUxNqDQ45Ek7udp0TFim7nFK6/waILLfJ+US4T9jlkysqqRLXvT a0mU9oO0Vd7+ebu6YJg== X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX3xw/cPP0+Kwn k//WtGWGPUvkCh+7crB1kb22jE7Pb8Zm7TQwMZQ4wFnQcaVjipcx2gtXYgND3dnQHRrwAbY5ou2 sFzQSOOtlOQk4DFfbWEBP653EuUZ4As= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 phishscore=0 spamscore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 suspectscore=0 adultscore=0 malwarescore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1786964200263158500 Content-Type: text/plain; charset="utf-8" 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/misc/meson.build | 2 +- hw/misc/riscv_rpmi-stub.c | 16 +++++++ hw/riscv/Kconfig | 1 + hw/riscv/meson.build | 4 +- hw/riscv/rpmi-fdt-stub.c | 37 +++++++++++++++ hw/riscv/virt.c | 96 +++++++++++++++++++++++++++++++++++++++ include/hw/riscv/virt.h | 3 ++ 7 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 hw/misc/riscv_rpmi-stub.c create mode 100644 hw/riscv/rpmi-fdt-stub.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 6a19fe443c..fb761f94b3 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -173,4 +173,4 @@ system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi= .c')) system_ss.add(when: 'CONFIG_AXIADO_CLK', if_true: files('axiado_clk.c')) system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files( 'riscv_rpmi.c', -), librpmi]) +), librpmi], if_false: files('riscv_rpmi-stub.c')) diff --git a/hw/misc/riscv_rpmi-stub.c b/hw/misc/riscv_rpmi-stub.c new file mode 100644 index 0000000000..dc32b43227 --- /dev/null +++ b/hw/misc/riscv_rpmi-stub.c @@ -0,0 +1,16 @@ +/* + * RISC-V RPMI stubs. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/misc/riscv_rpmi.h" + +DeviceState *riscv_rpmi_create(const RiscvRpmiConfig *cfg G_GNUC_UNUSED, + Error **errp) +{ + error_setg(errp, "RISC-V RPMI support is not compiled in"); + return NULL; +} diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index de37c08cae..40a37abb27 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/meson.build b/hw/riscv/meson.build index 17e23265f8..87601f8523 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -4,7 +4,9 @@ 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(when: 'CONFIG_RISCV_RPMI', if_true: files('rpmi-fdt.c')) +riscv_ss.add(when: 'CONFIG_RISCV_RPMI', + if_true: files('rpmi-fdt.c'), + if_false: files('rpmi-fdt-stub.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-stub.c b/hw/riscv/rpmi-fdt-stub.c new file mode 100644 index 0000000000..28e72adad5 --- /dev/null +++ b/hw/riscv/rpmi-fdt-stub.c @@ -0,0 +1,37 @@ +/* + * RISC-V RPMI device-tree helper stubs. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/riscv/rpmi-fdt.h" + +void riscv_rpmi_fdt_add_mbox(void *fdt G_GNUC_UNUSED, + const RiscvRpmiFdtMboxConfig *cfg G_GNUC_UNUS= ED, + uint32_t *phandle G_GNUC_UNUSED, + uint32_t *mbox_handle G_GNUC_UNUSED) +{ + g_assert_not_reached(); +} + +void riscv_rpmi_fdt_add_service(void *fdt G_GNUC_UNUSED, + hwaddr shmem_base G_GNUC_UNUSED, + const char *node_name G_GNUC_UNUSED, + const char *compatible G_GNUC_UNUSED, + uint32_t mbox_handle G_GNUC_UNUSED, + uint32_t service_group G_GNUC_UNUSED, + bool has_mpxy_channel G_GNUC_UNUSED, + uint32_t mpxy_channel G_GNUC_UNUSED) +{ + g_assert_not_reached(); +} + +void riscv_rpmi_fdt_add_service_node(void *fdt G_GNUC_UNUSED, + hwaddr shmem_base G_GNUC_UNUSED, + const RiscvRpmiServiceConfig *service + G_GNUC_UNUSED, + uint32_t mbox_handle G_GNUC_UNUSED) +{ + g_assert_not_reached(); +} diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 51bac47a91..fa0e0db0c3 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -44,6 +44,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" @@ -98,6 +100,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 }, @@ -975,6 +979,40 @@ static void create_fdt_iommu(RISCVVirtState *s, uint16= _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; @@ -994,6 +1032,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); @@ -1321,6 +1363,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++) { @@ -1471,6 +1525,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", @@ -1555,6 +1628,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; s->num_sources =3D VIRT_IRQCHIP_NUM_SOURCES; @@ -1630,6 +1704,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; @@ -1751,6 +1840,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/riscv/virt.h b/include/hw/riscv/virt.h index 36a2def410..35edd20ecd 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; @@ -80,6 +81,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 Mon Sep 28 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=1786964185; cv=none; d=zohomail.com; s=zohoarc; b=O7poHoChQ5oEjRS0XKRvUTNjRtnBJ3ljJNXj+VAu4bTZsSZIEzXf1dtyJMAkRGqMLf+NsKG4r0a4b9At8TQ2ZXfyjLTGWSAVGPOvIL760HDoPSRxduxeYh+x33sKpe/NKSNBmu6SIaCGclFanmtEhmV0Gz0Ozzb9iLTsx6bnRfI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964185; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zpGpbe/Q0FQdZ7Jtcx3rA+APRp3M0vJzhfB8vj4t02Y=; b=kHF/MOzKe4xEpxK/aUzLf9o0hbfRwkKjw6W+VjpDjBXuDau2CWgeXZckXVNZY62wUHQ3og2rUceufqT3KAPiCvLCkvIE7XJ04RZGHQypL9pPdFZu9EpTqfgQzCwa3GJzRpR9WTB/mBIFQT1Z6+rJA9n8tuOowQaCDZKnMVqrDVQ= 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 1786964185478702.7157141186182; Mon, 17 Aug 2026 03:56:25 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0h-0003kx-HG; Mon, 17 Aug 2026 06:56:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wvv0V-0003KH-ES for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56: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 1wvv0S-00069z-Dn for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55:55 -0400 Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67H9dfEr1533560 for ; Mon, 17 Aug 2026 10:55:51 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 4g3xb1gn81-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:55:50 +0000 (GMT) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-2cae7a8b9easo6313645ad.3 for ; Mon, 17 Aug 2026 03:55:50 -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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.55.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:55:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=zpGpbe/Q0FQ dZ7Jtcx3rA+APRp3M0vJzhfB8vj4t02Y=; b=aXYx53ZgAohav0sbU33B0yRjuI7 UdqziNx2rV0doJIRiqs8VA3XE6yzeE7h1OhegwTlA6aOIqrnPflqwQekCcHyNs9i 86Mnr6F3hM4pSOP5Fn2kvqLz//NJY51U54sVhN8bV+HEz+V8jAZhZBRDo2tHRmbn +s9KF2Hjaie2iedl9vpipK5X1JFlA73jrQ4+lHXk7tScP01e3hJeUE/sMHMyU7eV MjXL5jeBqWHEPGQvXvA07qDyr5SRPL2wHIR0pJJ5s+gIifCNfZaY5C0317vNv+W9 HSLIfctJ4gIC8g+OnY0oJlAttXu9EeDBgjCEbfHBF/ie50qzi+zRM8ibqEA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964150; x=1787568950; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=zpGpbe/Q0FQdZ7Jtcx3rA+APRp3M0vJzhfB8vj4t02Y=; b=Y5ukTqBEt6FpJPC7tktAZjLEtOj8MRYzwZgygS15vNS8U5eZposDlMZ9I00cqRjRAi h+P9SrsCH19fN2EYcEqghIpAp3W5uLNnBPB2Vj6+i6zOYP3A/q/hhSDF5uhuukDYDWHy IdlkF8DBGAeGzlxvMTi5gCx+ScP/hwi4YKxNVoLPPAfKEdRE4q7pwhyNtKQ5N1cXCwgB 8WP8aQ8g+px0swH8vLPo62rt0huIHui8FQ8GK6VNMbXATAgdOncUKHh/4r/Al+rmi0al CX+b9cso1Brc00ydSB5RCbiBhmsOc2VGDft1+7/5go3y6IoLPDyV6sHxQ1gbNPMfLis3 WW7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964150; x=1787568950; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=zpGpbe/Q0FQdZ7Jtcx3rA+APRp3M0vJzhfB8vj4t02Y=; b=P1mdL1QCVWA1FIGeOAe8KpnkZJKcj2JtYpFN0InYCiF98pq6EZ20m8BvyfzZ5PJ12D nU2+/u37f7OOOZyI4wglvdx4UiC2ecEqcgcMJpnjmFZ/Wxx20Ku6zn0v1MTn8U2iRaoV ezt7daf13wkOtH3HzuIG/XRNyEWA1HakjGnJwAo3A1xDUx5NPJ2p2vPk1yeciOlxtLWP /fBKQKq/4orbC2BIwwTbYFZGhVextGHoJCIX9hRDDekVI4bWkZVt/U6Xyy/9jfM9Ku1Q arVSZ05TQsT2laYH0phzeTdGy4Gqw1ZDRqi2vJSFl8+hNJW+EjDxT9SzIG2oomfb5834 wB3w== X-Gm-Message-State: AOJu0YyPgoNwY3XLcLkm4beHI8aDOVf/uh38OihBD0OXDKsMjdjyyUmf XmsLyYGnmKh1wauSv4yUOzm0CPzSqvVdC50Y0f27oIK17LRCytBUXCXVrHI1K8qvhM+UFoQyUgV BmDfIru7BoY5KCl0Ci0LH1touUKaOIZO4bgr9N6zCJQVsIOWMhSu3g1UBLWXEV4JmSbgT X-Gm-Gg: AR+sD11npvnyeMKm/tslPtPgZeOVqrPXrDjKAta7oETbbOkyhklZCWTA0pRAv+QaUod oqJ2ab0wUMRemUQoI46nDb6RqCzG0gZMMneTrMH6lkZTdD7YwTPGYsh1syKtizXu2Mlcju0jxnt tjT/zIPIebJO+5Sd2i+gMKc0/gTakKQ10XbW4PSjYDNFPOnvtx/qJaok93S/jEYSwBbynDmB2Oz FaeNJqV6E7003wQyQIFSqUfFxdstJydoCGfmFxeK5mfWJiZZlExaeTbK31o+fuBZ+wu1yuhG73u Z+R7+xA/njDbJ2DXKoaLwX09AMuMMy5+JDgcyeSahwuTGVegMhga+3iNTKyEnig/rRQ+qrX1W8w NGpCp55eMmtqd25uBnnFpbY4olSgEZ/gUwyTB6Bpu0OXC3GQfK34E2A0Q+hUXCuJ7h7B4+BW5/i QPWYCrgPpLgpoXJIY2icYhF6QgSYm4/do= X-Received: by 2002:a17:902:cf09:b0:2d3:a50c:5e19 with SMTP id d9443c01a7336-2d3b082b49amr209542655ad.1.1786964149971; Mon, 17 Aug 2026 03:55:49 -0700 (PDT) X-Received: by 2002:a17:902:cf09:b0:2d3:a50c:5e19 with SMTP id d9443c01a7336-2d3b082b49amr209542165ad.1.1786964149437; Mon, 17 Aug 2026 03:55:49 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Daniel Henrique Barboza , Palmer Dabbelt , Alistair Francis , Weiwei Li , Liu Zhiwei , Chao Liu Subject: [PATCH v9 05/10] riscv: add RPMI system reset service Date: Mon, 17 Aug 2026 16:24:59 +0530 Message-ID: <20260817105505.2607506-6-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Authority-Analysis: v=2.4 cv=Ua9hjqSN c=1 sm=1 tr=0 ts=6a82e8b7 cx=c_pps a=IZJwPbhc+fLeJZngyXXI0A==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_K5XuSEh1TEqbUxoQ0s3:22 a=EUspDBNiAAAA:8 a=99SOxnSlc15Quf5CO00A:9 a=uG9DUKGECoFWVXl0Dc02:22 X-Proofpoint-GUID: u2GE1tWhie-uMnu2gZEja_8RRUcGsREO X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfXxbMEG7L2EVAr rkdVZW//Kg2OKwkFkLXyCqkrvCFsH03OG2m0y9EbQIiuMdLnPKCM0RV/gvT1rfnKgZUPX4kYzch PU6HoR3Cgymkf0yp/vWCx7kgINNzhWmC1lF8Yaafw1zkm3Yd7szDAZTIysNF4FYqaNNMUaLEcx2 B6qSlCeni7BATEQ0KLxRh6pmUEtOjJdHl4Zs7p2wrwZqgB9lg26GLnBeeqQXrr/2x5rUsApSeb8 gLnodQioE6rnB2oh1u1nBFrr9MMzDZRVAFlWPJtiiMcBY41/lu0Wml7sjEMumUh3ZKVaJq/QXST i0CnQ4pqShPpJPXoqXnKJYJTKq1EqqU81sw4UoA4ZJ+QlFfNuPVg5V1LRSEiCm6VSLdEnXsWwfV qyWKCoe3MRPBgbTep/12+Ef1PgqypvJIGJlWbIiQAdYCNpsbbwU+DcLF4NrrIxQlYkzQkhFlM8f l+I3TUiqI+8GNUeA1wA== X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX0SQ2PYANkCJz cwSqnH53PL+qZXuA6JFJtF8DGYKpvYlEuBBnlLmwgllttZcxAtdM6buCFDXjmqZ8VHsDLowjJlZ ilkXthY0Yxqmv0ZZBPLpfZuIE8aSSv0= X-Proofpoint-ORIG-GUID: u2GE1tWhie-uMnu2gZEja_8RRUcGsREO X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 adultscore=0 priorityscore=1501 malwarescore=0 suspectscore=0 impostorscore=0 bulkscore=0 lowpriorityscore=0 phishscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1786964186136158500 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Daniel Henrique Barboza --- hw/misc/meson.build | 1 + hw/misc/riscv_rpmi.c | 70 +++++++++++- hw/misc/riscv_rpmi_internal.h | 12 +- hw/misc/riscv_rpmi_sysreset.c | 206 ++++++++++++++++++++++++++++++++++ hw/riscv/virt.c | 51 ++++++++- include/hw/misc/riscv_rpmi.h | 15 +-- include/hw/riscv/rpmi-fdt.h | 11 ++ 7 files changed, 349 insertions(+), 17 deletions(-) create mode 100644 hw/misc/riscv_rpmi_sysreset.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index fb761f94b3..f8a317b8f6 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -173,4 +173,5 @@ system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi= .c')) system_ss.add(when: 'CONFIG_AXIADO_CLK', if_true: files('axiado_clk.c')) system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files( 'riscv_rpmi.c', + 'riscv_rpmi_sysreset.c', ), librpmi], if_false: files('riscv_rpmi-stub.c')) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c index 8598a3f133..97517766e9 100644 --- a/hw/misc/riscv_rpmi.c +++ b/hw/misc/riscv_rpmi.c @@ -171,10 +171,37 @@ static bool riscv_rpmi_transport_indices_valid(RiscvR= pmiState *s) s->a2p_req_size); } =20 +typedef struct RiscvRpmiServiceOps { + uint32_t service_group; + bool (*add)(RiscvRpmiState *s, Error **errp); + void (*remove)(RiscvRpmiState *s); +} RiscvRpmiServiceOps; + +static const RiscvRpmiServiceOps riscv_rpmi_service_ops[] =3D { + { + .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_RESET, + .add =3D riscv_rpmi_sysreset_add, + .remove =3D riscv_rpmi_sysreset_remove, + }, +}; + +static const RiscvRpmiServiceOps *riscv_rpmi_service_ops_by_group( + uint32_t service_group) +{ + for (uint32_t i =3D 0; i < ARRAY_SIZE(riscv_rpmi_service_ops); i++) { + if (riscv_rpmi_service_ops[i].service_group =3D=3D service_group) { + return &riscv_rpmi_service_ops[i]; + } + } + + return NULL; +} + 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->services =3D cfg->services; s->service_count =3D cfg->service_count; =20 @@ -211,7 +238,9 @@ static void riscv_rpmi_reset_hold(Object *obj, ResetTyp= e type) =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); @@ -234,12 +263,12 @@ static void riscv_rpmi_cleanup(RiscvRpmiState *s) } } =20 -bool riscv_rpmi_service_enabled(RiscvRpmiState *s, RiscvRpmiServiceKind ki= nd) +bool riscv_rpmi_service_enabled(RiscvRpmiState *s, uint32_t service_group) { uint32_t i; =20 for (i =3D 0; i < s->service_count; i++) { - if (s->services[i].kind =3D=3D kind) { + if (s->services[i].service_group =3D=3D service_group) { return true; } } @@ -247,6 +276,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 +371,16 @@ static bool riscv_rpmi_add_service_group(RiscvRpmiSta= te *s, const RiscvRpmiServiceConfig *ser= vice, Error **errp) { - switch (service->kind) { - default: - error_setg(errp, "unsupported RPMI service kind %d", service->kind= ); + const RiscvRpmiServiceOps *ops; + + ops =3D riscv_rpmi_service_ops_by_group(service->service_group); + if (!ops) { + error_setg(errp, "unsupported RPMI service group %u", + service->service_group); 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 c263033634..ca9838d256 100644 --- a/hw/misc/riscv_rpmi_internal.h +++ b/hw/misc/riscv_rpmi_internal.h @@ -18,7 +18,15 @@ #define RPMI_PLAT_INFO "QEMU RISC-V RPMI" =20 extern const struct rpmi_shmem_platform_ops rpmi_shmem_qemu_ops; -bool riscv_rpmi_service_enabled(RiscvRpmiState *s, - RiscvRpmiServiceKind kind); +bool riscv_rpmi_service_enabled(RiscvRpmiState *s, uint32_t service_group); +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..775eb5483f --- /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(); + } +} + +static void riscv_rpmi_sysreset_shutdown(RiscvRpmiState *s) +{ + const RiscvRpmiMachineOps *ops =3D s->machine_ops; + + if (ops && ops->system_shutdown) { + ops->system_shutdown(); + } +} + +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 fa0e0db0c3..1a69fd7cfe 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -767,7 +767,8 @@ static void create_fdt_pcie(RISCVVirtState *s, create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle); } =20 -static void create_fdt_reset(RISCVVirtState *s, uint32_t *phandle) +static void create_fdt_reset(RISCVVirtState *s, uint32_t *phandle, + bool use_syscon_reset) { char *name; uint32_t test_phandle; @@ -791,6 +792,14 @@ static void create_fdt_reset(RISCVVirtState *s, uint32= _t *phandle) test_phandle =3D qemu_fdt_get_phandle(ms->fdt, name); g_free(name); =20 + /* + * When RPMI is enabled, advertise reset and shutdown through RPMI so + * firmware routes these operations through the RPMI system reset serv= ice. + */ + if (!use_syscon_reset) { + return; + } + name =3D g_strdup_printf("/reboot"); qemu_fdt_add_subnode(ms->fdt, name); qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-reboot"); @@ -980,6 +989,34 @@ static void create_fdt_iommu(RISCVVirtState *s, uint16= _t bdf) } =20 =20 +static const RiscvRpmiServiceConfig virt_rpmi_services[] =3D { + { + .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) +{ + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); +} + +static void virt_rpmi_system_shutdown(void) +{ + 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) @@ -991,8 +1028,11 @@ static RiscvRpmiConfig virt_rpmi_config(RISCVVirtStat= e *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, .hart_ids =3D hart_ids, .hart_count =3D hart_count, + .services =3D virt_rpmi_services, + .service_count =3D virt_rpmi_service_count(s), }; } =20 @@ -1001,6 +1041,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, @@ -1011,6 +1052,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) @@ -1036,7 +1083,7 @@ static void finalize_fdt(RISCVVirtState *s) create_fdt_rpmi(s, &phandle, msi_pcie_phandle); } =20 - create_fdt_reset(s, &phandle); + create_fdt_reset(s, &phandle, !s->have_rpmi); =20 create_fdt_uart(s, irq_mmio_phandle); =20 diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h index f5fd1ee8c7..a9ccc950e9 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) @@ -36,12 +37,11 @@ struct rpmi_service_group; struct rpmi_shmem; struct rpmi_transport; =20 -typedef enum RiscvRpmiServiceKind { - RISCV_RPMI_SERVICE_INVALID =3D 0, -} RiscvRpmiServiceKind; - +typedef struct RiscvRpmiMachineOps { + void (*system_reset)(void); + void (*system_shutdown)(void); +} RiscvRpmiMachineOps; typedef struct RiscvRpmiServiceConfig { - RiscvRpmiServiceKind kind; const char *node_name; const char *compatible; uint32_t service_group; @@ -56,7 +56,7 @@ typedef struct RiscvRpmiConfig { uint32_t a2p_req_size; uint32_t p2a_req_size; const char *platform_info; - + const RiscvRpmiMachineOps *machine_ops; const uint32_t *hart_ids; uint32_t hart_count; const RiscvRpmiServiceConfig *services; @@ -73,7 +73,8 @@ struct RiscvRpmiState { uint32_t a2p_req_size; uint32_t p2a_req_size; char *platform_info; - + const RiscvRpmiMachineOps *machine_ops; + 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 b157bda1d1..60c5df75d0 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 Mon Sep 28 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=1786964225; cv=none; d=zohomail.com; s=zohoarc; b=SpWbfuCGPswJq/EDhy+ZYdGt9GXtEcRQgoz70YG1wa/TCrG7KYoOd6mNkVWkfAZlUutR0cupq5ZnpCn+Fkfc7Mm72fz5yxAFx/o1nVPvNSe65UehkLYBqRf5Jk5F/xaJ8Vp/JEVBlWQedvmz1FkqM0pn77OiFzA9p9zzu1eLNo8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964225; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=3BO2YSHtlb7JEEbnyEWBVMda9uxNupZotLP7HOkEIGI=; b=e8P01FpKAygos7atJUktYWz9dJmu8vGBd+hqo3ZIcEcPPETpyexJMgoDDQbpSEwcAj+/+JFm5+O5j1PkxbBMvD3w4CcnUxwvSweEhJ+njs0qnVa3zga4YEvIqX/pPQy/MKuIP8Iwl4c1UoFVXtBZZ+dXQNgNxg6bA5SZ0mHjFIE= 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 1786964225780699.4275960078123; Mon, 17 Aug 2026 03:57:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0h-0003kD-DI; Mon, 17 Aug 2026 06:56:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wvv0Y-0003LQ-GG for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56:03 -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 1wvv0V-0006Am-V3 for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:55:58 -0400 Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67H9devT1533514 for ; Mon, 17 Aug 2026 10:55:54 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 4g3xb1gn8d-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:55:54 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-3809cc5dcccso743422a91.0 for ; Mon, 17 Aug 2026 03:55: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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.55.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:55:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=3BO2YSHtlb7 JEEbnyEWBVMda9uxNupZotLP7HOkEIGI=; b=dNlAaSZKK0GNlWNBxRsflm3bFax Bh5gFVeaLbsMPZIhg+J6xoLMZRTQR5rDqpXhD3XQ1fosw9a+Xk/PbmKm4Pv0ouw7 +Nci4WsfvjcB/5AJDZ5bLM2mxo1afSI8XJqkZNhisoH5psE4f7SVTUhwShQvO8Zr +BbfMcU2065vd6EwPPK1PcYnvuYUJB4n/3dROMyAmDNETabm79BcH8JYXBUpY7Jx /H15dFpds6TZvaRd5HEhszoPQR4zupqtuHcY4kNQaufhFtPKj+JCh0IMIq65vT74 +h/sOGIimGYagFGjOWnkbv3swj/sSlGkzyRoIihCUKSwQiNPsfrxcB+oYMw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964154; x=1787568954; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3BO2YSHtlb7JEEbnyEWBVMda9uxNupZotLP7HOkEIGI=; b=dvxNchS8uagEwjBXISwH50JXQXgEceHNGb6FsjTQvvlGJl/xWAZeZgUXxMMsnAxDYz BK+S2p24c7QzPhVVD7sznD5Y5Th61acMG3RbTDmSKdOG6YQujQ35aC3Mh8pnGV7eoHAx p9P/nM4mve4UGZ7hs2qJwEY/9OsGYVK9dXuQru+z5ErAsz6cOMElvhNVONC7evc2daVE nrp54g7TstFX/IMg0JgNqkFYUqyt79b6mpH8pGn0rJDGXNPrt6LAt4V3nNCHRWDunga2 4WOEUzZH5tz31xmhdq/Xwhr2RSFmFkQlzba5i2HQOFESU0DxmK82ENvkMEULWDKcJisw dn0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964154; x=1787568954; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=3BO2YSHtlb7JEEbnyEWBVMda9uxNupZotLP7HOkEIGI=; b=PrYQP67UWkGF6zKpFYHXWUijjNMKSDtsmQ5sf7+8my3vTlTNQF9cvMnm6kdkive3oB 66HSdvOzxW9GGp1iCQkG0lkbUedNbVNm20OxMExgSDsrvvtZIJTaFb3IH39t17PS905T /DNuIYltdvktMRmF7R643fgJ9ZLzjTU5yClLAxTTU3uNnqiKLACS5rFlcINI+Ufn7wk/ mJB2IibFTl8YJPFs5gDylvvg9K1+MMs+WX4oyLolb0fHdnfCwIsaUYTkn78TR54QKs62 jSnd8mhDS+auzm8wy1HHL22XczNiDd5Epl0UpJnEYmtsyZ29dL9zwPmNpA1cv4FAnRVA g6Yg== X-Gm-Message-State: AOJu0YwgznWGe4H43w7Odl1DO1tZk1nAWy/afrV7wVdkhitxLf/dHuHB SD8GnVEV8D0Q7cDMIqgutSIJEPVcFxzeYVP+oZBV3NM/5fla1NarQAVxOpcypySrulfM5GctYRO 1xs/ZG5+4Oq3yKchhXEt9IzwdgZWeMqfGXGXlDRmxuQzkycjOKdSL95Gn00FRRUsFpRGS X-Gm-Gg: AR+sD12647gGDV7q+P7+wS3Y7Vz9xBILJG7ecGjqWbgAF2XmL0iQOjWgIWUspcBiK8B tlvl7OX+vJYin5RsP+ZVkbwRKqn9B0g9aTEJUtVMFTYfv9WvnksBnu7tsfnaNd4+Kp9uzCNS0t8 RwKj7M7TLlJ5lqSPrCnvk/nq9SlDLI02mRVQ1lAxnSDF+aw0OmWCBWPQX4g1JP4UWVy5Ntf9cy1 GGMr4ne5F48P9wmhLvHtOK/mhC4ma1rAMV+NtFOlP7CjcNSeXTrb4pLh3/U0NoVTwSdxmXZGAAK aNdow/nmvQRaQcSwIjGxDAMGb+ir0YLXwazIfKEnKQt+OoFYyJHIbqbr3UGUoO2XddwoyZNy4In ULRDRQI2k7/XqVhct0lTB0u7aYkS1uLTuFqKhyGhUYMAYmP6JudFZi/cpVpzztGlMM1kRFECqC2 QDLbMzb7BVs9e7nR/pFju8q9RcThulG4M= X-Received: by 2002:a17:90b:2d8e:b0:38e:6d4c:14df with SMTP id 98e67ed59e1d1-3933bd2c8bdmr17424128a91.1.1786964153741; Mon, 17 Aug 2026 03:55:53 -0700 (PDT) X-Received: by 2002:a17:90b:2d8e:b0:38e:6d4c:14df with SMTP id 98e67ed59e1d1-3933bd2c8bdmr17424097a91.1.1786964153257; Mon, 17 Aug 2026 03:55:53 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Daniel Henrique Barboza , Palmer Dabbelt , Alistair Francis , Weiwei Li , Liu Zhiwei , Chao Liu Subject: [PATCH v9 06/10] riscv: add RPMI HSM service Date: Mon, 17 Aug 2026 16:25:00 +0530 Message-ID: <20260817105505.2607506-7-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Authority-Analysis: v=2.4 cv=Ua9hjqSN c=1 sm=1 tr=0 ts=6a82e8ba cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_K5XuSEh1TEqbUxoQ0s3:22 a=EUspDBNiAAAA:8 a=itn9ZVZVmevHaGIKV1oA:9 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-GUID: ox_co8T6PiihdNx4SLett9rIEUpnVUxF X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX7BBsSFet/YRu kCwUNXmMQDe+93IBbgw7TsF04U2SH6C7MYOj1IjbxJtjPCGKV4GEHytjMpqX6TmxEzqdEBwMu4t 84Zpt4I2LByB0lu3R1oKgL91Womf3WLcwKOpUeCkjLc0FE6FwOS4dzg/Ny31Fm7qiDiUC7rV2aL lTWppJL4ARlhKtqDeSuobXm1kbx8mSoSY/oL70XDcuOhk/oNkNwBQ7Ey0uo9ZUDw9TatEgs/FOn JA/LauCYqHVXY3KKt6ALzJQFEqwMS18CvWSvbLsAU1K68dt0W+1Z+1LdfXyO6Wo0kgw6aN4IXEl GwetqxW4SH8Ov7/94YkhpFkf2lsQ/xs5S7Po5V6MxygKWqib0yUbXWBJU9T5Q1vG8HODUiDt36g VMdnwvsqY5vYdrfxtmD3p9gqnLK6QK+ZEpTmpH5KoKOKhD0UauQNcbRj2c7+tlJiTXhlPx+vAfz MHKFx9nFYCFh+2UxOuw== X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfXxOfoaJxs5f+k PiGx1SCinaATk1UAwKd9cWzjiPIyR5Cd53AGOel7/Jq5nCY+KiGrxultxD3iJnk53JET9wSjb30 rssyen9m23IT0osX/HzCBt2TGOATTOM= X-Proofpoint-ORIG-GUID: ox_co8T6PiihdNx4SLett9rIEUpnVUxF X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 adultscore=0 priorityscore=1501 malwarescore=0 suspectscore=0 impostorscore=0 bulkscore=0 lowpriorityscore=0 phishscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1786964226502158500 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Daniel Henrique Barboza --- hw/misc/meson.build | 1 + hw/misc/riscv_rpmi.c | 5 + hw/misc/riscv_rpmi_hsm.c | 280 ++++++++++++++++++++++++++++++++++ hw/misc/riscv_rpmi_internal.h | 4 + hw/riscv/virt.c | 5 + include/hw/misc/riscv_rpmi.h | 5 + 6 files changed, 300 insertions(+) create mode 100644 hw/misc/riscv_rpmi_hsm.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index f8a317b8f6..a053242518 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -174,4 +174,5 @@ system_ss.add(when: 'CONFIG_AXIADO_CLK', if_true: files= ('axiado_clk.c')) system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files( 'riscv_rpmi.c', 'riscv_rpmi_sysreset.c', + 'riscv_rpmi_hsm.c', ), librpmi], if_false: files('riscv_rpmi-stub.c')) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c index 97517766e9..01cc61d023 100644 --- a/hw/misc/riscv_rpmi.c +++ b/hw/misc/riscv_rpmi.c @@ -182,6 +182,10 @@ static const RiscvRpmiServiceOps riscv_rpmi_service_op= s[] =3D { .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_RESET, .add =3D riscv_rpmi_sysreset_add, .remove =3D riscv_rpmi_sysreset_remove, + }, { + .service_group =3D RISCV_RPMI_SRVGRP_HSM, + .add =3D riscv_rpmi_hsm_add, + .remove =3D riscv_rpmi_hsm_remove, }, }; =20 @@ -234,6 +238,7 @@ static void riscv_rpmi_reset_hold(Object *obj, ResetTyp= e type) 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..006ddc3b5a --- /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 ca9838d256..3b8546a553 100644 --- a/hw/misc/riscv_rpmi_internal.h +++ b/hw/misc/riscv_rpmi_internal.h @@ -29,4 +29,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 1a69fd7cfe..e0c9ca4f5f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -995,6 +995,11 @@ static const RiscvRpmiServiceConfig virt_rpmi_services= [] =3D { .compatible =3D "riscv,rpmi-system-reset", .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_RESET, }, + { + .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 a9ccc950e9..13a058a062 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,6 +37,7 @@ struct rpmi_context; struct rpmi_service_group; struct rpmi_shmem; struct rpmi_transport; +struct rpmi_hsm; =20 typedef struct RiscvRpmiMachineOps { void (*system_reset)(void); @@ -75,6 +77,9 @@ struct RiscvRpmiState { char *platform_info; const RiscvRpmiMachineOps *machine_ops; 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 Mon Sep 28 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=1786964179; cv=none; d=zohomail.com; s=zohoarc; b=Aq8nBAGCmSd/eHah4yFLFTcmGyz5YVxezS5m+hjVuHZ/fYOGGxh+vWpYuQldBeH7cFgLgWAwQ9+pXlsk8LiugncHYqFUGFRw7cRg93PEXrwwfLmuOm8EBTuqdHddYqmQAyOz1wp90sdZWk7ve1ZJuk0IAcxZzOZcaI+aaXdTT5c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964179; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=4MQ7m/xnNTlmAd2yUWdE7VLPWFRjZ33tIbtXSHmhzQE=; b=NT7RjDgo1TabL91BmacI+Yj3YvXyRN7HjOpy//HGTz+yAi1q0iQafaJ2kNZ4JQlpg9oAkmJurloo6gER1zaI2eEdWFvsRcKkmX04ko0DTUuDy3y1NJTqr/UzD8n3VbV84zstW8TqzkThoFfPAgJgUT2cf4fh8VPrnmeH0xd/W6c= 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 1786964179611725.5078113940122; Mon, 17 Aug 2026 03:56:19 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0i-0003nz-Rc; Mon, 17 Aug 2026 06:56:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wvv0d-0003Q4-KF for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56:03 -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 1wvv0a-0006Bd-3p for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56:02 -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 67H9dcve1466545 for ; Mon, 17 Aug 2026 10:55:58 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 4g3xx7ggm4-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:55:58 +0000 (GMT) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-2ced1ed870fso8255845ad.2 for ; Mon, 17 Aug 2026 03:55:58 -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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.55.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:55:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=4MQ7m/xnNTl mAd2yUWdE7VLPWFRjZ33tIbtXSHmhzQE=; b=Zw2nmo4DRb6ERKVbc9Dr0SFh/Kn UFietLkgGBH+OSSub3AwgAovZMTl9XzhfAzBm7LystFwX5GR0kPt1zIeV0llFwiN txOqAIOYq1JrXP74v+et3CBjLZkW2JKrTvVYklNI14k73/4ZXo1hD+VgaRWFYVXN MuGXqvBLwojmNmgudsPgOWYR5pe6Rcani8tTmO2IP6WipGukbss4bJRP3Ozi3cjX w+MoxnDmgnSLmp2XfjRiVgRqbrGKTLsBhYBdvzDsbaVkgT3wUR9quHBmXUHRqsEa ZDQFpTUPMILgoLHydLZM9FtMDX2VlwnP90Yzz6dJJywnm3YrWqcWgdSy0FA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964157; x=1787568957; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=4MQ7m/xnNTlmAd2yUWdE7VLPWFRjZ33tIbtXSHmhzQE=; b=PyemcxzhRxgl2nq5wQcFEJ5CvS0BX2QCXHmPU0SfDuusdSqllYTHerbFV9eSqU+GWt rOJzEe77CTqXoMBZKNipncs2VioHZs3sAxKSJ9K5I/PmQ8whdcp8wHiD1u5sA/fRX/Er YT9FHGt/N61NX/gX5E4lc2UF36y3E1OPSgNOQKTJpNBZlRa7DBXd1SO0ve3vrjyIyKxe UR61pUqtNt47/2O7hipY7nwSEtxuXmkY9176/XsMvu3BrUgT9cfqRFxUavm4SX4JhIfD UnNZFWX7G/lud/0AzjnhvuQmWoK0s8VWJiusTk8kwARPK46RBB4OC9lZ3QLwfldkOYlS Mi4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964157; x=1787568957; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=4MQ7m/xnNTlmAd2yUWdE7VLPWFRjZ33tIbtXSHmhzQE=; b=iirOCnJTTzVbwx1onSGUgo8PHet8FAQXE1BRZ2d+BFA7UZqiqunD2MleaU5Jbe4hpa 39ESHbFEFVpsVJ9j4+u9jDY5iHC/nepWfZhoIN3U5rJCdQ2dwhQ782oRCy1juO8awuX3 KeEU8HojlZjMZw6LsgIY+Dpz8t7ydJz6sBNo5MZBjmgdB7C77+osEgxkZbpz+JJtO0uU 6twsN49unCWoU+dUmaH9YFmH8m5tNCgbbwbwUFoRAsn7IwdSUV9efm1RhFr6fy2tQh23 +meFEQJiagUlcJnuYEZ2MyTOMR9HU47FnbuRRtdgLtkONMTWhAamas3PFJMnL7brLJBA mN3A== X-Gm-Message-State: AOJu0YxJ35LSNKjo0BIdsebFfUFKEZNvpvl1zHKU+He2I50NburGDBpD /+DefcygGpxs9FcxR8l8SWZ3ON4pgXIccZHU0fsEj2Z6/0bqQeRpGyE+eQmScGM+79GxSSzUkF4 3demv5HYcJcJ5kwSH397H96Dqys8CSKCh9+zl3Oh2Q0+1NKjRQ4EdzR6Oz9AaiuJ0wdRo X-Gm-Gg: AR+sD12QHuD0rw2LVTcp6tQAiQNFWM3BhwVXljuTgO3wQpLOP2OXPMiQ44mvjygzANQ CbxNFbpuv+mT/Q2H+MlZbhnFp2Z90QH1/ru63r3+AFij/eepq8qhzjpG9lTUrN9ndrEMe9AxlEZ HfSfRkqdqV8LapSwJS6v0a9s4rfbeEsdmG0WCuhnhi7B+ypCTtfdQpB1gTJ+t6LoeRCDw3q/du9 veGogO9+QnELjUujclatXUoiECQsxAscKyp3l2N/9gyblxjZMGpXEiBXTGg9jv5mub7HSrdhRwy WBs7+yK+kGYM5r/lTxpBb39hdFFb+d+muNt9YCsROL7c3V9L2N4IeA/suDD3FW0hkBb6d3WcwSD DcbEzT9LRwV3I20EHa+KV0YLMQZJFzw6ObI8iSknsoNSPIJBnk1e61sQBKcQUSDfXwDUBAVTGht ryLV4qC1RR2g2Jt4S0QhvOZN8b4qNbx9w= X-Received: by 2002:a17:903:3847:b0:2cc:f4d4:29a0 with SMTP id d9443c01a7336-2d3b0c9938cmr215693745ad.3.1786964157373; Mon, 17 Aug 2026 03:55:57 -0700 (PDT) X-Received: by 2002:a17:903:3847:b0:2cc:f4d4:29a0 with SMTP id d9443c01a7336-2d3b0c9938cmr215693415ad.3.1786964156944; Mon, 17 Aug 2026 03:55:56 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Daniel Henrique Barboza , Palmer Dabbelt , Alistair Francis , Weiwei Li , Liu Zhiwei , Chao Liu Subject: [PATCH v9 07/10] riscv: add RPMI system suspend service Date: Mon, 17 Aug 2026 16:25:01 +0530 Message-ID: <20260817105505.2607506-8-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX5j0JJgKXkf95 bwsu0CMh7x5a2Pz7PDTrenDGB1WbGp6VDlRnaiYwd3uU+bqUPBgjlPDBaV4jefhh6cd7V2F7DkI sIk2wGt48yaJ4f+UsfYcg0lMu5XCahE= X-Authority-Analysis: v=2.4 cv=TK91jVla c=1 sm=1 tr=0 ts=6a82e8be cx=c_pps a=JL+w9abYAAE89/QcEU+0QA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=lod_E3DmNdtbfVLvUbsA:9 a=324X-CrmTo6CU4MGRt3R:22 X-Proofpoint-GUID: GIew3CczTA23052YeaVz7kz3uvcmPjP3 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX+SzbLxvDMnoo icU1JeYVGkw7qIekzejYWOB3UGDqzW9silPmSxjueMsKS9Mbj/wd5wFZ6Xi/VcxhOBWLcYqdtKV XkyxIte+JvALHUx/VEgWRlkT+6HQxEuFkfVx7Cn1FS0p6IQAb4lk5QfhYluubDsE2Hrhx70FxyF kSsxKq9ue5OVF2CNBekgu7IU3mI1PBmSFCD0Ez1XDs2LefhYcG+uvN7pn479uj/RJwGg0QoXpMw ZO4qMLb5MWRx7QcAb6ILV1qfCZV2UQIWV/z2/oFEL1AwUFOGs1tORG+hrUCEvsl2A272e5VyVxe AMkfmDEQqi1n5x++LRp7i9TN7nCx5+MsqQwQj7bQF7vRTPHmnG/pJhMruEIJkSUGhelgbbJ8xQB Ubj09TBGSKGH70jwinLGUMKEFevGGb7fyYRehKkEhWIAQyFn5lYiA4zuwDFONo59so2KuTsuN5L j/CdRb+LsgkcvFTl8dQ== X-Proofpoint-ORIG-GUID: GIew3CczTA23052YeaVz7kz3uvcmPjP3 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 phishscore=0 lowpriorityscore=0 spamscore=0 bulkscore=0 impostorscore=0 adultscore=0 suspectscore=0 clxscore=1015 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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-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: 1786964180144158500 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Daniel Henrique Barboza --- 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 | 24 +++++ include/hw/misc/riscv_rpmi.h | 10 ++ 7 files changed, 243 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 a053242518..4ec78a34a1 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -175,4 +175,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], if_false: files('riscv_rpmi-stub.c')) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c index 01cc61d023..5b1e33c4a8 100644 --- a/hw/misc/riscv_rpmi.c +++ b/hw/misc/riscv_rpmi.c @@ -186,6 +186,10 @@ static const RiscvRpmiServiceOps riscv_rpmi_service_op= s[] =3D { .service_group =3D RISCV_RPMI_SRVGRP_HSM, .add =3D riscv_rpmi_hsm_add, .remove =3D riscv_rpmi_hsm_remove, + }, { + .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_SUSPEND, + .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 006ddc3b5a..037952dd22 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 3b8546a553..56b46a66df 100644 --- a/hw/misc/riscv_rpmi_internal.h +++ b/hw/misc/riscv_rpmi_internal.h @@ -32,5 +32,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..1773828757 --- /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(); + } + 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(); + } +} + +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(); + } + + 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(); + } + 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 e0c9ca4f5f..b92945f072 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -50,6 +50,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" @@ -1000,6 +1001,11 @@ static const RiscvRpmiServiceConfig virt_rpmi_servic= es[] =3D { .compatible =3D "riscv,rpmi-hsm", .service_group =3D RISCV_RPMI_SRVGRP_HSM, }, + { + .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) @@ -1017,9 +1023,27 @@ static void virt_rpmi_system_shutdown(void) qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } =20 +static void virt_rpmi_system_suspend(void) +{ + qemu_system_suspend_request(); +} + +static void virt_rpmi_register_wakeup_support(void) +{ + qemu_register_wakeup_support(); +} + +static bool virt_rpmi_system_can_resume(void) +{ + 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 13a058a062..cb4f208ee8 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) @@ -42,6 +43,9 @@ struct rpmi_hsm; typedef struct RiscvRpmiMachineOps { void (*system_reset)(void); void (*system_shutdown)(void); + void (*system_suspend)(void); + void (*register_wakeup_support)(void); + bool (*system_can_resume)(void); } RiscvRpmiMachineOps; typedef struct RiscvRpmiServiceConfig { const char *node_name; @@ -77,9 +81,15 @@ struct RiscvRpmiState { char *platform_info; const RiscvRpmiMachineOps *machine_ops; 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 Mon Sep 28 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=1786964209; cv=none; d=zohomail.com; s=zohoarc; b=aYtiCJ66WdcZlMdIkqBt9z1n0kD4D3aLUJZGTJ8bbv+Q8unfh/+j+Lv8JCG5wrLEXJMRE9KLkVKdbe/EZ8XmR0VUP7icLcXiZG0P0OIdB0FOdIxzCCzAPizfsxYld//jS+NpQoREX4f2nOidgnpEeu8a7syuSX3p9+PODr+0SnI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964209; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=EVB6iwJXUSOlmyMdMzCUVLy7ZQwQiUGcEHKB8v/DuME=; b=PiXmgc9tMNne+nfQM7x/aaA3rjhSsLmnCfZdnfULvaYAe/C8GJSl7i3nq52dgnR0+NnRL+0lwAYbqtcPZprQ3EfCAyyzx92QiFvAUvBXGUnD39H7Ay5tVlELGHKCMKgRX9Xcl1Z/ktwKnsho2iw2ojkSij2XlLwolBQexCs5Tr4= 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 1786964209666740.9661391942329; Mon, 17 Aug 2026 03:56:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0l-0003yQ-3w; Mon, 17 Aug 2026 06:56:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wvv0e-0003Ys-RT for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56: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 1wvv0c-0006C6-8h for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56:04 -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 67H9djV81932191 for ; Mon, 17 Aug 2026 10:56:01 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 4g3txy9fs8-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:56:00 +0000 (GMT) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2cc98d6a88bso7879245ad.0 for ; Mon, 17 Aug 2026 03:56:00 -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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.55.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:55:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=EVB6iwJXUSO lmyMdMzCUVLy7ZQwQiUGcEHKB8v/DuME=; b=ZpT+6FIacRAXNLh+lIsco2F5LHp hyR+DVfzi+LFDbF3nE8aFJx9pvSdVXRuPSQozVYKWNcEBqWgEKmcc4yOtrZ9KJ4c bEy/FRAU9+pxxLBjOtsnyQvN/e+RZPFqv2dfqtZd+TcmQrTuR/bLaW0EsJ18NV/l n1Qf38jQz+IodkSpIhEGLh3dhVr0uOXbPSZE2yPNjg3rP7mqPro/QI92ADNPX8b4 310gaAA2+UlmZVtTLp8Soi0/BJkxwZbAOI/rws0J4/p2adO+brRpErzUdrQTfLVL vm4uxftbR00mksA/G+z/+K+LDs0KMXhcT+K9tNfBPTVQZhRadvoOhvaNqSw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964160; x=1787568960; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=EVB6iwJXUSOlmyMdMzCUVLy7ZQwQiUGcEHKB8v/DuME=; b=UnEg7EP1+b8ceWGl6mnkyg22zPocqwrX5qlG8VvR8oykh8orC3KKRBArp1C9gheHix FOQCeV3HYtHH0UfUpSRbYnMnVwk5Roy3h3vQ2I8M/GPmGAybbMEss/jyigyQ8iFX0iSx VP//Cct2LBygwexvh+zoN3mzz8yTlG4SDRq20RUzcoEkh+U2dD6VN+mGgMXuQtAG9GQU wGQ79ce6Z3/6eEtzvPqC/dAQZ//G104oNm+q16KBS/RQ6JpFyuUtHYUHgz7W2ZJo3B9d 91U1jYOvgSNswZUq2pfh38nj+taprGYNbvprA9H1J5fTrtp50drFICsSF4r8gnhmFOIJ Y0xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964160; x=1787568960; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=EVB6iwJXUSOlmyMdMzCUVLy7ZQwQiUGcEHKB8v/DuME=; b=TwpxQDARW9crY6OBTailMCwBSU9cYHQy0IaL16VhAmA6QdEdBy7Wnh07b8uNJ1OpXg m2eD3RBD3QeZkon0TupItWc1FT9XU9/6G/sp8UJdTKa1JtyOqP5nI+fe+M7W6d1GZjyN TkMYBqlhgl3VI8uolyzEd5Ip5nygLFh4k9NPM54dgdY4/Ddl51JWLO8frNoXQiRYvmNH LUtEkrIL4LmnpKe09yRSyKWoWNgpzhIE4UQs+TJkqUuB2rUPXkZTcW63OSF6Xm0ywB/K MDrczRQ1Ipg2i1AQdsaII1cOWTnVUOi2f4pKFboyGpxIg7TZJKLSJtjBhKvztYHKTAXE KurA== X-Gm-Message-State: AOJu0YzTIdvpv+MQcp0VAafm1t0ioue560hYaAZ8ElKY28L9HpVVtXZ3 +kaRO+ioS2AZLB/uiFaxz4zP+7jtVyH4gtuwVUtPofUUL0CZD3d67DwIfbXKWF9siJZudZuFaRv gbAprjlnmeWdaFKD1pYrD9MJXYQnzxuFYvBXDJuL665BX3xKYjCsIm9jBs+LXsHOlYnxd X-Gm-Gg: AR+sD12gDeoFrJY4ttiZWcFWJ5HGq3n43yv1moDaBfpCIuquBK8hj+TkacPuBmf+BLf aFJuw2ro4rfrVmNNMtnyCWtcYP/jdgdivmEDi8Ea/0UKgLNmEnP2wNmpXvsscWEU/pooKJ4sjaz +xaEKgDHFZAdLyVbFMIHTquuU+UF6if9+n7JLv9JXfZFNomEk083FYzV9DH9xu8CRu8FgTblZ7E 1IO+2cdDtbPSQ4jcaeIDbAEIoK0SnryvYCtvjuyWSvLSvNNpEA59EE/ZG/RlhO/ZmbQx8bJE9vG O1nesZXUbN6KLPhI8RZ5SKWQ7sdHjpoeQDJKh16vlV8ey7x22lekqnmcbqRarQ/+PwfiNVVmCRn ssZSvKA2TeYXk43OpsQfnic3yAv4En9AK9IQTdBz1y4eRpH9Xef5SMiYwT1Hn7jhjccNkfsjmPc lEPMb8Okt11J7CnAqyDML0iY52lVgKUn8= X-Received: by 2002:a17:902:c944:b0:2c9:e846:a582 with SMTP id d9443c01a7336-2d3b04fdcb2mr193012725ad.0.1786964160131; Mon, 17 Aug 2026 03:56:00 -0700 (PDT) X-Received: by 2002:a17:902:c944:b0:2c9:e846:a582 with SMTP id d9443c01a7336-2d3b04fdcb2mr193012395ad.0.1786964159647; Mon, 17 Aug 2026 03:55:59 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Daniel Henrique Barboza , Pierrick Bouvier Subject: [PATCH v9 08/10] docs/system/riscv: document initial virt RPMI support Date: Mon, 17 Aug 2026 16:25:02 +0530 Message-ID: <20260817105505.2607506-9-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfXy82Bs7giLBqN EJ8oiA9TwUOIkXmne7ZfAi28P5xM9vnD8l5fqr6C59gfOcaSdqB1wZ0YO6fix4riILoDgy8oKCZ cs/f/PsEvMREBdPAo3MgqgFvkCsd50w= X-Authority-Analysis: v=2.4 cv=auGCzyZV c=1 sm=1 tr=0 ts=6a82e8c0 cx=c_pps a=cmESyDAEBpBGqyK7t0alAg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=NEAV23lmAAAA:8 a=V1jnuoLLAAAA:20 a=EUspDBNiAAAA:8 a=bNRx8rSjxjkR0t5bZ0UA:9 a=1OuFwYUASf3TG4hYMiVC:22 a=bA3UWDv6hWIuX7UZL3qL:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX1HHtAxQedBdq WTJxSVTfm0HKxdNpk36BTxNl5SfwyaqUeasAFr2kNlPdCKcWyqtt4PmqATwOnTKsELVGBDDYaVz WbDFeMZB5p2/XjoSv2bXaxpq+LqDdElu0uWPL9Pg4PfrwTocxyRv0+gugJa+ERLOh01MT6RDAa7 Cjz0D1bX9hPMeZ7LNqruDneCXxTc6WqpvgNZvvW1KqyfLnQ+/rlO1VQjDbW16hIVBG2EvehaEYT M5QKhOeuraP5DCd9fn09KZ4uiDmwWgrDJH0QIL07PpO5NGfXeoSH6uUhC+XEO3JPvkBuV/CE+Vt eO/uFYzz1YRwYMNEEobwvLJ4di2Az8ZyDjnFwMOfM71kV9y5HFbidwGMVUvXqDvA92XJ9rll6oq dek2sThT3L5h4rKtzWyfpEifWb57N7n5/UA+c5VinXdaa98Mefiqa7x/qbXxom1LiPRjLYdYD0g xGyw6Ojva3P3bwm9mpg== X-Proofpoint-GUID: QeOIOxFDUgMcRdEpo8tYYPA-rxJ6QCQ7 X-Proofpoint-ORIG-GUID: QeOIOxFDUgMcRdEpo8tYYPA-rxJ6QCQ7 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 impostorscore=0 adultscore=0 suspectscore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 priorityscore=1501 phishscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1786964210161158500 Content-Type: text/plain; charset="utf-8" Document the opt-in virt RPMI transport and the initial HSM, system reset, and system suspend service groups. Signed-off-by: Subrahmanya Lingappa Reviewed-by: Daniel Henrique Barboza --- docs/system/riscv/virt.rst | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst index 60850970ce..0b5b2d4718 100644 --- a/docs/system/riscv/virt.rst +++ b/docs/system/riscv/virt.rst @@ -146,6 +146,86 @@ 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`_. QEMU requires librpmi 1.= 0.0 + or newer. If the host distribution does not provide a librpmi development + package, build and install it from the upstream source tree so that + ``pkg-config`` can find ``librpmi.pc``: + + .. code-block:: bash + + $ git clone https://github.com/riscv-software-src/librpmi.git + $ cd librpmi + $ make + $ make install I=3D/usr/local + $ export PKG_CONFIG_PATH=3D/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH + $ pkg-config --modversion librpmi + + The librpmi repository can also generate installable ``librpmi-dev`` Deb= ian + packages with ``make deb-pkg`` and ``librpmi-devel`` RPM packages with + ``make rpm-pkg``. After installing librpmi, 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 qtest coverage +------------------- + +QEMU includes qtest coverage for the RPMI transport and the initial service +groups in ``tests/qtest/riscv-rpmi-test.c``. To run the qtest from a build +configured with librpmi support and the ``riscv64-softmmu`` target: + +.. code-block:: bash + + $ meson test -C build qemu:qtest-riscv64/riscv-rpmi-test + +The qtest covers Base service discovery, System Reset, HSM, System Suspend, +negative transport cases, reset behavior, and migration blocking while RPMI +VMState support is being designed. + +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 Mon Sep 28 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=1786964195; cv=none; d=zohomail.com; s=zohoarc; b=RLY7lm3NbVLP91OePfkDHMueUauSFVTM951xGuzNupc2gnqKo4ycWCuEuiJX4ErmL1E0RwyZQi+GxihqbA8FdmTVtPcJBA5kiNLq/CPRoBFD2TxhCJK2IiNYQ69ZvmZlHR+OVgCfXOwvycN4/Pec9fqedcGZW3SYCDxn0hR1z6E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964195; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=scdMlLC5yR+PfqRmiZt6WCYor4c0RzTrIjewAtFJbgQ=; b=Z2XCh2qUFqolTTN4nO2I5Y3aCuQBoNQ2HAjB4VgKaYU/avWc/9jbpPx8XvR9R4JVuAKjkcvqX7HhCRRrbtDOldiMS74qFoZ2jpwHJF6/ZugXdOYv4VgC0Q6Ud+g1rJSDDMC0S3/zWdfaunlLb5CVOmaTSImWHu5YBN13SZntwfg= 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 1786964195314424.2937309220364; Mon, 17 Aug 2026 03:56:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0m-000422-O6; Mon, 17 Aug 2026 06:56:12 -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 1wvv0k-0003yA-UX for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56:10 -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 1wvv0h-0006Dn-Fp for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56:10 -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 67H9dgDq727928 for ; Mon, 17 Aug 2026 10:56:06 GMT Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4g3wke0vrf-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:56:06 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-38f005ae3d1so642906a91.3 for ; Mon, 17 Aug 2026 03:56:06 -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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.56.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:56:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=scdMlLC5yR+ PfqRmiZt6WCYor4c0RzTrIjewAtFJbgQ=; b=VKWvsxEXpUrHgCzsc5CgqSxWSc5 5e9Ua2gKaGHxB8Indl7tCjDt9nIk4duEu1VRTUmNCOLEdEdbR5PEIIAySJlCWcea 2k3s4FtpszARpYVnpK3ZH5U3QC/L4sPieAKVAI5MurpsWi+wdqp3zYgWyYuaRXyp mFKO4eCTmTTe0Zu2dmMuCbondYyd29uJJrLyl9Ilt73TDNbGwZhKIfvuvJ+9gTIc H9vYeehneyP1K3cTLpVfYAEK3R2PfNJcKjBW3cICpKEoibLwVz5vy2TQW/udubgt qDBAhEqS/f5HLLAoyQNxWAPc33VZOUEXecBfQSmODgBn4VHLTjR5CP9ZraA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964165; x=1787568965; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=scdMlLC5yR+PfqRmiZt6WCYor4c0RzTrIjewAtFJbgQ=; b=QVkj/J9Om6KERuqjIhAyI9zSkdLBUZpDj853J5+NBEl5F1U232CP8B2b30waCsoM9H lY2NBcODhS9wj0vWLo+0KXwK2Y4F49yhDqhu+AJpzL7kNs0U1RS9IrKkg1NzE2NXl80m cTJxOqB6OlWB+ihXpbWU2tSfcUtdUrNT3QvBpyZ+IZmdjuETs3V+YQNxeaOMXjhlU+FT ZMd9B27RGIW23d9KlpZSHHJDuMUeFQcFe7xEG7J2MSE2Qqhi7wTauuJOnDmR7Gz0XajV 71tXSsGDiChxwSexDw3rmFT6HOfrNicxZYVUmwWtku5efkTNuPseFHjB0Rwu3IyEr9lJ m5ag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964165; x=1787568965; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=scdMlLC5yR+PfqRmiZt6WCYor4c0RzTrIjewAtFJbgQ=; b=mt/nCiBvS7sNUoI59s/3wkKwsjl5Ls/azIWXV+nUoJWVQPjvcVsrrmHPSFmd5N19kd xIPxScMBvxXIlvqEESxYbquoIrVSsn5tUmKAYvez2dz2pqUJ2pRONTEtvCV1XdEyARzC 0HQEH7YuxQs4bWvO4Eus0VrzgNKELamc6V6empjGnjFvDl01G4o9tCxH2Rl8AfHZmDWv miXqvVBE5OX3dL+QEGTYsig0E0HlN11oJ2j8nD7GGMqWe+8MYCJskCi2I+BLvDHAy9qF Xj+1s77rKI7brUkWrTpxxvxHdTVMarFHyd2w0Hm/5Mb25pi/jqXDWzesEWStDuI/EKtN JSRg== X-Gm-Message-State: AOJu0YyEacZJPODszftNGmfIFecnoBMp98DPhtpKvi/WL1DUYty4pASK CyRrP+htX8SxWCJQvngtTdnm2h18UNfI/cDsZPV6CPFr675eMg4uA9bWT/ARHRdX9kDM8Nf34lT 4IbRji1d+UbPFPIBTcR7SOZ+gMf+VXee1TEheKNS6I5sbE35mBMJcMuWbr5Hq+/tlU8ek X-Gm-Gg: AR+sD127W+EsgBQLKIVvbzLxQar8vYKHRB8wCEn3xQHGwRdcYGNAthpNyN5+LXBoJug KcJQrQwh9aVB3gApC+luhwwP57GBzfbb+1HUa90LpnNfekW0n2lW26zEy0ldpQjLXW22Vn7/P+W D88lkE/VXbmqDzd62RzYaSmkTsx2l1eh8mbJdVLMw1e2Ta4C5JvfZqD03cox4ND0s4Ww1jMzZXz 2AHCZ+YBNJF8TBod0GX3cnv4FeDPWgPbJ5K6QaWCwExdHq77wU3JMtk+87vPP6UnngKoSyed5cg jOueVwFICBxOGl9U8gTmc+GcZOQX2egfLCp79jDnDAJseSN19Emha2qXa1MXWNLRagPtXo0do/f LzEUD3MJB2BNbB3x80AwJau1ZkSUuH4/gDQevsiZZilwxuVYPATPxFwR/3CF985wRFT+4j+vrPt Pm3sN050gC/8GEJMGJ8XGq3zftuvyF4vQ= X-Received: by 2002:a17:90b:3142:b0:390:af7c:fe5e with SMTP id 98e67ed59e1d1-3933e5e1b69mr16674456a91.2.1786964164938; Mon, 17 Aug 2026 03:56:04 -0700 (PDT) X-Received: by 2002:a17:90b:3142:b0:390:af7c:fe5e with SMTP id 98e67ed59e1d1-3933e5e1b69mr16674414a91.2.1786964164181; Mon, 17 Aug 2026 03:56:04 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Daniel Henrique Barboza , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Liu Zhiwei , Chao Liu Subject: [PATCH v9 09/10] tests/qtest: cover initial RISC-V RPMI services Date: Mon, 17 Aug 2026 16:25:03 +0530 Message-ID: <20260817105505.2607506-10-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX5mwxs+p8Zny3 fKcYIepPpoBIP+DzgWZcgtL3poY4b+TdTuSp5bkc0SNXY1y2Ram8Mf35uVbi1QUy/HJpZMm3cPW rrcwgRzBtWO/pO86eUsXS7wb/vXB53ibFsp+iCZQ8/BM+IVXu3dEJdybJ8Tgjy2wV3frC+o3DUN BYSAB9bJQqs9nLBlwbS6x5U3QaIicc9X3Jhgli0bg1lBkIDJIfQM0mJrAgVfZKphvm35LMk2q+j wDVAlvbBpoqtCNvcirLy90my3o6ix1Bg1jfuyys6WyO9FLeopafuxpOK7u6Z4DeP7AVuID7cJ5g iGsp2Hq/tEH0AosA/EuZfTnhqgbUXRGhq2XkFzQI1vVVTTFEunXWLqN1YQo9Zitu/NvV7pJXZix coJmokt43Swg3UEyGOm9f7p3xW4iMlhGuK9IffVdV/mGz94KyZ0Ejfm16kGQX7cvq0wl6Qy4bU5 ZR9uStM9pdQJV5DG9Kg== X-Authority-Analysis: v=2.4 cv=QetWeMbv c=1 sm=1 tr=0 ts=6a82e8c6 cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=Emc1XLxsCFVyjqgSCtcA:9 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-ORIG-GUID: x24Iy3Wgc7LyfXNfmm7-t6OkvEM_KHSA X-Proofpoint-GUID: x24Iy3Wgc7LyfXNfmm7-t6OkvEM_KHSA X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX4Dkz81J1bYtz ejQa7s7LUUvQQC9pl/SaVRWJ9PBgF5dMATyh9RRYeJuhMd0AU0P7wS9k/1EKnVd9qmupgqTJp6z +ZB6dre9RoemKrFbqjh4VSBSuj7gKSg= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 adultscore=0 clxscore=1015 impostorscore=0 lowpriorityscore=0 spamscore=0 bulkscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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-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: 1786964196159158500 Content-Type: text/plain; charset="utf-8" Add qtests for the RPMI transport plus Base, system reset, HSM, and system suspend service groups. Signed-off-by: Subrahmanya Lingappa Reviewed-by: Daniel Henrique Barboza --- 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 c742a71ee6..50cd12655f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -374,6 +374,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 f7c7d06620..4eda021957 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -294,6 +294,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..dab723b999 --- /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 Mon Sep 28 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=1786964212; cv=none; d=zohomail.com; s=zohoarc; b=dv5z8GmtTDfZYj2l3I2wuGQrsOz5LUSur+73gGhaKWsLj5tF1d2y+aRxVDrKxIHaADEZMvMbhzc/eLKZ6er36R0fhWvGh/9xREPLQfmpjSCyYQIIZQDJvbe/BcDjdkl3K38/3FUR8a6JrlJfFd6AAOC2OpVI7tyWMMZfVLsSZbA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786964212; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=qRRwiGrsxIddxqlNmu4g0WsWnr2EbhJrohLUTwLE9dc=; b=WCyucKIQS6TJuivQGhj3CtIF5Ejnf9UfusBlWzd1Zd1k5GDYU3mAjQWLhak0sqJWxbHXppI8ehKE+PO3h45CqJokpXmuqdniJieqS6lT/zXjmx3fh1J1gWjzPaNEVvCxwqeuEn8LWiQr0CPoHmO22MNaF0uZYJqod5mci0PMnNg= 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 1786964212714351.1600026008673; Mon, 17 Aug 2026 03:56:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wvv0q-0004Cu-89; Mon, 17 Aug 2026 06:56:16 -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 1wvv0o-000431-5j for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56:14 -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 1wvv0l-0006EO-9p for qemu-devel@nongnu.org; Mon, 17 Aug 2026 06:56:13 -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 67H9dmGk1058538 for ; Mon, 17 Aug 2026 10:56:09 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 4g3x30gqe6-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 17 Aug 2026 10:56:09 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-38e8d1600b3so960706a91.1 for ; Mon, 17 Aug 2026 03:56:09 -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 5a478bee46e88-3267c389363sm5431136eec.23.2026.08.17.03.56.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2026 03:56:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=qRRwiGrsxId dxqlNmu4g0WsWnr2EbhJrohLUTwLE9dc=; b=BXOgW/nr1fJ6M9Ou909GkLQ1/kO YZ14QS+9cM9ISsJul6C9lOE4BquNy02YLZxlegx6JMDCXdpfv3lGZRtTWtsLjACV rBCq+56WySavxAkBYEit29LjZn6yALHCL3V+xoSitQYLygUcNKNOgvqR7tmCUFWX l9v7DvAmDhdQ/47CnIwwwxFcnNa7WjjCCTKxYrEMaP/vJUx58+mkO0531IyWP2FS KMdN/jG/mnQmwuIW9nWy4hdAFM+79HYzNT9FJJXCmCXOmY6eXL7iqdKF82eCHpcB ILsxEf9I4XVrJ9wrPuG6QZA/y4RCYA6vi52sX0c193q62U4xWQO8oTdyeKA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1786964169; x=1787568969; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=qRRwiGrsxIddxqlNmu4g0WsWnr2EbhJrohLUTwLE9dc=; b=Ocq7rPTl1eeQQIdDWaFfh0YuIAGE/VjY4UNDAKrUMqKJ7n6y8M+iFiOyALwWSI3LDZ WY2ep5i9YVyP0660dv4ibPO5vqUNmNS0LI+lrplctyBOVZcWKiYqm982th2rvIp4ELEu wel1S5WD4jg03ak7u/yDxFKs3o1CXNvENKhK4GjFmUTfM7yZA/OS1LgHPWohnvYL9Lsu Kzz/ddH2U269ely1rdkl/wjASOCobnVyYVSdbjnZqFQqqUdbT//+8cPdrxMKJMKuSz6O lESlLaMhSfxBLlQ26gylyU2BFIJbBpXHEMofuBRrmN+eqYn/7nl391sRyCjQam2xL2zN AdJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786964169; x=1787568969; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=qRRwiGrsxIddxqlNmu4g0WsWnr2EbhJrohLUTwLE9dc=; b=g+MJ4wdqUdqKgqdGAE/h8ai+eunxzJUDY3vLhGINeY2T15mqjG9Yf+Q6G3HqSdkjOH z/mcSRPhwwJxiuGKTu1WgbJV1aAuG48M85qoep3vOg76CeBSSX69yFpQSz5q8HzywoZh EOFngjcmXDyFiqgmZvj/Y7iGXNmzYmhnQPfJTqdr+v1mN7zfjoxjKTmlgmIfwKTWG4Cp itLLmA6UHJZro7+PEy+f6n6omSN9KfQ1wOgoLqPtWSz5vbJOE8UmXN1Prqz1IczVgqp3 58M4spdj1ZxvQjRn+8r2FJ0xcRA89P1OP4xYMCQUft2dC+KJ/Z5TJ0b6CAPwWs3qYiPE oxZg== X-Gm-Message-State: AOJu0YwG1w6Z0e3MKz/8XXyQr3mASAyKGAXsbIeJsCfQuKDTiV5MnfJ1 +viCi43V4gwgbZjfsTwfEa3L4cIGeL3a5u9K+tL6FB4BIGjO1KK48bpGZtUDB/3j4kKj/3ciAcv vf6RNB1X6v5L4tp8G7SxlHtV3wYrlvvsOa2tm4x7Yjtz1yorkz6Vf4FlG+58O3/Zz1ADL X-Gm-Gg: AR+sD13kfxVQYDIo4fqylzRaOqu3bdaOdMqMLcHkiiJ2uUmouzlu8N5L/0q/VGNNuo9 nFXo9joNzSNueDe/RqOBA8etZRmE+iC53Rn3n41Kxy6tO1y5f6s15lkUBvu8qomqFqYEgK0VHJi JyCwm4v3eSSOGcmp35svxKcmoqLBSbYxQ3kEQC4RilpBTfXK3hMTeUWE4r5o8Mt9uw8qZsC9GO/ uNza+5nw85Peuouhlgp+wDpJM71MIiJXTyWEURsH8fvlFdLN1v8ze1AEOw9Kqzu9QmAx/5z03wa Y8VOZ8/OkgSdpClu+lf6zFkfTqbmmV9rei+fFhqitjuO3+0Ej5bghUVgs4k9IvVngpPsq1OZoyQ ZbkAUrIS/nRxwJSwGpWiDxsCaii8P8vBtTI/k3uHOPq6f4t9zOgNol9RtwW3kXLcZs0tTOUGdeN hFVPnqFunteMv42dSEMoObMancM1o8/m8= X-Received: by 2002:a17:90b:3907:b0:38f:aa76:88b with SMTP id 98e67ed59e1d1-3933bd12631mr17031215a91.4.1786964168562; Mon, 17 Aug 2026 03:56:08 -0700 (PDT) X-Received: by 2002:a17:90b:3907:b0:38f:aa76:88b with SMTP id 98e67ed59e1d1-3933bd12631mr17031181a91.4.1786964168035; Mon, 17 Aug 2026 03:56:08 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, Subrahmanya Lingappa , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Chao Liu Subject: [PATCH v9 10/10] tests/functional: add initial RPMI virt guest smoke Date: Mon, 17 Aug 2026 16:25:04 +0530 Message-ID: <20260817105505.2607506-11-subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> References: <20260817105505.2607506-1-subrahmanya.lingappa@oss.qualcomm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfX0k2YJMLR02XT O1HnJXv9zMmbeyeN0FmhLL/UMs1qniza5nYOw77h6ZrSE/t8HoXm6gNlbv7X+eRHy1rlyOjylK1 zYz5XUMHJ1wfQE9tsk3Nb5Qh96GQJ1psxUC/U6xCU2JGUoXq4ZtXqoVe3trx9F5GuwXeojGHvXN PCeYGQdwCKz/Ah/g4t3aGf8stcZ6A6NpOeTr8T9zSO4duB6SaSJnwArsbC+s0GBGiWchc7gVkcE D03ziQ0EarWW1m6fF7zBd4NulH5ZYBgCde2yaeifTtxPcLMSBESF7IiyMfCmZTwAjZsapG3NMMo JCp2Rgl9iXYkNUuureidJNfxa2E/8dTrzP9eVDxnM6REUVCf6t6gjaX9WP6ljbN7hkdcoe1Kz1J 5FqwQyqc5EYUNdKqZxes3Nu/8ZYI4tHuriOttS5hslC3VcmXj4fvFTnrgIivQiVKXhs19BfBJkn i7zYu87dtHkZSmsr1gw== X-Proofpoint-GUID: fPhrz1Vad0IgdKhcpjTS8mCuanhzCBm3 X-Proofpoint-ORIG-GUID: fPhrz1Vad0IgdKhcpjTS8mCuanhzCBm3 X-Authority-Analysis: v=2.4 cv=Y9/IdBeN c=1 sm=1 tr=0 ts=6a82e8c9 cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=Sv0fKeRqtYgA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=rFS5Cn7EypwXJqSoKdAA:9 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwODE3MDA4MSBTYWx0ZWRfXyjs5eJ5s2mcU I3EANH3gT9qH/SFcCdWKAyGcDG2xWTOz526EKqvI+Iv2KJMsm3y7UgDGeoEuUkPB4XZyG2lZ36i JBfpIdRn+5DqvU8O/aIhE4P2iDwCpQc= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-16_06,2026-08-12_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 adultscore=0 priorityscore=1501 impostorscore=0 clxscore=1015 bulkscore=0 malwarescore=0 phishscore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608170081 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=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1786964214315158500 Content-Type: text/plain; charset="utf-8" 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 | 184 +++++++++++++++++++++ 2 files changed, 186 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 d1a3e6c2bf..1b35ba8cd7 100644 --- a/tests/functional/riscv64/meson.build +++ b/tests/functional/riscv64/meson.build @@ -4,6 +4,7 @@ test_riscv64_timeouts =3D { 'boston' : 120, 'k230' : 120, 'tuxrun' : 120, + 'rpmi_virt' : 300, } =20 tests_riscv64_system_quick =3D [ @@ -18,4 +19,5 @@ tests_riscv64_system_thorough =3D [ 'sifive_u', 'tt_atlantis', '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..831895103c --- /dev/null +++ b/tests/functional/riscv64/test_rpmi_virt.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python3 +# +# RISC-V virt RPMI Linux guest integration tests +# +# 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 Reboot Device : rpmi-system-reset', + 'Platform Shutdown Device : rpmi-system-reset', + '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 _validate_reset_reboot(self): + exec_command(self, 'echo RPMI_LINUX_RESET_REBOOT_BEGIN; reboot -f') + wait_for_console_pattern(self, 'RPMI_LINUX_RESET_REBOOT_BEGIN') + wait_for_console_pattern(self, 'reboot: Restarting system') + wait_for_console_pattern(self, 'OpenSBI') + + 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() + + def test_linux_guest_reset_reboot(self): + self._boot_guest(smp=3D1) + self._expect_rpmi_firmware_and_linux() + self._validate_reset_reboot() + + +if __name__ =3D=3D '__main__': + QemuSystemTest.main() --=20 2.43.0