mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-17 20:40:33 -05:00
gpu: nova-core: firmware: add support for common firmware header
Several firmware files loaded from userspace feature a common header that describes their payload. Add basic support for it so subsequent patches can leverage it. Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/r/20250913-nova_firmware-v6-5-9007079548b0@nvidia.com Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
@@ -4,11 +4,13 @@
|
||||
//! to be loaded into a given execution unit.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use core::mem::size_of;
|
||||
|
||||
use kernel::device;
|
||||
use kernel::firmware;
|
||||
use kernel::prelude::*;
|
||||
use kernel::str::CString;
|
||||
use kernel::transmute::FromBytes;
|
||||
|
||||
use crate::dma::DmaObject;
|
||||
use crate::falcon::FalconFirmware;
|
||||
@@ -156,6 +158,66 @@ fn no_patch_signature(self) -> FirmwareDmaObject<F, Signed> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Header common to most firmware files.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
struct BinHdr {
|
||||
/// Magic number, must be `0x10de`.
|
||||
bin_magic: u32,
|
||||
/// Version of the header.
|
||||
bin_ver: u32,
|
||||
/// Size in bytes of the binary (to be ignored).
|
||||
bin_size: u32,
|
||||
/// Offset of the start of the application-specific header.
|
||||
header_offset: u32,
|
||||
/// Offset of the start of the data payload.
|
||||
data_offset: u32,
|
||||
/// Size in bytes of the data payload.
|
||||
data_size: u32,
|
||||
}
|
||||
|
||||
// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
|
||||
unsafe impl FromBytes for BinHdr {}
|
||||
|
||||
// A firmware blob starting with a `BinHdr`.
|
||||
struct BinFirmware<'a> {
|
||||
hdr: BinHdr,
|
||||
fw: &'a [u8],
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
impl<'a> BinFirmware<'a> {
|
||||
/// Interpret `fw` as a firmware image starting with a [`BinHdr`], and returns the
|
||||
/// corresponding [`BinFirmware`] that can be used to extract its payload.
|
||||
fn new(fw: &'a firmware::Firmware) -> Result<Self> {
|
||||
const BIN_MAGIC: u32 = 0x10de;
|
||||
let fw = fw.data();
|
||||
|
||||
fw.get(0..size_of::<BinHdr>())
|
||||
// Extract header.
|
||||
.and_then(BinHdr::from_bytes_copy)
|
||||
// Validate header.
|
||||
.and_then(|hdr| {
|
||||
if hdr.bin_magic == BIN_MAGIC {
|
||||
Some(hdr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|hdr| Self { hdr, fw })
|
||||
.ok_or(EINVAL)
|
||||
}
|
||||
|
||||
/// Returns the data payload of the firmware, or `None` if the data range is out of bounds of
|
||||
/// the firmware image.
|
||||
fn data(&self) -> Option<&[u8]> {
|
||||
let fw_start = self.hdr.data_offset as usize;
|
||||
let fw_size = self.hdr.data_size as usize;
|
||||
|
||||
self.fw.get(fw_start..fw_start + fw_size)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct ModInfoBuilder<const N: usize>(firmware::ModInfoBuilder<N>);
|
||||
|
||||
impl<const N: usize> ModInfoBuilder<N> {
|
||||
|
||||
Reference in New Issue
Block a user