[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251110-gsp_boot-v9-10-8ae4058e3c0e@nvidia.com>
Date: Mon, 10 Nov 2025 22:34:18 +0900
From: Alexandre Courbot <acourbot@...dia.com>
To: Danilo Krummrich <dakr@...nel.org>, Alice Ryhl <aliceryhl@...gle.com>,
David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>,
Benno Lossin <lossin@...nel.org>, Miguel Ojeda <ojeda@...nel.org>,
Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Andreas Hindborg <a.hindborg@...nel.org>, Trevor Gross <tmgross@...ch.edu>
Cc: John Hubbard <jhubbard@...dia.com>,
Alistair Popple <apopple@...dia.com>,
Joel Fernandes <joelagnelf@...dia.com>, Timur Tabi <ttabi@...dia.com>,
Edwin Peer <epeer@...dia.com>, nouveau@...ts.freedesktop.org,
dri-devel@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
rust-for-linux@...r.kernel.org, Alexandre Courbot <acourbot@...dia.com>
Subject: [PATCH v9 10/15] gpu: nova-core: gsp: Create rmargs
From: Alistair Popple <apopple@...dia.com>
Initialise the GSP resource manager arguments (rmargs) which provides
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.
Co-developed-by: Alexandre Courbot <acourbot@...dia.com>
Signed-off-by: Alexandre Courbot <acourbot@...dia.com>
Signed-off-by: Alistair Popple <apopple@...dia.com>
---
drivers/gpu/nova-core/gsp.rs | 18 ++++++++++++++--
drivers/gpu/nova-core/gsp/cmdq.rs | 27 +++++++++++++++++++++++-
drivers/gpu/nova-core/gsp/fw.rs | 44 ++++++++++++++++++++++++++++++++++++++-
3 files changed, 85 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index f9819a04bb40..609f8e5f2dcc 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -24,8 +24,11 @@
use crate::{
gsp::cmdq::Cmdq,
- gsp::fw::LibosMemoryRegionInitArgument,
- num, //
+ gsp::fw::{
+ GspArgumentsCached,
+ LibosMemoryRegionInitArgument, //
+ },
+ num,
};
pub(crate) const GSP_PAGE_SHIFT: usize = 12;
@@ -108,6 +111,8 @@ pub(crate) struct Gsp {
logrm: LogBuffer,
/// Command queue.
pub(crate) cmdq: Cmdq,
+ /// RM arguments.
+ rmargs: CoherentAllocation<GspArgumentsCached>,
}
impl Gsp {
@@ -134,11 +139,20 @@ pub(crate) fn new(pdev: &pci::Device<device::Bound>) -> Result<impl PinInit<Self
let cmdq = Cmdq::new(dev)?;
+ let rmargs = CoherentAllocation::<GspArgumentsCached>::alloc_coherent(
+ dev,
+ 1,
+ GFP_KERNEL | __GFP_ZERO,
+ )?;
+ dma_write!(rmargs[0] = fw::GspArgumentsCached::new(&cmdq))?;
+ dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", &rmargs))?;
+
Ok(try_pin_init!(Self {
libos,
loginit,
logintr,
logrm,
+ rmargs,
cmdq,
}))
}
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index c00d9fa9b79b..295903c28922 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -11,7 +11,10 @@
use kernel::{
device,
- dma::CoherentAllocation,
+ dma::{
+ CoherentAllocation,
+ DmaAddress, //
+ },
dma_write,
io::poll::read_poll_timeout,
prelude::*,
@@ -33,6 +36,7 @@
MsgqTxHeader, //
},
PteArray,
+ GSP_PAGE_SHIFT,
GSP_PAGE_SIZE, //
},
num,
@@ -429,6 +433,22 @@ pub(crate) struct Cmdq {
}
impl Cmdq {
+ /// Offset of the data after the PTEs.
+ const POST_PTE_OFFSET: usize = core::mem::offset_of!(GspMem, cpuq);
+
+ /// Offset of command queue ring buffer.
+ pub(crate) const CMDQ_OFFSET: usize = core::mem::offset_of!(GspMem, cpuq)
+ + core::mem::offset_of!(Msgq, msgq)
+ - Self::POST_PTE_OFFSET;
+
+ /// Offset of message queue ring buffer.
+ pub(crate) const STATQ_OFFSET: usize = core::mem::offset_of!(GspMem, gspq)
+ + core::mem::offset_of!(Msgq, msgq)
+ - Self::POST_PTE_OFFSET;
+
+ /// Number of page table entries for the GSP shared region.
+ pub(crate) const NUM_PTES: usize = size_of::<GspMem>() >> GSP_PAGE_SHIFT;
+
/// Creates a new command queue for `dev`.
pub(crate) fn new(dev: &device::Device<device::Bound>) -> Result<Cmdq> {
let gsp_mem = DmaGspMem::new(dev)?;
@@ -653,4 +673,9 @@ pub(crate) fn receive_msg<M: MessageFromGsp>(&mut self, timeout: Delta) -> Resul
result
}
+
+ /// Returns the DMA handle of the command queue's shared memory region.
+ pub(crate) fn dma_handle(&self) -> DmaAddress {
+ self.gsp_mem.0.dma_handle()
+ }
}
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index ceda61c99b92..b083a6a5754c 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -31,7 +31,10 @@
fb::FbLayout,
firmware::gsp::GspFirmware,
gpu::Chipset,
- gsp::GSP_PAGE_SIZE,
+ gsp::{
+ cmdq::Cmdq, //
+ GSP_PAGE_SIZE,
+ },
num::{
self,
FromSafeCast, //
@@ -568,3 +571,42 @@ unsafe impl AsBytes for GspMsgElement {}
// SAFETY: This struct only contains integer types for which all bit patterns
// are valid.
unsafe impl FromBytes for GspMsgElement {}
+
+/// Arguments for GSP startup.
+#[repr(transparent)]
+pub(crate) struct GspArgumentsCached(bindings::GSP_ARGUMENTS_CACHED);
+
+impl GspArgumentsCached {
+ /// Creates the arguments for starting the GSP up using `cmdq` as its command queue.
+ pub(crate) fn new(cmdq: &Cmdq) -> Self {
+ Self(bindings::GSP_ARGUMENTS_CACHED {
+ messageQueueInitArguments: MessageQueueInitArguments::new(cmdq).0,
+ bDmemStack: 1,
+ ..Default::default()
+ })
+ }
+}
+
+// SAFETY: Padding is explicit and will not contain uninitialized data.
+unsafe impl AsBytes for GspArgumentsCached {}
+
+// SAFETY: This struct only contains integer types for which all bit patterns
+// are valid.
+unsafe impl FromBytes for GspArgumentsCached {}
+
+/// Init arguments for the message queue.
+#[repr(transparent)]
+struct MessageQueueInitArguments(bindings::MESSAGE_QUEUE_INIT_ARGUMENTS);
+
+impl MessageQueueInitArguments {
+ /// Creates a new init arguments structure for `cmdq`.
+ fn new(cmdq: &Cmdq) -> Self {
+ Self(bindings::MESSAGE_QUEUE_INIT_ARGUMENTS {
+ sharedMemPhysAddr: cmdq.dma_handle(),
+ pageTableEntryCount: num::usize_into_u32::<{ Cmdq::NUM_PTES }>(),
+ cmdQueueOffset: num::usize_as_u64(Cmdq::CMDQ_OFFSET),
+ statQueueOffset: num::usize_as_u64(Cmdq::STATQ_OFFSET),
+ ..Default::default()
+ })
+ }
+}
--
2.51.2
Powered by blists - more mailing lists