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 <[email protected]> --- 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 | 82 +++++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs index c71c45462efd..0796e6c0baf2 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; 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..8bb7b11736b9 --- /dev/null +++ b/drivers/gpu/nova-core/gsp/fw/rm.rs @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 + +use kernel::{ + prelude::*, + transmute::{ + AsBytes, + FromBytes, // + }, // +}; + +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, +} + +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. +#[derive(Zeroable)] +#[repr(transparent)] +pub(crate) struct GspRmControl { + inner: bindings::rpc_gsp_rm_control_v03_00, +} + +impl GspRmControl { + /// Creates a new RM control command. + pub(crate) fn new( + h_client: u32, + h_object: u32, + cmd: RmControlMsgFunction, + params_size: u32, + ) -> Self { + Self { + inner: bindings::rpc_gsp_rm_control_v03_00 { + hClient: h_client, + hObject: h_object, + 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
