Initialise the GSP resource manager arguments (rmargs) which provide initialisation parameters to the GSP firmware during boot. The rmargs structure contains arguments to configure the GSP message/command queue location.
These are mapped for coherent DMA and added to the libos data structure for access when booting GSP. Signed-off-by: Alistair Popple <apop...@nvidia.com> --- drivers/gpu/nova-core/gsp.rs | 44 +++++++++++++++++-- drivers/gpu/nova-core/gsp/cmdq.rs | 13 +++++- drivers/gpu/nova-core/nvfw.rs | 6 +++ .../gpu/nova-core/nvfw/r570_144_bindings.rs | 33 ++++++++++++++ 4 files changed, 91 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs index 41a88087d9baa..56a6be7b9eb15 100644 --- a/drivers/gpu/nova-core/gsp.rs +++ b/drivers/gpu/nova-core/gsp.rs @@ -17,8 +17,9 @@ use crate::nvfw::{ GspFwWprMeta, GspFwWprMetaBootInfo, GspFwWprMetaBootResumeInfo, LibosMemoryRegionInitArgument, LibosMemoryRegionKind_LIBOS_MEMORY_REGION_CONTIGUOUS, - LibosMemoryRegionLoc_LIBOS_MEMORY_REGION_LOC_SYSMEM, GSP_FW_WPR_META_MAGIC, - GSP_FW_WPR_META_REVISION, + LibosMemoryRegionLoc_LIBOS_MEMORY_REGION_LOC_SYSMEM, GSP_ARGUMENTS_CACHED, + GSP_FW_WPR_META_MAGIC, GSP_FW_WPR_META_REVISION, GSP_SR_INIT_ARGUMENTS, + MESSAGE_QUEUE_INIT_ARGUMENTS, }; pub(crate) mod cmdq; @@ -41,6 +42,19 @@ unsafe impl AsBytes for GspFwWprMeta {} // are valid. unsafe impl FromBytes for GspFwWprMeta {} +// SAFETY: Padding is explicit and will not contain uninitialized data. +unsafe impl AsBytes for GSP_ARGUMENTS_CACHED {} + +// SAFETY: This struct only contains integer types for which all bit patterns +// are valid. +unsafe impl FromBytes for GSP_ARGUMENTS_CACHED {} + +// SAFETY: Padding is explicit and will not contain uninitialized data. +unsafe impl AsBytes for MESSAGE_QUEUE_INIT_ARGUMENTS {} + +// SAFETY: Padding is explicit and will not contain uninitialized data. +unsafe impl AsBytes for GSP_SR_INIT_ARGUMENTS {} + #[allow(unused)] pub(crate) struct GspMemObjects { libos: CoherentAllocation<LibosMemoryRegionInitArgument>, @@ -49,6 +63,7 @@ pub(crate) struct GspMemObjects { pub logrm: CoherentAllocation<u8>, pub wpr_meta: CoherentAllocation<GspFwWprMeta>, pub cmdq: GspCmdq, + rmargs: CoherentAllocation<GSP_ARGUMENTS_CACHED>, } pub(crate) fn build_wpr_meta( @@ -179,13 +194,36 @@ pub(crate) fn new( let wpr_meta = build_wpr_meta(dev, fw, fb_layout)?; // Creates its own PTE array - let cmdq = GspCmdq::new(dev)?; + let mut cmdq = GspCmdq::new(dev)?; + let rmargs = + create_coherent_dma_object::<GSP_ARGUMENTS_CACHED>(dev, "RMARGS", 1, &mut libos, 3)?; + let (shared_mem_phys_addr, cmd_queue_offset, stat_queue_offset) = cmdq.get_cmdq_offsets(); + + dma_write!( + rmargs[0].messageQueueInitArguments = MESSAGE_QUEUE_INIT_ARGUMENTS { + sharedMemPhysAddr: shared_mem_phys_addr, + pageTableEntryCount: cmdq.nr_ptes, + cmdQueueOffset: cmd_queue_offset, + statQueueOffset: stat_queue_offset, + ..Default::default() + } + )?; + dma_write!( + rmargs[0].srInitArguments = GSP_SR_INIT_ARGUMENTS { + oldLevel: 0, + flags: 0, + bInPMTransition: 0, + ..Default::default() + } + )?; + dma_write!(rmargs[0].bDmemStack = 1)?; Ok(GspMemObjects { libos, loginit, logintr, logrm, + rmargs, wpr_meta, cmdq, }) diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs index 3f5d31c8e68f2..134ed0e20d9e3 100644 --- a/drivers/gpu/nova-core/gsp/cmdq.rs +++ b/drivers/gpu/nova-core/gsp/cmdq.rs @@ -162,7 +162,7 @@ pub(crate) struct GspCmdq { msg_count: u32, seq: u32, gsp_mem: CoherentAllocation<GspMem>, - pub _nr_ptes: u32, + pub nr_ptes: u32, } // A reference to a message currently sitting in the GSP command queue. May @@ -289,7 +289,7 @@ pub(crate) fn new(dev: &device::Device<device::Bound>) -> Result<GspCmdq> { msg_count: MSG_COUNT, seq: 0, gsp_mem, - _nr_ptes: nr_ptes as u32, + nr_ptes: nr_ptes as u32, }) } @@ -639,6 +639,15 @@ pub(crate) fn receive_msg_from_gsp<'a>(&'a mut self) -> Result<GspQueueMessage<' Ok(gspq_msg) } + pub(crate) fn get_cmdq_offsets(&self) -> (u64, u64, u64) { + ( + self.gsp_mem.dma_handle(), + core::mem::offset_of!(Msgq, msgq) as u64, + (core::mem::offset_of!(GspMem, gspq) - core::mem::offset_of!(GspMem, cpuq) + + core::mem::offset_of!(Msgq, msgq)) as u64, + ) + } + fn ack_msg(&mut self, length: u32) -> Result { const HEADER_SIZE: u32 = (size_of::<GspMsgHeader>() + size_of::<GspRpcHeader>()) as u32; let mut rptr = self.cpu_rptr(); diff --git a/drivers/gpu/nova-core/nvfw.rs b/drivers/gpu/nova-core/nvfw.rs index 0db4e18f7dc97..3d934cc95feb0 100644 --- a/drivers/gpu/nova-core/nvfw.rs +++ b/drivers/gpu/nova-core/nvfw.rs @@ -47,9 +47,15 @@ pub(crate) struct LibosParams { LibosMemoryRegionKind_LIBOS_MEMORY_REGION_CONTIGUOUS, LibosMemoryRegionLoc_LIBOS_MEMORY_REGION_LOC_SYSMEM, + GSP_ARGUMENTS_CACHED, + // GSP firmware constants GSP_FW_WPR_META_MAGIC, GSP_FW_WPR_META_REVISION, + GSP_SR_INIT_ARGUMENTS, + + // RM message queue parameters + MESSAGE_QUEUE_INIT_ARGUMENTS, // GSP events NV_VGPU_MSG_EVENT_GSP_INIT_DONE, diff --git a/drivers/gpu/nova-core/nvfw/r570_144_bindings.rs b/drivers/gpu/nova-core/nvfw/r570_144_bindings.rs index 8820c488cd25f..ab331fe6b1c81 100644 --- a/drivers/gpu/nova-core/nvfw/r570_144_bindings.rs +++ b/drivers/gpu/nova-core/nvfw/r570_144_bindings.rs @@ -288,6 +288,39 @@ 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 MESSAGE_QUEUE_INIT_ARGUMENTS { + pub sharedMemPhysAddr: u64_, + pub pageTableEntryCount: u32_, + pub __bindgen_padding_0: [u8; 4usize], + pub cmdQueueOffset: u64_, + pub statQueueOffset: u64_, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct GSP_SR_INIT_ARGUMENTS { + pub oldLevel: u32_, + pub flags: u32_, + pub bInPMTransition: u8_, + pub __bindgen_padding_0: [u8; 3usize], +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct GSP_ARGUMENTS_CACHED { + pub messageQueueInitArguments: MESSAGE_QUEUE_INIT_ARGUMENTS, + pub srInitArguments: GSP_SR_INIT_ARGUMENTS, + pub gpuInstance: u32_, + pub bDmemStack: u8_, + pub __bindgen_padding_0: [u8; 7usize], + pub profilerArgs: GSP_ARGUMENTS_CACHED__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct GSP_ARGUMENTS_CACHED__bindgen_ty_1 { + pub pa: u64_, + pub size: u64_, +} +#[repr(C)] #[derive(Copy, Clone)] pub struct GspFwWprMeta { pub magic: u64_, -- 2.47.2