drivers/gpu/nova-core/firmware/fsp.rs

Source file repositories/reference/linux-study-clean/drivers/gpu/nova-core/firmware/fsp.rs

File Facts

System
Linux kernel
Corpus path
drivers/gpu/nova-core/firmware/fsp.rs
Extension
.rs
Size
4628 bytes
Lines
129
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.

//! FSP is a hardware unit that runs FMC firmware.

use kernel::{
    device,
    dma::Coherent,
    firmware::Firmware,
    prelude::*, //
};

use crate::{
    firmware::elf,
    gpu::Chipset, //
};

/// Size of the FSP SHA-384 hash, in bytes.
const FSP_HASH_SIZE: usize = 48;
/// Maximum size of the FSP public key (RSA-3072), in bytes.
///
/// The FMC ELF `publickey` section may be shorter, so the remaining bytes are zero-padded.
const FSP_PKEY_SIZE: usize = 384;
/// Maximum size of the FSP signature (RSA-3072), in bytes.
///
/// The FMC ELF `signature` section may be shorter, so the remaining bytes are zero-padded.
const FSP_SIG_SIZE: usize = 384;

/// Structure to hold FMC signatures.
///
/// C representation is used because this type is used for communication with the FSP.
#[derive(Debug, Clone, Copy, Zeroable)]
#[repr(C)]
pub(crate) struct FmcSignatures {
    pub(crate) hash384: [u8; FSP_HASH_SIZE],
    pub(crate) public_key: [u8; FSP_PKEY_SIZE],
    pub(crate) signature: [u8; FSP_SIG_SIZE],
}

pub(crate) struct FspFirmware {
    /// FMC firmware image data (only the "image" ELF section).
    pub(crate) fmc_image: Coherent<[u8]>,
    /// FMC firmware signatures.
    pub(crate) fmc_sigs: KBox<FmcSignatures>,
}

impl FspFirmware {
    pub(crate) fn new(
        dev: &device::Device<device::Bound>,
        chipset: Chipset,
        ver: &str,
    ) -> Result<Self> {
        let fw = super::request_firmware(dev, chipset, "fmc", ver)?;

        // 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
        })?;
        let fmc_image = Coherent::from_slice(dev, fmc_image_data, GFP_KERNEL)?;

        Ok(Self {
            fmc_image,
            fmc_sigs: Self::extract_fmc_signatures(&fw, dev)?,
        })
    }

    /// Extract FMC firmware signatures for Chain of Trust verification.
    ///
    /// Extracts real cryptographic signatures from FMC ELF32 firmware sections.
    /// Returns signatures in a heap-allocated structure to prevent stack overflow.
    fn extract_fmc_signatures(
        fmc_fw: &Firmware,
        dev: &device::Device,
    ) -> Result<KBox<FmcSignatures>> {
        let get_section = |name: &str, max_len: usize| {
            elf::elf_section(fmc_fw.data(), name)
                .ok_or(EINVAL)
                .inspect_err(|_| dev_err!(dev, "FMC firmware missing '{}' section\n", name))
                .and_then(|section| {
                    if section.len() > max_len {
                        dev_err!(
                            dev,
                            "FMC {} section size {} > maximum {}\n",
                            name,
                            section.len(),
                            max_len
                        );
                        Err(EINVAL)
                    } else {

Annotation

Implementation Notes