Re: [PATCH v2 5/9] gpu: nova-core: gsp: add types for RM control RPCs
From: Alistair Popple
Date: Fri Mar 20 2026 - 00:26:33 EST
On 2026-03-18 at 18:14 +1100, Eliot Courtney <ecourtney@xxxxxxxxxx> wrote...
> Add `RmControlMsgFunction` which mirrors `MsgFunction` in fw.rs. This
> denotes the type of RM control RPC. For now it contains a single
> discriminant only (which will be used later), which is needed to prevent
> compile errors when using an otherwise empty enum.
>
> Add `GspRmControl` which wraps the RM control RPC structure from the
> bindings.
>
> Signed-off-by: Eliot Courtney <ecourtney@xxxxxxxxxx>
> ---
> drivers/gpu/nova-core/gsp/commands.rs | 1 -
> drivers/gpu/nova-core/gsp/fw.rs | 1 +
> drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs | 1 +
> drivers/gpu/nova-core/gsp/fw/rm.rs | 88 +++++++++++++++++++++++
> 4 files changed, 90 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
> index f3566f3ea6a7..8c9599aa227b 100644
> --- a/drivers/gpu/nova-core/gsp/commands.rs
> +++ b/drivers/gpu/nova-core/gsp/commands.rs
> @@ -77,7 +77,6 @@ pub(crate) fn new(raw: u32) -> Self {
> }
>
> /// Returns the raw handle value.
> - #[expect(dead_code)]
> pub(crate) fn as_raw(self) -> u32 {
> self.0
> }
> diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
> index 37831034ec3e..8cbe90ce8271 100644
> --- a/drivers/gpu/nova-core/gsp/fw.rs
> +++ b/drivers/gpu/nova-core/gsp/fw.rs
> @@ -2,6 +2,7 @@
>
> pub(crate) mod commands;
> mod r570_144;
> +pub(crate) mod rm;
>
> // Alias to avoid repeating the version number with every use.
> use r570_144 as bindings;
> diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
> index 05e205e6dc58..ece31cc32f5b 100644
> --- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
> +++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
> @@ -44,6 +44,7 @@ fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
> pub const GSP_FW_WPR_META_MAGIC: i64 = -2577556379034558285;
> pub const REGISTRY_TABLE_ENTRY_TYPE_DWORD: u32 = 1;
> pub const GSP_MSG_QUEUE_ELEMENT_SIZE_MAX: u32 = 65536;
> +pub const NV2080_CTRL_CMD_CE_GET_FAULT_METHOD_BUFFER_SIZE: u32 = 545270280;
I'm sure you can guess my comment here based on my comments for patch 1 and 4 :-)
I wonder if it would be better to just add all the bindings in one patch at the
start of the series?
Everything else here looked sensible to me and my limited experience though, so:
Reviewed-by: Alistair Popple <apopple@xxxxxxxxxx>
> pub type __u8 = ffi::c_uchar;
> pub type __u16 = ffi::c_ushort;
> pub type __u32 = ffi::c_uint;
> diff --git a/drivers/gpu/nova-core/gsp/fw/rm.rs b/drivers/gpu/nova-core/gsp/fw/rm.rs
> new file mode 100644
> index 000000000000..4a4f97d88ecf
> --- /dev/null
> +++ b/drivers/gpu/nova-core/gsp/fw/rm.rs
> @@ -0,0 +1,88 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +use kernel::{
> + prelude::*,
> + transmute::{
> + AsBytes,
> + FromBytes, //
> + }, //
> +};
> +
> +use crate::gsp::commands::{
> + Client,
> + Handle, //
> +};
> +
> +use super::{
> + bindings,
> + NvStatus, //
> +};
> +
> +/// Command code for RM control RPCs sent using [`MsgFunction::GspRmControl`].
> +#[derive(Copy, Clone, Debug, PartialEq)]
> +#[repr(u32)]
> +pub(crate) enum RmControlMsgFunction {
> + /// Get the CE fault method buffer size.
> + CeGetFaultMethodBufferSize = bindings::NV2080_CTRL_CMD_CE_GET_FAULT_METHOD_BUFFER_SIZE,
> +}
> +
> +// TODO[FPRI]: replace with 'FromPrimitive'.
> +impl TryFrom<u32> for RmControlMsgFunction {
> + type Error = kernel::error::Error;
> +
> + fn try_from(value: u32) -> Result<Self> {
> + match value {
> + bindings::NV2080_CTRL_CMD_CE_GET_FAULT_METHOD_BUFFER_SIZE => {
> + Ok(Self::CeGetFaultMethodBufferSize)
> + }
> + _ => Err(EINVAL),
> + }
> + }
> +}
> +
> +impl From<RmControlMsgFunction> for u32 {
> + fn from(value: RmControlMsgFunction) -> Self {
> + // CAST: `RmControlMsgFunction` is `repr(u32)` and can thus be cast losslessly.
> + value as u32
> + }
> +}
> +
> +/// RM control message element structure.
> +#[repr(transparent)]
> +pub(crate) struct GspRmControl {
> + inner: bindings::rpc_gsp_rm_control_v03_00,
> +}
> +
> +#[expect(dead_code)]
> +impl GspRmControl {
> + /// Creates a new RM control command.
> + pub(crate) fn new<T>(
> + client: Handle<Client>,
> + object: Handle<T>,
> + cmd: RmControlMsgFunction,
> + params_size: u32,
> + ) -> Self {
> + Self {
> + inner: bindings::rpc_gsp_rm_control_v03_00 {
> + hClient: client.as_raw(),
> + hObject: object.as_raw(),
> + cmd: u32::from(cmd),
> + status: 0,
> + paramsSize: params_size,
> + flags: 0,
> + params: Default::default(),
> + },
> + }
> + }
> +
> + /// Returns the status from the RM control response.
> + pub(crate) fn status(&self) -> NvStatus {
> + NvStatus::from(self.inner.status)
> + }
> +}
> +
> +// SAFETY: This struct only contains integer types for which all bit patterns are valid.
> +unsafe impl FromBytes for GspRmControl {}
> +
> +// SAFETY: This struct contains no padding.
> +unsafe impl AsBytes for GspRmControl {}
>
> --
> 2.53.0
>