gpu: nova-core: gsp: Add SetSystemInfo command

Add support for sending the SetSystemInfo command, which provides
required hardware information to the GSP and is critical to its
initialization.

Signed-off-by: Alistair Popple <apopple@nvidia.com>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Message-ID: <20251110-gsp_boot-v9-11-8ae4058e3c0e@nvidia.com>
This commit is contained in:
Alistair Popple
2025-11-10 22:34:19 +09:00
committed by Alexandre Courbot
parent 4fd4acd973
commit edcb134264
7 changed files with 235 additions and 3 deletions

View File

@@ -15,6 +15,7 @@ use kernel::{
};
pub(crate) mod cmdq;
pub(crate) mod commands;
mod fw;
pub(crate) use fw::{

View File

@@ -29,7 +29,10 @@ use crate::{
FIRMWARE_VERSION, //
},
gpu::Chipset,
gsp::GspFwWprMeta,
gsp::{
commands,
GspFwWprMeta, //
},
regs,
vbios::Vbios,
};
@@ -119,7 +122,7 @@ impl super::Gsp {
///
/// Upon return, the GSP is up and running, and its runtime object given as return value.
pub(crate) fn boot(
self: Pin<&mut Self>,
mut self: Pin<&mut Self>,
pdev: &pci::Device<device::Bound>,
bar: &Bar0,
chipset: Chipset,
@@ -153,6 +156,9 @@ impl super::Gsp {
CoherentAllocation::<GspFwWprMeta>::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?;
dma_write!(wpr_meta[0] = GspFwWprMeta::new(&gsp_fw, &fb_layout))?;
self.cmdq
.send_command(bar, commands::SetSystemInfo::new(pdev))?;
Ok(())
}
}

View File

@@ -489,7 +489,6 @@ impl Cmdq {
/// written to by its [`CommandToGsp::init_variable_payload`] method.
///
/// Error codes returned by the command initializers are propagated as-is.
#[expect(unused)]
pub(crate) fn send_command<M>(&mut self, bar: &Bar0, command: M) -> Result
where
M: CommandToGsp,

View File

@@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-2.0
use kernel::{
device,
pci,
prelude::*, //
};
use crate::gsp::{
cmdq::CommandToGsp,
fw::{
commands::GspSetSystemInfo,
MsgFunction, //
},
};
/// The `GspSetSystemInfo` command.
pub(crate) struct SetSystemInfo<'a> {
pdev: &'a pci::Device<device::Bound>,
}
impl<'a> SetSystemInfo<'a> {
/// Creates a new `GspSetSystemInfo` command using the parameters of `pdev`.
pub(crate) fn new(pdev: &'a pci::Device<device::Bound>) -> Self {
Self { pdev }
}
}
impl<'a> CommandToGsp for SetSystemInfo<'a> {
const FUNCTION: MsgFunction = MsgFunction::GspSetSystemInfo;
type Command = GspSetSystemInfo;
type InitError = Error;
fn init(&self) -> impl Init<Self::Command, Self::InitError> {
GspSetSystemInfo::init(self.pdev)
}
}

View File

@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pub(crate) mod commands;
mod r570_144;
// Alias to avoid repeating the version number with every use.

View File

@@ -0,0 +1,56 @@
// SPDX-License-Identifier: GPL-2.0
use kernel::prelude::*;
use kernel::transmute::{AsBytes, FromBytes};
use kernel::{device, pci};
use crate::gsp::GSP_PAGE_SIZE;
use super::bindings;
/// Payload of the `GspSetSystemInfo` command.
#[repr(transparent)]
pub(crate) struct GspSetSystemInfo {
inner: bindings::GspSystemInfo,
}
static_assert!(size_of::<GspSetSystemInfo>() < GSP_PAGE_SIZE);
impl GspSetSystemInfo {
/// Returns an in-place initializer for the `GspSetSystemInfo` command.
#[allow(non_snake_case)]
pub(crate) fn init<'a>(dev: &'a pci::Device<device::Bound>) -> impl Init<Self, Error> + 'a {
type InnerGspSystemInfo = bindings::GspSystemInfo;
let init_inner = try_init!(InnerGspSystemInfo {
gpuPhysAddr: dev.resource_start(0)?,
gpuPhysFbAddr: dev.resource_start(1)?,
gpuPhysInstAddr: dev.resource_start(3)?,
nvDomainBusDeviceFunc: u64::from(dev.dev_id()),
// Using TASK_SIZE in r535_gsp_rpc_set_system_info() seems wrong because
// TASK_SIZE is per-task. That's probably a design issue in GSP-RM though.
maxUserVa: (1 << 47) - 4096,
pciConfigMirrorBase: 0x088000,
pciConfigMirrorSize: 0x001000,
PCIDeviceID: (u32::from(dev.device_id()) << 16) | u32::from(dev.vendor_id().as_raw()),
PCISubDeviceID: (u32::from(dev.subsystem_device_id()) << 16)
| u32::from(dev.subsystem_vendor_id()),
PCIRevisionID: u32::from(dev.revision_id()),
bIsPrimary: 0,
bPreserveVideoMemoryAllocations: 0,
..Zeroable::init_zeroed()
});
try_init!(GspSetSystemInfo {
inner <- init_inner,
})
}
}
// SAFETY: These structs don't meet the no-padding requirements of AsBytes but
// that is not a problem because they are not used outside the kernel.
unsafe impl AsBytes for GspSetSystemInfo {}
// SAFETY: These structs don't meet the no-padding requirements of FromBytes but
// that is not a problem because they are not used outside the kernel.
unsafe impl FromBytes for GspSetSystemInfo {}

