mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
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:
parent
258a6f9ab1
commit
ad5f9977a9
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))?
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user