Commit 13f85988 authored by Alistair Popple's avatar Alistair Popple Committed by Alexandre Courbot
Browse files

gpu: nova-core: gsp: Retrieve GSP static info to gather GPU information



After GSP initialization is complete, retrieve the static configuration
information from GSP-RM. This information includes GPU name, capabilities,
memory configuration, and other properties. On some GPU variants, it is
also required to do this for initialization to complete.

Signed-off-by: default avatarAlistair Popple <apopple@nvidia.com>
Co-developed-by: default avatarJoel Fernandes <joelagnelf@nvidia.com>
Signed-off-by: default avatarJoel Fernandes <joelagnelf@nvidia.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
[acourbot@nvidia.com: properly abstract the command's bindings, add
relevant methods, make str_from_null_terminated return an Option, fix
size of GPU name array.]
Co-developed-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Message-ID: <20251114195552.739371-14-joelagnelf@nvidia.com>
parent 0e7d572b
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -239,6 +239,14 @@ pub(crate) fn boot(
        // Wait until GSP is fully initialized.
        commands::wait_gsp_init_done(&mut self.cmdq)?;

        // Obtain and display basic GPU information.
        let info = commands::get_gsp_info(&mut self.cmdq, bar)?;
        dev_info!(
            pdev.as_ref(),
            "GPU name: {}\n",
            info.gpu_name().unwrap_or("invalid GPU name")
        );

        Ok(())
    }
}
+56 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
};

use crate::{
    driver::Bar0,
    gsp::{
        cmdq::{
            Cmdq,
@@ -29,6 +30,7 @@
        },
    },
    sbuffer::SBufferIter,
    util,
};

/// The `GspSetSystemInfo` command.
@@ -169,3 +171,57 @@ pub(crate) fn wait_gsp_init_done(cmdq: &mut Cmdq) -> Result {
        }
    }
}

/// The `GetGspStaticInfo` command.
struct GetGspStaticInfo;

impl CommandToGsp for GetGspStaticInfo {
    const FUNCTION: MsgFunction = MsgFunction::GetGspStaticInfo;
    type Command = GspStaticConfigInfo;
    type InitError = Infallible;

    fn init(&self) -> impl Init<Self::Command, Self::InitError> {
        GspStaticConfigInfo::init_zeroed()
    }
}

/// The reply from the GSP to the [`GetGspInfo`] command.
pub(crate) struct GetGspStaticInfoReply {
    gpu_name: [u8; 64],
}

impl MessageFromGsp for GetGspStaticInfoReply {
    const FUNCTION: MsgFunction = MsgFunction::GetGspStaticInfo;
    type Message = GspStaticConfigInfo;
    type InitError = Infallible;

    fn read(
        msg: &Self::Message,
        _sbuffer: &mut SBufferIter<array::IntoIter<&[u8], 2>>,
    ) -> Result<Self, Self::InitError> {
        Ok(GetGspStaticInfoReply {
            gpu_name: msg.gpu_name_str(),
        })
    }
}

impl GetGspStaticInfoReply {
    /// Returns the name of the GPU as a string, or `None` if the string given by the GSP was
    /// invalid.
    pub(crate) fn gpu_name(&self) -> Option<&str> {
        util::str_from_null_terminated(&self.gpu_name)
    }
}

/// Send the [`GetGspInfo`] command and awaits for its reply.
pub(crate) fn get_gsp_info(cmdq: &mut Cmdq, bar: &Bar0) -> Result<GetGspStaticInfoReply> {
    cmdq.send_command(bar, GetGspStaticInfo)?;

    loop {
        match cmdq.receive_msg::<GetGspStaticInfoReply>(Delta::from_secs(5)) {
            Ok(info) => return Ok(info),
            Err(ERANGE) => continue,
            Err(e) => return Err(e),
        }
    }
}
+22 −0
Original line number Diff line number Diff line
@@ -104,3 +104,25 @@ unsafe impl AsBytes for PackedRegistryTable {}
// SAFETY: This struct only contains integer types for which all bit patterns
// are valid.
unsafe impl FromBytes for PackedRegistryTable {}

/// Payload of the `GetGspStaticInfo` command and message.
#[repr(transparent)]
pub(crate) struct GspStaticConfigInfo(bindings::GspStaticConfigInfo_t);

impl GspStaticConfigInfo {
    /// Returns a bytes array containing the (hopefully) zero-terminated name of this GPU.
    pub(crate) fn gpu_name_str(&self) -> [u8; 64] {
        self.0.gpuNameString
    }
}

// SAFETY: Padding is explicit and will not contain uninitialized data.
unsafe impl AsBytes for GspStaticConfigInfo {}

// SAFETY: This struct only contains integer types for which all bit patterns
// are valid.
unsafe impl FromBytes for GspStaticConfigInfo {}

