summaryrefslogtreecommitdiff
path: root/drivers/gpu/nova-core/vbios.rs
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nova-core/vbios.rs')
-rw-r--r--drivers/gpu/nova-core/vbios.rs73
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.