From nobody Sun Jul 12 00:33:30 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=1783686125; cv=none; d=zohomail.com; s=zohoarc; b=G6uaMmf7HA8X1fTma6HWIjvXI/X4IOhcZQV+C9sctNcKS2rtxgY4fy79zgcFMQx5OGt79SswUMzQbNBv8g4SYX5/7FUigaLvtwENYmYqXsBKU/XhBQqQ9T6VdrRB0CUcXxrqbFj8AnIk9woZbmF4RjN5t59aGoYDQCMgswuQQe4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686125; h=Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To:Cc; bh=VaD0AacToDfloRwmZ9rCEJAESLcJZa4/t4f8anAA3z0=; b=ddrnhadyBJ06Bk0AbfkWM9x7Gx0OUfw22/xCGDcaUuMY5W9TtpcXh5cWCl7f9uJ8B3iGZg7aBw/sZrbQz1I1dsIyKA2+If9tNiTi/o6imJlgvR2paehNHpFGzSY3fs5bCGWPJ+wDc/qUPuRG0UD5kPgFiSsCbqAMNdQ7uge/hps= 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 1783686125433316.4502814688958; Fri, 10 Jul 2026 05:22:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEa-0006T5-Dh; Fri, 10 Jul 2026 08:21:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi41J-0002Ds-P0 for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:43:30 -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 1wi41H-0007ih-Qu for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:43:29 -0400 Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3n5Cs3802274 for ; Fri, 10 Jul 2026 05:43:26 GMT Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4facqpkg8t-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:43:26 +0000 (GMT) Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-384d033f7f5so164901a91.1 for ; Thu, 09 Jul 2026 22:43:26 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659c865asm39112785c88.11.2026.07.09.22.43.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:43:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=VaD0AacToDf loRwmZ9rCEJAESLcJZa4/t4f8anAA3z0=; b=MyOyKgUva+qZv2oU6USUwAxsYR6 OvyxjHchK6qsSW1kTZZZIvZLrPktOGLj3ovX3H+dgf5tMSNSk8u+i/tzYIVnZSzw Z3GMlBkHG1ERpP78/jWuKgL/lqK3D7JoV0lSBBNc4MGH7dAo/pZ7n9EEuHrlmDzB /IUbVvCeVHpSMB6N5DIHnaFAGVc12//ILP2p+HtibLNIVJpw5mXBpiczNczYOeF1 7hlkR+J2YREOyvuoHFD4uxBekKuZNdK38me5FNqjnb9d0UFHod0o5ct8uT4Yw+CG cIcLimTnOVFcAzCGDlwzB03hFdlobjt9HKo1Aso9n3sN9ieVh1WzbvosVrA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783662205; x=1784267005; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=VaD0AacToDfloRwmZ9rCEJAESLcJZa4/t4f8anAA3z0=; b=Qlt8iTcXAdXxzUHQ0xJMq5CvV2pfKk4AGBMyzjaxpnIc62xlQmoSmvQPwvl1T2EUtQ 7T/XvrEfF9StSMu3TDfokYrhgVoWf67oVG7PiGRPaDxRhuJV0XPNtb6gPG8ISpbbCTBy Q5JZPRTEAnxhGxS91CLxZvaVr/GlzC4o+WAGqjDxkqB+2Hbney4H+7sUhDOOAHeN/RV7 dxhQdsgS8XfNQvWTLdDZndIos5JCUlPkJkd6Q5i9Esov07hNv6kYIMi0/koQm5HqTD/A cOijdA0NUibka6U8JoHHwvrFy+BBPzKdKyc7ycsvBiM92eoNu2ZlmgSY5q8MgPbmor6/ us/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783662205; x=1784267005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=VaD0AacToDfloRwmZ9rCEJAESLcJZa4/t4f8anAA3z0=; b=sQ06aCHupmZYf8jtcjw0XKlItA1Q7m11wtIx7WNiZ4t3KWEU15wqyYLKN0IC0tlHHN z6vVIyKuRDwBOx3V0Tkeh3CpqWZVXO280nE84K6qJAy2eT7egmdem1KTykPp/zuS9qtu WO1VbsYYvEd+ECc3KeJYPYpCxVzTCLaVcVs8cBCMrvo7hTInv/kQnnddfnF0X4UcrNsa 9LB2EbEDBNLMJdNAh6wLm5+pD8uATAlz5Oyjh/mMvqZfRLA6h3K1Km5I3CGp2JdwEJle QGPzkfdZyh8imQCQlmawSq3nQXTPdR5GzGwfuwYaIrWNvqT4NOvSTSe4yYl2enU2XOyN NOlg== X-Gm-Message-State: AOJu0YyPxPSPGYJhzUFOpGDVMRcHC92vl5zuz9n0uD0Lw+Vd0GbPO6Us ybPotvsbUbaDMoOeVQeHeHxi9eOOij6GIL/chiqo9chjOAWSlCFGsrsU6oknxFDN7Ue9g7/mpsv KReht8rJjJnYQwybH8B5/Kx6NGKgllJ5+/mAREmclolUmdkJ1Km9l6rQix7O8kHg4JA== X-Gm-Gg: AfdE7cnXqy4zF9jUXiGopgzP1qZBOEwXYtES2U1tr/tDfAsSgXGsrUO2MjJT0/mCqFN xPKHSLw2K7jEUKV6QAvM3G72Zux4Aun9O82SHHu+emIlgC1hsVDjnPXdp53TYYDRXLsxcxX0OAk n/qeQk6f5vqReK+aVIEg0iWMLhAdMlTckrnc9+7rgxCfX9+NBUOetG5TrxEKJnmRLH9UaKORek6 7EySBOe/iGasWg5rFXoxr3hdgXGFhogaMHYSJn2D6l+mKEowxOOZN4E0i8fHG3z7QYpMUONUyR4 PuHwV47I8xwEOHmQsKru9L6gFoBFfAPqBhy/VpJx1O5xTz2DNifBnI76Wf579d6EusOTgCWEbhC cwCnk6O1a11wDDUpT0+MUkUCTJRD9HI1900LwlHZ5K3RKwlYrKXr9/gfvGA2BmjKvLxsdqLD95Y MfUg5+NWZvsNukkaHjEkD3CnmkhFt44zbJXH7vEOW17A== X-Received: by 2002:a17:90b:33cb:b0:383:5a16:bd67 with SMTP id 98e67ed59e1d1-389419cdeccmr7431403a91.4.1783662205355; Thu, 09 Jul 2026 22:43:25 -0700 (PDT) X-Received: by 2002:a17:90b:33cb:b0:383:5a16:bd67 with SMTP id 98e67ed59e1d1-389419cdeccmr7431373a91.4.1783662204774; Thu, 09 Jul 2026 22:43:24 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH v2 01/10] build: add optional librpmi dependency Date: Fri, 10 Jul 2026 11:13:09 +0530 Message-ID: <1f2732b7220280efc1b5f69ae022b318dbbc3827.1783660209.git.subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA1MiBTYWx0ZWRfX+GV54gvLFHUi LleEE5o9Y+jjpPWw+pW/NzPC/fUsIrEsOkkmgSj6J8LOYaP8h+l1maL4ix8Lo1mwZdYviSmx2u6 zax/vR7YdZvXnGsNTEfxj1T8c06nV9k/n6Ssh/NGISn8p/cf0+i2WkSa+7libKdODsgtpFMi7pr us4vjKESIij+NUWnKcJLTBH97VT2dYxHaCF0Bu0uRzt4vsWIK1YldP3U0D/5uF5faM/3skmI1W0 5NyV1kEWe0z/BivAgIgKa/Ii6eJk6iCog5thRuxaoZ8uw0RU1hGMkxg/MaeYwbYrbt8Kk3rjuTS U+Pzw8AlzfEoWoquLBPiF7RtgzcGl9l73rfh1M3isF5wU7VgX6b8k2nz/nyiE1uPUd3enFeESBd qq03i8PZKIWdrclrdtbkUgyZjl2wSbBOnXddOiC1H/k6Ycxu9it2ttLz2Dq9X2VB+RE6PmoM0bj KxZSgh6u3RTOKRtomDA== X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA1MiBTYWx0ZWRfXyHXu6sTyUBnV 1OId6anWInFvNKcabwFry8j8A7rg0bmF5p8T7KVnvze2HrMEigGHUXI8Pj3YELVYZjpTRxwNovd mKj4q05yaJXVVXV94I1/krY5IrMrYbg= X-Proofpoint-GUID: G61EANEg83iXEI9DwS4mASvOiSmqGHnk X-Proofpoint-ORIG-GUID: G61EANEg83iXEI9DwS4mASvOiSmqGHnk X-Authority-Analysis: v=2.4 cv=GJ441ONK c=1 sm=1 tr=0 ts=6a50867e cx=c_pps a=vVfyC5vLCtgYJKYeQD43oA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=_6tmRKQHnRYSWcN6IbQA:9 a=rl5im9kqc5Lf4LNbBjHf:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 priorityscore=1501 clxscore=1015 suspectscore=0 spamscore=0 phishscore=0 adultscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100052 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=205.220.180.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0b-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686126892158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add a meson option and config probe for librpmi so RISC-V machines can opt into RPMI support when the library is available. Keep the dependency optional so default builds without librpmi continue to work. Signed-off-by: Subrahmanya Lingappa --- Kconfig.host | 3 +++ meson.build | 14 ++++++++++++++ meson_options.txt | 2 ++ scripts/meson-buildoptions.sh | 3 +++ 4 files changed, 22 insertions(+) diff --git a/Kconfig.host b/Kconfig.host index 933425c74b..6f98dadb2e 100644 --- a/Kconfig.host +++ b/Kconfig.host @@ -8,6 +8,9 @@ config LINUX config LIBCBOR bool =20 +config LIBRPMI + bool + config GNUTLS bool =20 diff --git a/meson.build b/meson.build index 19e123423b..103b4649b8 100644 --- a/meson.build +++ b/meson.build @@ -2005,6 +2005,17 @@ if lzo.found() and not cc.links(''' endif endif =20 +librpmi =3D not_found +if not get_option('librpmi').auto() or have_system + librpmi =3D dependency('librpmi', required: get_option('librpmi'), + method: 'pkg-config') + if librpmi.found() and not cc.has_header_symbol('librpmi.h', + 'rpmi_service_group_logg= ing_create', + dependencies: librpmi) + error('librpmi support requires the RPMI logging service group API') + endif +endif + numa =3D not_found if not get_option('numa').auto() or have_system or have_tools numa =3D cc.find_library('numa', has_headers: ['numa.h'], @@ -2427,6 +2438,7 @@ config_host_data.set('CONFIG_LINUX', host_os =3D=3D '= linux') config_host_data.set('CONFIG_POSIX', host_os !=3D 'windows') config_host_data.set('CONFIG_WIN32', host_os =3D=3D 'windows') config_host_data.set('CONFIG_LZO', lzo.found()) +config_host_data.set('CONFIG_LIBRPMI', librpmi.found()) config_host_data.set('CONFIG_MPATH', mpathpersist.found()) config_host_data.set('CONFIG_BLKIO', blkio.found()) if blkio.found() @@ -3258,6 +3270,7 @@ host_kconfig =3D \ (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=3Dy'] : []) + \ (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=3Dy'] : []= ) + \ (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=3Dy'] : []) + \ + (librpmi.found() ? ['CONFIG_LIBRPMI=3Dy'] : []) + \ (have_rust ? ['CONFIG_HAVE_RUST=3Dy'] : []) =20 ignored =3D [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR' ] @@ -4971,6 +4984,7 @@ summary_info +=3D {'TPM support': have_tpm} summary_info +=3D {'IGVM support': igvm} summary_info +=3D {'libssh support': libssh} summary_info +=3D {'lzo support': lzo} +summary_info +=3D {'librpmi support': librpmi} summary_info +=3D {'snappy support': snappy} summary_info +=3D {'bzip2 support': libbzip2} summary_info +=3D {'lzfse support': liblzfse} diff --git a/meson_options.txt b/meson_options.txt index a07cb47d35..9f773a7886 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -204,6 +204,8 @@ option('lzfse', type : 'feature', value : 'auto', description: 'lzfse support for DMG images') option('lzo', type : 'feature', value : 'auto', description: 'lzo compression support') +option('librpmi', type : 'feature', value : 'auto', + description: 'RISC-V RPMI support') option('pvg', type: 'feature', value: 'auto', description: 'macOS paravirtualized graphics support') option('rbd', type : 'feature', value : 'auto', diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index c003985047..e8a20068e7 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -140,6 +140,7 @@ meson_options_help() { printf "%s\n" ' libkeyutils Linux keyutils support' printf "%s\n" ' libnfs libnfs block device driver' printf "%s\n" ' libpmem libpmem support' + printf "%s\n" ' librpmi RISC-V RPMI support' printf "%s\n" ' libssh ssh block device support' printf "%s\n" ' libudev Use libudev to enumerate host devices' printf "%s\n" ' libusb libusb support for USB passthrough' @@ -376,6 +377,8 @@ _meson_option_parse() { --disable-libnfs) printf "%s" -Dlibnfs=3Ddisabled ;; --enable-libpmem) printf "%s" -Dlibpmem=3Denabled ;; --disable-libpmem) printf "%s" -Dlibpmem=3Ddisabled ;; + --enable-librpmi) printf "%s" -Dlibrpmi=3Denabled ;; + --disable-librpmi) printf "%s" -Dlibrpmi=3Ddisabled ;; --enable-libssh) printf "%s" -Dlibssh=3Denabled ;; --disable-libssh) printf "%s" -Dlibssh=3Ddisabled ;; --enable-libudev) printf "%s" -Dlibudev=3Denabled ;; --=20 2.43.0 From nobody Sun Jul 12 00:33:30 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=1783686113; cv=none; d=zohomail.com; s=zohoarc; b=l2YXIunaDQ/O+3H+gRunfqMTQMXhG0+OEgtZftaH8ror12GcoLf8hnpz7WMESZpvQG1W2H3oBxO6nDDnC8dSP46k8ikao4NqMxBCtWyEP3dZhmVYayxdjK9h7csvMi2sPYfhvMKGerbMVO6fT0AvyfTtl4bO6Hll45O1IkReSi8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686113; 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=7u2VoyzruceaNtDJJe1B506UztsOTzRZXv5pWRhnX2U=; b=h3ftq5FhGotqL6fHv+aA6CSNwzu7oF4Qngmr2JAMTs8aCbHRqUu13K9KeFuAswjVWMWAFLWD15i+jNclh8j6ab2yCsOnB0jlwnL9TP7V/r4N6ygw8MHf5xuOwerOMD+rCLrNtk/qlc1fIvVQe4uEhzSw4S49AJnYckcCqgJnn98= 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 1783686113880210.55799377237759; Fri, 10 Jul 2026 05:21:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEb-0006V2-QG; Fri, 10 Jul 2026 08:21:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi6ml-0000Y2-9S for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:39 -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 1wi6mg-0001rX-Ci for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:39 -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 66A7dW2E235369 for ; Fri, 10 Jul 2026 08:40:22 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 4faeg3km5f-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 08:40:22 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-384d033f7f5so191805a91.1 for ; Fri, 10 Jul 2026 01:40:22 -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-3118389d9bcsm29164925eec.20.2026.07.10.01.40.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 01:40:20 -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=7u2Voyzruce aNtDJJe1B506UztsOTzRZXv5pWRhnX2U=; b=dn3n1xhydT1Li+e52/k26Prgzd5 H5C6R8PxpZiFpQ/KvyMVeuY6/2VUZq9HHv8PVlgv52Z/2I9g84enMcLCvwLvOhmq aESNyceEA8j44HUyUn2t7YtBiJc7CqGnYKjF7ALeR78XulM0ClzlNGe6yG8i0mGB VHoxl2qUrNjHtYgHjvCGtgiBXdlevB59Vo1cWJGDjOZYbl8PoN2X/p6tvVnPTyBd tiOCWAKnhZ02Psk7RYYPWWbEyyIzPEcqfAB98DQASD4fzKB+5N3R2RbCpdRSqw/S KqoTJaoqrGbTOcIbDhAm2udHHx+rzZ0/irVpqqOph5MsXx69+JmDSA999sw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783672822; x=1784277622; 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=7u2VoyzruceaNtDJJe1B506UztsOTzRZXv5pWRhnX2U=; b=MQ3CzVrec1ZUOJfariw+ClUQKuKbhG5NHuCO+sogM2cHqw5Q8md4UDthzqWn3hQcts 26qvut1Hl2qM2YurtkCLDGb97zlqV+8TlzdKHuZBYScC/oQFnBX1Me10fy7KzmHnvy6s HpAhL2uZl5g37btqEHJA4YMh6wNG+eA6Fpp/CyUs1yuwaFVHkYpe/XEP5ZdkMNA2M50P hGJm7N7cr5Tq+TyvPywgyYuvHL8SASNIPh1fvzX6Furv1npnpfaqQ4qkS98jM5oIgu7N 35w2dcIpXEzjHIcIHBnuC2PhCEp7muAfujyghsws4fqNTZjgjNbCkoh2iIiUsoj5BL00 7xcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783672822; x=1784277622; 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=7u2VoyzruceaNtDJJe1B506UztsOTzRZXv5pWRhnX2U=; b=fiIyaxlr2z8aE/A56jHr6S475pIxtZRaUetNR71EysaVqeSZlBdncjXVzr71aMG1Fc JElw2OHbFVxOmzjskRwleMtwRbHfg8j4pD4R3yMdPtzmJ4DY36d07rN8cA8J+x+DKmth bGENsrDGZnbnuzj3SBWegXqywW6OMb16FjCsa2As4FQQl122n19UeL+IxNFIqHdFBZdL COgQwjgZ1YDmP5kKIm9OBx36MRgW3Tk9Tcz9vFB4QUU43/GK90Nq1uY8fmW1x0j59357 v3bse0a/N/E0J6kY+Q2rAPfKzPUng0jCfR+6b9HZKu0cuECHe7Vzr2RHzGdn7AU28J/0 Wj4w== X-Gm-Message-State: AOJu0YyfX0EaRHJVgTM9uVZljCvO6i+SxakE/RN8nX+savo/cwqOERHY oM1LfVGtfh/cBS4oLAvhXLLwbNh5JaKhgqh5ykWp879G2/Cstnt0/37xPEqORuDOf6CGFsibB78 Nr9D/+mm8uWUpnFhY6iB81dJ98cAUdqsGQWOa+qAaOwJWO9dPgX5iONMDLmNEhahMqg== X-Gm-Gg: AfdE7cl6LgKd5/uvdkkhuz8afJvy1mApI/rwYNPNZmwugNJ6rlEXlLQF9W8MB970Mwh 2Su5OQZ/zE22yuF4fUQsl2QyCUUj1X6SalJfu+ZIDP0UQp3MfX/MokMMAthypXHPTr/xU0wXepT FqIdIbOaVszP6sq8TcJ4sqDGaI45s95gX2GDY7KHprEYeTmucj3wh3tV4NNFlmPOOuQZHlT/XPO Mkw02ZuxUM1KplzbI4aPipaZtTpfI/JUVXeOK4XUjLZkeCMgqGwOXCee/NPhjJe7hSblANI+jiC eJnuITyEZO8GmU8OJjmcFmpegeemzfapeS8HbU0YSij76Y6pp+3xEj4cIAd/A+IRH/8+/ftDcNt qi2UchJmiI5vmJvJdrCspDs4hYJVMgr/UQngkqgx8VgIP/7l+map/Ppe4nPnR7gy3nIqvHtZIso X2WAf4edZlHzCbl7HtgvNlGu2A2en5IkDv/3HXDWbnPw== X-Received: by 2002:a17:90b:3fc8:b0:37f:df57:2ddf with SMTP id 98e67ed59e1d1-3893f97f9acmr8979943a91.1.1783672821623; Fri, 10 Jul 2026 01:40:21 -0700 (PDT) X-Received: by 2002:a17:90b:3fc8:b0:37f:df57:2ddf with SMTP id 98e67ed59e1d1-3893f97f9acmr8979916a91.1.1783672821037; Fri, 10 Jul 2026 01:40:21 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-riscv@nongnu.org Cc: qemu-devel@nongnu.org, daniel.barboza@oss.qualcomm.com, Subrahmanya Lingappa Subject: [PATCH v2 02/10] hw/misc: add RISC-V RPMI transport and Base support Date: Fri, 10 Jul 2026 14:09:44 +0530 Message-ID: <37eeb3754b10d5310c62169e72211c65114e21bc.1783660209.git.subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA4MyBTYWx0ZWRfX8Q0Ro+0JIgNN swu9cfV6WeC4lwwzLv7DSsdhVeRNMXn/lGtmSlONnS76iQUofgNRI+UnZUnDb7GzauGs4MHGNTm bUDHf/tuLKoi5SM4QCL7XHuIFSO+V91C3lat5VwfL1jmVz93iPxMaF3HgIKFNSgEIcsyl8HGdl9 KdpIkOk55xQCUJ4T5Bm32C8UhbuR2zoXbCv5EBOt2xFINtuNO666MM0qa1IBGlfGovHS999oMgE Jm6SQJ6aMNpoKWYTiGGctwxtU+8tP9rbwzyLp9zBzX6SK9dpPb5gR+TwReJWpbMLNS7+VNA+sFG TvguzkT5ANNgOPKytUyLMsWJtbpdsMoI+Hg3z1CTY/JIMjhR0lo9nKbgfa2Q1PruJ04hKFV7Tfm bqxQ49p/DNrcx5btaQe6F4QQU3wYovPLh0sEYsKswHCYnw3WhyDonFpTxIyRBzkC1H+AmvPBMma fPSwADI5Q8Ak3R9612A== X-Authority-Analysis: v=2.4 cv=ZcMt8MVA c=1 sm=1 tr=0 ts=6a50aff6 cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=V1jnuoLLAAAA:20 a=NEAV23lmAAAA:8 a=EUspDBNiAAAA:8 a=nbwKsA5dBi2aoCUYr7oA:9 a=mQ_c8vxmzFEMiUWkPHU9:22 a=bA3UWDv6hWIuX7UZL3qL:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA4MyBTYWx0ZWRfXznIbMUi4G6ni u6WhE2FMpK5nbiKjI+lIfUgN6dRFuIh3rQ+Fao423qWbPPNNEvwKe6cCHUded7eYbXt6Oz+efS7 hFDEFTzdBfj+bvKUnsxKsezllgZ7CRc= X-Proofpoint-GUID: 47mcw1b8hoJ8svkoEDybQzxRz_S7dQX5 X-Proofpoint-ORIG-GUID: 47mcw1b8hoJ8svkoEDybQzxRz_S7dQX5 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_02,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 clxscore=1015 lowpriorityscore=0 malwarescore=0 bulkscore=0 suspectscore=0 priorityscore=1501 impostorscore=0 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100083 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-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686116875158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa RPMI (RISC-V Platform Management Interface) is the RISC-V non-ISA platform management specification. It defines a shared-memory transport, message protocol, and service groups for platform management. Add the QEMU transport backend and Base service plumbing for virt using librpmi. This implementation targets the RISC-V Platform Management Interface (RPMI) Specification v1.0 Ratified: https://github.com/riscv-non-isa/riscv-rpmi/releases/download/v1.0/riscv-rp= mi.pdf The librpmi backend is maintained at: https://github.com/riscv-software-src/librpmi Signed-off-by: Subrahmanya Lingappa --- MAINTAINERS | 2 + hw/misc/Kconfig | 4 + hw/misc/meson.build | 3 + hw/misc/riscv_rpmi.c | 476 ++++++++++++++++++++++++++++++++++ hw/misc/riscv_rpmi_internal.h | 24 ++ include/hw/misc/riscv_rpmi.h | 90 +++++++ 6 files changed, 599 insertions(+) create mode 100644 hw/misc/riscv_rpmi.c create mode 100644 hw/misc/riscv_rpmi_internal.h create mode 100644 include/hw/misc/riscv_rpmi.h diff --git a/MAINTAINERS b/MAINTAINERS index 93df53d87f..8e91a31757 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -359,6 +359,8 @@ F: target/riscv/ F: hw/char/riscv_htif.c F: hw/riscv/ F: hw/intc/riscv* +F: hw/misc/riscv_rpmi* +F: include/hw/misc/riscv_rpmi.h F: include/hw/char/riscv_htif.h F: include/hw/riscv/ F: common-user/host/riscv* diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 1543ee6653..998944c342 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -258,3 +258,7 @@ config XLNX_ZYNQ_DDRC bool =20 source macio/Kconfig + +config RISCV_RPMI + bool + depends on LIBRPMI diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 23265f6035..e7c2ebe28f 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -168,3 +168,6 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('= sbsa_ec.c')) =20 # HPPA devices system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c')) +system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files( + 'riscv_rpmi.c', +), librpmi]) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c new file mode 100644 index 0000000000..c4b115b659 --- /dev/null +++ b/hw/misc/riscv_rpmi.c @@ -0,0 +1,476 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI transport device. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "exec/cpu-common.h" +#include "hw/core/qdev-properties.h" +#include "hw/misc/riscv_rpmi.h" +#include "hw/misc/riscv_rpmi_internal.h" +#include "migration/vmstate.h" +#include "system/address-spaces.h" +#include "system/runstate.h" +#include "librpmi.h" +#include "librpmi_env.h" + +void *rpmi_env_zalloc(rpmi_size_t size) +{ + return g_malloc0(size); +} + +void rpmi_env_free(void *ptr) +{ + g_free(ptr); +} + +void rpmi_env_writel(rpmi_uint64_t addr, rpmi_uint32_t val) +{ + cpu_physical_memory_write(addr, &val, sizeof(val)); +} + +static bool riscv_rpmi_addr_in_range(uint64_t addr, uint32_t len, + uint64_t base, uint64_t size) +{ + return len && size >=3D len && addr >=3D base && addr - base <=3D size= - len; +} + +static enum rpmi_error shmem_qemu_read(void *priv, rpmi_uint64_t addr, + void *buf, rpmi_uint32_t len) +{ + RiscvRpmiState *s =3D RISCV_RPMI(priv); + + if (!riscv_rpmi_addr_in_range(addr, len, s->shmem_base, s->shmem_size)= || + addr !=3D (rpmi_uint64_t)addr || len !=3D (rpmi_uint32_t)len) { + return RPMI_ERR_INVALID_ADDR; + } + + cpu_physical_memory_read(addr, buf, len); + return RPMI_SUCCESS; +} + +static enum rpmi_error shmem_qemu_write(void *priv, rpmi_uint64_t addr, + const void *buf, rpmi_uint32_t len) +{ + RiscvRpmiState *s =3D RISCV_RPMI(priv); + + if (!riscv_rpmi_addr_in_range(addr, len, s->shmem_base, s->shmem_size)= || + addr !=3D (rpmi_uint64_t)addr || len !=3D (rpmi_uint32_t)len) { + return RPMI_ERR_INVALID_ADDR; + } + + cpu_physical_memory_write(addr, buf, len); + return RPMI_SUCCESS; +} + +static enum rpmi_error shmem_qemu_fill(void *priv, rpmi_uint64_t addr, + char ch, rpmi_uint32_t len) +{ + while (len--) { + shmem_qemu_write(priv, addr++, &ch, sizeof(ch)); + } + + return RPMI_SUCCESS; +} + +const struct rpmi_shmem_platform_ops rpmi_shmem_qemu_ops =3D { + .read =3D shmem_qemu_read, + .write =3D shmem_qemu_write, + .fill =3D shmem_qemu_fill, +}; + +static uint64_t riscv_rpmi_read(void *opaque, hwaddr offset, unsigned int = size) +{ + RiscvRpmiState *s =3D opaque; + + if (offset !=3D 0 || size !=3D 4) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid read at 0x%" HWADDR_PRIx " size %u\n", + __func__, offset, size); + return 0; + } + + return s->doorbell; +} + +static bool riscv_rpmi_transport_indices_valid(RiscvRpmiState *s); + +static void riscv_rpmi_write(void *opaque, hwaddr offset, uint64_t value, + unsigned int size) +{ + RiscvRpmiState *s =3D opaque; + + if (offset !=3D 0 || size !=3D 4) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid write at 0x%" HWADDR_PRIx " size %u\n", + __func__, offset, size); + return; + } + + s->doorbell =3D value; + + if (value =3D=3D 1) { + if (s->context && riscv_rpmi_transport_indices_valid(s)) { + rpmi_context_process_a2p_request(s->context); + rpmi_context_process_all_events(s->context); + } + s->doorbell =3D 0; + } +} + +static const MemoryRegionOps riscv_rpmi_ops =3D { + .read =3D riscv_rpmi_read, + .write =3D riscv_rpmi_write, + .endianness =3D DEVICE_LITTLE_ENDIAN, + .valid =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, +}; + +static bool riscv_rpmi_queue_indices_valid(RiscvRpmiState *s, + uint64_t queue_base, + uint32_t queue_size) +{ + uint8_t *shmem =3D memory_region_get_ram_ptr(&s->shmem); + uint32_t data_slots =3D queue_size / RPMI_QUEUE_SLOT_SIZE - 2; + uint32_t head; + uint32_t tail; + + head =3D ldl_le_p(shmem + queue_base); + tail =3D ldl_le_p(shmem + queue_base + RPMI_QUEUE_SLOT_SIZE); + if (head >=3D data_slots || tail >=3D data_slots) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid queue indices head %u tail %u slots %u\= n", + __func__, head, tail, data_slots); + return false; + } + + return true; +} + +static bool riscv_rpmi_transport_indices_valid(RiscvRpmiState *s) +{ + if (!s->has_shmem || !s->a2p_req_size) { + return false; + } + + if (!riscv_rpmi_queue_indices_valid(s, 0, s->a2p_req_size)) { + return false; + } + + return riscv_rpmi_queue_indices_valid(s, s->a2p_req_size, + s->a2p_req_size); +} + +static void riscv_rpmi_configure_base(RiscvRpmiState *s, + const RiscvRpmiConfig *cfg) +{ + s->platform_info =3D g_strdup(cfg->platform_info); + s->services =3D cfg->services; + s->service_count =3D cfg->service_count; + + if (cfg->hart_count) { + s->hart_count =3D cfg->hart_count; + if (cfg->hart_ids) { + s->hart_ids =3D g_memdup2(cfg->hart_ids, + cfg->hart_count * sizeof(*cfg->hart_id= s)); + } + } +} + +static void riscv_rpmi_init(Object *obj) +{ + RiscvRpmiState *s =3D RISCV_RPMI(obj); + + memory_region_init_io(&s->mmio, obj, &riscv_rpmi_ops, s, + TYPE_RISCV_RPMI, RPMI_DBREG_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); +} + +static void riscv_rpmi_reset(DeviceState *dev) +{ + RiscvRpmiState *s =3D RISCV_RPMI(dev); + + s->doorbell =3D 0; + + if (s->has_shmem) { + memset(memory_region_get_ram_ptr(&s->shmem), 0, s->shmem_size); + memory_region_set_dirty(&s->shmem, 0, s->shmem_size); + } + +} + +static void riscv_rpmi_cleanup(RiscvRpmiState *s) +{ + + + if (s->context) { + rpmi_context_destroy(s->context); + s->context =3D NULL; + } + + if (s->transport) { + rpmi_transport_shmem_destroy(s->transport); + s->transport =3D NULL; + } + + if (s->rpmi_shmem) { + rpmi_shmem_destroy(s->rpmi_shmem); + s->rpmi_shmem =3D NULL; + } + + if (s->has_shmem) { + memory_region_del_subregion(get_system_memory(), &s->shmem); + s->has_shmem =3D false; + } +} + +bool riscv_rpmi_service_enabled(RiscvRpmiState *s, RiscvRpmiServiceKind ki= nd) +{ + uint32_t i; + + for (i =3D 0; i < s->service_count; i++) { + if (s->services[i].kind =3D=3D kind) { + return true; + } + } + + return false; +} + +static bool riscv_rpmi_validate_config(RiscvRpmiState *s, Error **errp) +{ + uint64_t queue_bytes; + + if (!s->shmem_size) { + error_setg(errp, "RPMI shared memory size must be non-zero"); + return false; + } + + if (s->shmem_base & (RPMI_QUEUE_SLOT_SIZE - 1)) { + error_setg(errp, "RPMI shared memory base must be %u-byte aligned", + RPMI_QUEUE_SLOT_SIZE); + return false; + } + + if (!s->a2p_req_size) { + error_setg(errp, "RPMI A2P request queue size must be non-zero"); + return false; + } + + if (!s->hart_count || !s->hart_ids) { + error_setg(errp, "RPMI transport requires hart IDs"); + return false; + } + + for (uint32_t i =3D 0; i < s->hart_count; i++) { + for (uint32_t j =3D i + 1; j < s->hart_count; j++) { + if (s->hart_ids[i] =3D=3D s->hart_ids[j]) { + error_setg(errp, "RPMI hart ID %u is duplicated", + s->hart_ids[i]); + return false; + } + } + } + + if (s->service_count && !s->services) { + error_setg(errp, "RPMI service count requires service descriptors"= ); + return false; + } + + if (s->a2p_req_size % RPMI_QUEUE_SLOT_SIZE) { + error_setg(errp, + "RPMI A2P request queue size must be a multiple of %u", + RPMI_QUEUE_SLOT_SIZE); + return false; + } + + if (s->p2a_req_size % RPMI_QUEUE_SLOT_SIZE) { + error_setg(errp, + "RPMI P2A request queue size must be a multiple of %u", + RPMI_QUEUE_SLOT_SIZE); + return false; + } + + queue_bytes =3D 2 * (uint64_t)s->a2p_req_size + + 2 * (uint64_t)s->p2a_req_size; + if (queue_bytes > s->shmem_size) { + error_setg(errp, + "RPMI shared memory size 0x%" PRIx64 + " is too small for queues 0x%" PRIx64, + s->shmem_size, queue_bytes); + return false; + } + + return true; +} + +static bool riscv_rpmi_add_service_group(RiscvRpmiState *s, + const RiscvRpmiServiceConfig *ser= vice, + Error **errp) +{ + switch (service->kind) { + default: + error_setg(errp, "unsupported RPMI service kind %d", service->kind= ); + return false; + } +} + +static bool riscv_rpmi_init_services(RiscvRpmiState *s, Error **errp) +{ + uint32_t i; + + for (i =3D 0; i < s->service_count; i++) { + if (!riscv_rpmi_add_service_group(s, &s->services[i], errp)) { + return false; + } + } + + return true; +} + +static bool riscv_rpmi_init_context(RiscvRpmiState *s, Error **errp) +{ + const char *platform_info =3D s->platform_info ?: RPMI_PLAT_INFO; + + s->rpmi_shmem =3D rpmi_shmem_create("rpmi-shmem", s->shmem_base, + s->shmem_size, + &rpmi_shmem_qemu_ops, s); + if (!s->rpmi_shmem) { + error_setg(errp, "failed to create RPMI shared memory backend"); + return false; + } + + s->transport =3D rpmi_transport_shmem_create("rpmi-shmem-transport", + RPMI_QUEUE_SLOT_SIZE, + s->a2p_req_size, + s->p2a_req_size, + s->rpmi_shmem); + if (!s->transport) { + error_setg(errp, "failed to create RPMI shared memory transport"); + return false; + } + + s->context =3D rpmi_context_create("rpmi-virt", s->transport, + RPMI_SRVGRP_ID_MAX_COUNT, + RPMI_PRIVILEGE_M_MODE, + strlen(platform_info) + 1, + platform_info); + if (!s->context) { + error_setg(errp, "failed to create RPMI context"); + return false; + } + + return riscv_rpmi_init_services(s, errp); +} + +static void riscv_rpmi_realize(DeviceState *dev, Error **errp) +{ + RiscvRpmiState *s =3D RISCV_RPMI(dev); + g_autofree char *name =3D NULL; + + if (!riscv_rpmi_validate_config(s, errp)) { + return; + } + + name =3D g_strdup_printf("rpmi-shmem@%" PRIx64, s->shmem_base); + if (!memory_region_init_ram(&s->shmem, OBJECT(dev), name, s->shmem_siz= e, + errp)) { + return; + } + + memory_region_add_subregion(get_system_memory(), s->shmem_base, &s->sh= mem); + s->has_shmem =3D true; + + if (!riscv_rpmi_init_context(s, errp)) { + riscv_rpmi_cleanup(s); + } +} + +static void riscv_rpmi_unrealize(DeviceState *dev) +{ + riscv_rpmi_cleanup(RISCV_RPMI(dev)); +} + +static const VMStateDescription riscv_rpmi_vmstate =3D { + .name =3D TYPE_RISCV_RPMI, + .unmigratable =3D 1, +}; + +static const Property riscv_rpmi_properties[] =3D { + DEFINE_PROP_UINT64("shmem-base", RiscvRpmiState, shmem_base, 0), + DEFINE_PROP_UINT64("shmem-size", RiscvRpmiState, shmem_size, 0), + DEFINE_PROP_UINT32("a2p-req-size", RiscvRpmiState, a2p_req_size, 0), + DEFINE_PROP_UINT32("p2a-req-size", RiscvRpmiState, p2a_req_size, 0), +}; + +static void riscv_rpmi_finalize(Object *obj) +{ + RiscvRpmiState *s =3D RISCV_RPMI(obj); + + g_free(s->platform_info); + g_free(s->hart_ids); +} + +static void riscv_rpmi_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D riscv_rpmi_realize; + dc->unrealize =3D riscv_rpmi_unrealize; + dc->vmsd =3D &riscv_rpmi_vmstate; + device_class_set_legacy_reset(dc, riscv_rpmi_reset); + device_class_set_props(dc, riscv_rpmi_properties); +} + +static const TypeInfo riscv_rpmi_info =3D { + .name =3D TYPE_RISCV_RPMI, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(RiscvRpmiState), + .instance_init =3D riscv_rpmi_init, + .instance_finalize =3D riscv_rpmi_finalize, + .class_init =3D riscv_rpmi_class_init, +}; + +static void riscv_rpmi_register_types(void) +{ + type_register_static(&riscv_rpmi_info); +} + +type_init(riscv_rpmi_register_types) + +DeviceState *riscv_rpmi_create(const RiscvRpmiConfig *cfg, Error **errp) +{ + DeviceState *dev; + RiscvRpmiState *s; + + if (!cfg) { + error_setg(errp, "missing RPMI configuration"); + return NULL; + } + + dev =3D qdev_new(TYPE_RISCV_RPMI); + qdev_prop_set_uint64(dev, "shmem-base", cfg->shmem_base); + qdev_prop_set_uint64(dev, "shmem-size", cfg->shmem_size); + qdev_prop_set_uint32(dev, "a2p-req-size", cfg->a2p_req_size); + qdev_prop_set_uint32(dev, "p2a-req-size", cfg->p2a_req_size); + + s =3D RISCV_RPMI(dev); + riscv_rpmi_configure_base(s, cfg); + + if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp)) { + return NULL; + } + + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, cfg->doorbell_base); + return dev; +} diff --git a/hw/misc/riscv_rpmi_internal.h b/hw/misc/riscv_rpmi_internal.h new file mode 100644 index 0000000000..447c0acb55 --- /dev/null +++ b/hw/misc/riscv_rpmi_internal.h @@ -0,0 +1,24 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI internal service helpers. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#ifndef HW_MISC_RISCV_RPMI_INTERNAL_H +#define HW_MISC_RISCV_RPMI_INTERNAL_H + +#include "qapi/error.h" +#include "hw/misc/riscv_rpmi.h" +#include "librpmi.h" + +#define RPMI_PLAT_INFO "QEMU RISC-V RPMI" + +extern const struct rpmi_shmem_platform_ops rpmi_shmem_qemu_ops; +bool riscv_rpmi_service_enabled(RiscvRpmiState *s, + RiscvRpmiServiceKind kind); + +#endif diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h new file mode 100644 index 0000000000..cb2658e57e --- /dev/null +++ b/include/hw/misc/riscv_rpmi.h @@ -0,0 +1,90 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI definitions shared by RPMI transport and FDT helpers. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#ifndef HW_MISC_RISCV_RPMI_H +#define HW_MISC_RISCV_RPMI_H + +#include "exec/hwaddr.h" +#include "hw/core/sysbus.h" +#include "qom/object.h" +#include "qemu/notify.h" + +#define RPMI_QUEUE_SLOT_SIZE 64 +#define RPMI_DBREG_SIZE 0x1000 + +#define RPMI_ALL_NUM_QUEUES 4 +#define RPMI_A2P_NUM_QUEUES 2 +#define RPMI_ALL_NUM_REGS (RPMI_ALL_NUM_QUEUES + 1) +#define RPMI_A2P_NUM_REGS (RPMI_A2P_NUM_QUEUES + 1) + +#define VIRT_RPMI_A2P_REQ_SIZE (16 * RPMI_QUEUE_SLOT_SIZE) +#define VIRT_RPMI_P2A_REQ_SIZE 0 + + +#define TYPE_RISCV_RPMI "riscv-rpmi" +OBJECT_DECLARE_SIMPLE_TYPE(RiscvRpmiState, RISCV_RPMI) + +struct rpmi_context; +struct rpmi_service_group; +struct rpmi_shmem; +struct rpmi_transport; + +typedef enum RiscvRpmiServiceKind { + RISCV_RPMI_SERVICE_INVALID =3D 0, +} RiscvRpmiServiceKind; + +typedef struct RiscvRpmiServiceConfig { + RiscvRpmiServiceKind kind; + const char *node_name; + const char *compatible; + uint32_t service_group; + bool has_mpxy_channel; + uint32_t mpxy_channel; +} RiscvRpmiServiceConfig; + +typedef struct RiscvRpmiConfig { + hwaddr doorbell_base; + hwaddr shmem_base; + hwaddr shmem_size; + uint32_t a2p_req_size; + uint32_t p2a_req_size; + const char *platform_info; + + const uint32_t *hart_ids; + uint32_t hart_count; + const RiscvRpmiServiceConfig *services; + uint32_t service_count; +} RiscvRpmiConfig; + +struct RiscvRpmiState { + SysBusDevice parent_obj; + + MemoryRegion mmio; + MemoryRegion shmem; + uint64_t shmem_base; + uint64_t shmem_size; + uint32_t a2p_req_size; + uint32_t p2a_req_size; + char *platform_info; + + uint32_t *hart_ids; + uint32_t hart_count; + const RiscvRpmiServiceConfig *services; + uint32_t service_count; + uint32_t doorbell; + struct rpmi_shmem *rpmi_shmem; + struct rpmi_transport *transport; + struct rpmi_context *context; + bool has_shmem; +}; + +DeviceState *riscv_rpmi_create(const RiscvRpmiConfig *cfg, Error **errp); + +#endif --=20 2.43.0 From nobody Sun Jul 12 00:33:30 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=1783686114; cv=none; d=zohomail.com; s=zohoarc; b=atY/BCUdgMKa+WVqKtYkTBZnN+axzEvGvtALmu6SpUmDhgD/i5cl+Aa1w5w2eDvA4uz5bK07I1DxLFS13IlSgcpO33iKIFoxzW+yy2oT+1TDs91M9rapXYk8ZLAmzrr5WHJS2i4/0JL3EO+2fTU9BTHzlLtYIks+M+Lwpmfxyr8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686114; 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=IKyJmrjcSr9iKT+1GncuQy3zeUNSlN0odNLhTzFLUg8=; b=FFB6c6EOibaFxYexanzRI4cD7Eovw3L9MlWriOOuA3+3fXHAHNXtVGIbANO56H0Xbzkcc+FPOeFNXnVvebUKgZynTMmK9VhsU3xD69vBrzdyfnNhIj3pdsZPE65WmqPv5Odw4vjzWAYNP/OCNfDZ3d6phnKeQFxRQaPizyJUKg0= 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 1783686114610787.3203464738439; Fri, 10 Jul 2026 05:21:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEb-0006Tr-6j; Fri, 10 Jul 2026 08:21:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi6mk-0000Xe-Hk for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:38 -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 1wi6mg-0001rq-Cj for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:38 -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 66A7eJaf141562 for ; Fri, 10 Jul 2026 08:40:27 GMT Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4faf5mub7x-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 08:40:27 +0000 (GMT) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-384d033f7f5so191810a91.1 for ; Fri, 10 Jul 2026 01:40:27 -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-3118389d9bcsm29164925eec.20.2026.07.10.01.40.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 01:40:25 -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=IKyJmrjcSr9 iKT+1GncuQy3zeUNSlN0odNLhTzFLUg8=; b=QmEf0HxtmwO1t6K08hbcdgXJmoJ UbVPxCT7NyQMuM7bsqaSea0hCTISiB+KKSHOhH9Dy6VPX/9IpwY8M3BKu1jhy1XK kmOelnDxdMH+0N+MjwEUjf7a4/I3ikuRe3AVm22sZBRcTrqbF76QpTa/N7wqur1R iHN10anAECRIqKHQ6gYu9tcv3G09pa5RuOcoElDSpzHoeFkzfT3BVLUOn+HZ8+Ti sewPlJsnAvXXIJpoi1d/9isfI10hyVSiddbX+/JHniJRWvpqk5JLo0kTXw93njv6 2kI4XW83cPPAa7GeAHBAXNZ3mXi+PK42JVv+Cjj+DFqzuFtPDWPCKCAd3RA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783672826; x=1784277626; 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=IKyJmrjcSr9iKT+1GncuQy3zeUNSlN0odNLhTzFLUg8=; b=GqnGkBLSkA/eypl67uBp8FC/NFpmESaZsxp6UZNj+Ud3OipXTCT6nEd5GL/mmbp+nw 8DbtumXQu+Xj2Yap4AeEjAEm4HkBiDC4BnHmeKtjNPJ4ln0tGS6CYOdZro6ju2WHZD/B FEnWRKPaYoCloNBqUMfa05hLFzUqEpTcSDt+6tTerfs0bLU6ozqIicdFfCdiDQQGg/VX bcKKj9K9z9C57SlD5UcF5dtHeCMmCbjGAjrCWj13jbQjw+MtNneh54+1VfQ4MU8ta7zk oAKdC3H0sqJ9WGIhZ1/koMhtM/kCeRkP5X8DuCa9z4kuknisUKTYmrJXsiRj5Ae9ULWR ityw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783672826; x=1784277626; 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=IKyJmrjcSr9iKT+1GncuQy3zeUNSlN0odNLhTzFLUg8=; b=SMapH02+9SVxFSQsvgn3RESiFMmxajcqPB/Uw1ret9I0W9rRpd/IkSIsNMJMuRWgdt AZxGlLYtKU5q8OmOse7osTQTDHgyw/rflljlzzDD8OuxBXXPqtFimEJqETC0V0/NJuZX CzAX6C28K5J15NSakSzDEC2gFi2Mjx5XZFIShGlrsqHsxDoF2PoMd0bdWCJSgowQ/Guf F2kA3uB36UTpg7oKSLpurJotRGtIU25apO1i8v1XVUUfrB/j6cA19TiC8BurRiowpLV4 OqOHdxYqqlPOvJ6HVeaYmal8Smv1/IpYy+CRELD4kA1g0UQQm8/sfKqVLskxcz2vCWwk NGIw== X-Gm-Message-State: AOJu0YzzFMmrPVb3mycJfU1/Kl7P4TdbyWwN9GkJKQnV8b9v16JjgbLF eXGz3TCu3PoaFzelZd3Zv8A72WzS7F8eVHk0HPJLIrJ7mG+xRKDcy5l2qicn8HyzeI8fHrvWrOL XrdwUhz72eqFjwg/FxeSdF/tO6rebpbqb7w+Q4l3hNTyfScK4jhXnO94Mvg== X-Gm-Gg: AfdE7cnrkfBh2GOgPZlv0L1kXH1tb+vj1KNvrDVL7Zt8jkJrpzFUJ5MT549a7PNA8t2 qd0xET4+qWOC5Fo+Y5ECvWS7m/jlZWmMefoH97g1IcOceFfMZMkkGljPiBWkeEn8NSXm4TUR7bq tYkzddN/99PdfdwvZpOABi/YtIlBTU6IpLkFUf2pBA7GxbU+r0owt0gObr+Qi9u5OUx7pSHAbx0 KhZ/kpm+VacTViN7Qkik7EAIaD2rGguw9QO22RfA0kGgbtaOZ3hSFtD7GSs+RsVaxaVjDnT17Lm ZNqNSIeOKRYjwT+p0zdeusqEcYXSOmNMHDB2D2UkNJW/Nuh5FTSJ0ljvfPKK69qda22A0itoJb1 ld16WiLbuN0s/t4mRENTVCA1Pv9Kz9vj83cp9hl0OAygZDZkxaZIGL1TYAfTBwuQ0V432jEMMpm 2L9ml5GIZw0YULprK7/ruILddNgxc2Q3ODZRwHnydVyQ== X-Received: by 2002:a17:90b:33cb:b0:383:5a16:bd67 with SMTP id 98e67ed59e1d1-389419cdeccmr7838900a91.4.1783672826244; Fri, 10 Jul 2026 01:40:26 -0700 (PDT) X-Received: by 2002:a17:90b:33cb:b0:383:5a16:bd67 with SMTP id 98e67ed59e1d1-389419cdeccmr7838881a91.4.1783672825724; Fri, 10 Jul 2026 01:40:25 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-riscv@nongnu.org Cc: qemu-devel@nongnu.org, daniel.barboza@oss.qualcomm.com, Subrahmanya Lingappa Subject: [PATCH v2 03/10] hw/riscv: add RPMI FDT helpers Date: Fri, 10 Jul 2026 14:09:45 +0530 Message-ID: <0028254f03ea55c578dc6e79b7a8d9cbabaa201d.1783660209.git.subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-ORIG-GUID: ol95gbI1QoUghkEnmEWgD3At2vewX_pH X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA4MiBTYWx0ZWRfX+QkXoB3PAY5c TvzcDHFgHYFmgSP0IKtzc5ahhBphiOuchhNR8jBlBAFVF6lGih5e/8dRimwOuM/JjQBTXrj2R9c /cvPQus9RR4qGLVcgwdJXEM+M4mJ3rk= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA4MiBTYWx0ZWRfX0fumO1L+1QJP 8WDxgr76Dbsz/0eYSdheVH7zlpilI1MEPHbgSQDIlThvI/wQp2g7kWbBKRhfVdr6HsXyYN8Bh6c /hpNwry1xnwiBGlkBm9NBCHigqw3WGVuUgiJyyQphOXkcv0avMhUNEr5Fu4jgmSX1l4/ka80CDj hF050hbHECG++Jf46P4iAEUEFnlz90u/H8K+v+J6tZ55oZOHg7bVD9JRZCCqnC4GaMBNtkW/QRU D4b5SVr8G52fzYAZrKIYTdD6SFqPPVSwdPq8FZxgsTvC40M7S70ZKesGadbnW3AfvnF/lmUk21x 3SGW5pA/8g7grUMF77vb4GeU4Cls6yuooDrJj+7iJiZkXlnNtKduDWJ9PIhn1gurq4gyygTvQdd /4fQCqhYNBLnjGvVEVAvh8jPPNNCp0/ChYVzNiZ+59BKeGREXp5st5NuoJwxHW4Q8nOH3GJSqmR aEqiUKQuHPyE1QdWuOA== X-Proofpoint-GUID: ol95gbI1QoUghkEnmEWgD3At2vewX_pH X-Authority-Analysis: v=2.4 cv=N+QZ0W9B c=1 sm=1 tr=0 ts=6a50affb cx=c_pps a=RP+M6JBNLl+fLTcSJhASfg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=jHWy4UxqgUe44QwoGJQA:9 a=iS9zxrgQBfv6-_F4QbHw:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_02,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 suspectscore=0 impostorscore=0 spamscore=0 lowpriorityscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100082 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-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686116185158501 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add helper routines for describing RPMI shared-memory mailbox transports and service child nodes in the RISC-V virt device tree. The helpers keep RPMI node construction in one place so the virt machine can add service groups without open-coding compatible strings, channel IDs, interrupts, and shared-memory references at each call site. Signed-off-by: Subrahmanya Lingappa --- hw/riscv/meson.build | 1 + hw/riscv/rpmi-fdt.c | 103 ++++++++++++++++++++++++++++++++++++ include/hw/riscv/rpmi-fdt.h | 30 +++++++++++ 3 files changed, 134 insertions(+) create mode 100644 hw/riscv/rpmi-fdt.c create mode 100644 include/hw/riscv/rpmi-fdt.h diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build index b70a054579..529ec273fd 100644 --- a/hw/riscv/meson.build +++ b/hw/riscv/meson.build @@ -3,6 +3,7 @@ riscv_ss.add(files('boot.c')) riscv_ss.add(files('fdt-common.c')) riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c')) riscv_ss.add(files('riscv_hart.c')) +riscv_ss.add(files('rpmi-fdt.c')) riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c')) riscv_ss.add(when: 'CONFIG_RISCV_VIRT', if_true: files('virt.c')) riscv_ss.add(when: 'CONFIG_SHAKTI_C', if_true: files('shakti_c.c')) diff --git a/hw/riscv/rpmi-fdt.c b/hw/riscv/rpmi-fdt.c new file mode 100644 index 0000000000..b2b3daea1c --- /dev/null +++ b/hw/riscv/rpmi-fdt.c @@ -0,0 +1,103 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI device-tree helpers + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "qemu/bswap.h" +#include "hw/riscv/rpmi-fdt.h" +#include "hw/misc/riscv_rpmi.h" +#include "system/device_tree.h" + +void riscv_rpmi_fdt_add_mbox(void *fdt, + const RiscvRpmiFdtMboxConfig *cfg, + uint32_t *phandle, + uint32_t *mbox_handle) +{ + g_autofree char *name =3D NULL; + hwaddr a2p_req_base, p2a_ack_base, p2a_req_base, a2p_ack_base; + static const char * const regnames_all[RPMI_ALL_NUM_REGS] =3D { + "a2p-req", "p2a-ack", "p2a-req", "a2p-ack", "a2p-doorbell" + }; + static const char * const regnames_a2p[RPMI_A2P_NUM_REGS] =3D { + "a2p-req", "p2a-ack", "a2p-doorbell" + }; + + a2p_req_base =3D cfg->shmem_base; + p2a_ack_base =3D a2p_req_base + cfg->a2p_req_size; + p2a_req_base =3D p2a_ack_base + cfg->a2p_req_size; + a2p_ack_base =3D p2a_req_base + cfg->p2a_req_size; + + *mbox_handle =3D (*phandle)++; + name =3D g_strdup_printf("/soc/mailbox@%" HWADDR_PRIx, cfg->shmem_base= ); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,rpmi-shmem-mbo= x"); + qemu_fdt_setprop_cell(fdt, name, "riscv,slot-size", RPMI_QUEUE_SLOT_SI= ZE); + qemu_fdt_setprop_cell(fdt, name, "#mbox-cells", 1); + + if (cfg->p2a_req_size) { + qemu_fdt_setprop_string_array(fdt, name, "reg-names", + (char **)®names_all, + ARRAY_SIZE(regnames_all)); + qemu_fdt_setprop_cells(fdt, name, "reg", + (uint32_t)(a2p_req_base >> 32), (uint32_t)a2p_req_base, + 0x0, cfg->a2p_req_size, + (uint32_t)(p2a_ack_base >> 32), (uint32_t)p2a_ack_base, + 0x0, cfg->a2p_req_size, + (uint32_t)(p2a_req_base >> 32), (uint32_t)p2a_req_base, + 0x0, cfg->p2a_req_size, + (uint32_t)(a2p_ack_base >> 32), (uint32_t)a2p_ack_base, + 0x0, cfg->p2a_req_size, + (uint32_t)(cfg->doorbell_base >> 32), (uint32_t)cfg->doorbell_= base, + 0x0, cfg->doorbell_size); + } else { + qemu_fdt_setprop_string_array(fdt, name, "reg-names", + (char **)®names_a2p, + ARRAY_SIZE(regnames_a2p)); + qemu_fdt_setprop_cells(fdt, name, "reg", + (uint32_t)(a2p_req_base >> 32), (uint32_t)a2p_req_base, + 0x0, cfg->a2p_req_size, + (uint32_t)(p2a_ack_base >> 32), (uint32_t)p2a_ack_base, + 0x0, cfg->a2p_req_size, + (uint32_t)(cfg->doorbell_base >> 32), (uint32_t)cfg->doorbell_= base, + 0x0, cfg->doorbell_size); + } + + qemu_fdt_setprop_cells(fdt, name, "phandle", *mbox_handle); +} + +void riscv_rpmi_fdt_add_service(void *fdt, hwaddr shmem_base, + const char *node_name, + const char *compatible, + uint32_t mbox_handle, + uint32_t service_group, + bool has_mpxy_channel, + uint32_t mpxy_channel) +{ + g_autofree char *name =3D g_strdup_printf("/soc/mailbox@%" HWADDR_PRIx= "/%s", + shmem_base, node_name); + + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", compatible); + qemu_fdt_setprop_cells(fdt, name, "mboxes", mbox_handle, service_group= ); + if (has_mpxy_channel) { + qemu_fdt_setprop_cell(fdt, name, "riscv,sbi-mpxy-channel-id", + mpxy_channel); + } +} + +void riscv_rpmi_fdt_add_service_node(void *fdt, hwaddr shmem_base, + const RiscvRpmiServiceConfig *service, + uint32_t mbox_handle) +{ + riscv_rpmi_fdt_add_service(fdt, shmem_base, service->node_name, + service->compatible, mbox_handle, + service->service_group, + service->has_mpxy_channel, + service->mpxy_channel); +} diff --git a/include/hw/riscv/rpmi-fdt.h b/include/hw/riscv/rpmi-fdt.h new file mode 100644 index 0000000000..f053ae5d57 --- /dev/null +++ b/include/hw/riscv/rpmi-fdt.h @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI device-tree helpers + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#ifndef HW_RISCV_RPMI_FDT_H +#define HW_RISCV_RPMI_FDT_H + +#include "exec/hwaddr.h" +#include "hw/misc/riscv_rpmi.h" + +typedef struct RiscvRpmiFdtMboxConfig { + hwaddr shmem_base; + hwaddr doorbell_base; + uint32_t a2p_req_size; + uint32_t p2a_req_size; + uint32_t doorbell_size; +} RiscvRpmiFdtMboxConfig; + +void riscv_rpmi_fdt_add_mbox(void *fdt, + const RiscvRpmiFdtMboxConfig *cfg, + uint32_t *phandle, + uint32_t *mbox_handle); + +#endif --=20 2.43.0 From nobody Sun Jul 12 00:33:30 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=1783686115; cv=none; d=zohomail.com; s=zohoarc; b=UbL0HN/jIixUDKkiNRpIaGWaPRw4T/UH/WbtbUA7AzBdMWEfDXzfzBZjv+dpaXCUPtdollQJLr/72Gm4u+Y7CoL+jwP84KR9lt1I6qAIQZCdd+8gtek/2f+aZzJmgNTtIfqrqfI58ZmPDtiQ87jKk+dCDAFEWa5qT2stsQzly7s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686115; h=Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To:Cc; bh=xzeJ4AiYWR3ajTKkbjbIEkZWZjRq772CWz4lMhQHU3s=; b=f7DugdJid8AsC2JhJWpntrm1C8kGrjtxSMCIw8hL/H4AGZVut/HlgVAbAF0OUViJe4V6JHvihtNrQC5nj6W4vG956YnhQN4/jUYfYqyHpz4sXKt4Z56F0zMMECyNgJ1VtgcVY/6hlr1BV8cLT34rL5khQkEoEJJrLrGAb05/SIA= 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 1783686115068310.7057123791203; Fri, 10 Jul 2026 05:21:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEj-0006WH-PP; Fri, 10 Jul 2026 08:21:46 -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 1wi41O-0002Jl-LZ for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:43:35 -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 1wi41M-0007ny-Md for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:43:34 -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 66A3nSu93803904 for ; Fri, 10 Jul 2026 05:43:31 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 4faf5mtp8u-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:43:31 +0000 (GMT) Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-2caea278af8so2171045ad.2 for ; Thu, 09 Jul 2026 22:43:31 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659c865asm39112785c88.11.2026.07.09.22.43.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:43:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=xzeJ4AiYWR3 ajTKkbjbIEkZWZjRq772CWz4lMhQHU3s=; b=lU+EdTXApmnOgDlDguKdrV51i/s yEK2blTnq9arrwARdHvz3CQ6n53ZBk26xPtlVatJSa4NpdSj5oQjhgb2Ydf9FLxF O1SZYHfzmxIfXeOza7F406xx46IMkmpBBdek+Qq33P/8qYy3m4JbtBoZ6p8s02Dy OJji/hWbBHUT+DRjImifkKHVQj8GTiLeLusS/fCYuipQQq96+Jx2/ew3xc99aqdI T/dFFgo5NzArBqgtnZ+a8Y7EKCyYuiWh68upRwOPxIucrbaI8NXnCVGQoZ2MEq1z gZeEY7mrLTGF6MX1axsqZVAn6VHTUvTyzfv4Cb3HanDWSJ9AVRPfYF7B28w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783662211; x=1784267011; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=xzeJ4AiYWR3ajTKkbjbIEkZWZjRq772CWz4lMhQHU3s=; b=HijB1gQz4+ro0/TmeZKJhUHzV+TKXVITnMdqW8oVSgRdl2MXvnF1qqsU2wvZ/+emZJ zCg3giORXrBH5JWFJ11dZNIGNmmrHt2OvpITwiamPpCGzXaiZRrf7Wvq1Y14BZPHb2MH 5uJrd/C/gn9SC7eiMdVgQyE3VCZcceFLNZoVqThxmSNGbyMtCcpceud+Md2lJjxEIyIp 6Tl0P64XCruoZ74DDH803W0HWuvsvG98+wmP2Ib7tcviM6S7gvoX2T904MZ59j5/wmvJ K9gytRuBteHUWORPJx7kWLFo39tQ7lVzkPSQDEVmW5MHkzyBV1bqV2GDK64dR6DuOkgq 4Rrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783662211; x=1784267011; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=xzeJ4AiYWR3ajTKkbjbIEkZWZjRq772CWz4lMhQHU3s=; b=QSU1HfmbBpK19ypDTHRNrhok1E3HCrM47Hv06KGyPXE4aac00NpByUyI8eYKH4Cqdt KkQgOHR/thVbvlHaEF0lHCmtJyuMppeKcgbz41RcjXZt2JuMs8Dsr1cUvPI8VKAN+MCF bukUFxskRhhKlZFlCfw0gzXg/vOloWKWK6r2iEgtXyaj31Bp49v/cybTtkxiX09GsRk5 GUfudD+gwP61HrSp06DIEH9YREbAr7cc37wxrLlZO7x7PjQD1D+pgNyLmGmG3GqFPM6F BW1LAAIE2gSKZyKze5XjdqgV6sy6LAnGJQPQbcuOZ9G2XkJiZKx/XdL9Tm5b3M8SIw3v N+1A== X-Gm-Message-State: AOJu0Yyvbtbp0PikOEzcwCG4OICBejj/lI5I9TrEVnFy5+lFxNiHVc5E wxlhm8OsX6+VwNg0W6N+0gLLzABUDdeKnOJBCI4Z7++RDqzfUAY8rXSfX2MpXZvAce7CMa32ux5 BXcT7mNZAGX8UvpKRgvWFHDB9GzfNAq3m37s5WEueUHHQwPV0QPoyuH6Snq0SWDcB/Q== X-Gm-Gg: AfdE7cnvjzzC47edhcqYnVZyarxgEHPSwgDQBxeoxV5FO09h2ojhztCYaoMmAemTr3S TmKUwna8UL1QpfiO+FdrYzzdYatriuEZDzeIu+sDCkySnGy9Bd5uj8H2a7nAd7C8RWUvipiy476 DT2tYTVjwabLFpb7d6N9Ap8OcCfMrVDe+cI0s230qMXsFkG+4Ezf1p+vytTqAjgMb8B/hagSm4q E2YhNFWa71bRYHtjlvq3Axj/901yQslPrYkpOxGaE7rQmgQc0RmFfcVQGx+jA4GwT3rRiMlzlQB cAmjeqZtmksGSznDh/MimNoPt27Kulu8U/aSOsmgmnb+Sw2yrq9r6eQOn1wbeu0bzTkuLsO5uMS TMG8OyaB/Y5H/CkzHmEtuZU/T8b1SbnEBDHggmdFOk1J2JSxXkMO8fSitTWblneXYRgSskuTUeS EKlilQi3fNtcjzVd8c2W197gyjJJurAV8vLqTZ8sEENw== X-Received: by 2002:a17:903:2408:b0:2ca:ecf6:9105 with SMTP id d9443c01a7336-2ccfebd26c7mr58556465ad.1.1783662210648; Thu, 09 Jul 2026 22:43:30 -0700 (PDT) X-Received: by 2002:a17:903:2408:b0:2ca:ecf6:9105 with SMTP id d9443c01a7336-2ccfebd26c7mr58556215ad.1.1783662210047; Thu, 09 Jul 2026 22:43:30 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH v2 04/10] hw/riscv/virt: add opt-in RPMI base support Date: Fri, 10 Jul 2026 11:13:12 +0530 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-ORIG-GUID: pAHwMVOgi9SjbDq1Zaw4qkP-qeIy_BjH X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA1MiBTYWx0ZWRfX9uJ1v/J2/RhL 8O0BjU/lJrhIFh3dS5k10wuFxs27GP0QQau4ore5XWRUzrcFE/vk2sK51A3MvZ2hlbnT59NzEIb nK6nDHYp6RlxRM0iVan64Dpw/m6vhd0= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA1MiBTYWx0ZWRfX3jc7OGJQh+nN keQdBjdWqkR9c26ursosbLUTcsAX0YcgMHhN6WrMzFocreC0iSxT2ir6XkN1DD2wYLY7kJmLA5H nycyqRYg4R8zOR8NSBWz4A1YtZiGXFMa+TXWUEmor662cM+sChVwREg+W35gwZBVnbPcGqbOd4Y WWb/wOcuHjX8ucynV8Rv+eYnavL56BfKWxRoKMAig6EFBvESo5Jp6imoHYLoR0SZQHCxe/tm0kq 3y0jtYFNYjB5a8w+9t2ndfvAS4EBCsVzThzyv1jzXoqkQHY76gDPjek9RNhdrzd77394GIWKymq qo9M11Dpdf7yTaJUQknZT6teQ2rCjol86ZeAo1ntsxE5WcR300ISfHsoK2Sd+K4P+mNU0LXJuFJ 4o+u5WNXpW2jgU5ZFqLMPo+5FiYsMy34Hug8CipQlMzAsY8Z9UiYEeM64NYKNSDubq3nnKuHQu6 ny7fh3SwDjsGazB8qLQ== X-Proofpoint-GUID: pAHwMVOgi9SjbDq1Zaw4qkP-qeIy_BjH X-Authority-Analysis: v=2.4 cv=N+QZ0W9B c=1 sm=1 tr=0 ts=6a508683 cx=c_pps a=MTSHoo12Qbhz2p7MsH1ifg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=g5JW_UTvCJDKiRHPheAA:9 a=GvdueXVYPmCkWapjIL-Q:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 suspectscore=0 impostorscore=0 spamscore=0 lowpriorityscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100052 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=205.220.180.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0b-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686116215158501 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add the virt machine rpmi=3Don/off option and wire the initial RPMI Base transport into machine realization. The option remains disabled by default and requires TCG plus librpmi. Invalid accelerator/build combinations fail during machine initialization. When enabled, virt allocates the RPMI shared-memory transport, creates the RPMI device, configures Base service metadata, and emits the corresponding device-tree nodes for firmware discovery. Signed-off-by: Subrahmanya Lingappa --- hw/riscv/Kconfig | 1 + hw/riscv/virt.c | 96 ++++++++++++++++++++++++++++++++++++ include/hw/misc/riscv_rpmi.h | 10 ++++ include/hw/riscv/virt.h | 3 ++ 4 files changed, 110 insertions(+) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 54e41a6afc..4e25be113a 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -49,6 +49,7 @@ config RISCV_VIRT imply VIRTIO_VGA imply TEST_DEVICES imply TPM_TIS_SYSBUS + imply RISCV_RPMI select DEVICE_TREE select RISCV_NUMA select GOLDFISH_RTC diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 33775a61fd..e52ccfae1f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -45,6 +45,8 @@ #include "hw/intc/riscv_aplic.h" #include "hw/intc/sifive_plic.h" #include "hw/misc/sifive_test.h" +#include "hw/misc/riscv_rpmi.h" +#include "hw/riscv/rpmi-fdt.h" #include "hw/core/platform-bus.h" #include "chardev/char.h" #include "system/device_tree.h" @@ -97,6 +99,8 @@ static const MemMapEntry virt_memmap[] =3D { [VIRT_UART0] =3D { 0x10000000, 0x100 }, [VIRT_VIRTIO] =3D { 0x10001000, 0x1000 }, [VIRT_FW_CFG] =3D { 0x10100000, 0x18 }, + [VIRT_RPMI_SHMEM] =3D { 0x10200000, 0x20000 }, + [VIRT_RPMI_DOORBELL] =3D { 0x10230000, 0x1000 }, [VIRT_FLASH] =3D { 0x20000000, 0x4000000 }, [VIRT_IMSIC_M] =3D { 0x24000000, VIRT_IMSIC_MAX_SIZE }, [VIRT_IMSIC_S] =3D { 0x28000000, VIRT_IMSIC_MAX_SIZE }, @@ -1002,6 +1006,40 @@ static void create_fdt_iommu(RISCVVirtState *s, uint= 16_t bdf) s->pci_iommu_bdf =3D bdf; } =20 + +static RiscvRpmiConfig virt_rpmi_config(RISCVVirtState *s, + const uint32_t *hart_ids, + uint32_t hart_count) +{ + return (RiscvRpmiConfig) { + .doorbell_base =3D s->memmap[VIRT_RPMI_DOORBELL].base, + .shmem_base =3D s->memmap[VIRT_RPMI_SHMEM].base, + .shmem_size =3D s->memmap[VIRT_RPMI_SHMEM].size, + .a2p_req_size =3D VIRT_RPMI_A2P_REQ_SIZE, + .p2a_req_size =3D VIRT_RPMI_P2A_REQ_SIZE, + .platform_info =3D "QEMU RISC-V virt RPMI", + .hart_ids =3D hart_ids, + .hart_count =3D hart_count, + }; +} + +static void create_fdt_rpmi(RISCVVirtState *s, uint32_t *phandle, + uint32_t msi_phandle) +{ + RiscvRpmiConfig rpmi_cfg =3D virt_rpmi_config(s, NULL, 0); + uint32_t rpmi_mbox_handle; + RiscvRpmiFdtMboxConfig cfg =3D { + .shmem_base =3D rpmi_cfg.shmem_base, + .doorbell_base =3D rpmi_cfg.doorbell_base, + .a2p_req_size =3D rpmi_cfg.a2p_req_size, + .p2a_req_size =3D rpmi_cfg.p2a_req_size, + .doorbell_size =3D s->memmap[VIRT_RPMI_DOORBELL].size, + }; + + riscv_rpmi_fdt_add_mbox(MACHINE(s)->fdt, &cfg, phandle, + &rpmi_mbox_handle); +} + static void finalize_fdt(RISCVVirtState *s) { uint32_t phandle =3D 1, irq_mmio_phandle =3D 1, msi_pcie_phandle =3D 1; @@ -1021,6 +1059,10 @@ static void finalize_fdt(RISCVVirtState *s) create_fdt_pcie(s, irq_pcie_phandle, msi_pcie_phandle, iommu_sys_phandle); =20 + if (s->have_rpmi) { + create_fdt_rpmi(s, &phandle, msi_pcie_phandle); + } + create_fdt_reset(s, &phandle); =20 create_fdt_uart(s, irq_mmio_phandle); @@ -1410,6 +1452,18 @@ static void virt_machine_init(MachineState *machine) exit(1); } =20 + + if (s->have_rpmi) { +#ifndef CONFIG_LIBRPMI + error_report("RISC-V RPMI support is not compiled in"); + exit(1); +#else + if (kvm_enabled()) { + error_report("RISC-V RPMI support is not available with KVM"); + exit(1); + } +#endif + } /* Initialize sockets */ mmio_irqchip =3D virtio_irqchip =3D pcie_irqchip =3D NULL; for (i =3D 0; i < socket_count; i++) { @@ -1552,6 +1606,25 @@ static void virt_machine_init(MachineState *machine) /* SiFive Test MMIO device */ sifive_test_create(s->memmap[VIRT_TEST].base); =20 + if (s->have_rpmi) { + MachineClass *mc =3D MACHINE_GET_CLASS(machine); + const CPUArchIdList *possible_cpus =3D mc->possible_cpu_arch_ids(m= achine); + g_autofree uint32_t *rpmi_hart_ids =3D + g_new0(uint32_t, machine->smp.cpus); + RiscvRpmiConfig rpmi_cfg; + Error *local_err =3D NULL; + + for (i =3D 0; i < machine->smp.cpus; i++) { + rpmi_hart_ids[i] =3D possible_cpus->cpus[i].arch_id; + } + + rpmi_cfg =3D virt_rpmi_config(s, rpmi_hart_ids, machine->smp.cpus); + if (!riscv_rpmi_create(&rpmi_cfg, &local_err)) { + error_report_err(local_err); + exit(1); + } + } + /* VirtIO MMIO devices */ for (i =3D 0; i < VIRTIO_COUNT; i++) { sysbus_create_simple("virtio-mmio", @@ -1636,6 +1709,7 @@ static void virt_machine_instance_init(Object *obj) =20 s->oem_id =3D g_strndup(ACPI_BUILD_APPNAME6, 6); s->oem_table_id =3D g_strndup(ACPI_BUILD_APPNAME8, 8); + s->have_rpmi =3D false; s->acpi =3D ON_OFF_AUTO_AUTO; s->iommu_sys =3D ON_OFF_AUTO_AUTO; } @@ -1710,6 +1784,21 @@ static void virt_set_aclint(Object *obj, bool value,= Error **errp) s->have_aclint =3D value; } =20 + +static bool virt_get_rpmi(Object *obj, Error **errp) +{ + RISCVVirtState *s =3D RISCV_VIRT_MACHINE(obj); + + return s->have_rpmi; +} + +static void virt_set_rpmi(Object *obj, bool value, Error **errp) +{ + RISCVVirtState *s =3D RISCV_VIRT_MACHINE(obj); + + s->have_rpmi =3D value; +} + bool virt_is_iommu_sys_enabled(RISCVVirtState *s) { return s->iommu_sys =3D=3D ON_OFF_AUTO_ON; @@ -1831,6 +1920,13 @@ static void virt_machine_class_init(ObjectClass *oc,= const void *data) "enable/disable emulating " "ACLINT devices"); =20 + + object_class_property_add_bool(oc, "rpmi", virt_get_rpmi, + virt_set_rpmi); + object_class_property_set_description(oc, "rpmi", + "Set on/off to enable/disable " + "RISC-V RPMI devices"); + object_class_property_add_str(oc, "aia", virt_get_aia, virt_set_aia); object_class_property_set_description(oc, "aia", diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h index cb2658e57e..b5d8a32f9b 100644 --- a/include/hw/misc/riscv_rpmi.h +++ b/include/hw/misc/riscv_rpmi.h @@ -85,6 +85,16 @@ struct RiscvRpmiState { bool has_shmem; }; =20 +#ifdef CONFIG_LIBRPMI DeviceState *riscv_rpmi_create(const RiscvRpmiConfig *cfg, Error **errp); +#else +static inline DeviceState *riscv_rpmi_create(const RiscvRpmiConfig *cfg, + Error **errp) +{ + (void)cfg; + (void)errp; + return NULL; +} +#endif =20 #endif diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 18a2a323a3..f7c48613bf 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -55,6 +55,7 @@ struct RISCVVirtState { =20 int fdt_size; bool have_aclint; + bool have_rpmi; RISCVVirtAIAType aia_type; int aia_guests; char *oem_id; @@ -79,6 +80,8 @@ enum { VIRT_UART0, VIRT_VIRTIO, VIRT_FW_CFG, + VIRT_RPMI_SHMEM, + VIRT_RPMI_DOORBELL, VIRT_IMSIC_M, VIRT_IMSIC_S, VIRT_FLASH, --=20 2.43.0 From nobody Sun Jul 12 00:33:30 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=1783686113; cv=none; d=zohomail.com; s=zohoarc; b=OiloXD0IJji/wM9oiuIHn/fuXobKWNPApdgrdo6JxIyAew8NDvCQ4S1VZPouPTT4yzUETCoXywjnIo2WWHTk/btF0BpM3aTZH8kVyIA3ZunRAQa7kh5psqfHNJRBC3qwsDqPsrCy16M+Fy29yrGlub+ZIujEisJfmBdrKMoifwc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686113; 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=h1qAKkeuy63TsTKKdXSBb2qB4Ny1vxVvMN2n9VV1JXI=; b=a7gmQFcZ4dlFqkAnXivTN1p7haX9WYO064s3mUGMW45YB5j2FEFAJYk8lavUphdal8PPJFbaqQArCxMAcl4Z8B+eZWIlYVqPmrDYSedo3THm68vMOKgTLhXtv3sMgleG8wgVqWGlx+igxT0hWqtrRuxyzYZFYOpIDGeAlED2dqM= 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 17836861135701008.7190847706966; Fri, 10 Jul 2026 05:21:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEb-0006Tp-1l; Fri, 10 Jul 2026 08:21:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi6mm-0000Ys-P7 for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:40 -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 1wi6mi-0001sM-UY for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:40 -0400 Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A7dSnL172472 for ; Fri, 10 Jul 2026 08:40:33 GMT Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4fanwe9mad-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 08:40:33 +0000 (GMT) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-38459087607so333243a91.2 for ; Fri, 10 Jul 2026 01:40:33 -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-3118389d9bcsm29164925eec.20.2026.07.10.01.40.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 01:40:31 -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=h1qAKkeuy63 TsTKKdXSBb2qB4Ny1vxVvMN2n9VV1JXI=; b=nV3lMiI5KaPNCpOHN9F5OVNsz3e Zh3cqjTWmSGfGGcWBznoT5r5vDhMPPIYTeQxjHx+YYg5/GBLwr9pADYmUE+mxHfx +HRW4NrG223qFXBedFi10QFy6Sly56IUdzIkb6vaLI3bLX1CeJ72eyn0/uOn6K/W mJGzhUvnbbqdSyLQRW639zyFodVxRhMR7LPLvwnXFXwE1/o2jA/rACHoIbveY6iF yyNGAkTWtPv+GbVOiztwzEGjP7LCNHu1A3+0CKuK2kpUN+ODy6zsY6A4BCPPsXua 8bmvYEbYuhOzOo+W5Ap66guLXXeBU9TE8m5MqqWUU7Hn7669UX2U1PusmVg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783672832; x=1784277632; 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=h1qAKkeuy63TsTKKdXSBb2qB4Ny1vxVvMN2n9VV1JXI=; b=Yp3oQ3eMY8oeHIpxQDtjO8KO7G5uZx9GZ3HKp3Nl4gJT3mx5IV+DYtefhBZS/d6mNR N2w6DIKgvnHKOw6pL77yFjY40XgA4qp8yq4tHH4gQK9pVVOYfM2SXqdxK1kSk11fJR26 vcMRx0F3EJEN66MG6NH/MYKgHIx+uCwrPM/P/TLTthPZpm8vQiFAflQMNy7iygQ0SN5c YKaLErZ5HItzDToxQb4bbHx4DaCkJuduS4v4ppmv2AaS2Mu4q3fkV667sXYs4ft20Hf9 deSSmrICnBK4qJQ4/qvJYz89VzqEKdcyIFdDfn9WneBzV5QJvT778NZzVtlxbHWnwLPz D70Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783672832; x=1784277632; 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=h1qAKkeuy63TsTKKdXSBb2qB4Ny1vxVvMN2n9VV1JXI=; b=SoSRT45YB16SsGRe4xmCB4TYd6xiswsFfl8ujtqxA/9DlV3n4OuyXlhyR76P1X7zOi YDXgCOyU5Z5QDxvlKnTz/KW6CdKTmbbAvXAioS9yJu0Lp6jaq2dGFS07mtc/V90LXeE5 +BocuaPG/jUL/NBggpbMW7SlfJZ/99eHPrf0bMHmVj1mL3vL/INZm0gSZCUUPpC9ULsv OGDjeeVKV05CUcEY5Cbr0nWdMz1skrATQCSPAJDIyZ4mAYwjHMFJzV2gkv0l+jpkkNuq PMXPfh9OaUQS/89XHzFH2Fvc+d2cd3QMWaLq15o0TzFF3z3JQwFzEoaJ6yHxnhNmpM8s mdwg== X-Gm-Message-State: AOJu0YxsSaCCYYKg770QezTUgrLG/I8Pe6aSskA0iHiES3ThvCt/t6DU XuCY97aUP0UFq5Vr83tMIGwOHn5T2UNr9/qrzVMzP617he5+Xojx/MLjO3J9JufHH/pcof1H5rQ GpJk8fFOPrZGuWeD1eyNeW6BSktb9rRfKtKvVjSVXvu3s9kjiRTTnv3zAXg== X-Gm-Gg: AfdE7clUpJWG7nieGBTv4ORQRIIXaLmPD3MY019JFqXBHgjqtaE0nxkQ8C5LlgEXhI4 uTEs2VR5AZH/KRzwW1VcHA+mw85SJSK97EQOAFgIVyGV3DUm58pY2i5URTl0NqpB06/eB7cGYVA Hl4uDYIcxW4kdvMo6UJfRD4o8exxKdE1uvJ1zgfO2ypsBpZvhEzfbTQIPZrbf4EdeMxFXDtKTO4 AvWMwc3Gi7brq7XIo7/zEkzTbFJ7g9fEOd7FzrPtRf8BCPVwYkyuMTWiLzcwLoMBLCTh2cFpJIY fua0w+S5Cx4NK9picsntpE9U/jOIUdAYEVPRxu17dQz8IcEyCBboq/ZlrZx3Re2U1Zdn/7y0ykr Tq2eEe8r/UHhoU6CGOj/u2QX0Smsu2dqBk8NfTJKR4JNPqtRQOsjI3YninRxltgEi7cd0F8MQlA WG+rOrCpWgyqOMvNeFPkWPGF1gv5CgPhIvs+4BRFUB/Q== X-Received: by 2002:a17:90b:5886:b0:381:bcfb:e710 with SMTP id 98e67ed59e1d1-38a20e414e7mr6736690a91.3.1783672832317; Fri, 10 Jul 2026 01:40:32 -0700 (PDT) X-Received: by 2002:a17:90b:5886:b0:381:bcfb:e710 with SMTP id 98e67ed59e1d1-38a20e414e7mr6736656a91.3.1783672831740; Fri, 10 Jul 2026 01:40:31 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-riscv@nongnu.org Cc: qemu-devel@nongnu.org, daniel.barboza@oss.qualcomm.com, Subrahmanya Lingappa Subject: [PATCH v2 05/10] riscv: add RPMI system reset service Date: Fri, 10 Jul 2026 14:09:47 +0530 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Authority-Analysis: v=2.4 cv=LbIMLDfi c=1 sm=1 tr=0 ts=6a50b001 cx=c_pps a=RP+M6JBNLl+fLTcSJhASfg==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=EUspDBNiAAAA:8 a=blQ9iIGB7deKtsPWDqUA:9 a=iS9zxrgQBfv6-_F4QbHw:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA4MyBTYWx0ZWRfX07vyHIFzbTmB ToU91+fOY0f/JkKvSAOxcbJZPBufrcARKxjQnKb16IqAQIlObkvjhwTeofUDkSQqrPM5yz0CcRB FbizJUwf8AzazrtGHfgueeBRzp1rpmVLlf+Np2++UxwfgmR/MshWWPvGITqVFBNc1mUaIOKc5iz K9h4U89vYLXv/cEvg3DRLSDw3NFpIUMaYH1ff/wx2CZbJPzsbS13zCDu2KnxSaFU2jUflAtSN3s L0Fz6Zb87Eaxq8Hv/gejcsoh+1d+HtOrMAbfmHKN0JrMZ4evmlJh1q5HlIHRJjRM9HZLMUpOq0N 8JBstqzx4Uz9mamsgjyreWmgItCtEW6lOUkfF3rQyLAOfvPvCjZO452r8doaMXShl2EEEjwjr0w uDDVF3ksvNB1giM9s4ojnMYM0hgHe0r5BVR6kHDY0EA2sBcVPvboH5PRfHtXfJMlRpskIqNmSuO VRozktii43MK2jki/TA== X-Proofpoint-ORIG-GUID: MZcCp-heoFbnb39HlW52KzcEpWiftEuG X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA4MyBTYWx0ZWRfX0jneq/7j2BxJ J9GgXP7fnbrDo3MxtBtKHiEkVqxH6yxD8b2/1tLHT+oavbOwqdNErRoR93EyWNLNWEokmWP7AnF on+sTO6ffPEMyp7V/+3dk70Ff5TXr7s= X-Proofpoint-GUID: MZcCp-heoFbnb39HlW52KzcEpWiftEuG X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_02,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 suspectscore=0 lowpriorityscore=0 bulkscore=0 clxscore=1015 impostorscore=0 priorityscore=1501 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100083 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-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686116248158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add a QEMU implementation of the RPMI System Reset service group. The service advertises shutdown and cold reboot reset types, validates guest requests, and dispatches accepted requests through the machine reset and shutdown callbacks. This lets firmware use RPMI reset commands while keeping the board-specific reset policy in the RISC-V virt machine. Signed-off-by: Subrahmanya Lingappa --- hw/misc/meson.build | 1 + hw/misc/riscv_rpmi.c | 38 ++++++- hw/misc/riscv_rpmi_internal.h | 9 ++ hw/misc/riscv_rpmi_sysreset.c | 206 ++++++++++++++++++++++++++++++++++ hw/riscv/virt.c | 40 +++++++ include/hw/misc/riscv_rpmi.h | 13 ++- include/hw/riscv/rpmi-fdt.h | 11 ++ 7 files changed, 313 insertions(+), 5 deletions(-) create mode 100644 hw/misc/riscv_rpmi_sysreset.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index e7c2ebe28f..bca7819ee0 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -170,4 +170,5 @@ system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('= sbsa_ec.c')) system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c')) system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files( 'riscv_rpmi.c', + 'riscv_rpmi_sysreset.c', ), librpmi]) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c index c4b115b659..7a3f570ee7 100644 --- a/hw/misc/riscv_rpmi.c +++ b/hw/misc/riscv_rpmi.c @@ -175,6 +175,8 @@ static void riscv_rpmi_configure_base(RiscvRpmiState *s, const RiscvRpmiConfig *cfg) { s->platform_info =3D g_strdup(cfg->platform_info); + s->machine_ops =3D cfg->machine_ops; + s->machine_opaque =3D cfg->machine_opaque; s->services =3D cfg->services; s->service_count =3D cfg->service_count; =20 @@ -211,7 +213,9 @@ static void riscv_rpmi_reset(DeviceState *dev) =20 static void riscv_rpmi_cleanup(RiscvRpmiState *s) { - + for (uint32_t i =3D ARRAY_SIZE(riscv_rpmi_service_ops); i > 0; i--) { + riscv_rpmi_service_ops[i - 1].remove(s); + } =20 if (s->context) { rpmi_context_destroy(s->context); @@ -247,6 +251,30 @@ bool riscv_rpmi_service_enabled(RiscvRpmiState *s, Ris= cvRpmiServiceKind kind) return false; } =20 +bool riscv_rpmi_context_add_group(RiscvRpmiState *s, + struct rpmi_service_group *group, + const char *name, + Error **errp) +{ + enum rpmi_error rc; + + rc =3D rpmi_context_add_group(s->context, group); + if (rc !=3D RPMI_SUCCESS) { + error_setg(errp, "failed to add RPMI %s service group: %d", name, = rc); + return false; + } + + return true; +} + +void riscv_rpmi_context_remove_group(RiscvRpmiState *s, + struct rpmi_service_group *group) +{ + if (s->context && group) { + rpmi_context_remove_group(s->context, group); + } +} + static bool riscv_rpmi_validate_config(RiscvRpmiState *s, Error **errp) { uint64_t queue_bytes; @@ -318,11 +346,15 @@ static bool riscv_rpmi_add_service_group(RiscvRpmiSta= te *s, const RiscvRpmiServiceConfig *ser= vice, Error **errp) { - switch (service->kind) { - default: + const RiscvRpmiServiceOps *ops; + + ops =3D riscv_rpmi_service_ops_by_kind(service->kind); + if (!ops) { error_setg(errp, "unsupported RPMI service kind %d", service->kind= ); return false; } + + return ops->add(s, errp); } =20 static bool riscv_rpmi_init_services(RiscvRpmiState *s, Error **errp) diff --git a/hw/misc/riscv_rpmi_internal.h b/hw/misc/riscv_rpmi_internal.h index 447c0acb55..fe09804e69 100644 --- a/hw/misc/riscv_rpmi_internal.h +++ b/hw/misc/riscv_rpmi_internal.h @@ -20,5 +20,14 @@ extern const struct rpmi_shmem_platform_ops rpmi_shmem_qemu_ops; bool riscv_rpmi_service_enabled(RiscvRpmiState *s, RiscvRpmiServiceKind kind); +bool riscv_rpmi_context_add_group(RiscvRpmiState *s, + struct rpmi_service_group *group, + const char *name, + Error **errp); +void riscv_rpmi_context_remove_group(RiscvRpmiState *s, + struct rpmi_service_group *group); + +bool riscv_rpmi_sysreset_add(RiscvRpmiState *s, Error **errp); +void riscv_rpmi_sysreset_remove(RiscvRpmiState *s); =20 #endif diff --git a/hw/misc/riscv_rpmi_sysreset.c b/hw/misc/riscv_rpmi_sysreset.c new file mode 100644 index 0000000000..da6ef4c566 --- /dev/null +++ b/hw/misc/riscv_rpmi_sysreset.c @@ -0,0 +1,206 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI System Reset service. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "riscv_rpmi_internal.h" +#include "qemu/log.h" +#include "librpmi_env.h" + +typedef struct RiscvRpmiSysresetType { + uint32_t type; + void (*action)(RiscvRpmiState *s); +} RiscvRpmiSysresetType; + +typedef struct RiscvRpmiSysresetGroup { + struct rpmi_service_group group; + struct rpmi_service services[RPMI_SYSRST_SRV_ID_MAX]; + RiscvRpmiState *rpmi; +} RiscvRpmiSysresetGroup; + +static void riscv_rpmi_sysreset_reboot(RiscvRpmiState *s) +{ + const RiscvRpmiMachineOps *ops =3D s->machine_ops; + + if (ops && ops->system_reset) { + ops->system_reset(s->machine_opaque); + } +} + +static void riscv_rpmi_sysreset_shutdown(RiscvRpmiState *s) +{ + const RiscvRpmiMachineOps *ops =3D s->machine_ops; + + if (ops && ops->system_shutdown) { + ops->system_shutdown(s->machine_opaque); + } +} + +static const RiscvRpmiSysresetType riscv_rpmi_sysreset_types[] =3D { + { + .type =3D RPMI_SYSRST_TYPE_SHUTDOWN, + .action =3D riscv_rpmi_sysreset_shutdown, + }, { + .type =3D RPMI_SYSRST_TYPE_COLD_REBOOT, + .action =3D riscv_rpmi_sysreset_reboot, + }, +}; + +static const RiscvRpmiSysresetType *riscv_rpmi_sysreset_type_by_id( + uint32_t reset_type) +{ + for (uint32_t index =3D 0; index < ARRAY_SIZE(riscv_rpmi_sysreset_type= s); + index++) { + if (riscv_rpmi_sysreset_types[index].type =3D=3D reset_type) { + return &riscv_rpmi_sysreset_types[index]; + } + } + + return NULL; +} + +static void riscv_rpmi_do_system_reset(RiscvRpmiState *s, + rpmi_uint32_t reset_type) +{ + const RiscvRpmiSysresetType *type; + + type =3D riscv_rpmi_sysreset_type_by_id(reset_type); + if (type) { + type->action(s); + return; + } + + qemu_log_mask(LOG_GUEST_ERROR, "%s: unsupported reset type %u\n", + __func__, reset_type); +} + +static enum rpmi_error riscv_rpmi_sysreset_get_attributes( + struct rpmi_service_group *group, struct rpmi_service *service, + struct rpmi_transport *trans, rpmi_uint16_t request_data_len, + const rpmi_uint8_t *request_data, rpmi_uint16_t *response_data_len, + rpmi_uint8_t *response_data) +{ + uint32_t reset_type =3D ldl_le_p(request_data); + uint32_t *resp =3D (uint32_t *)response_data; + + *response_data_len =3D 2 * sizeof(*resp); + stl_le_p(&resp[0], RPMI_SUCCESS); + stl_le_p(&resp[1], riscv_rpmi_sysreset_type_by_id(reset_type) ? + RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE : 0); + + return RPMI_SUCCESS; +} + +static enum rpmi_error riscv_rpmi_sysreset_do_reset( + struct rpmi_service_group *group, struct rpmi_service *service, + struct rpmi_transport *trans, rpmi_uint16_t request_data_len, + const rpmi_uint8_t *request_data, rpmi_uint16_t *response_data_len, + rpmi_uint8_t *response_data) +{ + RiscvRpmiSysresetGroup *sysreset =3D group->priv; + uint32_t reset_type =3D ldl_le_p(request_data); + uint32_t *resp =3D (uint32_t *)response_data; + + *response_data_len =3D sizeof(*resp); + + if (!riscv_rpmi_sysreset_type_by_id(reset_type)) { + stl_le_p(resp, (uint32_t)RPMI_ERR_INVALID_PARAM); + return RPMI_SUCCESS; + } + + stl_le_p(resp, RPMI_SUCCESS); + riscv_rpmi_do_system_reset(sysreset->rpmi, reset_type); + return RPMI_SUCCESS; +} + +static const struct rpmi_service riscv_rpmi_sysreset_services[] =3D { + [RPMI_SYSRST_SRV_ENABLE_NOTIFICATION] =3D { + .service_id =3D RPMI_SYSRST_SRV_ENABLE_NOTIFICATION, + .min_a2p_request_datalen =3D 8, + }, + [RPMI_SYSRST_SRV_GET_ATTRIBUTES] =3D { + .service_id =3D RPMI_SYSRST_SRV_GET_ATTRIBUTES, + .min_a2p_request_datalen =3D 4, + .process_a2p_request =3D riscv_rpmi_sysreset_get_attributes, + }, + [RPMI_SYSRST_SRV_SYSTEM_RESET] =3D { + .service_id =3D RPMI_SYSRST_SRV_SYSTEM_RESET, + .min_a2p_request_datalen =3D 4, + .process_a2p_request =3D riscv_rpmi_sysreset_do_reset, + }, +}; + +static struct rpmi_service_group *riscv_rpmi_sysreset_create(RiscvRpmiStat= e *s) +{ + RiscvRpmiSysresetGroup *sysreset; + struct rpmi_service_group *group; + + sysreset =3D g_new0(RiscvRpmiSysresetGroup, 1); + sysreset->rpmi =3D s; + memcpy(sysreset->services, riscv_rpmi_sysreset_services, + sizeof(riscv_rpmi_sysreset_services)); + + group =3D &sysreset->group; + group->name =3D "sysreset"; + group->servicegroup_id =3D RPMI_SRVGRP_SYSTEM_RESET; + group->max_service_id =3D RPMI_SYSRST_SRV_ID_MAX; + group->servicegroup_version =3D + RPMI_BASE_VERSION(RPMI_SPEC_VERSION_MAJOR, RPMI_SPEC_VERSION_MINOR= ); + group->privilege_level_bitmap =3D RPMI_PRIVILEGE_M_MODE_MASK; + group->services =3D sysreset->services; + group->lock =3D rpmi_env_alloc_lock(); + group->priv =3D sysreset; + + return group; +} + +static void riscv_rpmi_sysreset_destroy(struct rpmi_service_group *group) +{ + if (!group) { + return; + } + + rpmi_env_free_lock(group->lock); + g_free(group->priv); +} + +bool riscv_rpmi_sysreset_add(RiscvRpmiState *s, Error **errp) +{ + struct rpmi_service_group *group; + + if (s->sysreset_group) { + error_setg(errp, "duplicate RPMI sysreset service descriptor"); + return false; + } + + group =3D riscv_rpmi_sysreset_create(s); + if (!group) { + error_setg(errp, "failed to create RPMI sysreset service group"); + return false; + } + + if (!riscv_rpmi_context_add_group(s, group, "sysreset", errp)) { + riscv_rpmi_sysreset_destroy(group); + return false; + } + + s->sysreset_group =3D group; + return true; +} + +void riscv_rpmi_sysreset_remove(RiscvRpmiState *s) +{ + if (!s->sysreset_group) { + return; + } + + riscv_rpmi_context_remove_group(s, s->sysreset_group); + riscv_rpmi_sysreset_destroy(s->sysreset_group); + s->sysreset_group =3D NULL; +} diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index e52ccfae1f..273a9aa04f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1007,6 +1007,35 @@ static void create_fdt_iommu(RISCVVirtState *s, uint= 16_t bdf) } =20 =20 +static const RiscvRpmiServiceConfig virt_rpmi_services[] =3D { + { + .kind =3D RISCV_RPMI_SERVICE_SYSRESET, + .node_name =3D "sysreset", + .compatible =3D "riscv,rpmi-system-reset", + .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_RESET, + }, +}; + +static uint32_t virt_rpmi_service_count(RISCVVirtState *s) +{ + return ARRAY_SIZE(virt_rpmi_services); +} + +static void virt_rpmi_system_reset(void *opaque) +{ + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); +} + +static void virt_rpmi_system_shutdown(void *opaque) +{ + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); +} + +static const RiscvRpmiMachineOps virt_rpmi_machine_ops =3D { + .system_reset =3D virt_rpmi_system_reset, + .system_shutdown =3D virt_rpmi_system_shutdown, +}; + static RiscvRpmiConfig virt_rpmi_config(RISCVVirtState *s, const uint32_t *hart_ids, uint32_t hart_count) @@ -1018,8 +1047,12 @@ static RiscvRpmiConfig virt_rpmi_config(RISCVVirtSta= te *s, .a2p_req_size =3D VIRT_RPMI_A2P_REQ_SIZE, .p2a_req_size =3D VIRT_RPMI_P2A_REQ_SIZE, .platform_info =3D "QEMU RISC-V virt RPMI", + .machine_ops =3D &virt_rpmi_machine_ops, + .machine_opaque =3D s, .hart_ids =3D hart_ids, .hart_count =3D hart_count, + .services =3D virt_rpmi_services, + .service_count =3D virt_rpmi_service_count(s), }; } =20 @@ -1028,6 +1061,7 @@ static void create_fdt_rpmi(RISCVVirtState *s, uint32= _t *phandle, { RiscvRpmiConfig rpmi_cfg =3D virt_rpmi_config(s, NULL, 0); uint32_t rpmi_mbox_handle; + uint32_t i; RiscvRpmiFdtMboxConfig cfg =3D { .shmem_base =3D rpmi_cfg.shmem_base, .doorbell_base =3D rpmi_cfg.doorbell_base, @@ -1038,6 +1072,12 @@ static void create_fdt_rpmi(RISCVVirtState *s, uint3= 2_t *phandle, =20 riscv_rpmi_fdt_add_mbox(MACHINE(s)->fdt, &cfg, phandle, &rpmi_mbox_handle); + + for (i =3D 0; i < rpmi_cfg.service_count; i++) { + riscv_rpmi_fdt_add_service_node(MACHINE(s)->fdt, rpmi_cfg.shmem_ba= se, + &rpmi_cfg.services[i], + rpmi_mbox_handle); + } } =20 static void finalize_fdt(RISCVVirtState *s) diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h index b5d8a32f9b..d11db87731 100644 --- a/include/hw/misc/riscv_rpmi.h +++ b/include/hw/misc/riscv_rpmi.h @@ -27,6 +27,7 @@ #define VIRT_RPMI_A2P_REQ_SIZE (16 * RPMI_QUEUE_SLOT_SIZE) #define VIRT_RPMI_P2A_REQ_SIZE 0 =20 +#define RISCV_RPMI_SRVGRP_SYSTEM_RESET 3 =20 #define TYPE_RISCV_RPMI "riscv-rpmi" OBJECT_DECLARE_SIMPLE_TYPE(RiscvRpmiState, RISCV_RPMI) @@ -38,8 +39,13 @@ struct rpmi_transport; =20 typedef enum RiscvRpmiServiceKind { RISCV_RPMI_SERVICE_INVALID =3D 0, + RISCV_RPMI_SERVICE_SYSRESET, } RiscvRpmiServiceKind; =20 +typedef struct RiscvRpmiMachineOps { + void (*system_reset)(void *opaque); + void (*system_shutdown)(void *opaque); +} RiscvRpmiMachineOps; typedef struct RiscvRpmiServiceConfig { RiscvRpmiServiceKind kind; const char *node_name; @@ -56,7 +62,8 @@ typedef struct RiscvRpmiConfig { uint32_t a2p_req_size; uint32_t p2a_req_size; const char *platform_info; - + const RiscvRpmiMachineOps *machine_ops; + void *machine_opaque; const uint32_t *hart_ids; uint32_t hart_count; const RiscvRpmiServiceConfig *services; @@ -73,7 +80,9 @@ struct RiscvRpmiState { uint32_t a2p_req_size; uint32_t p2a_req_size; char *platform_info; - + const RiscvRpmiMachineOps *machine_ops; + void *machine_opaque; + struct rpmi_service_group *sysreset_group; uint32_t *hart_ids; uint32_t hart_count; const RiscvRpmiServiceConfig *services; diff --git a/include/hw/riscv/rpmi-fdt.h b/include/hw/riscv/rpmi-fdt.h index f053ae5d57..af0e8a65ab 100644 --- a/include/hw/riscv/rpmi-fdt.h +++ b/include/hw/riscv/rpmi-fdt.h @@ -26,5 +26,16 @@ void riscv_rpmi_fdt_add_mbox(void *fdt, const RiscvRpmiFdtMboxConfig *cfg, uint32_t *phandle, uint32_t *mbox_handle); +void riscv_rpmi_fdt_add_service(void *fdt, hwaddr shmem_base, + const char *node_name, + const char *compatible, + uint32_t mbox_handle, + uint32_t service_group, + bool has_mpxy_channel, + uint32_t mpxy_channel); + +void riscv_rpmi_fdt_add_service_node(void *fdt, hwaddr shmem_base, + const RiscvRpmiServiceConfig *service, + uint32_t mbox_handle); =20 #endif --=20 2.43.0 From nobody Sun Jul 12 00:33:30 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=oss.qualcomm.com ARC-Seal: i=1; a=rsa-sha256; t=1783686149; cv=none; d=zohomail.com; s=zohoarc; b=KxcYnFo/SIie9GuSk+lvGim7QIJlv9WlMikP2pVX03CCgFy3jOW0TDOpA3LJq94+YqH2CO2JAFUu2cVRNwmqGDOfFvRHtgmHL2pgKCGPYzm4SI3spubPpNwC1TasnHujQ6hhX2+wNAMKFneAWZz2hha+sW72jwTv8+xH+GR7kX0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686149; 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=3Zi3YOFyUx87EoAznmuJNik04JSRbYxYi7RMXJIg/zc=; b=Oj0tQQOP+lwV0RGGz1b8N9rEDEbbhMKoYVbNjLS0mVAHYpuz/xgJHQlEwLIlIBI8YD+Ti4b/M53nySUkW1NdRzwCXiPoegBzNqIeFtGzYrybOAXQBD9B/ZexAnxZWFbATUPG4Uv8FEs5bmSBpIeLpM0k6H0KqAFiVeg6+ruVhq8= 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 1783686149077790.1941803064302; Fri, 10 Jul 2026 05:22:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAF5-0007KE-AH; Fri, 10 Jul 2026 08:22: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 1wi6mn-0000ZC-5Z for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40: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 1wi6mj-0001sq-8I for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:40 -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 66A7e8Xj189200 for ; Fri, 10 Jul 2026 08:40:36 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 4faeesujnu-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 08:40:35 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-388277fd89aso192803a91.2 for ; Fri, 10 Jul 2026 01:40: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-3118389d9bcsm29164925eec.20.2026.07.10.01.40.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 01:40:33 -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=3Zi3YOFyUx8 7EoAznmuJNik04JSRbYxYi7RMXJIg/zc=; b=XEtwZWiCYHNmQqhrxU7w2Twy4x8 ovGCYv0DUqOf/WQGBOHybXDMczmKGMpXAjCMJcKEPbW9zwkZDEXBh88EOA5EM8PG txqr9ap79Lvxfn15kAXPMy52PG5xAWLMrwvuJRDxxR55X0gGBGs0N00YGZrd4GWX 4dYhmiD/Qc5fwazTTms5wwwXvE8m1LdN+zfQ/3YLyBq6xxQYy1W1obJ9uwiH9abJ sIw0COPgJ9MXp5wlGCmwpAfQFEYFFIcrBj546+kqhcjvr6owQj6nV0r2OcN9/mDn 8/lNGYjNuGYWrAMIN8sq/82CCUg72QmJlJn600emdf+gRGuuvB00VMe64Cw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783672835; x=1784277635; 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=3Zi3YOFyUx87EoAznmuJNik04JSRbYxYi7RMXJIg/zc=; b=HGeauGCLFunK/WbqsPWQ84KdjvjIun8niFZjtcG9GVN/y3a2vYrq5jAZUHxWaUoCTJ N/9PF72S/jqRvWNcWx1KvyJcTZTaR3mdp0LqP60HHoYNkcwEDTmqBMibS2jnfNmRlAah ZtUE8RLOyC2B86GBzQsQkTwAHJXUi7WLQ0VmPZGkIfmI48M8lES0dGdPDjbAOYuQ0H19 xC7iWs0LD90iLdueryxSDNG7snNSaDI58eLLAG3ysq63Z4IEq70pEKbKyik0MEEJ5QAh fOUSx9sHbsJxukOWhTH5OsKkmsRcGTv7Nrd1zKHsDr3QQnGfT5Mfn5jhDRyBbd8KDAxv 7Adg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783672835; x=1784277635; 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=3Zi3YOFyUx87EoAznmuJNik04JSRbYxYi7RMXJIg/zc=; b=B2vZ9VDQLuNGYKIB6QYDF41e85Z79gJuBC/+yJuwtP2yoYpq7qU2+G6dkbFWquvW2G tAyRuy2G+IZOW3DsErXWNVaroEsV1LWIn9ixAjOgFOnjBvntgYJ1nvAu/twslEZtfkKM BWc1gQI7LKG5Y1LzquG0OB9I9x0OcdYrzgtGh1oUeJCWFoXhiVE/MSBL1BZGzJ+4qgjC YsNuQwwo3vgN05vCaMs6QRg8DPX30UQnPQ5w9teRSqlHwJ1lbYttYist6Ve/vY9KKTD3 vhwn70UOjAv/jMgBT5siCXoYoLe+NX5iroAH26n1Lyrhf9DedZXjSZTKJ+JZ3NKmrrN8 LN0w== X-Gm-Message-State: AOJu0YzN59LUuhPxTXgecsgU2Xb7cETG7bKLBR3ZVMQznX8ULqxl4dkw tSyw3XY6n6cp4QqOfEz0C+jK+WMPONunNjBVaeCD/QHSVHbwXjK0zAJdP4L6xqAbAtrSC2a5yCQ sZLu5O6WqsxoIDKi4J7/mxi/Wfuga0XWZDPMUOrTrvvV9btRVcp61z4aPmDyLt67NkA== X-Gm-Gg: AfdE7cmz1UEBQfo8L/9xNrhOUuqU8yRnBBMyynBWTOINBpD0BM+/AvKh7YAyM4Pa+SI DDhUucx2wFBwweNXryhrhNANbfTo93DTyymT1V+wApvYtuI4NUxGa6ihwqJX3ok2aPgSktLrDMY 7Bl4BVjO584KVHhp5pMDBvaWyGyr+87ZFaXjQAHFORNldUrxqM4KtO8Mn3ZbarJUZhCmDFusvdu WmweMMdLoifc9a8Gdr7+DoApOO8FEjsH/LINUyDkYXHu4iwHs6EP2qsSXbfHEo6j3/eSzcnW6ai IqyB0Tcg8q3/m92EXqXliyB9jukTjmHoNBNEzhn5dJrPCi8ShYEqad4tblTnXqfDekrRkU/eqgg dVQcaOoVcCqecKUuQQp+hJx63dXUE8aBiJHJlR084s5Qzsfn5+CSea2olTcNZ3rVGiYE11nprqI rf5a0htWV5OpJVn88f4GJ7S9PDOwDXXMXAEq7BIJ5Vqw== X-Received: by 2002:a17:90a:d606:b0:36a:5438:cff4 with SMTP id 98e67ed59e1d1-389421acc3cmr8842855a91.6.1783672834710; Fri, 10 Jul 2026 01:40:34 -0700 (PDT) X-Received: by 2002:a17:90a:d606:b0:36a:5438:cff4 with SMTP id 98e67ed59e1d1-389421acc3cmr8842841a91.6.1783672834256; Fri, 10 Jul 2026 01:40:34 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-riscv@nongnu.org Cc: qemu-devel@nongnu.org, daniel.barboza@oss.qualcomm.com, Subrahmanya Lingappa Subject: [PATCH v2 06/10] riscv: add RPMI HSM service Date: Fri, 10 Jul 2026 14:09:48 +0530 Message-ID: <21b8264726d7d4a2dfc2c4446e980ffc18f9829e.1783660209.git.subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: MGmXtmFZvrevp3mVk1Psfq3UHz3D93Am X-Authority-Analysis: v=2.4 cv=bbpbluPB c=1 sm=1 tr=0 ts=6a50b003 cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=hCKTHIyopvcgo9YcQkoA:9 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA4MiBTYWx0ZWRfX+5ZJZNi4wLA+ 9t2wTP+Rdm1JAK6cL1MaN4CftaN+3sSbm3pVfppWNQl7NqgNI18oKEGmqylsLJdhciX7uVaIjWY h8TfN9IKKSG2bljDeKHPbJ2i1Fq5lx4= X-Proofpoint-ORIG-GUID: MGmXtmFZvrevp3mVk1Psfq3UHz3D93Am X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA4MiBTYWx0ZWRfX+qXwSAAgT3aF tH76vvl/0/U0v2P/MhyUa0itIkBKRjLMpM9I90vESUO95GjCgcg2yKp+Y/rWld+nI6U2FdyTXHH 2+kS9BW5JrjjuItFmtCyl6OOEpe3vAwpmEtUDANXEGktUJUkq2dTUe2+p1fJIYt9eD7UTrlh/Qj rzR/rOf7P53kSswwxexiTL3udloO26qlFSZEBQd4fvOFgj9xfrMBTkyglaYI3VLvX8Yo44Sw7mQ rjOlHuyxZ9//U6X+YpPKhrO++204mE5Tw5HK+1YY0ww7t068DFgKVtI6qYxTMbVK/Z/e8yMiHjS agHMs5V3n47LXjO5E1ap5jFPiN5J9Dtj7lTlTCWfh5WD7sMAEwEndLb2H0MVvEyJtNNxIH1CBva 3WRNLfM62j2bRo9yLQeFWPnUThyl/Dgu5vlPE8QuPXaDRyujdWdUsE2tZZ+CeRbSqKJaCOjAW9z ytBoCpnbW2v/lhbh6Jw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_02,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 priorityscore=1501 malwarescore=0 bulkscore=0 suspectscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100082 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-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686150121158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add the RPMI Hart State Management service group for RISC-V virt. The service exposes the configured virt hart IDs to librpmi and keeps per-hart RPMI hardware state in the RPMI device. Start, stop, and suspend requests update QEMU CPU halted state and resume/kick vCPUs as needed so firmware can exercise RPMI HSM operations against the emulated topology. Signed-off-by: Subrahmanya Lingappa --- hw/misc/meson.build | 1 + hw/misc/riscv_rpmi.c | 46 ++++++ hw/misc/riscv_rpmi_hsm.c | 280 ++++++++++++++++++++++++++++++++++ hw/misc/riscv_rpmi_internal.h | 4 + hw/riscv/virt.c | 6 + include/hw/misc/riscv_rpmi.h | 6 + 6 files changed, 343 insertions(+) create mode 100644 hw/misc/riscv_rpmi_hsm.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index bca7819ee0..fc5b11ed57 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -171,4 +171,5 @@ system_ss.add(when: 'CONFIG_LASI', if_true: files('lasi= .c')) system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files( 'riscv_rpmi.c', 'riscv_rpmi_sysreset.c', + 'riscv_rpmi_hsm.c', ), librpmi]) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c index 7a3f570ee7..820b1d5d63 100644 --- a/hw/misc/riscv_rpmi.c +++ b/hw/misc/riscv_rpmi.c @@ -171,6 +171,49 @@ static bool riscv_rpmi_transport_indices_valid(RiscvRp= miState *s) s->a2p_req_size); } =20 +typedef struct RiscvRpmiServiceOps { + RiscvRpmiServiceKind kind; + void (*configure)(RiscvRpmiState *s, const RiscvRpmiConfig *cfg); + bool (*add)(RiscvRpmiState *s, Error **errp); + void (*remove)(RiscvRpmiState *s); +} RiscvRpmiServiceOps; + +static const RiscvRpmiServiceOps riscv_rpmi_service_ops[] =3D { + { + .kind =3D RISCV_RPMI_SERVICE_SYSRESET, + .add =3D riscv_rpmi_sysreset_add, + .remove =3D riscv_rpmi_sysreset_remove, + }, { + .kind =3D RISCV_RPMI_SERVICE_HSM, + .add =3D riscv_rpmi_hsm_add, + .remove =3D riscv_rpmi_hsm_remove, + }, +}; + +static const RiscvRpmiServiceOps *riscv_rpmi_service_ops_by_kind( + RiscvRpmiServiceKind kind) +{ + for (uint32_t i =3D 0; i < ARRAY_SIZE(riscv_rpmi_service_ops); i++) { + if (riscv_rpmi_service_ops[i].kind =3D=3D kind) { + return &riscv_rpmi_service_ops[i]; + } + } + + return NULL; +} + +static void riscv_rpmi_configure_services(RiscvRpmiState *s, + const RiscvRpmiConfig *cfg) +{ + for (uint32_t i =3D 0; i < ARRAY_SIZE(riscv_rpmi_service_ops); i++) { + const RiscvRpmiServiceOps *ops =3D &riscv_rpmi_service_ops[i]; + + if (ops->configure && riscv_rpmi_service_enabled(s, ops->kind)) { + ops->configure(s, cfg); + } + } +} + static void riscv_rpmi_configure_base(RiscvRpmiState *s, const RiscvRpmiConfig *cfg) { @@ -187,6 +230,8 @@ static void riscv_rpmi_configure_base(RiscvRpmiState *s, cfg->hart_count * sizeof(*cfg->hart_id= s)); } } + + riscv_rpmi_configure_services(s, cfg); } =20 static void riscv_rpmi_init(Object *obj) @@ -209,6 +254,7 @@ static void riscv_rpmi_reset(DeviceState *dev) memory_region_set_dirty(&s->shmem, 0, s->shmem_size); } =20 + riscv_rpmi_hsm_reset(s); } =20 static void riscv_rpmi_cleanup(RiscvRpmiState *s) diff --git a/hw/misc/riscv_rpmi_hsm.c b/hw/misc/riscv_rpmi_hsm.c new file mode 100644 index 0000000000..9a9859b10c --- /dev/null +++ b/hw/misc/riscv_rpmi_hsm.c @@ -0,0 +1,280 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI HSM service. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "riscv_rpmi_internal.h" +#include "hw/core/cpu.h" +#include "librpmi_env.h" + +static const struct rpmi_hsm_suspend_type riscv_rpmi_hsm_suspend_types[] = =3D { + { + .type =3D 0, + .info =3D { + .flags =3D 0, + .entry_latency_us =3D 0, + .exit_latency_us =3D 0, + .wakeup_latency_us =3D 0, + .min_residency_us =3D 0, + }, + }, +}; + +typedef struct RiscvRpmiHsmStateTransition { + enum rpmi_hart_hw_state state; + bool halted; + bool resume; +} RiscvRpmiHsmStateTransition; + +static const RiscvRpmiHsmStateTransition riscv_rpmi_hsm_state_transitions[= ] =3D { + { + .state =3D RPMI_HART_HW_STATE_STARTED, + .halted =3D false, + .resume =3D true, + }, { + .state =3D RPMI_HART_HW_STATE_STOPPED, + .halted =3D true, + .resume =3D false, + }, { + .state =3D RPMI_HART_HW_STATE_SUSPENDED, + .halted =3D true, + .resume =3D false, + }, +}; + +static const RiscvRpmiHsmStateTransition *riscv_rpmi_hsm_state_transition( + enum rpmi_hart_hw_state state) +{ + for (uint32_t index =3D 0; + index < ARRAY_SIZE(riscv_rpmi_hsm_state_transitions); index++) { + if (riscv_rpmi_hsm_state_transitions[index].state =3D=3D state) { + return &riscv_rpmi_hsm_state_transitions[index]; + } + } + + return NULL; +} + +static CPUState *riscv_rpmi_hart_cpu(RiscvRpmiState *s, uint32_t hart_inde= x) +{ + if (hart_index >=3D s->hart_count || !s->hart_ids) { + return NULL; + } + + return cpu_by_arch_id(s->hart_ids[hart_index]); +} + +static void riscv_rpmi_hsm_set_hw_state(RiscvRpmiState *s, + uint32_t hart_index, + enum rpmi_hart_hw_state state) +{ + CPUState *cpu =3D riscv_rpmi_hart_cpu(s, hart_index); + const RiscvRpmiHsmStateTransition *transition; + + if (hart_index >=3D s->hart_count || !s->hsm_hw_states) { + return; + } + + s->hsm_hw_states[hart_index] =3D state; + if (!cpu) { + return; + } + + transition =3D riscv_rpmi_hsm_state_transition(state); + if (!transition) { + return; + } + + cpu->halted =3D transition->halted; + if (transition->resume) { + cpu_resume(cpu); + } else { + qemu_cpu_kick(cpu); + } +} + +static enum rpmi_error riscv_rpmi_hsm_start_prepare( + void *priv, rpmi_uint32_t hart_index, rpmi_uint64_t start_addr) +{ + RiscvRpmiState *s =3D priv; + CPUState *cpu =3D riscv_rpmi_hart_cpu(s, hart_index); + + if (!cpu) { + return RPMI_ERR_INVALID_PARAM; + } + + riscv_rpmi_hsm_set_hw_state(s, hart_index, RPMI_HART_HW_STATE_STARTED); + return RPMI_SUCCESS; +} + +static void riscv_rpmi_hsm_start_finalize(void *priv, + rpmi_uint32_t hart_index, + rpmi_uint64_t start_addr) +{ +} + +static enum rpmi_error riscv_rpmi_hsm_stop_prepare(void *priv, + rpmi_uint32_t hart_inde= x) +{ + RiscvRpmiState *s =3D priv; + + if (!riscv_rpmi_hart_cpu(s, hart_index)) { + return RPMI_ERR_INVALID_PARAM; + } + + riscv_rpmi_hsm_set_hw_state(s, hart_index, RPMI_HART_HW_STATE_STOPPED); + return RPMI_SUCCESS; +} + +static void riscv_rpmi_hsm_stop_finalize(void *priv, rpmi_uint32_t hart_in= dex) +{ +} + +static enum rpmi_error riscv_rpmi_hsm_suspend_prepare( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_hsm_suspend_type *suspend_type, + rpmi_uint64_t resume_addr) +{ + RiscvRpmiState *s =3D priv; + + if (!suspend_type || !riscv_rpmi_hart_cpu(s, hart_index)) { + return RPMI_ERR_INVALID_PARAM; + } + + riscv_rpmi_hsm_set_hw_state(s, hart_index, RPMI_HART_HW_STATE_SUSPENDE= D); + return RPMI_SUCCESS; +} + +static void riscv_rpmi_hsm_suspend_finalize( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_hsm_suspend_type *suspend_type, + rpmi_uint64_t resume_addr) +{ +} + +static enum rpmi_hart_hw_state riscv_rpmi_hsm_get_hw_state( + void *priv, rpmi_uint32_t hart_index) +{ + RiscvRpmiState *s =3D priv; + + if (hart_index >=3D s->hart_count || !s->hsm_hw_states) { + return RPMI_HART_HW_STATE_STOPPED; + } + + return s->hsm_hw_states[hart_index]; +} + +static const struct rpmi_hsm_platform_ops riscv_rpmi_hsm_ops =3D { + .hart_get_hw_state =3D riscv_rpmi_hsm_get_hw_state, + .hart_start_prepare =3D riscv_rpmi_hsm_start_prepare, + .hart_start_finalize =3D riscv_rpmi_hsm_start_finalize, + .hart_stop_prepare =3D riscv_rpmi_hsm_stop_prepare, + .hart_stop_finalize =3D riscv_rpmi_hsm_stop_finalize, + .hart_suspend_prepare =3D riscv_rpmi_hsm_suspend_prepare, + .hart_suspend_finalize =3D riscv_rpmi_hsm_suspend_finalize, +}; + +static bool riscv_rpmi_hsm_create(RiscvRpmiState *s, + struct rpmi_service_group **group, + Error **errp) +{ + struct rpmi_hsm *hsm; + + if (!s->hart_count || !s->hart_ids) { + error_setg(errp, "RPMI HSM service requires hart IDs"); + return false; + } + + s->hsm_hw_states =3D g_new0(uint32_t, s->hart_count); + for (uint32_t i =3D 0; i < s->hart_count; i++) { + s->hsm_hw_states[i] =3D RPMI_HART_HW_STATE_STARTED; + } + + hsm =3D rpmi_hsm_create(s->hart_count, s->hart_ids, + ARRAY_SIZE(riscv_rpmi_hsm_suspend_types), + riscv_rpmi_hsm_suspend_types, + &riscv_rpmi_hsm_ops, s); + if (!hsm) { + g_clear_pointer(&s->hsm_hw_states, g_free); + error_setg(errp, "failed to create RPMI HSM context"); + return false; + } + + *group =3D rpmi_service_group_hsm_create(hsm); + if (!*group) { + rpmi_hsm_destroy(hsm); + g_clear_pointer(&s->hsm_hw_states, g_free); + error_setg(errp, "failed to create RPMI HSM service group"); + return false; + } + + s->hsm =3D hsm; + return true; +} + +static void riscv_rpmi_hsm_destroy(RiscvRpmiState *s) +{ + if (s->hsm_group) { + rpmi_env_free_lock(s->hsm_group->lock); + s->hsm_group->lock =3D NULL; + rpmi_service_group_hsm_destroy(s->hsm_group); + s->hsm_group =3D NULL; + } + + if (s->hsm) { + rpmi_hsm_destroy(s->hsm); + s->hsm =3D NULL; + } + + g_clear_pointer(&s->hsm_hw_states, g_free); +} + + +bool riscv_rpmi_hsm_add(RiscvRpmiState *s, Error **errp) +{ + struct rpmi_service_group *group; + + if (s->hsm_group) { + error_setg(errp, "duplicate RPMI HSM service descriptor"); + return false; + } + + if (!riscv_rpmi_hsm_create(s, &group, errp)) { + return false; + } + + if (!riscv_rpmi_context_add_group(s, group, "HSM", errp)) { + s->hsm_group =3D group; + riscv_rpmi_hsm_destroy(s); + return false; + } + + s->hsm_group =3D group; + return true; +} + +void riscv_rpmi_hsm_remove(RiscvRpmiState *s) +{ + riscv_rpmi_context_remove_group(s, s->hsm_group); + riscv_rpmi_hsm_destroy(s); +} + +void riscv_rpmi_hsm_reset(RiscvRpmiState *s) +{ + if (!s->hsm_hw_states) { + return; + } + + for (uint32_t i =3D 0; i < s->hart_count; i++) { + s->hsm_hw_states[i] =3D RPMI_HART_HW_STATE_STARTED; + } + if (s->hsm) { + rpmi_hsm_process_state_changes(s->hsm); + } +} diff --git a/hw/misc/riscv_rpmi_internal.h b/hw/misc/riscv_rpmi_internal.h index fe09804e69..42a6708907 100644 --- a/hw/misc/riscv_rpmi_internal.h +++ b/hw/misc/riscv_rpmi_internal.h @@ -30,4 +30,8 @@ void riscv_rpmi_context_remove_group(RiscvRpmiState *s, bool riscv_rpmi_sysreset_add(RiscvRpmiState *s, Error **errp); void riscv_rpmi_sysreset_remove(RiscvRpmiState *s); =20 +bool riscv_rpmi_hsm_add(RiscvRpmiState *s, Error **errp); +void riscv_rpmi_hsm_remove(RiscvRpmiState *s); +void riscv_rpmi_hsm_reset(RiscvRpmiState *s); + #endif diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 273a9aa04f..2b5f367bdb 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1014,6 +1014,12 @@ static const RiscvRpmiServiceConfig virt_rpmi_servic= es[] =3D { .compatible =3D "riscv,rpmi-system-reset", .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_RESET, }, + { + .kind =3D RISCV_RPMI_SERVICE_HSM, + .node_name =3D "hsm", + .compatible =3D "riscv,rpmi-hsm", + .service_group =3D RISCV_RPMI_SRVGRP_HSM, + }, }; =20 static uint32_t virt_rpmi_service_count(RISCVVirtState *s) diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h index d11db87731..37c56ea2e8 100644 --- a/include/hw/misc/riscv_rpmi.h +++ b/include/hw/misc/riscv_rpmi.h @@ -28,6 +28,7 @@ #define VIRT_RPMI_P2A_REQ_SIZE 0 =20 #define RISCV_RPMI_SRVGRP_SYSTEM_RESET 3 +#define RISCV_RPMI_SRVGRP_HSM 5 =20 #define TYPE_RISCV_RPMI "riscv-rpmi" OBJECT_DECLARE_SIMPLE_TYPE(RiscvRpmiState, RISCV_RPMI) @@ -36,10 +37,12 @@ struct rpmi_context; struct rpmi_service_group; struct rpmi_shmem; struct rpmi_transport; +struct rpmi_hsm; =20 typedef enum RiscvRpmiServiceKind { RISCV_RPMI_SERVICE_INVALID =3D 0, RISCV_RPMI_SERVICE_SYSRESET, + RISCV_RPMI_SERVICE_HSM, } RiscvRpmiServiceKind; =20 typedef struct RiscvRpmiMachineOps { @@ -83,6 +86,9 @@ struct RiscvRpmiState { const RiscvRpmiMachineOps *machine_ops; void *machine_opaque; struct rpmi_service_group *sysreset_group; + struct rpmi_hsm *hsm; + struct rpmi_service_group *hsm_group; + uint32_t *hsm_hw_states; uint32_t *hart_ids; uint32_t hart_count; const RiscvRpmiServiceConfig *services; --=20 2.43.0 From nobody Sun Jul 12 00:33:30 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=1783686175; cv=none; d=zohomail.com; s=zohoarc; b=WmVnWxhatraPIjOMqYO0ojBXRyO2U3Dec9ay9JoDir+1PmqV+XO+tjYo0SSt0+nPg8VRTXNjhpGoR2B1pFRgSoPMlo3PSPdwBQyWfry9H4BXLHlFV8xmeS1h1hX4KG156OYl0zWv0xECxRMkjr3L5IF/hSnxz2/wCC3lG8PB5O0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686175; 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=qFuBB0Bw7YStlxeNVzx+8nAmHvyJXWpNlRBHLBri/AU=; b=m1GZglEhBl4WEf48EzRArkGKry/FU1SbbtTapzj4xu5BK1YH+7wtiV4O1exgrS44qSAybGoWZzaBCIqdrXpv3SDU89kTD+irp2At4SaZBEYnI11+3relO5MQVpUL5mu/PEC+abbxxENYOmFfUQn4CEs8aD5gvkADjL6H7ktcq3c= 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 178368617529217.870474740488476; Fri, 10 Jul 2026 05:22:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEc-0006VY-Nr; Fri, 10 Jul 2026 08:21:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi6mo-0000ZQ-8r for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:42 -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 1wi6ml-0001tr-O7 for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:41 -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 66A7dcS6040916 for ; Fri, 10 Jul 2026 08:40:38 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 4faeg5kkr5-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 08:40:38 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-38459087607so333262a91.2 for ; Fri, 10 Jul 2026 01:40:38 -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-3118389d9bcsm29164925eec.20.2026.07.10.01.40.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 01:40:36 -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=qFuBB0Bw7YS tlxeNVzx+8nAmHvyJXWpNlRBHLBri/AU=; b=Eu0zYaPBH1x9Kkrn5SNUGigg6xP 73UcNwL862SPIaKBg+RPr37Ter6CunYiWdNkiEUTIIKTAYrRBne2FtWP+dV6av8E o72d7iukod6D5rFV41yzmeFELb6rB1Mg038pZ3iGzRiL2IXK/KBm3ocA5lILx+mS hUDUxYg837zjPra7Cbt9Hde5m07jcGw7soZvUReapH3FyJPEFu16XoOFv5pjjKCz 3+RDyFX2zzSQGDK6rUE5HUkR8CyGmes0CseJBEujtBPuWm3Y8zfMa1dfWX1mm/mH bB2iMC/nzijMPt4o/1gBTLyOv9Q/pauhw8y9zBTn2xfbkDzzy52zL3OwpRg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783672838; x=1784277638; 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=qFuBB0Bw7YStlxeNVzx+8nAmHvyJXWpNlRBHLBri/AU=; b=QI4J+RCiUmdK2ld1jocj+RX4zKYv//ez6x+LJVlRm9mSD6G4r3fs/2drlffaMRDbfU RjlJzAdUQdcffWd6TRuoIl4mrLznzsTBAXwBMy7Wg1y6tyVU07b3QMiLeWyB2uHS9Tn8 09WAZT5aToVl4x+sqXurudn30C5Pa11UrvBOak8wJnI290FHF61pZg5Yzvwda7OaJBDg mnCowHBQd/VrG/Fc76EGBwVM3Mo81V1Aoqc4qnkinwtEb94KGFfT7jx+lqw0egTMpfGL hKkOpoPpULMLrldqmmJ77myZ5gUc7iHQNJ63wxGchMUHk5q84HEqLS0Z28SBFYmt23CP 4dng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783672838; x=1784277638; 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=qFuBB0Bw7YStlxeNVzx+8nAmHvyJXWpNlRBHLBri/AU=; b=SuFk04vWUSvwUhTEG2eNTI12r8osSzLEJfMJF4cioCktIf+nrYYmHERwIf19qanOST Uz3hDb8D9yFYIAFecqHaHwFiWX0bl1tmBsYblG9y5J4yK9Tvclbkf75Bzbt91gicXI61 3Fqf+lphD3UWRSnajxyyUjVXRYVhQ+QWzdZntJeXcI2+vy3Zkol4Eb2NuK58HleHtt+3 ujiBeTV/ymTxut07Y538/DqACIP8k4HiLidh1MSsbgIosdclHf6gYS3u2KGeZbV/R7s0 SX+ONt62lRrgLAP6Wn2v/44jB5mNnyU7NtEUY/MHQRP/2LorZAUXwMIAEbE86orveeZS /nSg== X-Gm-Message-State: AOJu0Yz82CQUirl16dOq7S43e9+TcmApLlfH1DZ09uHLaFuVIvRnTKWj TJrMN5bgfT9h54UOusN2GJKr/pmjkGarGMM3xy9EiTAGUXPYotHB/cRYwCWr5wlfDHrgBYVw162 KFKlVZrDR/wDSuDCGHmBYjHU1YGPlrPtB9T4QG0HQnJ4cw4dkcHlpe2+u2Q== X-Gm-Gg: AfdE7cm9HlbOg7YykGtokX+IpZ4iAw5GOCL4bfrKHDPLX66N5tia4tYjcJ9HTRunZEs oinJ64qkqW7RDRB/e8K78Io051ZLCJbDxfGIb6lk1kNR5cGgRpPmy0g/H5K/ka3KZlonlH13fxF ZTiYuXKw22Xz8ee22G1GeOQqr9Qo02Vfy8pdnAHDvoaJpuR+j47eM71ABh8nCJ5qnxz86QSxEqe IL9y0z8WV1IX96Olvu9HbChQw+tWLXYNKm3mYTVZJFZTEHVDWJ7Xa1/jF3IW3oXRoJPcPG4zsPE E5Jk7ui30O1WG/Ulq1xSU7A9H36NvxLOHRY4z1gAF368iTsEqtlYzC4rgza5yM/84Hfs5ykDlWm p3kFDTkledpaScql1IOeBWimmsBcnv7QsIShdgu/YQN6ZbxhKCgrDpP7IDwyuD04QM9WN6g3Tl1 8PC+FLdw+gglnK5RsUDM1pqnLttllu7nI4YmERaBF0iQ== X-Received: by 2002:a17:90a:bf17:b0:38d:90c1:2485 with SMTP id 98e67ed59e1d1-38d90c136bamr750906a91.5.1783672837496; Fri, 10 Jul 2026 01:40:37 -0700 (PDT) X-Received: by 2002:a17:90a:bf17:b0:38d:90c1:2485 with SMTP id 98e67ed59e1d1-38d90c136bamr750877a91.5.1783672836674; Fri, 10 Jul 2026 01:40:36 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-riscv@nongnu.org Cc: qemu-devel@nongnu.org, daniel.barboza@oss.qualcomm.com, Subrahmanya Lingappa Subject: [PATCH v2 07/10] riscv: add RPMI system suspend service Date: Fri, 10 Jul 2026 14:09:49 +0530 Message-ID: <1362f2b24fc65169cf916bd3be4ef107f8d0c000.1783660209.git.subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Authority-Analysis: v=2.4 cv=FN8rAeos c=1 sm=1 tr=0 ts=6a50b006 cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=YpNgDGc-obDsCk2VH-MA:9 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA4MyBTYWx0ZWRfX60Hcq/KhrDtX yn6KoH92EAY0qjrtiYpXZ01kun/VyDTssCTKt3322g4/bh3B2ex4TLBkjWS05ZxscDw+B2jNzbf i8AHep4X38bCKHTbnxPVZBfca8X3i3E= X-Proofpoint-ORIG-GUID: BwXuHwqMYtmH_5QXn10qp1uqo6salZIC X-Proofpoint-GUID: BwXuHwqMYtmH_5QXn10qp1uqo6salZIC X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA4MyBTYWx0ZWRfX/I+2p2Ji7mEg D6vCQi6qhNPFLNCuj9Y8qrp3zzsqh6MbzGt5e6U8DARvSYfAMSogquU/ZsBvMymqVXHDSP3+ZP2 zTFchngLQolh8AEuO/AO1pXFyxAvwsI43er4aAWAoq9f675A+wILad7gdji53RISqUbD2rVrZyY r4hlcgX9VGtVcV4EmxmKhLKbhi4cEaCWb8Kflt7s0b1B78g8MsBpaGneelVfRRxHlFkXKjT8nsA 7TyBYIxEOcc6AN0bZVLUtEzHb0rfycnakVQ5GTbf58m8db/0H6k73RetyUDG1Q/Sxdf9ZFnsH36 +yv0LMTpMJkxfblXWOdYsybzosEubdSxxRqJ29pKj6E8+DBKAXnfRHq6i3Hxwqof4Wa7IF0nIw3 ZvEnA6Pf9DgjHF42i+dJkyoGKcpd+ZiB7FUTSeenRaUnhD8DUn6j7opzKXJYGoE1Qa9UQkjWYhe Bjh48lHNUfroQm7SMiw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_02,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 suspectscore=0 phishscore=0 clxscore=1015 impostorscore=0 spamscore=0 priorityscore=1501 lowpriorityscore=0 adultscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100083 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=205.220.168.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0a-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686176193158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add the RPMI System Suspend service group for RISC-V virt. The service advertises suspend-to-RAM support through librpmi, registers QEMU wakeup support, and routes the suspend finalize callback to the machine suspend path. On wakeup it processes RPMI group events and defers the HSM hart resume until vCPUs are ready to run again. Signed-off-by: Subrahmanya Lingappa --- hw/misc/meson.build | 1 + hw/misc/riscv_rpmi.c | 4 + hw/misc/riscv_rpmi_hsm.c | 9 +- hw/misc/riscv_rpmi_internal.h | 5 + hw/misc/riscv_rpmi_syssusp.c | 191 ++++++++++++++++++++++++++++++++++ hw/riscv/virt.c | 25 +++++ include/hw/misc/riscv_rpmi.h | 11 ++ 7 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 hw/misc/riscv_rpmi_syssusp.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index fc5b11ed57..cb093a8642 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -172,4 +172,5 @@ system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [file= s( 'riscv_rpmi.c', 'riscv_rpmi_sysreset.c', 'riscv_rpmi_hsm.c', + 'riscv_rpmi_syssusp.c', ), librpmi]) diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c index 820b1d5d63..08691861b0 100644 --- a/hw/misc/riscv_rpmi.c +++ b/hw/misc/riscv_rpmi.c @@ -187,6 +187,10 @@ static const RiscvRpmiServiceOps riscv_rpmi_service_op= s[] =3D { .kind =3D RISCV_RPMI_SERVICE_HSM, .add =3D riscv_rpmi_hsm_add, .remove =3D riscv_rpmi_hsm_remove, + }, { + .kind =3D RISCV_RPMI_SERVICE_SYSSUSP, + .add =3D riscv_rpmi_syssusp_add, + .remove =3D riscv_rpmi_syssusp_remove, }, }; =20 diff --git a/hw/misc/riscv_rpmi_hsm.c b/hw/misc/riscv_rpmi_hsm.c index 9a9859b10c..bacdabcac6 100644 --- a/hw/misc/riscv_rpmi_hsm.c +++ b/hw/misc/riscv_rpmi_hsm.c @@ -235,7 +235,6 @@ static void riscv_rpmi_hsm_destroy(RiscvRpmiState *s) g_clear_pointer(&s->hsm_hw_states, g_free); } =20 - bool riscv_rpmi_hsm_add(RiscvRpmiState *s, Error **errp) { struct rpmi_service_group *group; @@ -278,3 +277,11 @@ void riscv_rpmi_hsm_reset(RiscvRpmiState *s) rpmi_hsm_process_state_changes(s->hsm); } } + +void riscv_rpmi_hsm_resume(RiscvRpmiState *s, uint32_t hart_index) +{ + riscv_rpmi_hsm_set_hw_state(s, hart_index, RPMI_HART_HW_STATE_STARTED); + if (s->hsm) { + rpmi_hsm_process_state_changes(s->hsm); + } +} diff --git a/hw/misc/riscv_rpmi_internal.h b/hw/misc/riscv_rpmi_internal.h index 42a6708907..34cab35c32 100644 --- a/hw/misc/riscv_rpmi_internal.h +++ b/hw/misc/riscv_rpmi_internal.h @@ -33,5 +33,10 @@ void riscv_rpmi_sysreset_remove(RiscvRpmiState *s); bool riscv_rpmi_hsm_add(RiscvRpmiState *s, Error **errp); void riscv_rpmi_hsm_remove(RiscvRpmiState *s); void riscv_rpmi_hsm_reset(RiscvRpmiState *s); +void riscv_rpmi_hsm_resume(RiscvRpmiState *s, uint32_t hart_index); + +bool riscv_rpmi_syssusp_add(RiscvRpmiState *s, Error **errp); +void riscv_rpmi_syssusp_remove(RiscvRpmiState *s); + =20 #endif diff --git a/hw/misc/riscv_rpmi_syssusp.c b/hw/misc/riscv_rpmi_syssusp.c new file mode 100644 index 0000000000..d455e08163 --- /dev/null +++ b/hw/misc/riscv_rpmi_syssusp.c @@ -0,0 +1,191 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * RISC-V RPMI System Suspend service. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include "riscv_rpmi_internal.h" +#include "qemu/timer.h" +#include "system/runstate.h" + +static const struct rpmi_system_suspend_type riscv_rpmi_syssusp_types[] = =3D { + { + .type =3D RPMI_SYSSUSP_TYPE_SUSPEND_TO_RAM, + .attr =3D RPMI_SYSSUSP_ATTRS_FLAGS_RESUMEADDR, + }, +}; + +static enum rpmi_error riscv_rpmi_syssusp_prepare( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_system_suspend_type *syssusp_type, + rpmi_uint64_t resume_addr) +{ + RiscvRpmiState *s =3D priv; + + if (s->machine_ops && s->machine_ops->register_wakeup_support) { + s->machine_ops->register_wakeup_support(s->machine_opaque); + } + return RPMI_SUCCESS; +} + +static rpmi_bool_t riscv_rpmi_syssusp_ready(void *priv, + rpmi_uint32_t hart_index) +{ + return true; +} + +static void riscv_rpmi_syssusp_finalize( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_system_suspend_type *syssusp_type, + rpmi_uint64_t resume_addr) +{ + RiscvRpmiState *s =3D priv; + + if (s->machine_ops && s->machine_ops->system_suspend) { + s->machine_ops->system_suspend(s->machine_opaque); + } +} + +static rpmi_bool_t riscv_rpmi_syssusp_can_resume(void *priv, + rpmi_uint32_t hart_index) +{ + RiscvRpmiState *s =3D priv; + + if (s->machine_ops && s->machine_ops->system_can_resume) { + return s->machine_ops->system_can_resume(s->machine_opaque); + } + + return true; +} + +static enum rpmi_error riscv_rpmi_syssusp_resume( + void *priv, rpmi_uint32_t hart_index, + const struct rpmi_system_suspend_type *syssusp_type, + rpmi_uint64_t resume_addr) +{ + RiscvRpmiState *s =3D priv; + + s->syssusp_resume_hart_index =3D hart_index; + s->syssusp_resume_pending =3D true; + return RPMI_SUCCESS; +} + +static const struct rpmi_syssusp_platform_ops riscv_rpmi_syssusp_ops =3D { + .system_suspend_prepare =3D riscv_rpmi_syssusp_prepare, + .system_suspend_ready =3D riscv_rpmi_syssusp_ready, + .system_suspend_finalize =3D riscv_rpmi_syssusp_finalize, + .system_suspend_can_resume =3D riscv_rpmi_syssusp_can_resume, + .system_suspend_resume =3D riscv_rpmi_syssusp_resume, +}; + +static void riscv_rpmi_wakeup_timer(void *opaque) +{ + RiscvRpmiState *s =3D opaque; + + if (s->syssusp_resume_pending) { + riscv_rpmi_hsm_resume(s, s->syssusp_resume_hart_index); + s->syssusp_resume_pending =3D false; + } +} + +static void riscv_rpmi_wakeup_notify(Notifier *notifier, void *data) +{ + RiscvRpmiState *s =3D container_of(notifier, RiscvRpmiState, + wakeup_notifier); + + if (s->context) { + rpmi_context_process_group_events(s->context, + RPMI_SRVGRP_SYSTEM_SUSPEND); + } + if (s->wakeup_timer) { + /* + * Wakeup notifiers run before vCPUs resume. Defer the HSM + * kick so OpenSBI can leave WFI after QEMU restarts execution. + */ + timer_mod(s->wakeup_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) = + 10); + } +} + +static bool riscv_rpmi_syssusp_create(RiscvRpmiState *s, + struct rpmi_service_group **group, + Error **errp) +{ + if (!s->hsm) { + error_setg(errp, "RPMI system suspend service requires HSM service= "); + return false; + } + + if (s->machine_ops && s->machine_ops->register_wakeup_support) { + s->machine_ops->register_wakeup_support(s->machine_opaque); + } + if (!s->wakeup_timer) { + s->wakeup_timer =3D timer_new_ms(QEMU_CLOCK_REALTIME, + riscv_rpmi_wakeup_timer, s); + } + if (!s->wakeup_notifier_registered) { + s->wakeup_notifier.notify =3D riscv_rpmi_wakeup_notify; + qemu_register_wakeup_notifier(&s->wakeup_notifier); + s->wakeup_notifier_registered =3D true; + } + + *group =3D rpmi_service_group_syssusp_create( + s->hsm, ARRAY_SIZE(riscv_rpmi_syssusp_types), + riscv_rpmi_syssusp_types, &riscv_rpmi_syssusp_ops, s); + if (!*group) { + error_setg(errp, "failed to create RPMI system suspend service gro= up"); + return false; + } + + return true; +} + +static void riscv_rpmi_syssusp_destroy(RiscvRpmiState *s) +{ + if (s->wakeup_notifier_registered) { + notifier_remove(&s->wakeup_notifier); + s->wakeup_notifier_registered =3D false; + } + if (s->wakeup_timer) { + timer_free(s->wakeup_timer); + s->wakeup_timer =3D NULL; + } + + if (s->syssusp_group) { + rpmi_service_group_syssusp_destroy(s->syssusp_group); + s->syssusp_group =3D NULL; + } +} + +bool riscv_rpmi_syssusp_add(RiscvRpmiState *s, Error **errp) +{ + struct rpmi_service_group *group; + + if (s->syssusp_group) { + error_setg(errp, "duplicate RPMI system suspend descriptor"); + return false; + } + + if (!riscv_rpmi_syssusp_create(s, &group, errp)) { + return false; + } + + if (!riscv_rpmi_context_add_group(s, group, "system suspend", errp)) { + s->syssusp_group =3D group; + riscv_rpmi_syssusp_destroy(s); + return false; + } + + s->syssusp_group =3D group; + return true; +} + +void riscv_rpmi_syssusp_remove(RiscvRpmiState *s) +{ + riscv_rpmi_context_remove_group(s, s->syssusp_group); + riscv_rpmi_syssusp_destroy(s); +} diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 2b5f367bdb..21c218a78d 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -51,6 +51,7 @@ #include "chardev/char.h" #include "system/device_tree.h" #include "system/system.h" +#include "system/runstate.h" #include "system/tcg.h" #include "system/kvm.h" #include "system/tpm.h" @@ -1020,6 +1021,12 @@ static const RiscvRpmiServiceConfig virt_rpmi_servic= es[] =3D { .compatible =3D "riscv,rpmi-hsm", .service_group =3D RISCV_RPMI_SRVGRP_HSM, }, + { + .kind =3D RISCV_RPMI_SERVICE_SYSSUSP, + .node_name =3D "suspend", + .compatible =3D "riscv,rpmi-system-suspend", + .service_group =3D RISCV_RPMI_SRVGRP_SYSTEM_SUSPEND, + }, }; =20 static uint32_t virt_rpmi_service_count(RISCVVirtState *s) @@ -1037,9 +1044,27 @@ static void virt_rpmi_system_shutdown(void *opaque) qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } =20 +static void virt_rpmi_system_suspend(void *opaque) +{ + qemu_system_suspend_request(); +} + +static void virt_rpmi_register_wakeup_support(void *opaque) +{ + qemu_register_wakeup_support(); +} + +static bool virt_rpmi_system_can_resume(void *opaque) +{ + return runstate_check(RUN_STATE_RUNNING); +} + static const RiscvRpmiMachineOps virt_rpmi_machine_ops =3D { .system_reset =3D virt_rpmi_system_reset, .system_shutdown =3D virt_rpmi_system_shutdown, + .system_suspend =3D virt_rpmi_system_suspend, + .register_wakeup_support =3D virt_rpmi_register_wakeup_support, + .system_can_resume =3D virt_rpmi_system_can_resume, }; =20 static RiscvRpmiConfig virt_rpmi_config(RISCVVirtState *s, diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h index 37c56ea2e8..a4fe2aac63 100644 --- a/include/hw/misc/riscv_rpmi.h +++ b/include/hw/misc/riscv_rpmi.h @@ -29,6 +29,7 @@ =20 #define RISCV_RPMI_SRVGRP_SYSTEM_RESET 3 #define RISCV_RPMI_SRVGRP_HSM 5 +#define RISCV_RPMI_SRVGRP_SYSTEM_SUSPEND 4 =20 #define TYPE_RISCV_RPMI "riscv-rpmi" OBJECT_DECLARE_SIMPLE_TYPE(RiscvRpmiState, RISCV_RPMI) @@ -43,11 +44,15 @@ typedef enum RiscvRpmiServiceKind { RISCV_RPMI_SERVICE_INVALID =3D 0, RISCV_RPMI_SERVICE_SYSRESET, RISCV_RPMI_SERVICE_HSM, + RISCV_RPMI_SERVICE_SYSSUSP, } RiscvRpmiServiceKind; =20 typedef struct RiscvRpmiMachineOps { void (*system_reset)(void *opaque); void (*system_shutdown)(void *opaque); + void (*system_suspend)(void *opaque); + void (*register_wakeup_support)(void *opaque); + bool (*system_can_resume)(void *opaque); } RiscvRpmiMachineOps; typedef struct RiscvRpmiServiceConfig { RiscvRpmiServiceKind kind; @@ -86,9 +91,15 @@ struct RiscvRpmiState { const RiscvRpmiMachineOps *machine_ops; void *machine_opaque; struct rpmi_service_group *sysreset_group; + struct rpmi_service_group *syssusp_group; struct rpmi_hsm *hsm; struct rpmi_service_group *hsm_group; uint32_t *hsm_hw_states; + Notifier wakeup_notifier; + bool wakeup_notifier_registered; + QEMUTimer *wakeup_timer; + bool syssusp_resume_pending; + uint32_t syssusp_resume_hart_index; uint32_t *hart_ids; uint32_t hart_count; const RiscvRpmiServiceConfig *services; --=20 2.43.0 From nobody Sun Jul 12 00:33:30 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=1783686114; cv=none; d=zohomail.com; s=zohoarc; b=Nql4F+H1U9Cwi0OiG6Jg3SuyZ2+BjLr0WMW17id/T4LAetACfcYQXfiYPXZflK1LqFiXRsEmmrooJa5X2hVLMHY3HTf+lsCCuKknLfkdNL3aFDTRaWgpo7ybNFpUITmdiI6XotrNKosB/qkn20V7oRzEawJu6VU7PKC1JcGpGs8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686114; h=Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To:Cc; bh=xfihhQahT18tqw16GN07qOdNHK6O56x78Dza3ykZ+F8=; b=PKRJrKHmiQSZ6HKtNuy0K4T1FaibywjcZhmGzzNMC0pPzCHXjs3ADcAZuQpbhDV0B7GE5SW0aIraAi4MSYaq/AsXaWFYw2ZW7GcsKQcRE2LLIpNJ2wJvUoDOihL3Ecyp9AV6slGjtIykzMriWDYCBy2veteM91X6VJhe1d3yfDU= 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 1783686114577590.1963902781633; Fri, 10 Jul 2026 05:21:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAEf-0006Vg-8U; Fri, 10 Jul 2026 08:21:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi41V-0002Oy-MY for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:43:44 -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 1wi41U-0007rH-1J for qemu-devel@nongnu.org; Fri, 10 Jul 2026 01:43:41 -0400 Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A3n3V73661712 for ; Fri, 10 Jul 2026 05:43:39 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 4faf24trhv-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 05:43:38 +0000 (GMT) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-2ce756aa72eso2997045ad.1 for ; Thu, 09 Jul 2026 22:43:38 -0700 (PDT) Received: from hu-slingapp-blr.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com. [103.229.18.19]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13b659c865asm39112785c88.11.2026.07.09.22.43.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2026 22:43:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=xfihhQahT18 tqw16GN07qOdNHK6O56x78Dza3ykZ+F8=; b=Dpwn2P44Uo774Wpu4GHXkr5ieWD DG3i7SqKtf5NKUl0+j3Kex7hOiYo21WKUL4TPwvZ+PyStJJIbSfUfDtXSVAvkbj4 nnGpEeVGcVJmAR/AmdEx4epfeH/61LZa2CbbWpRtNc2B1gFtk9rVH3X0/iA6gG0h lrEMOE3MOx67XITli3mgZNce7rqEGT5lg+hrkUA88BUzCgxD2JKjQlYLLqJFf0Gh Tu+832K48ZlLKB7uf6wcYKnDrkL2ugR/F+kfecAMcO/OcNAVVAY+NVB+Rj3mwe7A ODiqqwUgrYkXUnbuj3GWwdFSy/IP8wIIPiw0C3VWsC+EdeVNfGNUqc1QIKQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783662218; x=1784267018; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=xfihhQahT18tqw16GN07qOdNHK6O56x78Dza3ykZ+F8=; b=OFcwey6EaOCv3sae5y4roli7y2bCNPCbeQYpsYeWepRr63+9WvTtAbW7bX5ygcrVQB ZcBkjhYRq43qdcIoWUNdtbfjuHFQBXjKtXwCe3aBln+mrGC3lRjJTW/rowIPK56VecT+ zXHppUzO4otNLO3FT74w8Q5hM7ZNgA3GhhfDfF0JDk9rZ2Lk9HwUuWfZy+jq6ZPdrOSf jwak7MT7LDx1HC9bZhM2OxKvmTylxUR5W2akm/HpmxYS7mynCnP5rxXpa7XD/gowZvKC G1Db7YI/yyLxmTsBrOOtjBZOA53rG4yxcf7ysvsqMl9rtLqzcB2YD2kHPIgYAtpm/RIn RH7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783662218; x=1784267018; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=xfihhQahT18tqw16GN07qOdNHK6O56x78Dza3ykZ+F8=; b=KS2gekigxTcPoc2ssc8xO55B32cCKh8l/CeSpikR28wZLhsdEBqixl/Sf15icYBdvo AI6YiYqJUI6zzAF6korm/YtaMIzYZCeN+C7RX1MYkc6OkZlwz34U71pSjyK/ZgLe45vJ h+TM8AqxM9j40Lz0ooBOK7SN5rsYSxRz4CqVgp7fEcTcCcbXpaJVKjSnx+53JP/ggzfc fRI3vyx5faYxRf7LcUnUije6ND+BsfWUMvP3btTWo5GsWV43+zn1FFl653NliyxudahF g5NUDC2GDJ/88ENyY8wn7igUVi7EoD/xfDUOfzPIUqRIupnCjGUH2PHB73bkqms2YRxS wVsA== X-Gm-Message-State: AOJu0YzKJTyBp+WrKFc4hS2P0dRl4txyyNYHkJ182lcdPlGtAsSsx/ok 0GaYz9n5HmItXSaefpTRKailSD5g4Z73936aKIwIKbhwsKSbLpOCvCyNsio7zK4sSuG+FlNwkaP 5sSdBjCd+4+rmh/EzrtsxaSfLiMNthbs3E97PHUvB12r5OYDLVIklNlisMDN9NGguPw== X-Gm-Gg: AfdE7cm1yV2RRXuDfPjDeTm7E3YTE6gZtjF1630lbtiKVwKZi/ijv6pz3wzBYnURMj0 S3jCTWxjIO8RE/ZpLHi+pxkWYxDQOEeVGpGeG3Vf0kkIGrB2Ot56DmC0VV03EVz/0MGf9DRbes6 7QxMf0vbY64YY2LKoJMRfJSz/A+4aYWdr+QY5Y1P6Nw3S2Bnaa5VbZzEPpbzp6mLh802xMVNnTr I8a+X8g2dEPuUQ2iGPSb9N83iFzHvm1sRgpvAEpvFXqS21vM7Sg6V0qULB3G2zkKJ8hZcXc9RY3 M2Vto6+PTCelGs4CLr2Km4qvYJoSFeQ1pIsApu/kphQ93Q5EcxhZuwJiTZq66Gb8wQhBWmzSd0w fljNPXZGt2po+op4uZogkdk1v8cU/JKhUgrM82tsBQjkWwwDDv97JCGy0A9CPn8SptceR1isSOe WgIexPFes+OQIi7EcEfy1xlUoF9Pi5tUjqYuW5Yh3X9Q== X-Received: by 2002:a17:902:d50e:b0:2cc:df15:91e2 with SMTP id d9443c01a7336-2ccff2e48eamr59417075ad.7.1783662218025; Thu, 09 Jul 2026 22:43:38 -0700 (PDT) X-Received: by 2002:a17:902:d50e:b0:2cc:df15:91e2 with SMTP id d9443c01a7336-2ccff2e48eamr59416795ad.7.1783662217240; Thu, 09 Jul 2026 22:43:37 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-devel@nongnu.org Subject: [PATCH v2 08/10] docs/system/riscv: document initial virt RPMI support Date: Fri, 10 Jul 2026 11:13:16 +0530 Message-ID: <10f13dfad6528556a3bb4aa077aca8c38e34bc24.1783660209.git.subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: brZgmet8YpLXKIibQQi0Lv2lpCVx-J6G X-Proofpoint-ORIG-GUID: brZgmet8YpLXKIibQQi0Lv2lpCVx-J6G X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA1MiBTYWx0ZWRfX//7JbKWtsIJC 3rZ7uQehNHnRAEhvAluizYFMLJGM23bdlBeWL4ZhMSkz/MaOKnaDk0MXfCB5toSM0gL31By01y5 ewM7S60cCjnz/O2r5EFUoTGdRNFPGBc= X-Authority-Analysis: v=2.4 cv=daKwG3Xe c=1 sm=1 tr=0 ts=6a50868b cx=c_pps a=IZJwPbhc+fLeJZngyXXI0A==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yx91gb_oNiZeI1HMLzn7:22 a=V1jnuoLLAAAA:20 a=NEAV23lmAAAA:8 a=EUspDBNiAAAA:8 a=RyhCfiGMEKD-kOZgqhYA:9 a=uG9DUKGECoFWVXl0Dc02:22 a=bA3UWDv6hWIuX7UZL3qL:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA1MiBTYWx0ZWRfX2Xpwg+iMm2Az huKE2hUU242VSItBdkOPttFs8dFBLG4kokt63eXuNawX+VJMLrKUYjfmd+cJv1yjxbyQ+Qwz7KW PWCsPmuu3yFukC70N01GWc2bopEa3BO4v1BLy66MwIXewjeOT4SkzIQV00aY1FLoOkEaGLAYyoy XYhN+2YyBp0V6roXlhh5njq07Wj9zg6WU+wf32jRD72QkztX4ulgUqtVnolV958sKKiIvqt4Tjq eSeZUF9qrYL2p7vpMSqZDptlDw+JhEp6qoioLHpzYmHD6XSnO7shNiLZ+jyF+ZM55Fc8jOQeK9q UnxotJKQentcU97UXP228XBgIgvKI8mKdr7QtTuqEkkRsFmY9HCv9JgJt8Kpl9f21l00JIhH0x4 GKdzxFkC6pu4/8SS9YE6j7HFHNG21dmve79bdmpgKQktlZYgj5ui/zYqNGwWeMb+BBtcfoK//E/ InEBVxmu6LWcyjGsNWg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_01,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 bulkscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100052 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=205.220.180.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0b-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686116160158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Document the opt-in virt RPMI transport and the initial HSM, system reset, and system suspend service groups. Signed-off-by: Subrahmanya Lingappa --- docs/system/riscv/virt.rst | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst index 60850970ce..8e88f780e1 100644 --- a/docs/system/riscv/virt.rst +++ b/docs/system/riscv/virt.rst @@ -146,6 +146,56 @@ The following machine-specific options are supported: =20 Enables the riscv-iommu-sys platform device. Defaults to 'off'. =20 +- rpmi=3D[on|off] + + Enables the RISC-V RPMI shared-memory transport. This option defaults to + "off", is TCG-only, and is available only when QEMU is built with librpmi + support. This support targets the RISC-V Platform Management Interface + (RPMI) Specification v1.0 Ratified (`RPMI v1.0 specification`_). The ini= tial + ``virt`` implementation exposes RPMI system reset, system suspend, and H= SM + service groups. System reset can request shutdown or cold reboot through + RPMI. HSM uses the ``virt`` hart IDs and supports hart discovery, status, + start, stop, and suspend commands. System suspend uses QEMU's suspend and + wakeup path. Migration is currently blocked while RPMI transport and ser= vice + VMState support is being designed. + + The build dependency is provided by `librpmi`_. Install librpmi so that + ``pkg-config`` can find ``librpmi.pc``, then configure QEMU with + ``--enable-librpmi`` or ``-Dlibrpmi=3Denabled``. + +.. _RPMI v1.0 specification: https://github.com/riscv-non-isa/riscv-rpmi/r= eleases/download/v1.0/riscv-rpmi.pdf +.. _librpmi: https://github.com/riscv-software-src/librpmi + +RPMI firmware and guest smoke +----------------------------- + +A firmware-level RPMI smoke test can be run with OpenSBI, a Linux kernel, = and a +RISC-V disk image: + +.. code-block:: bash + + $ qemu-system-riscv64 \ + -machine virt,rpmi=3Don \ + -cpu rv64 -smp 4 -m 4G -nographic \ + -bios /path/to/fw_jump.bin \ + -kernel /path/to/Image \ + -append "root=3D/dev/vda rw console=3DttyS0 earlycon=3Dsbi" \ + -drive file=3D/path/to/rootfs.img,format=3Draw,if=3Dvirtio,snapshot= =3Don + +The OpenSBI banner should report RPMI-backed HSM and system suspend suppor= t. +After the guest reaches a shell, normal guest reboot/poweroff commands exe= rcise +the RPMI system reset path. + +RPMI device tree policy +----------------------- + +RPMI is currently described through FDT only; no ACPI representation is em= itted +for the RPMI transport or service groups. The ``virt`` machine uses the +``riscv,rpmi-shmem-mbox`` shared-memory mailbox node plus child service no= des +with ``riscv,rpmi-*`` compatible strings. These binding names are part of = the +RPMI RFC surface and may be revised if the RISC-V RPMI bindings change dur= ing +review. + Running Linux kernel -------------------- =20 --=20 2.43.0 From nobody Sun Jul 12 00:33:30 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=1783686307; cv=none; d=zohomail.com; s=zohoarc; b=cMNxrAZNqLKERG6Qlha1ttCrsMYVS/Yqr3undV7PjdO+yr6SfPWG+IpReTzjkrpGwWG6U3zVJT3IhmAw3tgUIf9KN5eUX/aFrvhCKBZgO+sh0qe3z5pUWQpmvPxOrO1d89Eh4egptegsSTBF+Wq9IApZl21CmXTD4lS4smvDXpc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686307; 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=1nWYXrdaRGgmzKTlI0JBf/sTB+3hoQ2csXo3y6J6ACs=; b=mshxLmY7MHyXASK+pd9Prf5OdFm30ZaUprp9rsGBFskYMscQypziiutyzP0X177CuSg3aygjGq7jo+/0WwfHY2lJlhjf+Bljzi+lg2uWjS3GGqnxT3PPO2CrcQUYq36zFBKoTLYHp0iaa/yKnN11u11AsYW/VoAOp8Y+kuSz9t0= 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 1783686307775682.6987681007265; Fri, 10 Jul 2026 05:25:07 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAF4-0007Hb-9N; Fri, 10 Jul 2026 08:22: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 1wi6mu-0000du-TZ for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:48 -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 1wi6mr-0001x3-FH for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:48 -0400 Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66A7dWbF4194183 for ; Fri, 10 Jul 2026 08:40:44 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 4faf24udb3-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 08:40:44 +0000 (GMT) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-37fec882754so188124a91.3 for ; Fri, 10 Jul 2026 01:40:44 -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-3118389d9bcsm29164925eec.20.2026.07.10.01.40.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 01:40: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=1nWYXrdaRGg mzKTlI0JBf/sTB+3hoQ2csXo3y6J6ACs=; b=bPs9L8VBDyjR7TNSyHrqOJFz6jT CL1GYVnzkkNnxPGpV0JW3+zngSNT0rhQcwo7qtJZ9LoMnMN8KrDZ5/hy3+s/6pZx xk6cpM+kWvpVFuQyBiMHk+r2dxckuINb8v7TtOoxAJq2W2JupGNMR9chKm/NrD5k ikiLYl6uNbnH3RJjYCI8pPg84/i2r2J+uT7IEEe6kdEgmx88ZHtYpC+9bFqLmBTE 2wXd+wuWN3kIJkTWHBUE1InuouwMCmGXl9biaSxJv3XIuLYyVD+Kd/LxQtmYb9y9 E+KYGpsiQ3Jyj6E9Ood4judcPJzQDoYIdn4G7iy2Q5I3JWPA38BQnKQJzfg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783672843; x=1784277643; 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=1nWYXrdaRGgmzKTlI0JBf/sTB+3hoQ2csXo3y6J6ACs=; b=W2IUHfTWPPRXaBJ4fjbsXxNt60iGoz3SFL9qscGdhJm6hgQlUF1yyW5Uq0TlXk+WYd rGFI1hK8U0SSBEPPQ5NtLhomO4r3EFsIaDj8gYQchBP8uN6qrSuB/cm7O80GUYK1Xu0+ xqs0PiJOW34/0vrynD6XsuqWWiUToeewT7+svkoAHNvUxiqfxmx40VtTQhD+LsDS3fCp ik9HVzm4BGxPiSX995PDBCnCg5egE3DA1gasFBBBxKUoI9D8s1LCCS+IpYl7O6gg6SLA /nmKJO2Jht5rFHXzolzulgn4rFmYVpIwTqI1RgerbrLcqdT/tGNg8jh+67aEx1iMEH7A HNQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783672843; x=1784277643; 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=1nWYXrdaRGgmzKTlI0JBf/sTB+3hoQ2csXo3y6J6ACs=; b=X6oRcBelyWzCl+9QFCpKWQC19I9lOye1AqSiytTCWCtJeKfp6H/Hu1K6oeyFUcBB/j WdQeCIXji7N9zKzyaviD4eFw+Q6IxvruTiu+re2Wgd76bJu3yDCv0vmDzv0RGJ+J54n+ CXSIraHqeWF07ALXAYW7CTEpNb/h4lhIj2LHJ9POf8vua3zXs/NqD2Wfnie5D2Bk2ESr Pc7VWDHPfS5m+PVTn/7iADKDStElQ2XxTW7NoTM0T5ux9TRmxn4+jBOxOeUYbQsRdWZo 1AOUl/JKrNLCblncHteDrJ1caIqxr7WhLaznCcsaHmd10dVxa8+6ejh+6J6jGynCm0uP rRzQ== X-Gm-Message-State: AOJu0YyznhekwC8GvuiM6suc+rQ3qB3jxzJGffMqh034XtXOQRAS/RPn FYo+NN5WOqnCUfak9Y+UYvU9qEgN3dC1SlFMwxcqwrvJsx88hy9xTNjEvrgPBG29HxStfxzndHE z/mcUk09IFiUeYF/E7R6FdJnD+789xIWDdLxpx06hqtTQ0cMk+3FDqz91tg== X-Gm-Gg: AfdE7cn+KL5PvisIoQ4ATMyVnoiBT8oabEwDHZzL58d6yE88qRyyxbmaaKwwFplyTeS XtDQXt+C8S6YRyhqDvoWAXqGpSR30S772VWpq7iKX+8PnX4diUXi9VKvAurmMOnLmwlr2drAlWj vmqDXi17DjN9HJ+YQDcssGMn1jgQo5XCevFSCppkVWX/f2hMBrxB+v0zXOrwXlFKWprSj73zBJm VMibv61RtCpEP4WaEJDYN2NTmT4AMBGAU+yhnn2Toswi3z0rRS0pS7UXBotvD0xlW+R4+Ekel/1 I9H4F+oQe+kSmNcH1ne5VCj4npd91RgTQPagU0AdszlUEBSwfoBy+F7vkehLWs2sxDqbHu36dRv hB9ARIQoJbcyY1U7NL3W6isOXoxbDtxPIkjYsVQcDUU83tUnuPyrILefL6mnfpHZeUxlpwhjAf2 H3JA3CVeEGs+9IQSM8epw80mwfEehFeejiYM8+uhsdbg== X-Received: by 2002:a17:90b:3c05:b0:364:be8f:1d86 with SMTP id 98e67ed59e1d1-38a221c34f4mr6148109a91.8.1783672843233; Fri, 10 Jul 2026 01:40:43 -0700 (PDT) X-Received: by 2002:a17:90b:3c05:b0:364:be8f:1d86 with SMTP id 98e67ed59e1d1-38a221c34f4mr6148081a91.8.1783672842541; Fri, 10 Jul 2026 01:40:42 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-riscv@nongnu.org Cc: qemu-devel@nongnu.org, daniel.barboza@oss.qualcomm.com, Subrahmanya Lingappa Subject: [PATCH v2 09/10] tests/qtest: cover initial RISC-V RPMI services Date: Fri, 10 Jul 2026 14:09:51 +0530 Message-ID: <3ce559db08a853001115da730be724f76f95b802.1783660209.git.subrahmanya.lingappa@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: t5FNQV_MEv999t1Z7x0eycwvxjy92v15 X-Proofpoint-ORIG-GUID: t5FNQV_MEv999t1Z7x0eycwvxjy92v15 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA4MyBTYWx0ZWRfX41eWnhv7S6TH ny5L0des1TIbuBXjq+0eLtDdewTNV5PEw5maCTGre1/L90tUF1029B3nw41q+qXpGssXNIP/laa hxE+C24nc2Bk7K1ftqNoNtav5Ibxl6A= X-Authority-Analysis: v=2.4 cv=daKwG3Xe c=1 sm=1 tr=0 ts=6a50b00c cx=c_pps a=UNFcQwm+pnOIJct1K4W+Mw==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yx91gb_oNiZeI1HMLzn7:22 a=EUspDBNiAAAA:8 a=cXInsyxJmRBO8JMYNpUA:9 a=uKXjsCUrEbL0IQVhDsJ9:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA4MyBTYWx0ZWRfX7TBwTFfaNaGN dtpYoQVgXgt9iCEeHkXN8+++RDCtN0eICbY/tIgYk0QR+NpaH6l3hJrk4N/n+RdS7M5yzOKuY3o iqEgwTSaaguPJ8cK3OjooeUHS+RLSAh0k05xqcOW3lgMSxWjg70RsfpIaGG9j4IJ070LMPvMT39 hFfmMROi1G4MjtEyIgKcd0jT22UCqOnKJHLQaQGFLqHVJX0lOkKcThSFfcEBhJ72DCqL8+eboKi njTpbU4ZzDkKPAAY6V0nBwIzvi0J1tJwHrLvTpsqDGDRLI+7z7TuylXQA4wPRPOVjvwG8/tT9bW Tsye6cXdoWvHKwC/f5U9W4zdOi02r+orLjeiBoe0PMhLb9XavE62kywAfAwGdGehiqHPWIoIkbF bOjVAbhnPlejvtyRXpYXyS23q5Zrli6SajF3AARW67d4zAUa4IBIir6Ez4ALph9f8QPDy27COjO caOCUPV4vhIWPWZkf6A== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_02,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 bulkscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100083 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=205.220.180.131; envelope-from=subrahmanya.lingappa@oss.qualcomm.com; helo=mx0b-0031df01.pphosted.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686309109158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Add qtests for the RPMI transport plus Base, system reset, HSM, and system suspend service groups. Signed-off-by: Subrahmanya Lingappa --- MAINTAINERS | 1 + tests/qtest/meson.build | 2 + tests/qtest/riscv-rpmi-test.c | 684 ++++++++++++++++++++++++++++++++++ 3 files changed, 687 insertions(+) create mode 100644 tests/qtest/riscv-rpmi-test.c diff --git a/MAINTAINERS b/MAINTAINERS index 8e91a31757..6dd71c5a82 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -361,6 +361,7 @@ F: hw/riscv/ F: hw/intc/riscv* F: hw/misc/riscv_rpmi* F: include/hw/misc/riscv_rpmi.h +F: tests/qtest/riscv-rpmi-test.c F: include/hw/char/riscv_htif.h F: include/hw/riscv/ F: common-user/host/riscv* diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 4897325d84..d54b79cbcf 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -290,6 +290,8 @@ qtests_riscv32 =3D \ =20 qtests_riscv64 =3D ['riscv-csr-test'] + \ (unpack_edk2_blobs ? ['bios-tables-test'] : []) + \ + (config_all_devices.has_key('CONFIG_RISCV_RPMI') ? + ['riscv-rpmi-test'] : []) + \ (config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and config_all_devices.has_key('CONFIG_RISCV_IOMMU') ? ['iommu-riscv-test'] : []) + \ diff --git a/tests/qtest/riscv-rpmi-test.c b/tests/qtest/riscv-rpmi-test.c new file mode 100644 index 0000000000..ecd5b910c7 --- /dev/null +++ b/tests/qtest/riscv-rpmi-test.c @@ -0,0 +1,684 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * QTests for RISC-V RPMI devices. + * + * Copyright (c) 2026 Qualcomm Technologies, Inc. + * Author: + * Subrahmanya Lingappa + */ + +#include "qemu/osdep.h" +#include +#include "libqtest.h" +#include "qobject/qdict.h" + +#define RPMI_SHMEM_BASE 0x10200000ULL +#define RPMI_DOORBELL_BASE 0x10230000ULL +#define RPMI_IMSIC_S_BASE 0x28000000ULL +#define RPMI_CPPC_FASTCHAN_BASE 0x10240000ULL +#define RPMI_CPPC_FASTCHAN_SIZE 0x4000 +#define RPMI_CPPC_FASTCHAN_FEEDBACK_OFFSET 0x2000 +#define RPMI_SLOT_SIZE 64 + +#define RPMI_A2P_HEAD RPMI_SHMEM_BASE +#define RPMI_A2P_TAIL (RPMI_SHMEM_BASE + RPMI_SLOT_SIZE) +#define RPMI_A2P_SLOT0 (RPMI_SHMEM_BASE + 2 * RPMI_SLOT_SIZE) + +#define RPMI_SRVGRP_BASE 0x0001 +#define RPMI_SRVGRP_SYSTEM_MSI 0x0002 +#define RPMI_SRVGRP_SYSTEM_RESET 0x0003 +#define RPMI_SRVGRP_SYSTEM_SUSPEND 0x0004 +#define RPMI_SRVGRP_HSM 0x0005 +#define RPMI_SRVGRP_CPPC 0x0006 +#define RPMI_SRVGRP_CLOCK 0x0008 +#define RPMI_SRVGRP_MANAGEMENT_MODE 0x000b +#define RPMI_SRVGRP_LOGGING 0x000e +#define RPMI_BASE_SRV_GET_PLATFORM_INFO 0x05 +#define RPMI_BASE_SRV_PROBE_SERVICE_GROUP 0x06 +#define RPMI_SYSMSI_SRV_GET_ATTRIBUTES 0x02 +#define RPMI_SYSMSI_SRV_GET_MSI_ATTRIBUTES 0x03 +#define RPMI_SYSMSI_SRV_SET_MSI_STATE 0x04 +#define RPMI_SYSMSI_SRV_GET_MSI_STATE 0x05 +#define RPMI_SYSMSI_SRV_SET_MSI_TARGET 0x06 +#define RPMI_SYSMSI_SRV_GET_MSI_TARGET 0x07 +#define RPMI_SYSRST_SRV_GET_ATTRIBUTES 0x02 +#define RPMI_SYSRST_SRV_SYSTEM_RESET 0x03 +#define RPMI_HSM_SRV_GET_HART_STATUS 0x02 +#define RPMI_HSM_SRV_GET_HART_LIST 0x03 +#define RPMI_HSM_SRV_GET_SUSPEND_TYPES 0x04 +#define RPMI_HSM_SRV_GET_SUSPEND_INFO 0x05 +#define RPMI_HSM_SRV_HART_START 0x06 +#define RPMI_HSM_SRV_HART_STOP 0x07 +#define RPMI_HSM_SRV_HART_SUSPEND 0x08 +#define RPMI_SYSSUSP_SRV_GET_ATTRIBUTES 0x02 +#define RPMI_SYSSUSP_SRV_SYSTEM_SUSPEND 0x03 +#define RPMI_CPPC_SRV_PROBE_REG 0x02 +#define RPMI_CPPC_SRV_READ_REG 0x03 +#define RPMI_CPPC_SRV_WRITE_REG 0x04 +#define RPMI_CPPC_SRV_GET_FAST_CHANNEL_REGION 0x05 +#define RPMI_CPPC_SRV_GET_FAST_CHANNEL_OFFSET 0x06 +#define RPMI_CPPC_SRV_GET_HART_LIST 0x07 +#define RPMI_CPPC_NOMINAL_PERF 0x01 +#define RPMI_CPPC_DESIRED_PERF 0x05 +#define RPMI_CPPC_COUNTER_WRAPAROUND_TIME 0x0a +#define RPMI_CPPC_REFERENCE_PERF_COUNTER 0x0b +#define RPMI_CPPC_DELIVERED_PERF_COUNTER 0x0c +#define RPMI_CPPC_REG_LEN_64 64 +#define RPMI_CLK_SRV_GET_NUM_CLOCKS 0x02 +#define RPMI_CLK_SRV_GET_ATTRIBUTES 0x03 +#define RPMI_CLK_SRV_GET_SUPPORTED_RATES 0x04 +#define RPMI_CLK_SRV_SET_CONFIG 0x05 +#define RPMI_CLK_SRV_GET_CONFIG 0x06 +#define RPMI_CLK_SRV_SET_RATE 0x07 +#define RPMI_CLK_SRV_GET_RATE 0x08 +#define RPMI_MM_SRV_GET_ATTRIBUTES 0x02 +#define RPMI_MM_SRV_COMMUNICATE 0x03 +#define RPMI_LOGGING_SRV_SET_CONFIG 0x02 +#define RPMI_MSG_NORMAL_REQUEST 0x00 +#define RPMI_MSG_POSTED_REQUEST 0x01 +#define RPMI_MSG_ACKNOWLEDGEMENT 0x02 +#define RPMI_SYSRST_TYPE_SHUTDOWN 0x00 +#define RPMI_SYSRST_TYPE_COLD_REBOOT 0x01 +#define RPMI_SYSRST_TYPE_INVALID 0x03 +#define RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE 1 +#define RPMI_SYS_MSI_SHUTDOWN_INDEX 0 +#define RPMI_SYS_MSI_REBOOT_INDEX 1 +#define RPMI_SYS_MSI_SUSPEND_INDEX 2 +#define RPMI_SYS_NUM_MSI 4 +#define RPMI_SYSMSI_MSI_STATE_ENABLE 1 +#define RPMI_SYSMSI_MSI_STATE_PENDING 2 +#define RPMI_TOKEN 0x55aa +#define RPMI_ERR_NOTSUPP 0xfffffffeU +#define RPMI_ERR_INVALID_PARAM 0xfffffffdU +#define RPMI_ERR_INVALID_ADDR 0xfffffffbU +#define RPMI_ERR_DENIED 0xfffffffcU +#define RPMI_HSM_HART_STATE_STARTED 0x00 +#define RPMI_HSM_HART_STATE_STOPPED 0x01 +#define RPMI_HSM_HART_STATE_SUSPENDED 0x04 +#define VIRT_RPMI_CPPC_NOMINAL_PERF 30 +#define VIRT_RPMI_CLOCK_COUNT 6 +#define VIRT_RPMI_MM_VERSION 0x10000 +#define VIRT_RPMI_SHMEM_SIZE 0x20000 +#define RPMI_MM_INPUT_OFFSET 0x3000 +#define RPMI_MM_OUTPUT_OFFSET 0x3800 +#define RPMI_MM_BUFFER_SIZE 0x400 +#define RPMI_MM_INPUT_BASE (RPMI_SHMEM_BASE + RPMI_MM_INPUT_OFFSET) +#define RPMI_MM_OUTPUT_BASE (RPMI_SHMEM_BASE + RPMI_MM_OUTPUT_OFFSET) +#define MM_EFI_COMM_HEADER_SIZE 24 +#define EFI_VAR_COMM_HEADER_SIZE 16 +#define EFI_VAR_ACCESS_NAME_OFFSET 36 +#define EFI_VAR_NEXT_NAME_OFFSET 24 +#define EFI_VAR_FN_GET_VARIABLE 1 +#define EFI_VAR_FN_GET_NEXT_VARIABLE_NAME 2 +#define EFI_VAR_FN_SET_VARIABLE 3 +#define EFI_SUCCESS 0ULL +#define EFI_INVALID_PARAMETER 0x8000000000000002ULL +#define EFI_BUFFER_TOO_SMALL 0x8000000000000005ULL +#define EFI_NOT_FOUND 0x800000000000000eULL +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 + +#define RPMI_P2A_ACK_BASE (RPMI_SHMEM_BASE + 16 * RPMI_SLOT_SIZE) +#define RPMI_P2A_ACK_HEAD RPMI_P2A_ACK_BASE +#define RPMI_P2A_ACK_TAIL (RPMI_P2A_ACK_BASE + RPMI_SLOT_SIZE) +#define RPMI_P2A_ACK_SLOT0 (RPMI_P2A_ACK_BASE + 2 * RPMI_SLOT_SIZE) + +static uint64_t rpmi_response_base; + +static uint64_t rpmi_queue_slot(uint64_t queue_base, uint32_t index) +{ + return queue_base + (index + 2) * RPMI_SLOT_SIZE; +} + +static void rpmi_send_request(QTestState *qts, uint16_t service_group, + uint8_t service_id, uint8_t request_type, + const uint32_t *data, size_t data_words) +{ + uint32_t tail =3D qtest_readl(qts, RPMI_A2P_TAIL); + uint64_t slot =3D rpmi_queue_slot(RPMI_SHMEM_BASE, tail); + size_t i; + + qtest_writew(qts, slot, service_group); + qtest_writeb(qts, slot + 2, service_id); + qtest_writeb(qts, slot + 3, request_type); + qtest_writew(qts, slot + 4, data_words * sizeof(*data)); + qtest_writew(qts, slot + 6, RPMI_TOKEN); + + for (i =3D 0; i < data_words; i++) { + qtest_writel(qts, slot + 8 + i * sizeof(*data), data[i]); + } + + g_test_message( + "RPMI_A2P_REQ shmem=3D0x%016" PRIx64 " doorbell=3D0x%016" PRIx64 + " group=3D0x%04x service=3D0x%02x type=3D0x%02x data_len=3D%zu" + " token=3D0x%04x a2p_tail=3D%u slot=3D0x%016" PRIx64, + (uint64_t)RPMI_SHMEM_BASE, (uint64_t)RPMI_DOORBELL_BASE, + service_group, service_id, request_type, data_words * sizeof(*data= ), + RPMI_TOKEN, tail, slot); + + qtest_writel(qts, RPMI_A2P_TAIL, (tail + 1) % 16); + qtest_writel(qts, RPMI_DOORBELL_BASE, 1); +} + +static uint32_t rpmi_response_word(QTestState *qts, unsigned int word) +{ + return qtest_readl(qts, rpmi_response_base + 8 + word * sizeof(uint32_= t)); +} + +static void rpmi_expect_ack(QTestState *qts, uint16_t service_group, + uint8_t service_id, uint16_t data_len) +{ + uint32_t head =3D qtest_readl(qts, RPMI_P2A_ACK_HEAD); + uint32_t tail =3D qtest_readl(qts, RPMI_P2A_ACK_TAIL); + + g_assert_cmphex(tail, !=3D, head); + rpmi_response_base =3D rpmi_queue_slot(RPMI_P2A_ACK_BASE, head); + g_assert_cmphex(qtest_readw(qts, rpmi_response_base), =3D=3D, service_= group); + g_assert_cmphex(qtest_readb(qts, rpmi_response_base + 2), =3D=3D, + service_id); + g_assert_cmphex(qtest_readb(qts, rpmi_response_base + 3), =3D=3D, + RPMI_MSG_ACKNOWLEDGEMENT); + g_assert_cmphex(qtest_readw(qts, rpmi_response_base + 4), =3D=3D, data= _len); + g_assert_cmphex(qtest_readw(qts, rpmi_response_base + 6), =3D=3D, + RPMI_TOKEN); + g_test_message( + "RPMI_P2A_ACK shmem=3D0x%016" PRIx64 + " group=3D0x%04x service=3D0x%02x type=3D0x%02x data_len=3D%u" + " token=3D0x%04x p2a_head=3D%u slot=3D0x%016" PRIx64 + " status=3D0x%08x", + (uint64_t)RPMI_SHMEM_BASE, service_group, service_id, + RPMI_MSG_ACKNOWLEDGEMENT, data_len, RPMI_TOKEN, head, + rpmi_response_base, + data_len >=3D sizeof(uint32_t) ? rpmi_response_word(qts, 0) : 0); + qtest_writel(qts, RPMI_P2A_ACK_HEAD, (head + 1) % 16); +} + +static void rpmi_send_sysreset(QTestState *qts, uint32_t reset_type, + uint8_t request_type) +{ + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_SYSTEM_RESET, request_type, + &reset_type, 1); +} + +static void rpmi_expect_qemu_failure(const char *extra_args, + const char *stderr_needle) +{ + g_autoptr(GError) error =3D NULL; + g_auto(GStrv) split_args =3D NULL; + g_autoptr(GPtrArray) argv =3D g_ptr_array_new(); + g_autofree char *stderr_data =3D NULL; + gint wait_status; + gboolean spawned; + + g_assert_true(g_shell_parse_argv(extra_args, NULL, &split_args, &error= )); + g_assert_no_error(error); + + g_ptr_array_add(argv, (gpointer)qtest_qemu_binary(NULL)); + for (char **arg =3D split_args; *arg; arg++) { + g_ptr_array_add(argv, *arg); + } + g_ptr_array_add(argv, NULL); + + spawned =3D g_spawn_sync(NULL, (char **)argv->pdata, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL, + NULL, NULL, NULL, &stderr_data, + &wait_status, &error); + g_assert_true(spawned); + g_assert_no_error(error); + g_assert_false(g_spawn_check_exit_status(wait_status, NULL)); + g_assert_nonnull(stderr_data); + g_assert_nonnull(strstr(stderr_data, stderr_needle)); +} + +static void test_rpmi_machine_realize_off(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Doff"); + qtest_quit(qts); +} + +static void test_rpmi_machine_rejects_too_many_harts(void) +{ + rpmi_expect_qemu_failure( + "-machine virt,rpmi=3Don -smp 513 -display none -S", + "max CPUs supported by machine 'virt' is 512"); +} + +static void test_rpmi_base_platform_info(void) +{ + static const char expected[] =3D "QEMU RISC-V virt RPMI"; + QTestState *qts; + size_t i; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_request(qts, RPMI_SRVGRP_BASE, + RPMI_BASE_SRV_GET_PLATFORM_INFO, + RPMI_MSG_NORMAL_REQUEST, NULL, 0); + + rpmi_expect_ack(qts, RPMI_SRVGRP_BASE, + RPMI_BASE_SRV_GET_PLATFORM_INFO, + 2 * sizeof(uint32_t) + sizeof(expected)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, sizeof(expected)); + for (i =3D 0; i < sizeof(expected); i++) { + g_assert_cmphex(qtest_readb(qts, RPMI_P2A_ACK_SLOT0 + 16 + i), =3D= =3D, + expected[i]); + } + + qtest_quit(qts); +} + +static void rpmi_probe_group(QTestState *qts, uint32_t service_group, + bool present) +{ + rpmi_send_request(qts, RPMI_SRVGRP_BASE, + RPMI_BASE_SRV_PROBE_SERVICE_GROUP, + RPMI_MSG_NORMAL_REQUEST, &service_group, 1); + + rpmi_expect_ack(qts, RPMI_SRVGRP_BASE, + RPMI_BASE_SRV_PROBE_SERVICE_GROUP, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + if (present) { + g_assert_cmphex(rpmi_response_word(qts, 1), !=3D, 0); + } else { + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + } +} + +static void test_rpmi_base_probe_service_groups(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don,aia=3Daplic-imsic"); + rpmi_probe_group(qts, RPMI_SRVGRP_BASE, true); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_SYSTEM_RESET, true); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_HSM, true); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, true); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_CPPC, false); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_SYSTEM_MSI, false); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_CLOCK, false); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_MANAGEMENT_MODE, false); + qtest_system_reset(qts); + rpmi_probe_group(qts, RPMI_SRVGRP_LOGGING, false); + + qtest_quit(qts); +} + +static void test_rpmi_sysreset_attrs(void) +{ + QTestState *qts; + uint32_t reset_type =3D RPMI_SYSRST_TYPE_SHUTDOWN; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, &reset_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, + RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE); + + qtest_system_reset(qts); + reset_type =3D RPMI_SYSRST_TYPE_COLD_REBOOT; + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, &reset_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, + RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE); + + qtest_system_reset(qts); + reset_type =3D RPMI_SYSRST_TYPE_INVALID; + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, &reset_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + + qtest_quit(qts); +} + +static void test_rpmi_sysreset_shutdown(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_sysreset(qts, RPMI_SYSRST_TYPE_SHUTDOWN, + RPMI_MSG_POSTED_REQUEST); + qtest_qmp_eventwait(qts, "SHUTDOWN"); + qtest_quit(qts); +} + +static void test_rpmi_sysreset_cold_reboot(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don -no-reboot"); + rpmi_send_sysreset(qts, RPMI_SYSRST_TYPE_COLD_REBOOT, + RPMI_MSG_POSTED_REQUEST); + qtest_qmp_eventwait(qts, "SHUTDOWN"); + qtest_quit(qts); +} + +static void test_rpmi_sysreset_invalid_type(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_sysreset(qts, RPMI_SYSRST_TYPE_INVALID, + RPMI_MSG_NORMAL_REQUEST); + + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_SYSTEM_RESET, sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, + RPMI_ERR_INVALID_PARAM); + + qtest_quit(qts); +} + +static void test_rpmi_repeated_reset_after_traffic(void) +{ + QTestState *qts; + uint32_t reset_type =3D RPMI_SYSRST_TYPE_SHUTDOWN; + + qts =3D qtest_init("-machine virt,rpmi=3Don,aia=3Daplic-imsic"); + for (uint32_t i =3D 0; i < 5; i++) { + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, + &reset_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_GET_ATTRIBUTES, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + qtest_system_reset(qts); + } + qtest_quit(qts); +} + +static void test_rpmi_reset_clears_transport(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + rpmi_send_sysreset(qts, RPMI_SYSRST_TYPE_INVALID, + RPMI_MSG_NORMAL_REQUEST); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_RESET, + RPMI_SYSRST_SRV_SYSTEM_RESET, sizeof(uint32_t)); + + qtest_system_reset(qts); + + g_assert_cmphex(qtest_readl(qts, RPMI_A2P_TAIL), =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, RPMI_P2A_ACK_TAIL), =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, RPMI_DOORBELL_BASE), =3D=3D, 0); + + qtest_quit(qts); +} + +static void test_rpmi_doorbell_invalid_access(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + qtest_writeb(qts, RPMI_DOORBELL_BASE, 1); + qtest_writel(qts, RPMI_DOORBELL_BASE + 4, 1); + g_assert_cmphex(qtest_readl(qts, RPMI_DOORBELL_BASE), =3D=3D, 0); + + qtest_quit(qts); +} + +static void test_rpmi_queue_bounds(void) +{ + QTestState *qts; + + qts =3D qtest_init("-machine virt,rpmi=3Don"); + qtest_writel(qts, RPMI_A2P_TAIL, 0x1000); + qtest_writel(qts, RPMI_DOORBELL_BASE, 1); + g_assert_cmphex(qtest_readl(qts, RPMI_A2P_HEAD), =3D=3D, 0); + g_assert_cmphex(qtest_readl(qts, RPMI_P2A_ACK_TAIL), =3D=3D, 0); + + qtest_quit(qts); +} + +static void test_rpmi_migration_blocked(void) +{ + QTestState *qts; + QDict *error; + const char *desc; + + qts =3D qtest_init("-machine virt,rpmi=3Don -S"); + error =3D qtest_qmp_assert_failure_ref(qts, + "{ 'execute': 'migrate'," + " 'arguments': { 'uri': 'exec:cat > /dev/null' } }"); + desc =3D qdict_get_try_str(error, "desc"); + + g_assert_nonnull(desc); + g_assert_nonnull(strstr(desc, "non-migratable device")); + g_assert_nonnull(strstr(desc, "riscv-rpmi")); + + qobject_unref(error); + qtest_quit(qts); +} + +static void test_rpmi_hsm_hart_list(void) +{ + QTestState *qts; + uint32_t start_index =3D 0; + + qts =3D qtest_init("-machine virt,rpmi=3Don -smp 4"); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_LIST, + RPMI_MSG_NORMAL_REQUEST, &start_index, 1); + + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_LIST, + 7 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 2), =3D=3D, 4); + g_assert_cmphex(rpmi_response_word(qts, 3), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 4), =3D=3D, 1); + g_assert_cmphex(rpmi_response_word(qts, 5), =3D=3D, 2); + g_assert_cmphex(rpmi_response_word(qts, 6), =3D=3D, 3); + + qtest_quit(qts); +} + +static void test_rpmi_hsm_multi_socket_hart_list(void) +{ + QTestState *qts; + uint32_t start_index =3D 0; + + qts =3D qtest_init("-machine virt,rpmi=3Don " + "-smp 4,sockets=3D2,cores=3D2,threads=3D1"); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_LIST, + RPMI_MSG_NORMAL_REQUEST, &start_index, 1); + + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_LIST, + 7 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 2), =3D=3D, 4); + g_assert_cmphex(rpmi_response_word(qts, 3), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 4), =3D=3D, 1); + g_assert_cmphex(rpmi_response_word(qts, 5), =3D=3D, 2); + g_assert_cmphex(rpmi_response_word(qts, 6), =3D=3D, 3); + + qtest_quit(qts); +} + +static void test_rpmi_hsm_hart_status(void) +{ + QTestState *qts; + uint32_t hart_id =3D 3; + + qts =3D qtest_init("-machine virt,rpmi=3Don -smp 4"); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_STATUS, + RPMI_MSG_NORMAL_REQUEST, &hart_id, 1); + + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_STATUS, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, + RPMI_HSM_HART_STATE_STARTED); + + qtest_quit(qts); +} + +static void rpmi_expect_hsm_status(QTestState *qts, uint32_t hart_id, + uint32_t expected_state) +{ + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_STATUS, + RPMI_MSG_NORMAL_REQUEST, &hart_id, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_HART_STATUS, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, expected_state); +} + +static void test_rpmi_hsm_hart_control(void) +{ + QTestState *qts; + uint32_t hart_id =3D 1; + uint32_t stop_request[] =3D { hart_id }; + uint32_t start_request[] =3D { hart_id, 0x80000000, 0 }; + uint32_t suspend_request[] =3D { hart_id, 0, 0x80001000, 0 }; + uint32_t start_index =3D 0; + uint32_t suspend_type =3D 0; + + qts =3D qtest_init("-machine virt,rpmi=3Don -smp 2"); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_SUSPEND_TYPES, + RPMI_MSG_NORMAL_REQUEST, &start_index, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_SUSPEND_TYPES, + 4 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 2), =3D=3D, 1); + g_assert_cmphex(rpmi_response_word(qts, 3), =3D=3D, 0); + + qtest_system_reset(qts); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_SUSPEND_INFO, + RPMI_MSG_NORMAL_REQUEST, &suspend_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_GET_SUSPEND_INFO, + 6 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + + qtest_system_reset(qts); + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_STOP, + RPMI_MSG_NORMAL_REQUEST, stop_request, + ARRAY_SIZE(stop_request)); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_STOP, + sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + rpmi_expect_hsm_status(qts, hart_id, RPMI_HSM_HART_STATE_STOPPED); + + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_START, + RPMI_MSG_NORMAL_REQUEST, start_request, + ARRAY_SIZE(start_request)); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_START, + sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + rpmi_expect_hsm_status(qts, hart_id, RPMI_HSM_HART_STATE_STARTED); + + rpmi_send_request(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_SUSPEND, + RPMI_MSG_NORMAL_REQUEST, suspend_request, + ARRAY_SIZE(suspend_request)); + rpmi_expect_ack(qts, RPMI_SRVGRP_HSM, RPMI_HSM_SRV_HART_SUSPEND, + sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + rpmi_expect_hsm_status(qts, hart_id, RPMI_HSM_HART_STATE_SUSPENDED); + + qtest_quit(qts); +} + +static void test_rpmi_syssusp_attrs_and_suspend(void) +{ + QTestState *qts; + uint32_t suspend_type =3D 0; + uint32_t suspend_request[] =3D { 0, 0, 0x80000000, 0 }; + + qts =3D qtest_init("-machine virt,rpmi=3Don -smp 1"); + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, + RPMI_SYSSUSP_SRV_GET_ATTRIBUTES, + RPMI_MSG_NORMAL_REQUEST, &suspend_type, 1); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, + RPMI_SYSSUSP_SRV_GET_ATTRIBUTES, + 2 * sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + g_assert_cmphex(rpmi_response_word(qts, 1), =3D=3D, 3); + + qtest_system_reset(qts); + rpmi_send_request(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, + RPMI_SYSSUSP_SRV_SYSTEM_SUSPEND, + RPMI_MSG_NORMAL_REQUEST, suspend_request, + ARRAY_SIZE(suspend_request)); + rpmi_expect_ack(qts, RPMI_SRVGRP_SYSTEM_SUSPEND, + RPMI_SYSSUSP_SRV_SYSTEM_SUSPEND, sizeof(uint32_t)); + g_assert_cmphex(rpmi_response_word(qts, 0), =3D=3D, 0); + qtest_qmp_eventwait(qts, "SUSPEND"); + qtest_qmp_assert_success(qts, "{ 'execute': 'system_wakeup' }"); + qtest_qmp_eventwait(qts, "WAKEUP"); + + qtest_quit(qts); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + if (qtest_has_machine("virt")) { + qtest_add_func("/riscv/rpmi/machine/realize-off", + test_rpmi_machine_realize_off); + qtest_add_func("/riscv/rpmi/machine/rejects-too-many-harts", + test_rpmi_machine_rejects_too_many_harts); + qtest_add_func("/riscv/rpmi/base/platform-info", + test_rpmi_base_platform_info); + qtest_add_func("/riscv/rpmi/base/probe-service-groups", + test_rpmi_base_probe_service_groups); + qtest_add_func("/riscv/rpmi/sysreset/attrs", + test_rpmi_sysreset_attrs); + qtest_add_func("/riscv/rpmi/sysreset/shutdown", + test_rpmi_sysreset_shutdown); + qtest_add_func("/riscv/rpmi/sysreset/cold-reboot", + test_rpmi_sysreset_cold_reboot); + qtest_add_func("/riscv/rpmi/sysreset/invalid-type", + test_rpmi_sysreset_invalid_type); + qtest_add_func("/riscv/rpmi/reset/clears-transport", + test_rpmi_reset_clears_transport); + qtest_add_func("/riscv/rpmi/negative/doorbell-invalid-access", + test_rpmi_doorbell_invalid_access); + qtest_add_func("/riscv/rpmi/negative/queue-bounds", + test_rpmi_queue_bounds); + qtest_add_func("/riscv/rpmi/reset/repeated-after-traffic", + test_rpmi_repeated_reset_after_traffic); + qtest_add_func("/riscv/rpmi/migration/blocked", + test_rpmi_migration_blocked); + qtest_add_func("/riscv/rpmi/hsm/hart-list", + test_rpmi_hsm_hart_list); + qtest_add_func("/riscv/rpmi/hsm/multi-socket-hart-list", + test_rpmi_hsm_multi_socket_hart_list); + qtest_add_func("/riscv/rpmi/hsm/hart-status", + test_rpmi_hsm_hart_status); + qtest_add_func("/riscv/rpmi/hsm/hart-control", + test_rpmi_hsm_hart_control); + qtest_add_func("/riscv/rpmi/syssusp/attrs-and-suspend", + test_rpmi_syssusp_attrs_and_suspend); + } + + return g_test_run(); +} --=20 2.43.0 From nobody Sun Jul 12 00:33:30 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=1783686141; cv=none; d=zohomail.com; s=zohoarc; b=cYZDTT73itV+mWnQ8ZQo2oazT8FHv258b3PkEiqapD0Xl1hzpiTaZ7Nd/4Yg1puHoKE38U8Fo5Sev2uuwTE+AxiL1wFr8ZIBpMWSDVjCrcvFeZ0bwVmyD/17WJUsFP3gpS8Lm6V1AXP5+SBykIpn5S3HrfkcnLMcNUl47ietlhI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783686141; 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=rjxxoo+6u2bLA22O+8/iQdDj7+Ze0NliZ003o3atnfc=; b=SawDMFFjAiXIp1HVm7vFEEnc+fNzl1IaI7+CJG22c3n6k8Rw78HO18EwqYGRYwaLwvsO+EGpxmgtUGkq9YIlIu37LSy8+or3VyLRxY2ippEvDHpumr+PwxaF34MV6fN2yFwDnrd5ARolq12oDLxEyFMD8C0OmISGh36fDXeZgjo= 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 1783686141113994.4323611825014; Fri, 10 Jul 2026 05:22:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiAF9-0007MN-8B; Fri, 10 Jul 2026 08:22:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wi6n5-0000ik-UH for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:41:00 -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 1wi6n3-0001yg-Rd for qemu-devel@nongnu.org; Fri, 10 Jul 2026 04:40:59 -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 66A7eeKM092342 for ; Fri, 10 Jul 2026 08:40:47 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 4fadvjbsup-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 10 Jul 2026 08:40:46 +0000 (GMT) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-37fec882754so188137a91.3 for ; Fri, 10 Jul 2026 01:40:46 -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-3118389d9bcsm29164925eec.20.2026.07.10.01.40.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 01:40:44 -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=rjxxoo+6u2b LA22O+8/iQdDj7+Ze0NliZ003o3atnfc=; b=jw9qIplK44ryamyoek6CaBMx1Dk zKfBuloNC50CDO/hSLgrRhZp557/cooqBbla6n3Dl4P22Y82QfoK7g/gKSC4iY6g gLkdA52yCnhHT1TKUl09uhg9iVgh+HY7p3ETMAO5iT+w8RfEF8SRH96d4rQjombV QcOr6Qu7qXOY4F5pYZs9+/zsp9+kef7mx3KpBLYRhS73DcUm+P0Z7AyyN5gCttoG 9ThQhxtxMSI6sg/QYx1DJV83hNNxLrb9iwlFlqf7x2k7SNmXo8zQ2DK0bVCLeQMz cIuY4S9IXL0bE/BG1gkpMdoyZliDVR1sZnHtlatDnk8UmLNsGZ4h/U2oyrA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1783672846; x=1784277646; 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=rjxxoo+6u2bLA22O+8/iQdDj7+Ze0NliZ003o3atnfc=; b=VxXFMMW5TZInaaxPo+kTH9BQ+TXeLHOEGe5ud0nBUs40Deh0N4bbypuw7+bhxR9mJd lftM9WkMlzgb2Svkt5b35e14JpN5NUAErUsiPOk0/7cOFCzehdKZ3N16IidUoKIIPwIu JD2JvE+nndwkXzl2UeuOqSrCRykX36hxPn29b0IuRAp/vVi0cAV8YL8JOqUW81o3oLTo DHpQjVL0dQ7YRmDtGheiNGlmEjDaHTkoX1UxTryBgt2CEj1xRpacw25jhlwclIxYEfC6 djPVhLPCvNYge2vVsqmGEZHATMjKaZRG/peknJi502WezWhPDrqXnxLjMrsCiLNVenST I8ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783672846; x=1784277646; 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=rjxxoo+6u2bLA22O+8/iQdDj7+Ze0NliZ003o3atnfc=; b=D2eGOocg9lzIt/UiaicLvHighAn+eY8bqDXguKN3syk7EbMb+PIPHxBCJcqxpf3qXw 8C9N3Le2KKseKgxKo2IX8iIOOszCeqienXshWUwk9/JBAtjWwIoNl4UDJJBTrtyi/yMP SKPIIYDTk3XxajyUbsHx7ss8vqrGCB/qpYdXiJ+WFzXa8hHF4URRWO2TfHQt2JmdbSqm No4m+cqoCwBk6wJ8w3eDik2rUzuu3lrCVEominCRvq4pO8Y0yJL4ecwVA5EJN+RgJbFj vFkiIOU+fvIWTiFo1jzr+bILJRH7vby7yzQv5hgQingltHZ7Q0Ihbrq5mb8Y4zKYebgl ffaA== X-Gm-Message-State: AOJu0YzD8dkOHm/q4zDWAi5jB/2YQFi7W1ppnC417QyM0XVv7x5qpSuB FOmjx0pyRPBXwOqMeOaIoZqkinM/1uATOgN9W3MbPu2x0XjqSWeCoQ6AZRNrcnbmetEdyZ6w5in ZtV7UGcuu9aSyxIo3CpIsDsx84MyhglFm39rO7hLL0XtvSIfWlfZDLa4qdFovnSQ+HA== X-Gm-Gg: AfdE7cl99EIl79UKRCCH0t0M4fZ/icpbtzb3Z5x+wSA/3Y+hj+4IbkQOWs+yVgZfcsx B6TV5n7gMft76qBwU/OFxGvxwQOpA1HhngOdGGnEg+YbmiTr/DBYRjH/QSRB+VTl9ECnH3UsWVg ZjxmMfrrN/S0NRvr/ehmMdMRmU0bmo3Zk8LyvgIEmmV+9aZR7zkjJ0R3Rx9jt/F4mVkNmJ2F6to sH4x98N9BP7zZ4Pdi5ZVeFB0UhCTZnZ8btXQT1N0WAsARIKtKEPLy92CykvCnlhOybz9xafIeW0 MNzwh2NQ1PXbIKCvwq5f5oZoQFnyB6ZOjq18g1Xi6iUlvG+FX4svuaTRKcwZXlNUSkccfhcrRaG douqs/Qfrnasrjr6agdAZWaCObA+2ZzBqDzM99gdPWuHAKb6LyYP0Wbjab5N59cq6wcq7HOMYTF C4aBiYnMRFAU9R6ptWQm62XKa1tG/HBkpEMvCaGLHzNA== X-Received: by 2002:a17:90b:3881:b0:37d:f70f:fbf8 with SMTP id 98e67ed59e1d1-38a1c1b0a81mr5988410a91.0.1783672845808; Fri, 10 Jul 2026 01:40:45 -0700 (PDT) X-Received: by 2002:a17:90b:3881:b0:37d:f70f:fbf8 with SMTP id 98e67ed59e1d1-38a1c1b0a81mr5988385a91.0.1783672845271; Fri, 10 Jul 2026 01:40:45 -0700 (PDT) From: Subrahmanya Lingappa To: qemu-riscv@nongnu.org Cc: qemu-devel@nongnu.org, daniel.barboza@oss.qualcomm.com, Subrahmanya Lingappa Subject: [PATCH v2 10/10] tests/functional: add initial RPMI virt guest smoke Date: Fri, 10 Jul 2026 14:09:52 +0530 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDA4MiBTYWx0ZWRfX81pWcI6WemYc 83DzMO1WXUxNR/IP2MMT5c5WryjWvhDudZY3Cl6Z80n3i0EHyP0s/u9k8+MFZbTNPlfVFzqIAmb sl7/17pyyHgANVJsmUzdRf9XJqcX3bYj7o/1NBKazdRZ77dqJ/9sPBJVkcPOnvMDU6UMf/jQxBP MfAFyzAQTFb07j/VCv0QllNQttk/fYu0BF8YpXMC+Kod3E8c2l7DbWeIJJQ/N0SZI3pD1Da0TV2 /9EcEYzoMlouIRRsxlH1u2oUmOMcd/9iWpuhpz1yLeAl8geFt0uoSvxBRC8KVvQ9V1D1uHJ7MmT P3RaewxRgudbtQwwdszOAYzTkP7w8z8+ihXUQCNnzWSipveu1eInMNBhIeV2P0tv2mGwt9DBDLU NhS54nNt7oXxwBVB110N4PPyzJejHaEYTPYHvkD2A3kXHSHr+hnmbBxTpnwt91zM/kH8n1aCAfE ENI8OuAX3M9MyXmBZ6w== X-Authority-Analysis: v=2.4 cv=WpIb99fv c=1 sm=1 tr=0 ts=6a50b00e cx=c_pps a=0uOsjrqzRL749jD1oC5vDA==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=RAioF0-LDSMA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=rJkE3RaqiGZ5pbrm-msn:22 a=EUspDBNiAAAA:8 a=Cnp7e1vNUpDCZbjFkkcA:9 a=mQ_c8vxmzFEMiUWkPHU9:22 X-Proofpoint-GUID: ctRzefi-bK92N-ivdCW5Ve4rJUBKm8lY X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDA4MiBTYWx0ZWRfXxOMtDq0EDOt6 zkOM6wiDBceqnLH+Ot1dUkz+w6Gn4fLybjVp9CC6hcaU977ZfiZg/FltRPYsVgyamatLLZ4VbJ1 kJkRTeuUZancmu3tVicn6pZVnRxvznM= X-Proofpoint-ORIG-GUID: ctRzefi-bK92N-ivdCW5Ve4rJUBKm8lY X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_02,2026-07-09_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 impostorscore=0 adultscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 phishscore=0 spamscore=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-2607100082 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-Mailman-Approved-At: Fri, 10 Jul 2026 08:21:34 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @qualcomm.com) X-ZM-MESSAGEID: 1783686142130158500 Content-Type: text/plain; charset="utf-8" From: Subrahmanya Lingappa Boot an RPMI-enabled RISC-V virt guest and exercise the initial HSM, system suspend, and system reset paths. Signed-off-by: Subrahmanya Lingappa --- tests/functional/riscv64/meson.build | 2 + tests/functional/riscv64/test_rpmi_virt.py | 172 +++++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 tests/functional/riscv64/test_rpmi_virt.py diff --git a/tests/functional/riscv64/meson.build b/tests/functional/riscv6= 4/meson.build index 5871211e89..619a0735fa 100644 --- a/tests/functional/riscv64/meson.build +++ b/tests/functional/riscv64/meson.build @@ -3,6 +3,7 @@ test_riscv64_timeouts =3D { 'boston' : 120, 'tuxrun' : 120, + 'rpmi_virt' : 300, } =20 tests_riscv64_system_quick =3D [ @@ -15,4 +16,5 @@ tests_riscv64_system_thorough =3D [ 'boston', 'sifive_u', 'tuxrun', + 'rpmi_virt', ] diff --git a/tests/functional/riscv64/test_rpmi_virt.py b/tests/functional/= riscv64/test_rpmi_virt.py new file mode 100644 index 0000000000..c0f96f7d8d --- /dev/null +++ b/tests/functional/riscv64/test_rpmi_virt.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 +# +# RISC-V virt RPMI Linux guest integration tests +# +# Copyright (c) 2026 Ventana Micro Systems Inc. +# Copyright (c) 2026 Qualcomm Technologies, Inc. +# +# Author: +# Subrahmanya Lingappa +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +from pathlib import Path +import subprocess +import time + +from qemu_test import QemuSystemTest +from qemu_test import exec_command +from qemu_test import exec_command_and_wait_for_pattern +from qemu_test import get_qemu_img +from qemu_test import wait_for_console_pattern + + +class RiscvVirtRpmiGuestTest(QemuSystemTest): + """Boot Linux and exercise RPMI-backed services through guest APIs. + + This test intentionally keeps guest artifacts external. Set: + + QEMU_TEST_RPMI_OPENSBI=3D/path/to/fw_jump.bin + QEMU_TEST_RPMI_KERNEL=3D/path/to/Image + QEMU_TEST_RPMI_ROOTFS=3D/path/to/rootfs.ext4 + + Exact RPMI packet command-ID coverage remains in riscv-rpmi qtests. Th= is + functional test verifies Linux/OpenSBI integration paths visible from a + real guest without adding probe hooks to production RPMI sources. + """ + + timeout =3D 360 + PROMPT =3D 'root@tuxtest:~#' + + def _require_path(self, env_name): + value =3D os.getenv(env_name) + if not value: + self.skipTest(f'{env_name} is required') + path =3D Path(value) + if not path.exists(): + self.skipTest(f'{env_name} does not exist: {path}') + return path + + def setUp(self): + super().setUp() + self.opensbi =3D self._require_path('QEMU_TEST_RPMI_OPENSBI') + self.kernel =3D self._require_path('QEMU_TEST_RPMI_KERNEL') + self.rootfs =3D self._require_path('QEMU_TEST_RPMI_ROOTFS') + self.qemu_img =3D get_qemu_img(self) + + def _create_rootfs_overlay(self): + overlay =3D Path(self.scratch_file('rootfs.qcow2')) + subprocess.run([ + self.qemu_img, 'create', '-q', '-f', 'qcow2', '-F', 'raw', + '-b', str(self.rootfs), str(overlay), + ], check=3DTrue) + return overlay + + def _boot_guest(self, smp=3D4): + self.set_machine('virt') + self.machine =3D 'virt,rpmi=3Don,aia=3Daplic-imsic' + rootfs_overlay =3D self._create_rootfs_overlay() + + self.vm.set_console() + self.vm.add_args( + '-cpu', 'rv64', + '-smp', str(smp), + '-m', '1G', + '-bios', str(self.opensbi), + '-kernel', str(self.kernel), + '-append', 'printk.time=3D0 root=3D/dev/vda rw console=3DttyS0= ' + 'earlycon=3Dsbi loglevel=3D8 no_console_suspend', + '-blockdev', 'driver=3Dqcow2,file.driver=3Dfile,' + f'file.filename=3D{rootfs_overlay},node-name=3Dhd= 0', + '-device', 'virtio-blk-device,drive=3Dhd0', + ) + self.vm.launch() + + def _expect_rpmi_firmware_and_linux(self): + patterns =3D [ + 'Platform HSM Device : rpmi-hsm', + 'Platform Suspend Device : rpmi-system-suspend', + 'Standard SBI Extensions', + 'susp', + 'tuxtest login:', + ] + for pattern in patterns: + wait_for_console_pattern(self, pattern) + exec_command_and_wait_for_pattern(self, 'root', self.PROMPT) + + def _run_marker_command(self, command, marker, failure_marker=3DNone): + out =3D exec_command_and_wait_for_pattern(self, command, marker, + failure_message=3Dfailure_= marker) + self.assertIn(marker.encode(), out) + return out + + def _validate_hsm_boot_start(self, online_cpus): + self._run_marker_command( + 'echo RPMI_LINUX_HSM_START_BEGIN; ' + 'cat /sys/devices/system/cpu/present; ' + 'online=3D$(cat /sys/devices/system/cpu/online); ' + 'echo "$online"; ' + f'if [ "$online" =3D "{online_cpus}" ]; ' + 'then echo RPMI_LINUX_HSM_START_PASS; ' + 'else echo RPMI_LINUX_HSM_START_FAIL; fi', + 'RPMI_LINUX_HSM_START_PASS', 'RPMI_LINUX_HSM_START_FAIL') + + def _validate_hsm_stop(self): + self._run_marker_command( + 'echo RPMI_LINUX_HSM_STOP_BEGIN; ' + 'if [ -w /sys/devices/system/cpu/cpu1/online ]; then ' + 'echo 0 > /sys/devices/system/cpu/cpu1/online && ' + '[ "$(cat /sys/devices/system/cpu/online)" =3D 0 ] && ' + 'echo RPMI_LINUX_HSM_STOP_PASS || echo RPMI_LINUX_HSM_STOP_FAI= L; ' + 'else echo RPMI_LINUX_HSM_STOP_FAIL; fi', + 'RPMI_LINUX_HSM_STOP_PASS', 'RPMI_LINUX_HSM_STOP_FAIL') + + def _validate_system_suspend(self): + exec_command( + self, + 'echo RPMI_LINUX_SUSPEND_BEGIN; ' + 'if grep -qw mem /sys/power/state; then ' + 'echo mem > /sys/power/state; ' + 'else echo RPMI_LINUX_SUSPEND_FAIL; fi') + wait_for_console_pattern(self, 'RPMI_LINUX_SUSPEND_BEGIN') + wait_for_console_pattern(self, 'PM: suspend entry') + self.vm.event_wait('SUSPEND', 10) + self.vm.qmp('system_wakeup') + self.vm.event_wait('WAKEUP', 10) + wait_for_console_pattern(self, 'PM: suspend exit') + wait_for_console_pattern(self, self.PROMPT) + self._run_marker_command( + 'marker=3DRPMI_LINUX_WAKEUP; echo ${marker}_PASS', + 'RPMI_LINUX_WAKEUP_PASS') + + def _validate_reset_poweroff(self): + exec_command(self, 'echo RPMI_LINUX_RESET_POWEROFF_BEGIN; poweroff= -f') + wait_for_console_pattern(self, 'RPMI_LINUX_RESET_POWEROFF_BEGIN') + wait_for_console_pattern(self, 'reboot: Power down') + self.vm.wait() + + def test_linux_guest_service_enumeration(self): + self._boot_guest(smp=3D4) + self._expect_rpmi_firmware_and_linux() + self._validate_hsm_boot_start('0-3') + + def test_linux_guest_hsm_stop(self): + self._boot_guest(smp=3D2) + self._expect_rpmi_firmware_and_linux() + self._validate_hsm_boot_start('0-1') + self._validate_hsm_stop() + + def test_linux_guest_suspend(self): + self._boot_guest(smp=3D1) + self._expect_rpmi_firmware_and_linux() + self._validate_system_suspend() + + def test_linux_guest_reset_poweroff(self): + self._boot_guest(smp=3D1) + self._expect_rpmi_firmware_and_linux() + self._validate_reset_poweroff() + + +if __name__ =3D=3D '__main__': + QemuSystemTest.main() --=20 2.43.0