Commit 4fd4acd9 authored by Alistair Popple's avatar Alistair Popple Committed by Alexandre Courbot
Browse files

gpu: nova-core: gsp: Create rmargs



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.

Signed-off-by: default avatarAlistair Popple <apopple@nvidia.com>
Co-developed-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Message-ID: <20251110-gsp_boot-v9-10-8ae4058e3c0e@nvidia.com>
parent 75f6b1de
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -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,
        }))
    }
+26 −1
Original line number Diff line number Diff line
@@ -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()
    }
}
+43 −1
Original line number Diff line number Diff line
@@ -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()
        })
    }
}