[PATCH v8 12/31] gpu: nova-core: Hopper/Blackwell: add FMC firmware image, in support of FSP

John Hubbard posted 31 patches 1 week, 1 day ago
There is a newer version of this series
[PATCH v8 12/31] gpu: nova-core: Hopper/Blackwell: add FMC firmware image, in support of FSP
Posted by John Hubbard 1 week, 1 day ago
FSP is the Falcon that runs FMC firmware on Hopper and Blackwell.
Load the FMC ELF in two forms: the image section that FSP boots from,
and a CPU-side copy of the full ELF for later signature extraction
during Chain of Trust verification.

Co-developed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
 drivers/gpu/nova-core/firmware.rs     |  1 +
 drivers/gpu/nova-core/firmware/fsp.rs | 47 +++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 drivers/gpu/nova-core/firmware/fsp.rs

diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs
index bc217bfc225f..bc26807116e4 100644
--- a/drivers/gpu/nova-core/firmware.rs
+++ b/drivers/gpu/nova-core/firmware.rs
@@ -27,6 +27,7 @@
 };
 
 pub(crate) mod booter;
+pub(crate) mod fsp;
 pub(crate) mod fwsec;
 pub(crate) mod gsp;
 pub(crate) mod riscv;
diff --git a/drivers/gpu/nova-core/firmware/fsp.rs b/drivers/gpu/nova-core/firmware/fsp.rs
new file mode 100644
index 000000000000..5aedee8e6d41
--- /dev/null
+++ b/drivers/gpu/nova-core/firmware/fsp.rs
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! FSP is a hardware unit that runs FMC firmware.
+
+use kernel::{
+    alloc::KVec,
+    device,
+    prelude::*, //
+};
+
+use crate::{
+    dma::DmaObject,
+    firmware::elf,
+    gpu::Chipset, //
+};
+
+#[expect(unused)]
+pub(crate) struct FspFirmware {
+    /// FMC firmware image data (only the "image" ELF section).
+    fmc_image: DmaObject,
+    /// Full FMC ELF data (for signature extraction).
+    pub(crate) fmc_full: KVec<u8>,
+}
+
+impl FspFirmware {
+    #[expect(unused)]
+    pub(crate) fn new(
+        dev: &device::Device<device::Bound>,
+        chipset: Chipset,
+        ver: &str,
+    ) -> Result<Self> {
+        let fw = super::request_firmware(dev, chipset, "fmc", ver)?;
+        let mut fmc_full = KVec::with_capacity(fw.data().len(), GFP_KERNEL)?;
+        fmc_full.extend_from_slice(fw.data(), GFP_KERNEL)?;
+
+        // FSP expects only the "image" section, not the entire ELF file.
+        let fmc_image_data = elf::elf_section(fw.data(), "image").ok_or_else(|| {
+            dev_err!(dev, "FMC ELF file missing 'image' section\n");
+            EINVAL
+        })?;
+
+        Ok(Self {
+            fmc_image: DmaObject::from_data(dev, fmc_image_data)?,
+            fmc_full,
+        })
+    }
+}
-- 
2.53.0
Re: [PATCH v8 12/31] gpu: nova-core: Hopper/Blackwell: add FMC firmware image, in support of FSP
Posted by Gary Guo 1 week, 1 day ago
On Wed Mar 25, 2026 at 3:52 AM GMT, John Hubbard wrote:
> FSP is the Falcon that runs FMC firmware on Hopper and Blackwell.
> Load the FMC ELF in two forms: the image section that FSP boots from,
> and a CPU-side copy of the full ELF for later signature extraction
> during Chain of Trust verification.
>
> Co-developed-by: Alexandre Courbot <acourbot@nvidia.com>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
> ---
>  drivers/gpu/nova-core/firmware.rs     |  1 +
>  drivers/gpu/nova-core/firmware/fsp.rs | 47 +++++++++++++++++++++++++++
>  2 files changed, 48 insertions(+)
>  create mode 100644 drivers/gpu/nova-core/firmware/fsp.rs
>
> diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs
> index bc217bfc225f..bc26807116e4 100644
> --- a/drivers/gpu/nova-core/firmware.rs
> +++ b/drivers/gpu/nova-core/firmware.rs
> @@ -27,6 +27,7 @@
>  };
>  
>  pub(crate) mod booter;
> +pub(crate) mod fsp;
>  pub(crate) mod fwsec;
>  pub(crate) mod gsp;
>  pub(crate) mod riscv;
> diff --git a/drivers/gpu/nova-core/firmware/fsp.rs b/drivers/gpu/nova-core/firmware/fsp.rs
> new file mode 100644
> index 000000000000..5aedee8e6d41
> --- /dev/null
> +++ b/drivers/gpu/nova-core/firmware/fsp.rs
> @@ -0,0 +1,47 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! FSP is a hardware unit that runs FMC firmware.
> +
> +use kernel::{
> +    alloc::KVec,
> +    device,
> +    prelude::*, //
> +};
> +
> +use crate::{
> +    dma::DmaObject,
> +    firmware::elf,
> +    gpu::Chipset, //
> +};
> +
> +#[expect(unused)]
> +pub(crate) struct FspFirmware {
> +    /// FMC firmware image data (only the "image" ELF section).
> +    fmc_image: DmaObject,
> +    /// Full FMC ELF data (for signature extraction).
> +    pub(crate) fmc_full: KVec<u8>,
> +}
> +
> +impl FspFirmware {
> +    #[expect(unused)]
> +    pub(crate) fn new(
> +        dev: &device::Device<device::Bound>,
> +        chipset: Chipset,
> +        ver: &str,
> +    ) -> Result<Self> {
> +        let fw = super::request_firmware(dev, chipset, "fmc", ver)?;
> +        let mut fmc_full = KVec::with_capacity(fw.data().len(), GFP_KERNEL)?;
> +        fmc_full.extend_from_slice(fw.data(), GFP_KERNEL)?;

What's this copy for? It looks like you never need to modify it, so keeping hold
on `Firmware` should be fine?

Best,
Gary

> +
> +        // FSP expects only the "image" section, not the entire ELF file.
> +        let fmc_image_data = elf::elf_section(fw.data(), "image").ok_or_else(|| {
> +            dev_err!(dev, "FMC ELF file missing 'image' section\n");
> +            EINVAL
> +        })?;
> +
> +        Ok(Self {
> +            fmc_image: DmaObject::from_data(dev, fmc_image_data)?,
> +            fmc_full,
> +        })
> +    }
> +}
Re: [PATCH v8 12/31] gpu: nova-core: Hopper/Blackwell: add FMC firmware image, in support of FSP
Posted by John Hubbard 1 week, 1 day ago
On 3/25/26 8:52 AM, Gary Guo wrote:
> On Wed Mar 25, 2026 at 3:52 AM GMT, John Hubbard wrote:
>> FSP is the Falcon that runs FMC firmware on Hopper and Blackwell.
>> Load the FMC ELF in two forms: the image section that FSP boots from,
>> and a CPU-side copy of the full ELF for later signature extraction
>> during Chain of Trust verification.
>>
>> Co-developed-by: Alexandre Courbot <acourbot@nvidia.com>
>> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
>> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
>> ---
>>  drivers/gpu/nova-core/firmware.rs     |  1 +
>>  drivers/gpu/nova-core/firmware/fsp.rs | 47 +++++++++++++++++++++++++++
>>  2 files changed, 48 insertions(+)
>>  create mode 100644 drivers/gpu/nova-core/firmware/fsp.rs
>>
>> diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs
>> index bc217bfc225f..bc26807116e4 100644
>> --- a/drivers/gpu/nova-core/firmware.rs
>> +++ b/drivers/gpu/nova-core/firmware.rs
>> @@ -27,6 +27,7 @@
>>  };
>>  
>>  pub(crate) mod booter;
>> +pub(crate) mod fsp;
>>  pub(crate) mod fwsec;
>>  pub(crate) mod gsp;
>>  pub(crate) mod riscv;
>> diff --git a/drivers/gpu/nova-core/firmware/fsp.rs b/drivers/gpu/nova-core/firmware/fsp.rs
>> new file mode 100644
>> index 000000000000..5aedee8e6d41
>> --- /dev/null
>> +++ b/drivers/gpu/nova-core/firmware/fsp.rs
>> @@ -0,0 +1,47 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +//! FSP is a hardware unit that runs FMC firmware.
>> +
>> +use kernel::{
>> +    alloc::KVec,
>> +    device,
>> +    prelude::*, //
>> +};
>> +
>> +use crate::{
>> +    dma::DmaObject,
>> +    firmware::elf,
>> +    gpu::Chipset, //
>> +};
>> +
>> +#[expect(unused)]
>> +pub(crate) struct FspFirmware {
>> +    /// FMC firmware image data (only the "image" ELF section).
>> +    fmc_image: DmaObject,
>> +    /// Full FMC ELF data (for signature extraction).
>> +    pub(crate) fmc_full: KVec<u8>,
>> +}
>> +
>> +impl FspFirmware {
>> +    #[expect(unused)]
>> +    pub(crate) fn new(
>> +        dev: &device::Device<device::Bound>,
>> +        chipset: Chipset,
>> +        ver: &str,
>> +    ) -> Result<Self> {
>> +        let fw = super::request_firmware(dev, chipset, "fmc", ver)?;
>> +        let mut fmc_full = KVec::with_capacity(fw.data().len(), GFP_KERNEL)?;
>> +        fmc_full.extend_from_slice(fw.data(), GFP_KERNEL)?;
> 
> What's this copy for? It looks like you never need to modify it, so keeping hold
> on `Firmware` should be fine?
> 

Right. Fixed in v9, thanks.

thanks,
-- 
John Hubbard

>> +
>> +        // FSP expects only the "image" section, not the entire ELF file.
>> +        let fmc_image_data = elf::elf_section(fw.data(), "image").ok_or_else(|| {
>> +            dev_err!(dev, "FMC ELF file missing 'image' section\n");
>> +            EINVAL
>> +        })?;
>> +
>> +        Ok(Self {
>> +            fmc_image: DmaObject::from_data(dev, fmc_image_data)?,
>> +            fmc_full,
>> +        })
>> +    }
>> +}
>