mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 18:21:24 +02: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:
parent
ebe658732c
commit
d6cb7319e6
|
|
@ -4,11 +4,13 @@
|
||||||
//! to be loaded into a given execution unit.
|
//! to be loaded into a given execution unit.
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
use core::mem::size_of;
|
||||||
|
|
||||||
use kernel::device;
|
use kernel::device;
|
||||||
use kernel::firmware;
|
use kernel::firmware;
|
||||||
use kernel::prelude::*;
|
use kernel::prelude::*;
|
||||||
use kernel::str::CString;
|
use kernel::str::CString;
|
||||||
|
use kernel::transmute::FromBytes;
|
||||||
|
|
||||||
use crate::dma::DmaObject;
|
use crate::dma::DmaObject;
|
||||||
use crate::falcon::FalconFirmware;
|
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>);
|
pub(crate) struct ModInfoBuilder<const N: usize>(firmware::ModInfoBuilder<N>);
|
||||||
|
|
||||||
impl<const N: usize> ModInfoBuilder<N> {
|
impl<const N: usize> ModInfoBuilder<N> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user