Skip to content

Commit 4257d31

Browse files
johnhubbardGnurou
authored andcommitted
gpu: nova-core: Hopper/Blackwell: add FMC firmware image
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 the full Firmware object for later signature extraction during Chain of Trust verification. Declare the FMC image in the module's firmware table so it is bundled for FSP-based chipsets. Signed-off-by: John Hubbard <jhubbard@nvidia.com> Reviewed-by: Eliot Courtney <ecourtney@nvidia.com> Link: https://patch.msgid.link/20260602032111.224790-12-jhubbard@nvidia.com Co-developed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
1 parent 34599e0 commit 4257d31

4 files changed

Lines changed: 72 additions & 3 deletions

File tree

drivers/gpu/nova-core/firmware.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use crate::{
2828
};
2929

3030
pub(crate) mod booter;
31+
pub(crate) mod fsp;
3132
pub(crate) mod fwsec;
3233
pub(crate) mod gsp;
3334
pub(crate) mod riscv;
@@ -431,10 +432,16 @@ impl<const N: usize> ModInfoBuilder<N> {
431432
.make_entry_file(name, "bootloader")
432433
.make_entry_file(name, "gsp");
433434

434-
if chipset.needs_fwsec_bootloader() {
435+
let this = if chipset.needs_fwsec_bootloader() {
435436
this.make_entry_file(name, "gen_bootloader")
436437
} else {
437438
this
439+
};
440+
441+
if chipset.uses_fsp() {
442+
this.make_entry_file(name, "fmc")
443+
} else {
444+
this
438445
}
439446
}
440447

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
4+
//! FSP is a hardware unit that runs FMC firmware.
5+
6+
use kernel::{
7+
device,
8+
dma::Coherent,
9+
firmware::Firmware,
10+
prelude::*, //
11+
};
12+
13+
use crate::{
14+
firmware::elf,
15+
gpu::Chipset, //
16+
};
17+
18+
pub(crate) struct FspFirmware {
19+
/// FMC firmware image data (only the "image" ELF section).
20+
#[expect(dead_code)]
21+
pub(crate) fmc_image: Coherent<[u8]>,
22+
/// Full FMC ELF for signature extraction.
23+
#[expect(dead_code)]
24+
pub(crate) fmc_elf: Firmware,
25+
}
26+
27+
impl FspFirmware {
28+
pub(crate) fn new(
29+
dev: &device::Device<device::Bound>,
30+
chipset: Chipset,
31+
ver: &str,
32+
) -> Result<Self> {
33+
let fw = super::request_firmware(dev, chipset, "fmc", ver)?;
34+
35+
// FSP expects only the "image" section, not the entire ELF file.
36+
let fmc_image_data = elf::elf_section(fw.data(), "image").ok_or_else(|| {
37+
dev_err!(dev, "FMC ELF file missing 'image' section\n");
38+
EINVAL
39+
})?;
40+
let fmc_image = Coherent::from_slice(dev, fmc_image_data, GFP_KERNEL)?;
41+
42+
Ok(Self {
43+
fmc_image,
44+
fmc_elf: fw,
45+
})
46+
}
47+
}

drivers/gpu/nova-core/gpu.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,15 @@ impl Chipset {
137137
matches!(self.arch(), Architecture::Turing) || matches!(self, Self::GA100)
138138
}
139139

140+
/// Returns `true` if this chipset boots via FSP (Hopper and later), which requires the FMC
141+
/// firmware image.
142+
pub(crate) const fn uses_fsp(self) -> bool {
143+
matches!(
144+
self.arch(),
145+
Architecture::Hopper | Architecture::BlackwellGB10x | Architecture::BlackwellGB20x
146+
)
147+
}
148+
140149
/// Returns the address range of the PCI config mirror space.
141150
pub(crate) fn pci_config_mirror_range(self) -> Range<u32> {
142151
hal::gpu_hal(self).pci_config_mirror_range()

drivers/gpu/nova-core/gsp/hal/gh100.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ use crate::{
1616
Falcon, //
1717
},
1818
fb::FbLayout,
19+
firmware::{
20+
fsp::FspFirmware,
21+
FIRMWARE_VERSION, //
22+
},
1923
gpu::Chipset,
2024
gsp::{
2125
boot::BootUnloadGuard,
@@ -35,14 +39,16 @@ impl GspHal for Gh100 {
3539
fn boot<'a>(
3640
&self,
3741
_gsp: &'a Gsp,
38-
_dev: &'a device::Device<device::Bound>,
42+
dev: &'a device::Device<device::Bound>,
3943
_bar: &'a Bar0,
40-
_chipset: Chipset,
44+
chipset: Chipset,
4145
_fb_layout: &FbLayout,
4246
_wpr_meta: &Coherent<GspFwWprMeta>,
4347
_gsp_falcon: &'a Falcon<GspEngine>,
4448
_sec2_falcon: &'a Falcon<Sec2>,
4549
) -> Result<BootUnloadGuard<'a>> {
50+
let _fsp_fw = FspFirmware::new(dev, chipset, FIRMWARE_VERSION)?;
51+
4652
Err(ENOTSUPP)
4753
}
4854
}

0 commit comments

Comments
 (0)