Expose the `hInternalClient` and `hInternalSubdevice` handles. These are needed for RM control calls.
Signed-off-by: Eliot Courtney <[email protected]> --- drivers/gpu/nova-core/gsp/commands.rs | 65 ++++++++++++++++++++++++++++++++ drivers/gpu/nova-core/gsp/fw/commands.rs | 19 +++++++++- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs index c89c7b57a751..f3566f3ea6a7 100644 --- a/drivers/gpu/nova-core/gsp/commands.rs +++ b/drivers/gpu/nova-core/gsp/commands.rs @@ -4,6 +4,7 @@ array, convert::Infallible, ffi::FromBytesUntilNulError, + marker::PhantomData, str::Utf8Error, // }; @@ -34,6 +35,54 @@ sbuffer::SBufferIter, }; +/// Marker type for a GSP-RM client handle. +/// +/// A client handle identifies a client which provides a namespace for RM objects. Lookup of objects +/// happens within the client namespace. +pub(crate) struct Client; + +/// Marker type for a GSP-RM device handle. +/// +/// A device handle identifies a logical GPU device instance under a client. In multi-GPU +/// configurations it can represent a grouped or logical device. +#[expect(dead_code)] +pub(crate) struct Device; + +/// Marker type for a GSP-RM subdevice handle. +/// +/// A subdevice handle identifies a child of a device that selects one specific GPU within that +/// device. +pub(crate) struct Subdevice; + +/// A typed GSP-RM object handle. +/// +/// These handles form a tree structure with different types of RM objects, with client at the root. +/// An RM object is anything identified by a valid handle. For example, the tree may look like +/// Client -> Device -> Subdevice, where there may be multiple devices under each client, and +/// multiple subdevices under each device. +#[derive(Debug)] +pub(crate) struct Handle<T>(u32, PhantomData<T>); + +impl<T> Clone for Handle<T> { + fn clone(&self) -> Self { + *self + } +} +impl<T> Copy for Handle<T> {} + +impl<T> Handle<T> { + /// Creates a new handle from a raw value. + pub(crate) fn new(raw: u32) -> Self { + Self(raw, PhantomData) + } + + /// Returns the raw handle value. + #[expect(dead_code)] + pub(crate) fn as_raw(self) -> u32 { + self.0 + } +} + /// The `GspSetSystemInfo` command. pub(crate) struct SetSystemInfo<'a> { pdev: &'a pci::Device<device::Bound>, @@ -192,6 +241,8 @@ fn init(&self) -> impl Init<Self::Command, Self::InitError> { /// The reply from the GSP to the [`GetGspInfo`] command. pub(crate) struct GetGspStaticInfoReply { gpu_name: [u8; 64], + client: Handle<Client>, + subdevice: Handle<Subdevice>, } impl MessageFromGsp for GetGspStaticInfoReply { @@ -205,6 +256,8 @@ fn read( ) -> Result<Self, Self::InitError> { Ok(GetGspStaticInfoReply { gpu_name: msg.gpu_name_str(), + client: msg.client(), + subdevice: msg.subdevice(), }) } } @@ -231,6 +284,18 @@ pub(crate) fn gpu_name(&self) -> core::result::Result<&str, GpuNameError> { .to_str() .map_err(GpuNameError::InvalidUtf8) } + + /// Returns the client handle allocated by GSP-RM. + #[expect(dead_code)] + pub(crate) fn client(&self) -> Handle<Client> { + self.client + } + + /// Returns the subdevice handle allocated by GSP-RM. + #[expect(dead_code)] + pub(crate) fn subdevice(&self) -> Handle<Subdevice> { + self.subdevice + } } /// Send the [`GetGspInfo`] command and awaits for its reply. diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-core/gsp/fw/commands.rs index db46276430be..9fce6ffefbce 100644 --- a/drivers/gpu/nova-core/gsp/fw/commands.rs +++ b/drivers/gpu/nova-core/gsp/fw/commands.rs @@ -10,7 +10,14 @@ }, // }; -use crate::gsp::GSP_PAGE_SIZE; +use crate::gsp::{ + commands::{ + Client, + Handle, + Subdevice, // + }, + GSP_PAGE_SIZE, // +}; use super::bindings; @@ -121,6 +128,16 @@ impl GspStaticConfigInfo { pub(crate) fn gpu_name_str(&self) -> [u8; 64] { self.0.gpuNameString } + + /// Returns the client handle allocated by GSP-RM. + pub(crate) fn client(&self) -> Handle<Client> { + Handle::new(self.0.hInternalClient) + } + + /// Returns the subdevice handle allocated by GSP-RM. + pub(crate) fn subdevice(&self) -> Handle<Subdevice> { + Handle::new(self.0.hInternalSubdevice) + } } // SAFETY: Padding is explicit and will not contain uninitialized data. -- 2.53.0
