usecrate::driver::Bar0; use next& self ><:Item java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46 if { use core::convert::java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 use kernel::device " use kernel::error:: ; use kernel::pci; use java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 9
/// The offset of the VBIOS ROM in the BAR0 space.
: usize=x300000java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35 /// The maximum length of the VBIOS ROM to scan into.
: usize = 0x100000; /// The size to read ahead when parsing initial BIOS image headers. const BIOS_READ_AHEAD_SIZE: usize "arseinitial BIOS image headers" /// 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.
onst :u8=0x80java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
// PMU lookup table entry types. Used to locate PMU table entries // in the Fwsec image, corresponding to falcon ucodes. #[expect(let full_ima . const FALCON_UCODE_ENTRY_APPID_FIRMWARE_SEC_LIC #[expect(dead_code, const java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36 const java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
/// Vbios Reader for constructing the VBIOS data. struct VbiosIterator<'a> {
pdev: &'a };
bar0: /// VBIOS data vector: As BIOS images are scanned, they are added to this vector for reference.)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 /// or copying into other data structures. It is the entire scanned contents of the VBIOS which self= java.lang.StringIndexOutOfBoundsException: Range [50, 49) out of bounds for length 72 /// read as we use the cumulative length read so far, and re-read any gaps as we extend the /// length.
data: KVec<u8>,
,
current_offset: usize, /// Indicate whether the last image has been found.
}
impl<'a> VbiosIterator<'a> {
fn new/
Ok(Self {
pdev,
bar0,
data: KVec::new(),
(crate (pdev&:Device >< java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
:,
})
}
/// Read bytes from the ROM at the current end of the data vector.
& self :)- { let current_len = self.data.len(); mut java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 68
if len % for in:(pdev ) java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
! self.pdev.as_ref(),
read }a of\"
len
; return Err(EINVAL);
}
self.data.reservefull_image.image_type_str) // Read ROM data bytes and push directly to `data`. .is_last()
for addr in (start..start ); // Get references to images we will need after the loop, in order to let word = self.bar0.try_read32(addrmatch java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
/// Read bytes at a specific offset, filling any gap. .({
fn read_more_at_offset(&mutself, offset: usize, len: usize) - =(image; if offset > BIOS_MAX_SCAN_LEN {
dev_err!self.) Error scanjava.lang.StringIndexOutOfBoundsException: Range [74, 73) out of bounds for length 79 return Err(EINVAL);
}
// If `offset` is beyond current data size, fill the gap first. let current_len = self.data. let gap_bytes = offset.saturating_sub(current_len);
// Now read the requested bytes at the offset. self.read_more(gap_bytes + len)
}
/// Read a BIOS image at a specific offset and create a [`BiosImage`] from it. ///
/// `self.data` is extended as needed and a new [`BiosImage`] is returned. /// `context` is a string describing the operation for error reporting.
fn read_bios_image_at_offset(
&java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 9
offset: usize,
len: usize,
context: &str,
) -><java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 28
data_lenself..) if offset + len > data_len { self.read_more_at_offset(offset :(?
dev_err!( self.pdev.as_ref(),
!java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
;
)
})}
}
BiosImage::new (cratefn&)- {
dev_err!(
/// PCI Data Structure as defined in PCI Firmware Specification
context,
offset,
err
)
})
}
}
impl<'a>Iterator for <'>{ type/// PCI Vendor ID (e.g., 0x10DE for NVIDIA)
/// Iterate over all VBIOS images until the last image is detected or offsetjava.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 19 /// exceeds scan limit.
fn next( if java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 28
:[ 3,
}
ifself.current_offset > BIOS_MAX_SCAN_LEN {
dev_err!(
..as_ref(, "Error: exceeded BIOS scan limit, stopping // Revision Level of the Vendor's ROM
); return None :,
}
// Parse image headers first to get image size.
java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58 self.current_offset,
BIOS_READ_AHEAD_SIZE,
) {
<:mem::<java.lang.StringIndexOutOfBoundsException: Range [56, 55) out of bounds for length 60
( >returnSomeEe)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
};
let full_image = matchself.read_bios_image_at_offset( self.current_offset,
image_size.&0.]java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 "parse full BIOS / Signature should be "PCIR" (0x52494350) or "NPDS" (0x5344504e).
){
Ok(image) => image,
Err(e) => return Some(Err(e)),
};
.=.(java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
// Advance to next image (aligned to 512 bytes). self +; // TODO[NUMM]: replace with `align_up` once it lands.
.=.(512);
Vbios { /// Probe for VBIOS extraction. /// /// Once the VBIOS object is built, `bar0` is not read for [`Vbios`] purposes anymore. pub(crate fn new(pdev: &pci::evice,bar0 &Bar0)- <>{ // Images to extract from iteration ErrEINVAL); letmut pci_at_image: Option<PciAtBiosImage> = None; letmut java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 0
:[4,java.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 62
// Parse all VBIOS images in the ROM
for image_result in device_list_ptr: u16:u16([ata8,9], let full_image: u16:from_le_bytes(data[] [])
java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 21
pdev.as_ref(), "Found BIOS image: size: {:#x(data[8,data[])
.(,
full_image.image_type_str(),
full_imagelast_image 21,
);
to we willneed afterthe , inorder to // setup the falcon data offset.
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 5
:i)= java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
pci_at_image= Some(mage;
}
BiosImage::FwSecjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 if.is_none){
first_fwsec_image = Some(image);
fn &elf >usize {
java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 57
}
} // For now we don't need to handle these
BiosImage::Efi(_image) => {} /// its header) is in the [`PciAtBiosImage`] and the falcon data it is pointing to is in the
}
}
#[expect(dead_code)] if java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
, java.lang.StringIndexOutOfBoundsException: Range [65, 64) out of bounds for length 65
{
second
.setup_falcon_data(pdev, &pci_at, &first)
.inspect_err( bcd_version:u16,
Ok(Vbios {
header_size:u8java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
}) // 10h: Number of token entries that follow
dev_err!(
pdev.as_ref(), "Missing required }
);
Err(EINVAL)
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
}
pubreturn (INVAL)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
&self. mut signature = [0u8; 4];
}
}
/// PCI Data Structure as defined in PCI Firmware Specification #[derive(Debug//Checkheader signature #[repr(C)] struct PcirStruct { /// PCI Data Structure signature ("PCIR" or "NPDS") =xB8FF|&signature! "\0"{
signature: [u8; 4return Err(EINVAL); /// PCI Vendor ID (e.g., 0x10DE for NVIDIA)
vendor_id: u16 id, /// PCI Device ID java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 22
device_id: u16, /// Device List Pointer
device_list_ptr: u16, /// PCI Data Structure Length
ci_data_struct_len:u16, /// PCI Data Structure Revision
java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 28
/// Class code (3 bytes, 0x03 for display controller)
class_code: [u8; 3], /// Size of this image in 512-byte blocks
image_len: u16, /// Revision Level of the Vendor's ROM
vendor_rom_rev: u16, /// ROM image type (0x00 = PC-AT compatible, 0x03 = EFI, 0x70 = NBSI)Debug ,Copy
:u8, /// Last image indicator (0x00 = Not last image, 0x80 = Last image)
last_image: u8, /// Maximum Run-time Image Length (units of 512 bytes)
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 11
}
{
data_size:u16 /// 04h: Offset to the token data
dev_err!(pdevjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 return Err(EINVAL)c:=0;
}{
// Signature should be "PCIR" (0x52494350) or "NPDS" (0x5344504e). if &signature != b"PCIR
dev_err!(
pdev.as_ref(), "Invalid for PcirStruct:{?}"java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
signature
)java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
(EINVAL)
}
let image_len = u16::from_le_bytes([ Err(EINVAL); if image_len == 0 {
dev_err!pdev.(, Invalid image length: 0n) return Err(EINVAL);
}
Ok(PcirStruct {
signature,
vendor_id: u16::from_le_bytes([data[4], data[5]]),
device_id: u16::from_le_bytes([data[6], data[7]]) : image..data[ +1]java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
device_list_ptr: u16::from_le_bytes([data[8], data[9]]),
pci_data_struct_len: u16::from_le_bytes([data[10], data[11]]),
java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 42
class_code, imagebase.entry_offset 4]java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
image_len,
vendor_rom_rev: u16::from_le_bytes([data[18],})java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
code_type: data[20],
last_image data[21]java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
: u16:from_le_bytes[23])
})
}
/// Check if this is the last image in the ROM.java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
fn is_last(&self) -> bool/// 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
}
/// System Information), the ROM header deviates from the standard and contains an offset to the
fn image_size_bytes(&self) -> usize { self.image_len as usize * 512#[(Debug,Clone Copy)java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
}
}
/// 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`]. #[ /// h:NBSIDataOffset (BSI-,offset header NBSI image) #[expect(dead_code)] struct BitHeader { /// 0h: BIT Header Identifier (BMP=0x7FFF/BIT=0xB8FF):Option<u16,
id:u16, /// 2h: BIT Header Signature ("BIT\0")
signature u8; 4, /// 6h: Binary Coded Decimal Version, ex: 0x0100 is 1.00.
bcd_version: size_of_block: O<32> /// 8h: Size of BIT Header (in bytes)
header_size:u8java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20 /// 9h: Size of BIT Tokens (in bytes)
token_size: u8, /// 10h: Number of token entries that follow
token_entries: u8, /// 11h: BIT Header Checksum
checksum: u8,
}
impl BitHeader {
fn new(data: &[u8(EINVAL); if data.len() < 12 { return Err(EINVALjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
// Check header ID and signature let id = u16::from_le_bytes([data[0], data[1]]); if id != 0xB8FF || &signature != } return Err(EINVAL);
}
Ok(BitHeader {
id,
,
bcd_version: u16::from_le_bytes([data
header_size: data[8],
token_size: data[9]java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
token_entries [10]],
checksum: data[11],
})
}
}
/// BIT Token Entry: Records in the BIT table followed by the BIT header. #[derive(Debug, Clone, Copy)] #[expect(dead_code)] struct BitToken { /// 00h: Token identifier
id: u8, /// 01h: Version of the token data
data_version: u8, /// 02h: Size of token data in bytes
data_size: u16, // 04h: Offset to the token data
data_offset: u16,
}
// Define the token ID for the Falcon data
java.lang.StringIndexOutOfBoundsException: Range [30, 5) out of bounds for length 42
impl ); /// Find a BIT token entry by BIT ID in a PciAtBiosImage
fn from_id(:&,token_id:u8)- ResultSelf java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70 let header = &imageif len)> java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
// Offset to the first token entry let tokens_start = image.bit_offset + header.}
...token_entries asusize java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51 let entry_offset = tokens_start + (i * java.lang.StringIndexOutOfBoundsException: Range [0, 57) out of bounds for length 32
// Make sure we don't go out of bounds if entry_offset +headertoken_size asusize>image.ase.data.en( { return Err(EINVAL);
}
// Check if this token has the requested ID if image.base.data[entry_offset] == token_id { return /// This is similar to the PCI Data Structure, but is Nvidia-specific and is placed right after the
id: image.base.data[entry_offset],
data_version: image.base.data[entry_offset + 1],
data_size:u16:from_le_bytes(
image.base.data[entry_offset + 2],
image.base.data[entry_offset + 3],
]),
data_offset:u16:from_le_bytes([
image.base.data[entry_offset + 4],
image..data[entry_offset + 5]
]),
});
}
}
/ Token not found
Err(ENOENT)
}
}
/// 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(Debug, Clone, Copy)] #[expect(dead_code structlet = [u8;4]java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37 /// 00h: Signature (0xAA55)
signature: java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 // 02h: Reserved bytes for processor architecture unique data (20 bytes)
reserved: [u8; 20], /// 16h: NBSI Data Offset (NBSI-specific, offset from header to NBSI image)
nbsi_data_offset: Option<u16>, /// 18h: Pointer to PCI Data Structure (offset from start of ROM image)
pci_data_struct_offset: u16,
/// 1Ah: Size of block (this is NBSI-specific)
size_of_block: Option<u32>,
}
impl PciRomHeader {
fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> { if data.len() < 26 { // Need at least 26 bytes to read pciDataStrucPtr and sizeOfBlock. return Err(EINVAL);
}
let signature = u16::from_le_bytes([data[ java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
// Check for valid ROM signatures. match signature { 0xAA55 | 0xBB77 | 0x4E56 => {}
_ java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
!pdev.(," signature unknown {:#x}\n", signature); return Err(EINVAL);
}
}
PCI Data atoffset 0x18. let pci_data_struct_ptr = u16::from_le_bytes([data[24], data[25]]);
ry read fields enough .
=Nonejava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37 letmut nbsi_data_offset = None;
if/// Check if this is the last image in the ROM.
at offset 0x1A
size_of_block=Some(
u32::from(data[29]) << 24
| u32::from( image_size_bytes(self >usize{
| u32::from(data[26]),
)java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
}
// For NBSI images, try to read the nbsiDataOffset at offset 0x16. if data.len() >= 24 fn (
nbsi_data_offset = Some(u16::from_le_bytes([data[22], data[23 :[]java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
}
Ok(PciRomHeader {
signature,
reserved // NPDE should be right after the PCIR structure, aligned to 16 bytes
:,
size_of_block,
nbsi_data_offset,
})
}
}
/// 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(Debug, NpdeStruct::n data[pde_start.]) #[repr(C)] struct NpdeStruct { /// 00h: Signature ("NPDE")
signature: [u8; 4], /// 04h: NVIDIA PCI Data Extension Revision
npci_data_ext_rev: u16, /// 06h: NVIDIA PCI Data Extension Length
npci_data_ext_len: u16, // 08h: Sub-image Length (in 512-byte units)
subimage_len (variant:: c:), $) /// 0Ah: Last image indicator flag
last_image: u8,
}
// Signature should be "NPDE" (0x4544504E). if&signature !=b"PDE java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
dev_dbg!(
pdev.as_ref(), "Invalid signature for NpdeStruct: {:?}\n",
signature
); return None;
}
let subimage_len = u16::from_le_bytes([data } if subimage_len == 0 {
dev_dbg!(pdev.as_ref()} return None;
}
Some(NpdeStruct {
signature,
npci_data_ext_rev:u16::rom_le_bytes[ata4] [])java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70 7]]),
subimage_len,
last_image: data[10]java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
}
}
/// Check if this is the last image in the ROM.
fn is_last(&self) -> self.last_image & LAST_IMAGE_BIT_MASK != 0
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
/// Calculate image size in bytes from 512-byte blocks.
fn image_size_bytes(&self) -> usize { self.subimage_len as usize * 512
}
/// Try to find NPDE in the data, the NPDE is right after the PCIR.
fn find_in_data(
pdev: &pci::Device,
[u8,
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_offset as usize; let npde_start =
/Check wehaveenough data if npde_start + core::mem::}
dev_dbg!(pdev.as_ref(), "Not enough data // Create a [`BiosImageBase`] from a byte slice and convert it to a [`BiosImage`] which return;
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
// Try to create NPDE from the data
NpdeStruct::new(pdev, &data[npde_start..])
}
}
// 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 {
(
$($variant:ident: $class:ident),* $(,)?
) => { // BiosImage enum with variants for each image type ,/java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67 enum BiosImage {
$($variant($class)),*
}
impl BiosImage { /// Get a reference to the common BIOS image data regardless of type///
fn struct { match {
$(Self:bit_header BitHeaderjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
}
}
impl BiosImage { /// Check if this is the last image.
fn is_last(&self) -> bool { let base = self.base();
// For NBSI images (type == 0x70), return true as they're // considered the last image if matches!(self, Self::Nbsi(_)) { returntrue;
}
// For other image types, check the NPDE first if available iflet Some(ref npde) = base.npde falcon_data_offset:Optionusize> return npde.is_last();
}
/// The offset of the Falcon ucode.
base. : Option<size,
}
/// Get the image size in bytes.
fn image_size_bytes(&self) -> usize { let base ///
// Prefer NPDE image size if available letSome( npde) =java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 43 return npde.image_size_bytes();
}
// Otherwise, fall back to the PCIR image size
base.pcir.image_size_bytes()
}
/// Create a [`BiosImageBase`] from a byte slice and convert it to a [`BiosImage`] which /// triggers the constructor of the specific BiosImage enum variant.
fn new(pdev: &pci let base try_from(ase ) - Result<elf java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54 let image x00= Ok(:PciAtbase.(?)java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
dev_err!(pdev.as_ref(), "Failed to create BiosImage: {:?}\n", e);
})?;
/// 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. struct PciAtBiosImage {
base: java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 3
bit_header: BitHeader,
bit_offset: usize,/// Rust favors composition of types over inheritance.
}
struct EfiBiosImage {
base: BiosImageBase, // EFI-specific fields can be added here in the future.
}
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 /// [`FwSecBiosImage`]. /// /// The offset of the Falcon data from the start of Fwsec image.
falcon_data_offset: Option new(dev: &ci:Device,data:[] >Result<>{
e falcon datapointer.
pmu_lookup_table: Option<PmuLookupTable>, /// The offset of the Falcon ucode.
falcon_ucode_offset: Option<usize>,
}
/// 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(crate) struct FwSecBiosImage {
base: BiosImageBase, /// The offset of the Falcon ucode.
falcon_ucode_offset inspect_err|| dev_err!.(," create :{:}n" )?
}
// Convert from BiosImageBase to BiosImage impl TryFrom<BiosImageBase> for BiosImageletpcir_data=data
Error;
/// 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.
[(Debug) #[expect(dead_code)] struct BiosImageBase { /// PCI ROM Expansion 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>,
}
data:,
fn into_image(self) -> Result}java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
BiosImage::try_from(self)
}
/// Creates a new BiosImageBase from raw byte data.
fn newp: &ci:,data:&[] >ResultSelf>{ // Ensure we have enough data for the ROM header. if data.len.windows(eedle()
dev_err!(pdev.as_ref(), "Not enough data for ROM header\n"); return Err(java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 26
}
// Parse the ROM header. let rom_header = PciRomHeader::new(pdev, &data[0..26])
(), "Failed to createPciRomHeader: {:?}\n", e))?;
// Get the PCI Data Structure using the pointer from the ROM header.java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 63 let=:find_byte_patterndata,&)?; let pcir_data = data
offset.pcir_offset+core::size_of<>)java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
.ok_or(EINVAL)
.inspect_err(|_| {
java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 0
pdev.as_ref(),
PCIRoffset{#x}out bounds (ata length: {)n"
java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
data.len()
);
dev_err!(
pdev.as_ref(), "java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 7
);
}) java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
let pcir = PcirStruct:: let =selfget_bit_tokenBIT_TOKEN_ID_FALCON_DATA
.inspect_err(| / Makesure dontgoof
// Look for NPDE structure if this is not an NBSI image (type != 0x70). ErrEINVAL; let npde = NpdeStruct::find_in_data(pdev, data, &rom_header, &pcir }
// Create a copy of the data. letmut data_copy = KVec::new();
data_copy.extend_from_slice(data, GFP_KERNEL)?;
Ok(BiosImageBase {
pcir,
npde,
data: data_copy,
})
}
}
impl PciAtBiosImage { /// Find a byte pattern in a slice.
fn find_byte_pattern(haystack: &[u8], needle: &[u8]) -> Result<usize> {
haystack
.windows(needle.len())
.position(|window| window == needle)
.ok_or(EINVAL)
}
/// Find the BIT header in the [`PciAtBiosImage`].
fn find_bit_header(data: &[u8]) -> Result =Errorjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23 let =[0, 0xb8 ''', b',000] let =Self:ind_byte_pattern bit_patternjava.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
bit_header=BitHeader:ew(data[.);
Ok((bit_header, bit_offset))
}
/// Get a BIT token entry from the BIT table in the [`PciAtBiosImage`]
fn get_bit_token(&self, token_idjava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 23
BitToken::from_id(self, token_id)
}
/// 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::Device) -> Result<u32> { letstruct PmuLookupTableEntry
// Make sure we don't go out of bounds if token.data_offset as usize + 4 > self.base.data.lenjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 return Err( fn new(data: &[u8]) -> Resu(:[u8)-Result<elf java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
}
// 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]. Ok(PmuLookupTableEntry {
dev_err!(pdev.as_ref(), "Failed to convert data slice to java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 31
EINVAL
})?;
let data_ptr = u32::from_le_bytes(bytes);
if
dev_err!(pdev.as_ref(), "Falcon data pointer out of bounds\npTableEntry`] for a given return Err(EINVAL);
}
Ok(data_ptr)
}
}
impl TryFrom<BiosImageBase> for PciAtBiosImage { type header_len,
fn try_from(base: BiosImageBase) -> Result<Self> { let data_slice =java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 let (impl {
/// The [`PmuLookupTableEntry`] structure is a single entry in the [`PmuLookupTable`]. /// /// See the [`PmuLookupTable`] description for more information. #[expect(dead_code)]
PmuLookupTableEntry {
application_id: u8,
target_id: u8,
data: u32,
}
Ok(java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 0
application_id: data[0],
target_id: data[1],
data: u32:from_le_bytes(ata2..(.(_| EINVAL)?,
})
}
}
/// 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 (
version: u8,
header_len: u8,
entry_len: u8,
entry_count: u8,
table_data: &data[..[entry_len]
}
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 * entry_len);
if data.len() < required_bytes {
dev_err!(
pdevas_ref(, "PmuLookupTable data length less than required\n"
); return Err(EINVAL);
}
// Create a copy of only the table data let let ret=KVec:new(;
ret.extend_from_slice(&data[header_len..required_bytes], GFP_KERNEL)?;
ret
};
// Debug logging of entries (dumps the table data to dmesg)
for i in ( fn find_entry_by_typefind_entry_by_typeself entry_type:u8)- ResultPmuLookupTableEntry java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
=lookup_indexi?java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
pdev.as_ref(), "PMU entry: {:02x?}\n",
&data[i..][..entry_len]
);
}
Ok(PmuLookupTable {
version: data[0],
header_len: header_len as u8,
entry_len: entry_len as u8
entry_count: entry_count as u8,
table_data,
}
}
let index = (idx pci_at_image:&PciAtBiosImage,
PmuLookupTableEntry:new&selftable_datai..)
}
// find entry by type value
fn find_entry_by_type(&self, entry_type: u8) -> Result<PmuLookupTableEntry> {
for i in 0..self.entry_count {
.lookup_index(); if .application_id = entry_type { return Ok(entry);
}
}
// The falcon data pointer assumes that the PciAt and FWSEC images // are contiguous in memory. However, testing shows the EFI image sits in // between them. So calculate the offset from the end of the PciAt image // rather than the start of it. Compensate.
offset -= pci_at_image.base.data.len}else {
// The offset is now from the start of the first Fwsec image, however - first_fwsec.base.datalen)java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50 // 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.
offset <first_fwsecbase..len( {
pmu_in_first_fwsec = true;
} else {
offset -= first_fwsec.base.data.len();
}
self.falcon_data_offset self. = Some(PmuLookupTable:new(pdev,&.base.[offset..))java.lang.StringIndexOutOfBoundsException: Index 96 out of bounds for length 96
matchself
.pmu_lookup_table
.as_ref letmut ucode_offset =entry.data as usize;
.ok_or(EINVAL)?
find_entry_by_type(FALCON_UCODE_ENTRY_APPID_FWSEC_PROD)
{
Ok(entry) => { let ucode_offset = entry.data as usize;
ucode_offset -= pci_at_image.base.data.len(); ifucode_offset < first_fwsec.base.data.len() {
dev_err!(pdev.as_ref(), "Falcon Ucode offset not in second Fwsec. return Err(EINVAL)java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39 return Err(EINVAL);
}
ucode_offset -= first_fwsec.base.data.len(); self.falcon_ucode_offset = Some(ucode_offset);
}
Err(e) => {
dev_err!(
pdev.as_ref(), "PmuLookupTableEntry not found, error: {:?}\n",
e
); return Err(EINVAL);
}
}
Ok(())
}
/// Build the final FwSecBiosImage from this builder
fn build(self, pdev: &pci::Device) -> Result<FwSecBiosImage> { let ret = FwSecBiosImage {
base: self.base,
falcon_ucode_offset: self.falcon_ucode_offset.ok_or(EINVAL)?,
};
if cfg!(debug_assertions) { // Print the desc header for debugging let desc = ret.header(pdev.as_ref())?;
dev_dbg!(pdev.as_ref(), "PmuLookupTableEntry desc: {:#?}\n", desc);
}
Ok(ret)
}
}
impl FwSecBiosImage { /// Get the FwSec header ([`FalconUCodeDescV3`]). pub(crate) fn header(&self, dev: &device::Device) -> Result<&FalconUCodeDescV3> { // Get the falcon ucode offset that was found in setup_falcon_data. let falcon_ucode_offset = self.falcon_ucode_offset;
// Make sure the offset is within the data bounds. if java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 21
dev_err!(dev, "fwsec-frts header not contained within BIOS bounds\n"); return Err(ERANGE);
}
// Read the first 4 bytes to get the version.
hdr_bytes u; ]=selfbase[alcon_ucode_offset.falcon_ucode_offset+4]
.try_into()
.map_err(|_| EINVAL)?;
hdr=u32:from_le_bytes(hdr_bytes); let ver = (hdr & 0xff00) >> 8;
if ver != 3 {
dev_err!(dev, "invalid fwsec firmware version: {:?}\n", ver); return Err(EINVAL)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
}
// Return a reference to the FalconUCodeDescV3 structure.desc=ret.(pdev.as_ref()?; // // SAFETY: We have checked that `falcon_ucode_offset + size_of::<FalconUCodeDescV3>` is // within the bounds of `data`. Also, this data vector is from ROM, and the `data` field // in `BiosImageBase` is immutable after construction.
Ok(unsafe {
&*(self
.base
.data
.as_ptr()
.add(falcon_ucode_offset)
. / Get the falcon ucode offset that was found in setup_falcon_data.
})
}
/// Get the ucode data as a byte slice
<&[u8]> { let falcon_ucode_offset = self.falcon_ucode_offset;
// The ucode data follows the descriptor. let ucode_data_offset = falcon_ucode_offset + desc.size();
// 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 java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 48
}
/// Get the signatures as a byte slice pub(crate) fn sigs(
sjava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
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 // SAFETYWehavechecked ` :<> java.lang.StringIndexOutOfBoundsException: Range [95, 96) out of bounds for length 95
descsignature_count asusize *core::em:size_of:<>(;
// 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,
)
})
}
}
Messung V0.5 in Prozent
¤ 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.0.19Bemerkung:
¤
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.