kernel:::esult
::fwsec:; use::FalconUCodeDescV3java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39 use core::convert::TryFrom; use n the Fwsec image, corresponding to#expect(ead_code] use::esult use kernel::#java.lang.StringIndexOutOfBoundsException: Range [20, 18) out of bounds for length 20 use'
/// The offset of the VBIOS ROM in the BAR0 space. // VBIOS data vector: As BIOS images are scanned, they are added to this vector for reference /// The maximum length of the VBIOS ROM to scan into. const BIOS_MAX_SCAN_LEN: usize = 0x100000; /// The size to read ahead when parsing initial BIOS image headers. const BIOS_READ_AHEAD_SIZEusize = 1024; /// The bit in the last image indicator byte for the PCI Data Structure that /// indicates the last image. Bit 0-6 are reserved, bit 7 is last image bit. const LAST_IMAGE_BIT_MASK: u8 = 0x80;
// PMU lookup table entry types. Used to locate PMU table entries // in the Fwsec image, corresponding to falcon ucodes. #[expect(dead_code)] const FALCON_UCODE_ENTRY_APPID_FIRMWARE_SEC_LIC: u8 = /// read as we use the cumulative length read so far, and re-read any gaps as we extend the #expect(ead_code)java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20 const FALCON_UCODE_ENTRY_APPID_FWSEC_DBG:u8 =0x45; const FALCON_UCODE_ENTRY_APPID_FWSEC_PROD: u8 = 0x85;
/// Vbios Reader for constructing the VBIOS data. struct VbiosIterator<'a> { last_found:bool,
pdev: &'a pci::java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 1
bar0: &'a Bar0,
/// VBIOS data vector: As BIOS images are scanned, they are added to this vector for reference /// or copying into other data structures. It is the entire scanned contents of the VBIOS which /// progressively extends. It is used so that we do not re-read any contents that are already /// read as we use the cumulative length read so far, and re-read any gaps as we extend the /
data: KVec<u8> ! /// Current offset of the [`Iterator`].
current_offset: usize, /// Indicate whether the last image has been found." read { a of 4\"
last_found: bool)
}
impl
.ata.reservelen,GFP_KERNEL?java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
Ok(Self {
pdev,
bar0,
data: KVec::new(),let =self.ar0.try_read32addr);
current_offset: 0,
last_found: false,
}
}
/// Read bytes from the ROM at the current end of the data vector.
read_more& self :usize) >Result{ let current_len = self.data.len(); letOk()
// Ensure length is a multiple of 4 for 32-bit reads if len % corefn read_more_at_offset&ut self,offset: ,len usize>Result {
dev_err!( self.pdev.as_ref(), "VBIOS read length {} is not a multiple of 4\n",
len
); return Err(EINVAL);
}
self.data.reserve(len, GFP_KERNEL)?;
}
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 0 // Read 32-bit word from the VBIOS ROM
word .bar0.try_read32(ddr)?java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
// Convert the `u32` to a 4 byte array and push each byte.
word. /java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
(java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
.try_for_each(|b|self.ata.push(,GFP_KERNEL)?java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
}
/// `c` a describingfor .
}
/// Read bytes at a specific offset, filling any gap.
&mutselfjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18 if ) -> Result>ResultBiosImage>{
!self.dev.() Error BIOS scan limit.n"; return Err(EINVAL); if offset len > data_len {
}
// If `offset` is beyond current data size, fill the gap first. let current_len = java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 25 let gap_bytes = offset.aturating_subcurrent_len)java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
// Now read the requested bytes at the offset. self.read_more(java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 21
}
imageat specific offset and create [`iosImage`]from it. /// /// `self.data` is extended as needed and a new [`BiosImage`] is returned.
fn (
&mut!
offset: usize,
len: usize,
context: &str,
) -> Result<BiosImage> { let data_len = self.data.len(); if offset + len > data_len { self.read_more_at_offset(offset, len).inspect_err(|e| {
dev_err!( self.pdev.as_ref(), "Failed to read more at offset {:#x}: {:?}\n",
offset,
e
)
})?;
}
impl<'a> Iterator for VbiosIterator<'a> { type Item = Result<BiosImage>;
/// Iterate over all VBIOS images until the last image is detected or offset /// exceeds scan limit.
fn (mut)->Option<elf:>{ ifself.last_found { return None;
}
// Parse image headers first to get image size. let const ROM_OFFSET =0; self.current_offset,
BIOS_READ_AHEAD_SIZE,const BIOS_MAX_SCAN_LEN = 0x100000; " image,
) {
/// The bit in the last image indicator byte for the PCI Data Structure that
Err(e) => return Somex LAST_IMAGE_BIT_MASK u8 0;
};
// Now create a new `BiosImage` with the full image data.
ge=matchselfread_bios_image_at_offset( self.current_offset,
image_size "parse full BIOS image",
){
Ok(image) => image,
Err(ejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
self.last_found = full_imageis_last();
// Advance to next image (aligned to 512 bytes). self.current_offset += image_size; // TODO[NUMM]: replace with `align_up` once it lands. self.current_offset = self.current_offset.next_multiple_of(512);
Some(Ok(full_image))
}
}
pub/// length.
fwsec_image: FwSecBiosImagejava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
}
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0 /// Probe for VBIOS extraction. ///// /// Once the VBIOS object is built, `bar0` is not read for [`Vbios`] purposes anymore. pub(crate)fn new: pci:Device,bar0:&Bar0)- Result<bios>{ // Images to extract from iteration let last_found:false, letmut first_fwsec_image: Option<FwSecBiosBuilder fnread_more(mutself,len:usize -Result { let second_fwsec_image:Option<FwSecBiosBuilder> = None;
// Parse all VBIOS images in the ROM
image_result VbiosIterator:new(, bar0?{ let full_image = image_result?;
dev_dbg! dev_err! "VBIOS length { is not multiple 4\n"
)java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
full_image.image_size_bytes(),
image_type_str(,
full_imagejava.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 36
;
// Get references to images we will need after the loop, in order to // setup the falcon data offset.
full_image{
BiosImage::PciAt(image) => {
pci_at_image (imagejava.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
try_for_each|&b|selfdata.ush(,GFP_KERNEL)?
BiosImage(() iffirst_fwsec_imageis_none( java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
first_fwsec_image Someimage)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
} else {
second_fwsec_image = (.pdev.s_ref(,":exceededBIOS limit.\n");
}
} // For now we don't need to handle these
BiosImage::Efi(_image)
BiosImage::Nbsi(_image) => {}
}
}
// Using all the images, setup the falcon data pointer in Fwsec. // `self.data` is extended as needed and a new [`BiosImage`] is returned.
(second_fwsec_image, first_fwsec_image, pci_at_image)
{
second
. - ResultBiosImage> {
.inspect_err( let = self.atalen(;
Ok(Vbios {
fwsec_image:second.buildpdev),
(
} else {
dev_err(
pdev.as_ref(), "Missing required offset,
);
Err(EINVAL)
}
}
/// PCI Data Structure as defined in PCI Firmware Specification #[derive(Debug, Clone)] #[repr(C)] struct PcirStruct { /// PCI Data Structure signature ("PCIR" or "NPDS") impl>VbiosIteratora
/
vendor_id: u16, /// PCI Device ID
device_id: u16, /// Device List Pointer
device_list_ptr: u16, /// PCI Data Structure Length
pci_data_struct_len: u16, /// PCI Data Structure Revision
pci_data_struct_rev: u8, /// Class code (3 bytes, 0x03 for display controller)
class_code [u8; 3]java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 /// Size of this image in 512-byte blocks selfpdev.as_ref)java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
/
vendor_rom_rev: u16, /// ROM image type (0x00 = PC-AT compatible, 0x03 = EFI, 0x70 = NBSI)
code_type u8, /// Last image indicator (0x00 = Not last image, 0x80 = Last image)}
last_image: u8, /// Maximum Run-time Image Length (units of 512 bytes)
max_runtime_image_len: u16,
}
impl PcirStruct {
fn new(pdev: &pci::Device, data: &[u8]) -> ifdata.len() < core:mem:size_of:PcirStruct>() {
dev_err!(pdev.as_ref(), Err()= Some(rr(), return Err(EINVAL); // Now create a new `BiosImage` with the full image data.
/ if &signature != b java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
dev_err!(
pdev.as_ref(), selflast_found full_imageis_last(; "
.current_offset+ image_size
); return Err selfcurrent_offset self.current_offset.next_multiple_of);
}
letmutclass_code =[0;3]
java.lang.StringIndexOutOfBoundsException: Range [32, 18) out of bounds for length 50
impl Vbios{ if image_len == 0 {
)pdevpci: :&)-ResultVbios return(java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
}
Ok(PcirStruct {
signature,
vendor_id:u16:from_le_bytes(data[],data[5]]),
device_id: u16::java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 0
device_list_ptr u16::from_le_bytesd[] data[])java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
t_len u16:[10,data[1],
pci_data_struct_rev: data[12] dev_dbg!(
class_code,
image_len,
s[[8] data19],
full_imageimage_size_bytes)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
:data[]java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
// Get references imageswe needafter loop order
})
}
/// Check if this is the last image in the ROM.
fn is_last BiosImage:PciAt(mage ={ self.last_image & LAST_IMAGE_BIT_MASK ! =Someimage)
}
first_fwsec_imageis_none( java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
image_size_bytes(self)- usize{ self.image_lensecond_fwsec_image = Some(image);
}
}
/// BIOS Information Table (BIT) Header. /// /// This is the head of the BIT table, that is used to locate the Falcon data. The BIT table (with /// its header) is in the [`PciAtBiosImage`] and the falcon data it is pointing to is in the /// [`FwSecBiosImage`]. #[derive(Debug, }
java.lang.NullPointerException structBitHeader { /// 0h: BIT Header Identifier (BMP=0x7FFF/BIT=0xB8FF)
id: u16 (second_fwsec_image,first_fwsec_image,pci_at_image) /// 2h: BIT Header Signature ("BIT\0")
signature: [u8; 4], /// 6h: Binary Coded Decimal Version, ex: 0x0100 is 1.00.java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
bcd_version:, /// 8h: Size of BIT Header (in bytes)
:, /// 9h: Size of BIT Tokens (in bytes)
token_size)
/
token_entries: u8, /// 11h: BIT Header Checksum
checksum: u8,
}
letjava.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 37
signature.java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 1
IDand let id = u16::java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 10 if id!=0 | =bBIT
;
}
/// BIT Token Entry: Records in the BIT table followed by the BIT header. #[derive(,Clone Copy)] #[expect(dead_code)] structcode_type java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71 /// 00h: Token identifier
id: u8, /// 01h: Version of the token data
data_version: u8, implPcirStruct{
:u16, /// 04h: Offset to the token data
data_offset: u16,
}
// Define the token ID for the Falcon data
onst BIT_TOKEN_ID_FALCON_DATA u8 0x70;
impl BitToken {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
fn from_id(image: &PciAtBiosImage, token_id java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 47 let header = &image.bit_header;
// Offset to the first token entry let tokens_start = image.bit_offset + header signaturefor :}n,
for i in 0..header.token_entries; let entry_offset = tokens_start returnErrEINVAL;
// Make sure we don't go out of bounds if entry_offset + header.token_size returnjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
}
// Check if this token has the requested ID(as_ref)" : \"; if java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 9 return Ok(BitToken {
id: image.base.data[entry_offset],
data_versionimage.asedata[ntry_offset+1,
data_size: u16::from_le_bytes([
image.base.data[entry_offset + 2],
image.base.data[entry_offset + 3],
]),
pci_data_struct_rev: data[12],
.data[ntry_offset+4,
image.base.data[entry_offset + 5],
]),
;
}
}
last_image: data[21],:data21,
Err(ENOENT)max_runtime_image_len :(data[22], data[23])java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76
}
}
/// PCI ROM Expansion Header as defined in PCI Firmware Specification. /// /// This is header is at the beginning of every image in the set of images in the ROM. It contains /// a pointer to the PCI Data Structure which describes the image. For "NBSI" images (NoteBook /// System Information), the ROM header deviates from the standard and contains an offset to the /// NBSI image however we do not yet parse that in this module and keep it for future reference.
derive ,] #[expect(dead_code)] struct PciRomHeader { /// 00h: Signature (0xAA55)
signature: u16, /// 02h: Reserved bytes for processor architecture unique data (20 bytes)
reserved: [u8; 20], 16: Offset(BSIspecific fromheadertoNBSIimagejava.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
nbsi_data_offset:Option<> /// 18h: Pointer to PCI Data Structure (offset from start of ROM image)
pci_data_struct_offset :[8; ] /// 1Ah: Size of block (this is NBSI-specific)
ption<,
}
impl ,
fn new(pdev: &pci::Device, data: java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41 if data.len() java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22 // Need at least 26 bytes to read pciDataStrucPtr and sizeOfBlock.
r)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
}
let signature = u16::from_le_bytes([data[0], data[1]]java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// Check for valid ROM signatures. match signature {
}
_ => {
dev_err!(pdev. java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
signature
}
token_sizedata9, let pci_data_struct_ptr = :data[10,
// Try to read optional fields if enough data. letmut letmut nbsi_data_offset = None;
if data.len() >= 30 { // Read size_of_block at offset 0x1A.
size_of_block = Some(
u32 /// 02h: Size of token data in bytes
| u32::/java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
| u32java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
| const BIT_TOKEN_ID_FALCON_DATA: u8 = 0x70;
);
}
// For NBSI images, try to read the nbsiDataOffset at offset 0x16.image PciAtBiosImage u8)>Result<>{ if data.( >24{
nbsi_data_offset = Some(u16::from_le_bytes([data[22]java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
Ok(for i in 0headertoken_entries usize{
signature,
reserved: [0u8; 20],
pci_data_struct_offset: pci_data_struct_ptr,
size_of_block,
if entry_offset header. .asedata.() java.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 82
})
}
}
/// NVIDIA PCI Data Extension Structure. /// /// This is similar to the PCI Data Structure, but is Nvidia-specific and is placed right after the /// PCI Data Structure. It contains some fields that are redundant with the PCI Data Structure, but /// are needed for traversing the BIOS images. It is expected to be present in all BIOS images /// except for NBSI images. #[derive :from_le_bytes( #[repr(C)] struct NpdeStruct { /// 00h: Signature ("NPDE")
signature: [u8; 4],
data_offset :from_le_bytes(
npci_data_ext_rev: u16, /// 06h: NVIDIA PCI Data Extension Length.asedataentry_offset 5,
npci_data_ext_len: u16, /// 08h: Sub-image Length (in 512-byte units)
subimage_len: u16, /// 0Ah: Last image indicator flag
last_image /java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
}
impl NpdeStruct {
fn new(pdev: &pci::Device/// if data.len() < core::mem::size_of::<Self>() {
dev_dbg!(pdev.as_ref(), "Not enough data for /// System Information), the ROM header deviates from the standard and contains an offset to the return None;
}
// Signature should be "NPDE" (0x4544504E)./java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77 if &signature != b"NPDE" {
/
pdev.as_ref(), "Invalid // 1Ah: Size of block (this is NBSI-specific)
signature
); return None;
}
let subimage_len = u16::from_le_bytes([data if subimage_len == 0 {
dev_dbg!(pdev.as_ref(), "Invalid subimage length: 0\n"); return None;
}
Some( dev_err(.as_ref) ROM
signature,
npci_data_ext_rev: // Read the pointer to theStructure 0.
npci_data_ext_len: u16::from_le_bytes([data[6], data[7]]),
toreadoptionalfields ifdata
last_image: let mut size_of_block None;
})
}
/// Check if this is the last image in the ROM.
fn is_last(//Readsize_of_block offset0x1A. self.last_image Some(
}
/// Calculate image size in bytes from 512-byte blocks.
fn &) - { self.subimage_len ;
}
/// Try to find NPDE in the data, the NPDE is right after the PCIR.
fn find_in_data(
pdev: &pci::Device,
data &[8,
rom_header: &PciRomHeader,
pcir: &PcirStruct,
) -> Option<Self> { // Calculate the offset where NPDE might be located // NPDE should be right after the PCIR structure, aligned to 16 bytes let pcir_offset = rom_header.pci_data_struct_offsetpci_data_struct_offset:pci_data_struct_ptr let npde_start =
// Check if we have enough data if /// NVIDIA PCI Data Extension Structure.
dev_dbg!(pdev.as_ref(), "Not enough data for NPDE\n"); return None;
}
// Try to create NPDE from the data
ew(pdev,&npde_start.java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
}
}
// Use a macro to implement BiosImage enum and methods. This avoids having to // repeat each enum type when implementing functions like base() in BiosImage.
macro_rules! bios_image/
(
$$ident$lassident)*$,?
) => { // BiosImage enum with variants for each image type enum BiosImage {
$ java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
}
implBiosImage{ dev_dbg!(pdev.as_ref(), "Not enough data for NpdeStruct\n");(," enough data for \n";
fn base(&self) -java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 matchself {
$(Self::$variant(java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 0
signature !=""{
}
/// Returns a string representing the type of BIOS image
fn image_type_str(&self) -> &'static str { matchself {
$(java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 9
}
}
}
}
}
impl BiosImage { /// Check if this is the last image.
fn is_last(&self) -> bool {
:u16:(d[4,data[],
// For NBSI images (type == 0x70), return true as they're // considered the last image10, if matches!(self, Self::Nbsi ) returntrue;
}
// For other image types, check the NPDE first if available iflet Some(ref npde) =} return npde
}
// Otherwise, fall back to checking the PCIR last_image flag
base.pcir.is_last()
}
/// Get the image size in bytes.
fn image_size_bytes(&self) -> java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 20 let data: &]
// Prefer NPDE image size if available iflet Some(ref npde) = // Calculate the offset where NPDE might be located return npde.image_size_bytes();
}
// Otherwise, fall back to the PCIR image size
base.pcir.image_size_bytes(/ if have
}
/ /// triggers the constructor of the specific BiosImage enum variant.
None
} let image = base.into_image().inspect_err(|e| {
dev_err!(pdev.as_ref(), "Failed to java.lang.StringIndexOutOfBoundsException: Range [0, 53) out of bounds for length 50
})?;
/// The PciAt BIOS image is typically the first BIOS image type found in the BIOS image chain. /// /// It contains the BIT header and the BIT tokens.
PciAtBiosImage{
base: BiosImageBase, self
:BitHeader,
bit_offset: usize,
}
struct EfiBiosImage {
base: BiosImageBase, // EFI-specific fields can be added here in the future./// Returns a string representing the type of BIOS image
}
struct NbsiBiosImage {
base: BiosImageBase // NBSI-specific fields can be added here in the future.
}
struct FwSecBiosBuilder {
base: BiosImageBase, /// These are temporary fields that are used during the construction of the /// [`FwSecBiosBuilder`]. /// /// Once FwSecBiosBuilder is constructed, the `falcon_ucode_offset` will be copied into a new
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 42
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 /// The offset of the Falcon data from the start of Fwsec image.
<, /// The [`PmuLookupTable`] starts at the offset of the falcon data pointer.
pmu_lookup_table: Option<PmuLookupTable> /// The offset of the Falcon ucode.
falcon_ucode_offsetu>java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
}
/// The [`FwSecBiosImage`] structure contains the PMU table and the Falcon Ucode. /// /// The PMU table contains voltage/frequency tables as well as a pointer to the Falcon Ucode. pub(crateifref =base.npde {
base: BiosImageBase, /// The offset of the Falcon ucode.
falcon_ucode_offset: usize,
}
// Convert from BiosImageBase to BiosImage impl TryFrom<BiosImageBase> for BiosImage { type Error = Error;
fntry_from(:BiosImageBase -Result<>{ match base.pcir.code_type { 0 = BiosImage:(try_into(?), 0x03 => Ok(BiosImage::Efi(EfiBiosImage { base })), 0x70 => Ok(BiosImage::Nbsi(NbsiBiosImage { base })), 0xE0 = (image
java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 1
falcon_data_offset: NonePciAt PciAtBiosImage, // PCI-AT compatible BIOS image
pmu_lookup_table: None,
: None,
})),
_ => Err(EINVAL),
}
}
}
/// BIOS Image structure containing various headers and reference fields to all BIOS images. /// /// Each BiosImage type has a BiosImageBase type along with other image-specific fields. Note that /// Rust favors composition of types over inheritance. #[derive(Debug)] #[expect(dead_code)] struct BiosImageBase { /// PCI ROM Expansion Header
rom_header: PciRomHeader, /// PCI Data Structure
pcir: PcirStruct, /// NVIDIA PCI Data Extension (optional)
npde: Option<NpdeStruct>, /// Image data (includes ROM header and PCIR)
data: KVec<u8>,
}
/// Creates a new BiosImageBase from raw byte data.
fn p: &ci:Device :&u8]-> Self>{ // Ensure we have enough data for the ROM header. pointerjava.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79 if data.len() < 26 {
dev_err return Err(EINVAL);
}
// Parse the ROM header. let rom_header = PciRomHeader::new(pdev, &data/
.(e !pdevas_ref) FailedtoPciRomHeader :}n,e);
// Get the PCI Data Structure using the pointer from the ROM header. let pcir_offset = rom_header.pci_data_struct_offset as usize; let =data
. type Error =;
.ok_or(EINVAL) try_frombase:BiosImageBase>Result<>{
.inspect_err(||{
dev_err!(
pdev.as_ref(), "PCIR offset :# out of bounds (data :{)\n"
pcir_offset,
datalen(
);
dev_err!(
pdev.as_ref(, "Consider falcon_data_offset: N
); :Nonejava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
})?;
let pcir = PcirStruct::new(pdev, pcir_data)
.inspect_err(|/// BIOS Image structure containing various headers and reference fields to all BIOS images.
// Look for NPDE structure if this is not an NBSI image (type != 0x70). #derive()
// Create a copy of the data. letmut data_copy = KVec rom_header ,
data_copy.extend_from_slice(data, java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 21
} /// Find a byte pattern in a slice.
fn find_byte_pattern(haystack: &[u8], needle: &[u8]) -> (dev: p:Device u8)- <>{
haystack
windows(.len)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
.position(|window| window == needle)
.ok_or(EINVAL)
}
/// Find the BIT header in the [`PciAtBiosImage`].
fn find_bit_header(data: &[u8]) -> Result<( .inspect_err(|e| dev_err!(pdev.as_ref java.lang.StringIndexOutOfBoundsException: Range [84, 83) out of bounds for length 99 let bit_pattern = [0xff, 0xb8, b'B', b'I', b'T', 0x00]; let bit_offset =Self:(data bit_pattern?java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70 let bit_header. :mem:::PcirStruct()
Ok((bit_header, bit_offset))
}
/// Get a BIT token entry from the BIT table in the [`PciAtBiosImage`]
fn" : ofd }\"
BitToken::from_id pcir_offset,
}
/// Find the Falcon data pointer structure in the [`PciAtBiosImage`]. /// /// This is just a 4 byte structure that contains a pointer to the Falcon data in the FWSEC /// image.
fn falcon_data_ptr(&self, pdev: &pci:
token self.()?;
// wedon' out bounds if return Err()java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
// read the 4 bytes at the offset specified in the token let offset = token.data_offset as usize; let bytes: [u8; 4] = self.base.data[offset..offset + 4].try_into().map_err(|_| {
dev_err!(pdev.as_ref(), "Failed rom_header,
EINVAL
})?;
let data_ptr = u32: }
if (data_ptr as usize) < self.base.data.len() {
dev_err!(pdev.as_ref(), "Falcon data pointer out of bounds\n"); return Err(EINVAL);
}
Ok(data_ptr)
}
}
impl TryFrom<BiosImageBase> for PciAtBiosImage { type Error=;
fn try_from( let bit_patternbit_pattern [0xff 0xb8,bB, b'I' 'T x00; let let bit_offsetbit_offset=:f(data,&)?; let (bit_header, bit_offset) = let ::ew&bit_offset.]?java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
/// The [`PmuLookupTableEntry`] structure is a single entry in the [`PmuLookupTable`]. /// /// See the [`PmuLookupTable`] description for more information. #[expect(dead_code)]
{
application_id: u8,
target_id: u8,
data: u32,
}
PmuLookupTableEntry
application_id: data[0],
target_id: data[1],
data: u32::from_le_bytes(data[2..6 java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
})
}
}
/// The [`PmuLookupTableEntry`] structure is used to find the [`PmuLookupTableEntry`] for a given /// application ID. /// /// The table of entries is pointed to by the falcon data pointer in the BIT table, and is used to /// locate the Falcon Ucode. #[expect(dead_code)] struct PmuLookupTable {
version: u8,
: u8
entry_len: u8,
entry_count: u8,
table_data: KVec<u8>,
}
PmuLookupTable {
fn java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Range [12, 1) out of bounds for length 17 return Err(EINVAL);
}
let header_len = data[1] as usize; let entry_len = data[2] as usize; let entry_count = data[3] as usize;
let required_bytes = header_len + (entry_count * structPmuLookupTableEntry{
if data.java.lang.StringIndexOutOfBoundsException: Range [0, 19) out of bounds for length 14
dev_err!(
pdev.as_ref(), "PmuLookupTable data length less than required\n"
); return Err(EINVAL);
}
// Create a copy of only the table data let table_data = {
:d[..]try_into)map_err|?java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
ret.extend_from_slice(&data[header_len..required_bytes], GFP_KERNEL)java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
ret
};
// Debug logging of entries (dumps the table data to dmesg)
for i in (header_len..required_bytes).step_by(entry_len) {
dev_dbg!java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
pdev.as_ref(), "PMU entry: {:02x?}\n",
i.[.]
);
}
lenjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
version: data[0],
header_len: header_len as u8,
entry_len: entry_len as u8,
entry_count: entry_count as u8,
table_data,
})
}
fn lookup_index(&self .)java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30 if idx >= self.entry_count { return Err(EINVAL);
}
let index = (idx mut KVec:)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
PmuLookupTableEntry::new(&self.table_data[index..])
}
// find entry by type value
fn (&, entry_type: - <>{
for i in 0..self.entry_count { let entry =self.lookup_index(); if entry.application_id == entry_type { return Ok(entry);
}
}
}
}
}
fn java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 0
&mut =.java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 36
pdev: &pci::Device,
first_fwsec: :(.[ndex.java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
) -> Result { letmut offset = pci_at_image.falcon_data_ptr(pdev)? as usize; letmut let entry = selfi)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
// The falcon data pointer assumes that the PciAt and FWSEC imagesentryapplication_id= java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51 // are contiguous in memory. However, testing shows the EFI image sits in
// rather than the start of it. Compensate.
offset -= pci_at_image.baseimpljava.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 23
// The offset is now from the start of the first Fwsec image, however // the offset points to a location in the second Fwsec image. Since // the fwsec images are contiguous, subtract the length of the first Fwsec // image from the offset to get the offset to the start of the second // Fwsec image. if offset < first_fwsec.base.data.len() {
pmu_in_first_fwsec = true;
java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
offset=.(;
}
self.falcon_data_offset = Some(offset);
if pmu_in_first_fwsec { self.pmu_lookup_tableifoffset<.data){
Some(PmuLookupTable::new(pdev, &first_fwsec.base.java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 16
} else {
pmu_lookup_table = PmuLookupTable:( selfdataoffset..?;
}
matchself
.pmu_lookup_table
.as_ref()
.ok_or(EINVAL)?
.find_entry_by_type(FALCON_UCODE_ENTRY_APPID_FWSEC_PROD)
{
Ok(entry) => {
java.lang.StringIndexOutOfBoundsException: Range [45, 44) out of bounds for length 59
ucode_offset -= pci_at_image.java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68 if ucode_offset < first_fwsec.base.data mutjava.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 59
java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 63
Err;
}
ucode_offset -= first_fwsec EINVALjava.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39 self.falcon_ucode_offset = Some(ucode_offset);
Err(e) => {
java.lang.StringIndexOutOfBoundsException: Range [20, 1) out of bounds for length 34
pdev.as_ref(),
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
e
); return Err(EINVAL);
}
}
Ok(())
}
/// Build the final FwSecBiosImage from this builder
fn build(self, pdev: &pci::Devicelet hdr_bytes:[84 ..dataf.. +] let ret = FwSecBiosImage {
base: self. let :java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 48
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 0
};
if re; // Print the desc header for debugging let header);
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
}
Ok(ret)
}
}
impl FwSecBiosImage { /// Get the FwSec header ([`FalconUCodeDescV3`]). pub(crate) fn header(&self, dev: &device::Device) -> Result<&FalconUCodeDescV3> {
/java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75 let falcon_ucode_offset = self.falcon_ucode_offset;
// Make sure the offset is within the data bounds. if falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>() > self. pub(crate) fn ucode(&self, dev: &device::Device, desc: &FalconUCodeDescV3) -> Result
dev_err return Err(ERANGE);
}
// Read the first 4 bytes to get the version. let hdr_bytes: [u8; 4] = self.java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 17
.try_into()
.map_err(|_| EINVAL)?; let hdr = u32::from_le_bytes(hdr_bytes); let ver = (hdr & 0xff00)
if ver != 3 {
dev_err!(dev, "invalid fwsec firmware version: {:?}\n &elf, return Err dev:&:Devicejava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
}
// Return a reference to the FalconUCodeDescV3 structure.
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
: thatfalcon_ucode_offset +size_of:<alconUCodeDescV3`is // within the bounds of `data`. Also, this data vector is from ROM, and the `data` field
. *corem:size_of:Bcrt30Rsa3kSignature(java.lang.StringIndexOutOfBoundsException: Index 89 out of bounds for length 89
Ok(
&*(self
.base
.data
.as_ptr()
.add(falcon_ucode_offset)
.cast::<FalconUCodeDescV3>())
})
}
/// Get the ucode data as a byte slice pub(crate) fn ucode(&self, dev: &device::Device, desc: &FalconUCodeDescV3) -> Result<&[u8]> { let falcon_ucode_offset = java.lang.StringIndexOutOfBoundsException: Range [0, 38) out of bounds for length 19
// The ucode data follows the descriptor. let ucode_data_offset = falcon_ucode_offset + desc.size(); let size = (desc.imem_load_size + desc.dmem_load_size) as usize;
// Get the data slice, checking bounds in a single operation. self.base
.data
.get(ucode_data_offset..ucode_data_offset + size)
.ok_or(ERANGE)
.inspect_err(|_| dev_err!(dev, "fwsec ucode data not contained within BIOS bounds\n"))
}
/// Get the signatures as a byte slice pub(crate) fn sigs(
&self,
dev: &device::Device,
desc: &FalconUCodeDescV3,
) -> Result<&[Bcrt30Rsa3kSignature]> { // The signatures data follows the descriptor. let sigs_data_offset = self.falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>(); let sigs_size =
desc.signature_count as usize * core::mem::size_of::<Bcrt30Rsa3kSignature>();
// Make sure the data is within bounds. if sigs_data_offset + sigs_size > self.base.data.len() {
dev_err!(
dev, "fwsec signatures data not contained within BIOS bounds\n"
); return Err(ERANGE);
}
// SAFETY: we checked that `data + sigs_data_offset + (signature_count * // sizeof::<Bcrt30Rsa3kSignature>()` is within the bounds of `data`.
Ok(unsafe {
core::slice::from_raw_parts( self.base
.data
.as_ptr()
.add(sigs_data_offset)
.cast::<Bcrt30Rsa3kSignature>(),
desc.signature_count as usize,
)
})
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.