[PATCH v3 16/33] gpu: nova-core: move the bootloader DMEM descriptor out of FWSEC

From: John Hubbard

Date: Thu Sep 17 2026 - 21:13:52 EST


The generic falcon bootloader reads its load parameters from a
descriptor that the driver places in DMEM. The r000 load-and-execute
bootloader event carries such a descriptor, so its handler in the
following patch needs the descriptor type.

The descriptor was defined in the FWSEC code, which was its only user.

Move the definition, unchanged, into the generic bootloader module. Its
fields become pub(crate) so that the FWSEC code can still fill them in.

No functional changes.

Assisted-by: LLM
Signed-off-by: John Hubbard <jhubbard@xxxxxxxxxx>
---
.../nova-core/firmware/fwsec/bootloader.rs | 52 ++-----------------
.../gpu/nova-core/firmware/gen_bootloader.rs | 48 +++++++++++++++++
2 files changed, 52 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
index 1584a4b814d2..96ad223df16f 100644
--- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
+++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
@@ -35,60 +35,16 @@
},
firmware::{
fwsec::FwsecFirmware,
- gen_bootloader::GenericBootloader, //
+ gen_bootloader::{
+ BootloaderDmemDescV2,
+ GenericBootloader, //
+ },
},
gpu::Chipset,
num::FromSafeCast, //
regs,
};

-/// Structure used by the boot-loader to load the rest of the code.
-///
-/// This has to be filled by the GPU driver and copied into DMEM at offset
-/// [`BootloaderDesc.dmem_load_off`].
-#[repr(C, packed)]
-#[derive(Debug, Clone)]
-struct BootloaderDmemDescV2 {
- /// Reserved, should always be first element.
- reserved: [u32; 4],
- /// 16B signature for secure code, 0s if no secure code.
- signature: [u32; 4],
- /// DMA context used by the bootloader while loading code/data.
- ctx_dma: u32,
- /// 256B-aligned physical FB address where code is located.
- code_dma_base: u64,
- /// Offset from `code_dma_base` where the non-secure code is located.
- ///
- /// Also used as destination IMEM offset of non-secure code as the DMA firmware object is
- /// expected to be a mirror image of its loaded state.
- ///
- /// Must be multiple of 256.
- non_sec_code_off: u32,
- /// Size of the non-secure code part.
- non_sec_code_size: u32,
- /// Offset from `code_dma_base` where the secure code is located (must be multiple of 256).
- ///
- /// Also used as destination IMEM offset of secure code as the DMA firmware object is expected
- /// to be a mirror image of its loaded state.
- ///
- /// Must be multiple of 256.
- sec_code_off: u32,
- /// Size of the secure code part.
- sec_code_size: u32,
- /// Code entry point invoked by the bootloader after code is loaded.
- code_entry_point: u32,
- /// 256B-aligned physical FB address where data is located.
- data_dma_base: u64,
- /// Size of data block (should be multiple of 256B).
- data_size: u32,
- /// Number of arguments to be passed to the target firmware being loaded.
- argc: u32,
- /// Arguments to be passed to the target firmware being loaded.
- argv: u32,
-}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for BootloaderDmemDescV2 {}
-
/// Wrapper for [`FwsecFirmware`] that includes the bootloader performing the actual load
/// operation.
pub(crate) struct FwsecFirmwareWithBl<'a> {
diff --git a/drivers/gpu/nova-core/firmware/gen_bootloader.rs b/drivers/gpu/nova-core/firmware/gen_bootloader.rs
index 65af57a34940..943a5bc16e93 100644
--- a/drivers/gpu/nova-core/firmware/gen_bootloader.rs
+++ b/drivers/gpu/nova-core/firmware/gen_bootloader.rs
@@ -12,6 +12,7 @@
Alignable,
Alignment, //
},
+ transmute::AsBytes, //
};

use crate::{
@@ -27,6 +28,53 @@
num::FromSafeCast, //
};

+/// Structure used by the boot-loader to load the rest of the code.
+///
+/// This has to be filled by the GPU driver and copied into DMEM at offset
+/// [`BootloaderDesc.dmem_load_off`].
+#[repr(C, packed)]
+#[derive(Debug, Clone)]
+pub(crate) struct BootloaderDmemDescV2 {
+ /// Reserved, should always be first element.
+ pub(crate) reserved: [u32; 4],
+ /// 16B signature for secure code, 0s if no secure code.
+ pub(crate) signature: [u32; 4],
+ /// DMA context used by the bootloader while loading code/data.
+ pub(crate) ctx_dma: u32,
+ /// 256B-aligned physical FB address where code is located.
+ pub(crate) code_dma_base: u64,
+ /// Offset from `code_dma_base` where the non-secure code is located.
+ ///
+ /// Also used as destination IMEM offset of non-secure code as the DMA firmware object is
+ /// expected to be a mirror image of its loaded state.
+ ///
+ /// Must be multiple of 256.
+ pub(crate) non_sec_code_off: u32,
+ /// Size of the non-secure code part.
+ pub(crate) non_sec_code_size: u32,
+ /// Offset from `code_dma_base` where the secure code is located (must be multiple of 256).
+ ///
+ /// Also used as destination IMEM offset of secure code as the DMA firmware object is expected
+ /// to be a mirror image of its loaded state.
+ ///
+ /// Must be multiple of 256.
+ pub(crate) sec_code_off: u32,
+ /// Size of the secure code part.
+ pub(crate) sec_code_size: u32,
+ /// Code entry point invoked by the bootloader after code is loaded.
+ pub(crate) code_entry_point: u32,
+ /// 256B-aligned physical FB address where data is located.
+ pub(crate) data_dma_base: u64,
+ /// Size of data block (should be multiple of 256B).
+ pub(crate) data_size: u32,
+ /// Number of arguments to be passed to the target firmware being loaded.
+ pub(crate) argc: u32,
+ /// Arguments to be passed to the target firmware being loaded.
+ pub(crate) argv: u32,
+}
+// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
+unsafe impl AsBytes for BootloaderDmemDescV2 {}
+
/// The generic falcon bootloader image and its IMEM load parameters.
pub(crate) struct GenericBootloader {
/// Bootloader code, zero-padded to a whole number of falcon memory blocks.
--
2.55.0