diff options
Diffstat (limited to 'drivers/gpu/nova-core/vbios.rs')
| -rw-r--r-- | drivers/gpu/nova-core/vbios.rs | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/drivers/gpu/nova-core/vbios.rs b/drivers/gpu/nova-core/vbios.rs index abf423560ff4..72cba8659a2d 100644 --- a/drivers/gpu/nova-core/vbios.rs +++ b/drivers/gpu/nova-core/vbios.rs @@ -11,14 +11,16 @@ use kernel::{ Alignable, Alignment, // }, + sync::aref::ARef, transmute::FromBytes, - types::ARef, }; use crate::{ driver::Bar0, firmware::{ fwsec::Bcrt30Rsa3kSignature, + FalconUCodeDesc, + FalconUCodeDescV2, FalconUCodeDescV3, // }, num::FromSafeCast, @@ -790,7 +792,7 @@ impl PciAtBiosImage { // read the 4 bytes at the offset specified in the token let offset = usize::from(token.data_offset); let bytes: [u8; 4] = self.base.data[offset..offset + 4].try_into().map_err(|_| { - dev_err!(self.base.dev, "Failed to convert data slice to array"); + dev_err!(self.base.dev, "Failed to convert data slice to array\n"); EINVAL })?; @@ -887,11 +889,6 @@ impl PmuLookupTable { ret }; - // Debug logging of entries (dumps the table data to dmesg) - for i in (header_len..required_bytes).step_by(entry_len) { - dev_dbg!(dev, "PMU entry: {:02x?}\n", &data[i..][..entry_len]); - } - Ok(PmuLookupTable { header, table_data }) } @@ -1003,20 +1000,11 @@ impl FwSecBiosBuilder { } impl FwSecBiosImage { - /// Get the FwSec header ([`FalconUCodeDescV3`]). - pub(crate) fn header(&self) -> Result<&FalconUCodeDescV3> { + /// Get the FwSec header ([`FalconUCodeDesc`]). + pub(crate) fn header(&self) -> Result<FalconUCodeDesc> { // 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 falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>() > self.base.data.len() { - dev_err!( - self.base.dev, - "fwsec-frts header not contained within BIOS bounds\n" - ); - return Err(ERANGE); - } - // Read the first 4 bytes to get the version. let hdr_bytes: [u8; 4] = self.base.data[falcon_ucode_offset..falcon_ucode_offset + 4] .try_into() @@ -1024,33 +1012,34 @@ impl FwSecBiosImage { let hdr = u32::from_le_bytes(hdr_bytes); let ver = (hdr & 0xff00) >> 8; - if ver != 3 { - dev_err!(self.base.dev, "invalid fwsec firmware version: {:?}\n", ver); - return Err(EINVAL); + let data = self.base.data.get(falcon_ucode_offset..).ok_or(EINVAL)?; + match ver { + 2 => { + let v2 = FalconUCodeDescV2::from_bytes_copy_prefix(data) + .ok_or(EINVAL)? + .0; + Ok(FalconUCodeDesc::V2(v2)) + } + 3 => { + let v3 = FalconUCodeDescV3::from_bytes_copy_prefix(data) + .ok_or(EINVAL)? + .0; + Ok(FalconUCodeDesc::V3(v3)) + } + _ => { + dev_err!(self.base.dev, "invalid fwsec firmware version: {:?}\n", ver); + Err(EINVAL) + } } - - // Return a reference to the FalconUCodeDescV3 structure. - // - // 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) - .cast::<FalconUCodeDescV3>()) - }) } /// Get the ucode data as a byte slice - pub(crate) fn ucode(&self, desc: &FalconUCodeDescV3) -> Result<&[u8]> { + pub(crate) fn ucode(&self, desc: &FalconUCodeDesc) -> Result<&[u8]> { let falcon_ucode_offset = self.falcon_ucode_offset; // The ucode data follows the descriptor. let ucode_data_offset = falcon_ucode_offset + desc.size(); - let size = usize::from_safe_cast(desc.imem_load_size + desc.dmem_load_size); + let size = usize::from_safe_cast(desc.imem_load_size() + desc.dmem_load_size()); // Get the data slice, checking bounds in a single operation. self.base @@ -1066,10 +1055,14 @@ impl FwSecBiosImage { } /// Get the signatures as a byte slice - pub(crate) fn sigs(&self, desc: &FalconUCodeDescV3) -> Result<&[Bcrt30Rsa3kSignature]> { + pub(crate) fn sigs(&self, desc: &FalconUCodeDesc) -> Result<&[Bcrt30Rsa3kSignature]> { + let hdr_size = match desc { + FalconUCodeDesc::V2(_v2) => core::mem::size_of::<FalconUCodeDescV2>(), + FalconUCodeDesc::V3(_v3) => core::mem::size_of::<FalconUCodeDescV3>(), + }; // The signatures data follows the descriptor. - let sigs_data_offset = self.falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>(); - let sigs_count = usize::from(desc.signature_count); + let sigs_data_offset = self.falcon_ucode_offset + hdr_size; + let sigs_count = usize::from(desc.signature_count()); let sigs_size = sigs_count * core::mem::size_of::<Bcrt30Rsa3kSignature>(); // Make sure the data is within bounds. |