// SAFETY: This struct only contains integer types and fixed-size arrays for which
// all bit patterns are valid.
unsafe impl Zeroable for GspStaticConfigInfo {}
+163 −0
Original line number Diff line number Diff line
@@ -320,6 +320,77 @@ fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
pub const NV_VGPU_MSG_EVENT_NUM_EVENTS: _bindgen_ty_3 = 4131;
pub type _bindgen_ty_3 = ffi::c_uint;
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS {
    pub totalVFs: u32_,
    pub firstVfOffset: u32_,
    pub vfFeatureMask: u32_,
    pub FirstVFBar0Address: u64_,
    pub FirstVFBar1Address: u64_,
    pub FirstVFBar2Address: u64_,
    pub bar0Size: u64_,
    pub bar1Size: u64_,
    pub bar2Size: u64_,
    pub b64bitBar0: u8_,
    pub b64bitBar1: u8_,
    pub b64bitBar2: u8_,
    pub bSriovEnabled: u8_,
    pub bSriovHeavyEnabled: u8_,
    pub bEmulateVFBar0TlbInvalidationRegister: u8_,
    pub bClientRmAllocatedCtxBuffer: u8_,
    pub bNonPowerOf2ChannelCountSupported: u8_,
    pub bVfResizableBAR1Supported: u8_,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS {
    pub BoardID: u32_,
    pub chipSKU: [ffi::c_char; 9usize],
    pub chipSKUMod: [ffi::c_char; 5usize],
    pub skuConfigVersion: u32_,
    pub project: [ffi::c_char; 5usize],
    pub projectSKU: [ffi::c_char; 5usize],
    pub CDP: [ffi::c_char; 6usize],
    pub projectSKUMod: [ffi::c_char; 2usize],
    pub businessCycle: u32_,
}
pub type NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG = [u8_; 17usize];
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO {
    pub base: u64_,
    pub limit: u64_,
    pub reserved: u64_,
    pub performance: u32_,
    pub supportCompressed: u8_,
    pub supportISO: u8_,
    pub bProtected: u8_,
    pub blackList: NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS {
    pub numFBRegions: u32_,
    pub fbRegion: [NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO; 16usize],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct NV2080_CTRL_GPU_GET_GID_INFO_PARAMS {
    pub index: u32_,
    pub flags: u32_,
    pub length: u32_,
    pub data: [u8_; 256usize],
}
impl Default for NV2080_CTRL_GPU_GET_GID_INFO_PARAMS {
    fn default() -> Self {
        let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct DOD_METHOD_DATA {
    pub status: u32_,
@@ -367,6 +438,19 @@ pub struct ACPI_METHOD_DATA {
    pub capsMethodData: CAPS_METHOD_DATA,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS {
    pub headIndex: u32_,
    pub maxHResolution: u32_,
    pub maxVResolution: u32_,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS {
    pub numHeads: u32_,
    pub maxNumHeads: u32_,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct BUSINFO {
    pub deviceID: u16_,
@@ -395,6 +479,85 @@ pub struct GSP_PCIE_CONFIG_REG {
    pub linkCap: u32_,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct EcidManufacturingInfo {
    pub ecidLow: u32_,
    pub ecidHigh: u32_,
    pub ecidExtended: u32_,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct FW_WPR_LAYOUT_OFFSET {
    pub nonWprHeapOffset: u64_,
    pub frtsOffset: u64_,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct GspStaticConfigInfo_t {
    pub grCapsBits: [u8_; 23usize],
    pub gidInfo: NV2080_CTRL_GPU_GET_GID_INFO_PARAMS,
    pub SKUInfo: NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS,
    pub fbRegionInfoParams: NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS,
    pub sriovCaps: NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS,
    pub sriovMaxGfid: u32_,
    pub engineCaps: [u32_; 3usize],
    pub poisonFuseEnabled: u8_,
    pub fb_length: u64_,
    pub fbio_mask: u64_,
    pub fb_bus_width: u32_,
    pub fb_ram_type: u32_,
    pub fbp_mask: u64_,
    pub l2_cache_size: u32_,
    pub gpuNameString: [u8_; 64usize],
    pub gpuShortNameString: [u8_; 64usize],
    pub gpuNameString_Unicode: [u16_; 64usize],
    pub bGpuInternalSku: u8_,
    pub bIsQuadroGeneric: u8_,
    pub bIsQuadroAd: u8_,
    pub bIsNvidiaNvs: u8_,
    pub bIsVgx: u8_,
    pub bGeforceSmb: u8_,
    pub bIsTitan: u8_,
    pub bIsTesla: u8_,
    pub bIsMobile: u8_,
    pub bIsGc6Rtd3Allowed: u8_,
    pub bIsGc8Rtd3Allowed: u8_,
    pub bIsGcOffRtd3Allowed: u8_,
    pub bIsGcoffLegacyAllowed: u8_,
    pub bIsMigSupported: u8_,
    pub RTD3GC6TotalBoardPower: u16_,
    pub RTD3GC6PerstDelay: u16_,
    pub bar1PdeBase: u64_,
    pub bar2PdeBase: u64_,
    pub bVbiosValid: u8_,
    pub vbiosSubVendor: u32_,
    pub vbiosSubDevice: u32_,
    pub bPageRetirementSupported: u8_,
    pub bSplitVasBetweenServerClientRm: u8_,
    pub bClRootportNeedsNosnoopWAR: u8_,
    pub displaylessMaxHeads: VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS,
    pub displaylessMaxResolution: VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS,
    pub displaylessMaxPixels: u64_,
    pub hInternalClient: u32_,
    pub hInternalDevice: u32_,
    pub hInternalSubdevice: u32_,
    pub bSelfHostedMode: u8_,
    pub bAtsSupported: u8_,
    pub bIsGpuUefi: u8_,
    pub bIsEfiInit: u8_,
    pub ecidInfo: [EcidManufacturingInfo; 2usize],
    pub fwWprLayoutOffset: FW_WPR_LAYOUT_OFFSET,
}
impl Default for GspStaticConfigInfo_t {
    fn default() -> Self {
        let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct GspSystemInfo {
    pub gpuPhysAddr: u64_,
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
mod num;
mod regs;
mod sbuffer;
mod util;
mod vbios;

pub(crate) const MODULE_NAME: &kernel::str::CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
Loading