View File

@@ -321,6 +321,138 @@ 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, Zeroable)]
pub struct DOD_METHOD_DATA {
pub status: u32_,
pub acpiIdListLen: u32_,
pub acpiIdList: [u32_; 16usize],
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct JT_METHOD_DATA {
pub status: u32_,
pub jtCaps: u32_,
pub jtRevId: u16_,
pub bSBIOSCaps: u8_,
pub __bindgen_padding_0: u8,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct MUX_METHOD_DATA_ELEMENT {
pub acpiId: u32_,
pub mode: u32_,
pub status: u32_,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct MUX_METHOD_DATA {
pub tableLen: u32_,
pub acpiIdMuxModeTable: [MUX_METHOD_DATA_ELEMENT; 16usize],
pub acpiIdMuxPartTable: [MUX_METHOD_DATA_ELEMENT; 16usize],
pub acpiIdMuxStateTable: [MUX_METHOD_DATA_ELEMENT; 16usize],
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct CAPS_METHOD_DATA {
pub status: u32_,
pub optimusCaps: u32_,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct ACPI_METHOD_DATA {
pub bValid: u8_,
pub __bindgen_padding_0: [u8; 3usize],
pub dodMethodData: DOD_METHOD_DATA,
pub jtMethodData: JT_METHOD_DATA,
pub muxMethodData: MUX_METHOD_DATA,
pub capsMethodData: CAPS_METHOD_DATA,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct BUSINFO {
pub deviceID: u16_,
pub vendorID: u16_,
pub subdeviceID: u16_,
pub subvendorID: u16_,
pub revisionID: u8_,
pub __bindgen_padding_0: u8,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct GSP_VF_INFO {
pub totalVFs: u32_,
pub firstVFOffset: u32_,
pub FirstVFBar0Address: u64_,
pub FirstVFBar1Address: u64_,
pub FirstVFBar2Address: u64_,
pub b64bitBar0: u8_,
pub b64bitBar1: u8_,
pub b64bitBar2: u8_,
pub __bindgen_padding_0: [u8; 5usize],
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct GSP_PCIE_CONFIG_REG {
pub linkCap: u32_,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct GspSystemInfo {
pub gpuPhysAddr: u64_,
pub gpuPhysFbAddr: u64_,
pub gpuPhysInstAddr: u64_,
pub gpuPhysIoAddr: u64_,
pub nvDomainBusDeviceFunc: u64_,
pub simAccessBufPhysAddr: u64_,
pub notifyOpSharedSurfacePhysAddr: u64_,
pub pcieAtomicsOpMask: u64_,
pub consoleMemSize: u64_,
pub maxUserVa: u64_,
pub pciConfigMirrorBase: u32_,
pub pciConfigMirrorSize: u32_,
pub PCIDeviceID: u32_,
pub PCISubDeviceID: u32_,
pub PCIRevisionID: u32_,
pub pcieAtomicsCplDeviceCapMask: u32_,
pub oorArch: u8_,
pub __bindgen_padding_0: [u8; 7usize],
pub clPdbProperties: u64_,
pub Chipset: u32_,
pub bGpuBehindBridge: u8_,
pub bFlrSupported: u8_,
pub b64bBar0Supported: u8_,
pub bMnocAvailable: u8_,
pub chipsetL1ssEnable: u32_,
pub bUpstreamL0sUnsupported: u8_,
pub bUpstreamL1Unsupported: u8_,
pub bUpstreamL1PorSupported: u8_,
pub bUpstreamL1PorMobileOnly: u8_,
pub bSystemHasMux: u8_,
pub upstreamAddressValid: u8_,
pub FHBBusInfo: BUSINFO,
pub chipsetIDInfo: BUSINFO,
pub __bindgen_padding_1: [u8; 2usize],
pub acpiMethodData: ACPI_METHOD_DATA,
pub hypervisorType: u32_,
pub bIsPassthru: u8_,
pub __bindgen_padding_2: [u8; 7usize],
pub sysTimerOffsetNs: u64_,
pub gspVFInfo: GSP_VF_INFO,
pub bIsPrimary: u8_,
pub isGridBuild: u8_,
pub __bindgen_padding_3: [u8; 2usize],
pub pcieConfigReg: GSP_PCIE_CONFIG_REG,
pub gridBuildCsp: u32_,
pub bPreserveVideoMemoryAllocations: u8_,
pub bTdrEventSupported: u8_,
pub bFeatureStretchVblankCapable: u8_,
pub bEnableDynamicGranularityPageArrays: u8_,
pub bClockBoostSupported: u8_,
pub bRouteDispIntrsToCPU: u8_,
pub __bindgen_padding_4: [u8; 6usize],
pub hostPageSize: u64_,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Zeroable)]
pub struct MESSAGE_QUEUE_INIT_ARGUMENTS {
pub sharedMemPhysAddr: u64_,
pub pageTableEntryCount: u32_,