gpu: nova-core: add auto-detection of 32-bit, 64-bit firmware images

A firmware image may be either a 32-bit or a 64-bit ELF, and callers
should not have to know which. Detect the ELF class from the image
header at parse time and dispatch to the matching parser, so a single
entry point handles both layouts.

Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Reviewed-by: Eliot Courtney <ecourtney@nvidia.com>
Link: https://patch.msgid.link/20260602032111.224790-10-jhubbard@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
John Hubbard 2026-06-01 20:20:57 -07:00 committed by Alexandre Courbot
parent 258a6f9ab1
commit ad5f9977a9
2 changed files with 25 additions and 6 deletions

View File

@ -629,14 +629,33 @@ fn elf_section_generic<'a, F>(elf: &'a [u8], name: &str) -> Option<&'a [u8]>
})
}
/// Tries to extract section with name `name` from the ELF64 image `elf`, and returns it.
pub(super) fn elf64_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
/// Extract the section with name `name` from the ELF64 image `elf`.
fn elf64_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
elf_section_generic::<Elf64Format>(elf, name)
}
/// Extract the section with name `name` from the ELF32 image `elf`.
#[expect(dead_code)]
pub(super) fn elf32_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
fn elf32_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
elf_section_generic::<Elf32Format>(elf, name)
}
/// Automatically detects ELF32 vs ELF64 based on the ELF header.
pub(super) fn elf_section<'a>(elf: &'a [u8], name: &str) -> Option<&'a [u8]> {
// ELF identification: a 4-byte magic followed by a class byte (32- vs 64-bit).
const ELFMAG: &[u8] = b"\x7fELF";
const SELFMAG: usize = ELFMAG.len();
const EI_CLASS: usize = 4;
const ELFCLASS32: u8 = 1;
const ELFCLASS64: u8 = 2;
if elf.get(0..SELFMAG) != Some(ELFMAG) {
return None;
}
match *elf.get(EI_CLASS)? {
ELFCLASS32 => elf32_section(elf, name),
ELFCLASS64 => elf64_section(elf, name),
_ => None,
}
}
}

View File

@ -88,7 +88,7 @@ pub(crate) fn new<'a>(
pin_init::pin_init_scope(move || {
let firmware = super::request_firmware(dev, chipset, "gsp", ver)?;
let fw_section = elf::elf64_section(firmware.data(), ".fwimage").ok_or(EINVAL)?;
let fw_section = elf::elf_section(firmware.data(), ".fwimage").ok_or(EINVAL)?;
let size = fw_section.len();
@ -148,7 +148,7 @@ pub(crate) fn new<'a>(
signatures: {
let sigs_section = Self::find_gsp_sigs_section(chipset);
elf::elf64_section(firmware.data(), sigs_section)
elf::elf_section(firmware.data(), sigs_section)
.ok_or(EINVAL)
.and_then(|data| Coherent::from_slice(dev, data, GFP_KERNEL))?
},