* [PATCH 0/2] gpu: nova-core: vbios: simplify device use
@ 2025-08-08 2:46 Alexandre Courbot
2025-08-08 2:46 ` [PATCH 1/2] gpu: nova-core: vbios: replace pci::Device with device::Device Alexandre Courbot
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Alexandre Courbot @ 2025-08-08 2:46 UTC (permalink / raw)
To: Danilo Krummrich, David Airlie, Simona Vetter, Joel Fernandes
Cc: nouveau, dri-devel, rust-for-linux, linux-kernel,
Alexandre Courbot
This small cleanup series simplifies the use of `Device` in vbios
methods.
The device is used for logging purposes only; thus we don't need a
pci::Device, neither do we need it to be bound. This latter property
allows us to store an `ARef` to it into structures that require logging
instead of having all their methods take an extra `dev` argument.
Removing this argument streamlines the code a bit.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
Alexandre Courbot (2):
gpu: nova-core: vbios: replace pci::Device with device::Device
gpu: nova-core: vbios: store reference to Device where relevant
drivers/gpu/nova-core/firmware/fwsec.rs | 8 +-
drivers/gpu/nova-core/gpu.rs | 2 +-
drivers/gpu/nova-core/vbios.rs | 168 +++++++++++++++-----------------
3 files changed, 85 insertions(+), 93 deletions(-)
---
base-commit: 14ae91a81ec8fa0bc23170d4aa16dd2a20d54105
change-id: 20250808-vbios_device-b0a912aff149
Best regards,
--
Alexandre Courbot <acourbot@nvidia.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] gpu: nova-core: vbios: replace pci::Device with device::Device
2025-08-08 2:46 [PATCH 0/2] gpu: nova-core: vbios: simplify device use Alexandre Courbot
@ 2025-08-08 2:46 ` Alexandre Courbot
2025-08-29 13:43 ` Joel Fernandes
2025-08-08 2:46 ` [PATCH 2/2] gpu: nova-core: vbios: store reference to Device where relevant Alexandre Courbot
2025-09-01 10:37 ` [PATCH 0/2] gpu: nova-core: vbios: simplify device use Danilo Krummrich
2 siblings, 1 reply; 7+ messages in thread
From: Alexandre Courbot @ 2025-08-08 2:46 UTC (permalink / raw)
To: Danilo Krummrich, David Airlie, Simona Vetter, Joel Fernandes
Cc: nouveau, dri-devel, rust-for-linux, linux-kernel,
Alexandre Courbot
The passed pci::Device is exclusively used for logging purposes, so it
can be replaced by a regular device::Device, which allows us to remove
the `as_ref()` indirections at each logging site.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/nova-core/gpu.rs | 2 +-
drivers/gpu/nova-core/vbios.rs | 135 +++++++++++++++++------------------------
2 files changed, 57 insertions(+), 80 deletions(-)
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 72d40b0124f0c1a2a381484172c289af523511df..33082ac45873ee4cf91d7d8af499efa984af4ba9 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -298,7 +298,7 @@ pub(crate) fn new(
let fb_layout = FbLayout::new(spec.chipset, bar)?;
dev_dbg!(pdev.as_ref(), "{:#x?}\n", fb_layout);
- let bios = Vbios::new(pdev, bar)?;
+ let bios = Vbios::new(pdev.as_ref(), bar)?;
Self::run_fwsec_frts(pdev.as_ref(), &gsp_falcon, bar, &bios, &fb_layout)?;
diff --git a/drivers/gpu/nova-core/vbios.rs b/drivers/gpu/nova-core/vbios.rs
index 5b5d9f38cbb3a6b1c374c1e0eee2509eb8d5660c..b5564b4d3e4758e77178aa403635e4780f0378cc 100644
--- a/drivers/gpu/nova-core/vbios.rs
+++ b/drivers/gpu/nova-core/vbios.rs
@@ -8,7 +8,6 @@
use core::convert::TryFrom;
use kernel::device;
use kernel::error::Result;
-use kernel::pci;
use kernel::prelude::*;
/// The offset of the VBIOS ROM in the BAR0 space.
@@ -31,7 +30,7 @@
/// Vbios Reader for constructing the VBIOS data.
struct VbiosIterator<'a> {
- pdev: &'a pci::Device,
+ dev: &'a device::Device,
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
@@ -46,9 +45,9 @@ struct VbiosIterator<'a> {
}
impl<'a> VbiosIterator<'a> {
- fn new(pdev: &'a pci::Device, bar0: &'a Bar0) -> Result<Self> {
+ fn new(dev: &'a device::Device, bar0: &'a Bar0) -> Result<Self> {
Ok(Self {
- pdev,
+ dev,
bar0,
data: KVec::new(),
current_offset: 0,
@@ -64,7 +63,7 @@ fn read_more(&mut self, len: usize) -> Result {
// Ensure length is a multiple of 4 for 32-bit reads
if len % core::mem::size_of::<u32>() != 0 {
dev_err!(
- self.pdev.as_ref(),
+ self.dev,
"VBIOS read length {} is not a multiple of 4\n",
len
);
@@ -89,7 +88,7 @@ fn read_more(&mut self, len: usize) -> Result {
/// Read bytes at a specific offset, filling any gap.
fn read_more_at_offset(&mut self, offset: usize, len: usize) -> Result {
if offset > BIOS_MAX_SCAN_LEN {
- dev_err!(self.pdev.as_ref(), "Error: exceeded BIOS scan limit.\n");
+ dev_err!(self.dev, "Error: exceeded BIOS scan limit.\n");
return Err(EINVAL);
}
@@ -115,7 +114,7 @@ fn read_bios_image_at_offset(
if offset + len > data_len {
self.read_more_at_offset(offset, len).inspect_err(|e| {
dev_err!(
- self.pdev.as_ref(),
+ self.dev,
"Failed to read more at offset {:#x}: {:?}\n",
offset,
e
@@ -123,9 +122,9 @@ fn read_bios_image_at_offset(
})?;
}
- BiosImage::new(self.pdev, &self.data[offset..offset + len]).inspect_err(|err| {
+ BiosImage::new(self.dev, &self.data[offset..offset + len]).inspect_err(|err| {
dev_err!(
- self.pdev.as_ref(),
+ self.dev,
"Failed to {} at offset {:#x}: {:?}\n",
context,
offset,
@@ -146,10 +145,7 @@ fn next(&mut self) -> Option<Self::Item> {
}
if self.current_offset > BIOS_MAX_SCAN_LEN {
- dev_err!(
- self.pdev.as_ref(),
- "Error: exceeded BIOS scan limit, stopping scan\n"
- );
+ dev_err!(self.dev, "Error: exceeded BIOS scan limit, stopping scan\n");
return None;
}
@@ -192,18 +188,18 @@ impl 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::Device, bar0: &Bar0) -> Result<Vbios> {
+ pub(crate) fn new(dev: &device::Device, bar0: &Bar0) -> Result<Vbios> {
// Images to extract from iteration
let mut pci_at_image: Option<PciAtBiosImage> = None;
let mut first_fwsec_image: Option<FwSecBiosBuilder> = None;
let mut second_fwsec_image: Option<FwSecBiosBuilder> = None;
// Parse all VBIOS images in the ROM
- for image_result in VbiosIterator::new(pdev, bar0)? {
+ for image_result in VbiosIterator::new(dev, bar0)? {
let full_image = image_result?;
dev_dbg!(
- pdev.as_ref(),
+ dev,
"Found BIOS image: size: {:#x}, type: {}, last: {}\n",
full_image.image_size_bytes(),
full_image.image_type_str(),
@@ -234,14 +230,14 @@ pub(crate) fn new(pdev: &pci::Device, bar0: &Bar0) -> Result<Vbios> {
(second_fwsec_image, first_fwsec_image, pci_at_image)
{
second
- .setup_falcon_data(pdev, &pci_at, &first)
- .inspect_err(|e| dev_err!(pdev.as_ref(), "Falcon data setup failed: {:?}\n", e))?;
+ .setup_falcon_data(dev, &pci_at, &first)
+ .inspect_err(|e| dev_err!(dev, "Falcon data setup failed: {:?}\n", e))?;
Ok(Vbios {
- fwsec_image: second.build(pdev)?,
+ fwsec_image: second.build(dev)?,
})
} else {
dev_err!(
- pdev.as_ref(),
+ dev,
"Missing required images for falcon data setup, skipping\n"
);
Err(EINVAL)
@@ -284,9 +280,9 @@ struct PcirStruct {
}
impl PcirStruct {
- fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
+ fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
if data.len() < core::mem::size_of::<PcirStruct>() {
- dev_err!(pdev.as_ref(), "Not enough data for PcirStruct\n");
+ dev_err!(dev, "Not enough data for PcirStruct\n");
return Err(EINVAL);
}
@@ -295,11 +291,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
// Signature should be "PCIR" (0x52494350) or "NPDS" (0x5344504e).
if &signature != b"PCIR" && &signature != b"NPDS" {
- dev_err!(
- pdev.as_ref(),
- "Invalid signature for PcirStruct: {:?}\n",
- signature
- );
+ dev_err!(dev, "Invalid signature for PcirStruct: {:?}\n", signature);
return Err(EINVAL);
}
@@ -308,7 +300,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
let image_len = u16::from_le_bytes([data[16], data[17]]);
if image_len == 0 {
- dev_err!(pdev.as_ref(), "Invalid image length: 0\n");
+ dev_err!(dev, "Invalid image length: 0\n");
return Err(EINVAL);
}
@@ -467,7 +459,7 @@ struct PciRomHeader {
}
impl PciRomHeader {
- fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
+ fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
if data.len() < 26 {
// Need at least 26 bytes to read pciDataStrucPtr and sizeOfBlock.
return Err(EINVAL);
@@ -479,7 +471,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
match signature {
0xAA55 | 0xBB77 | 0x4E56 => {}
_ => {
- dev_err!(pdev.as_ref(), "ROM signature unknown {:#x}\n", signature);
+ dev_err!(dev, "ROM signature unknown {:#x}\n", signature);
return Err(EINVAL);
}
}
@@ -538,9 +530,9 @@ struct NpdeStruct {
}
impl NpdeStruct {
- fn new(pdev: &pci::Device, data: &[u8]) -> Option<Self> {
+ fn new(dev: &device::Device, data: &[u8]) -> Option<Self> {
if data.len() < core::mem::size_of::<Self>() {
- dev_dbg!(pdev.as_ref(), "Not enough data for NpdeStruct\n");
+ dev_dbg!(dev, "Not enough data for NpdeStruct\n");
return None;
}
@@ -549,17 +541,13 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Option<Self> {
// Signature should be "NPDE" (0x4544504E).
if &signature != b"NPDE" {
- dev_dbg!(
- pdev.as_ref(),
- "Invalid signature for NpdeStruct: {:?}\n",
- signature
- );
+ dev_dbg!(dev, "Invalid signature for NpdeStruct: {:?}\n", signature);
return None;
}
let subimage_len = u16::from_le_bytes([data[8], data[9]]);
if subimage_len == 0 {
- dev_dbg!(pdev.as_ref(), "Invalid subimage length: 0\n");
+ dev_dbg!(dev, "Invalid subimage length: 0\n");
return None;
}
@@ -584,7 +572,7 @@ fn image_size_bytes(&self) -> usize {
/// Try to find NPDE in the data, the NPDE is right after the PCIR.
fn find_in_data(
- pdev: &pci::Device,
+ dev: &device::Device,
data: &[u8],
rom_header: &PciRomHeader,
pcir: &PcirStruct,
@@ -596,12 +584,12 @@ fn find_in_data(
// Check if we have enough data
if npde_start + core::mem::size_of::<Self>() > data.len() {
- dev_dbg!(pdev.as_ref(), "Not enough data for NPDE\n");
+ dev_dbg!(dev, "Not enough data for NPDE\n");
return None;
}
// Try to create NPDE from the data
- NpdeStruct::new(pdev, &data[npde_start..])
+ NpdeStruct::new(dev, &data[npde_start..])
}
}
@@ -669,10 +657,10 @@ fn image_size_bytes(&self) -> usize {
/// 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::Device, data: &[u8]) -> Result<Self> {
- let base = BiosImageBase::new(pdev, data)?;
+ fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
+ let base = BiosImageBase::new(dev, data)?;
let image = base.into_image().inspect_err(|e| {
- dev_err!(pdev.as_ref(), "Failed to create BiosImage: {:?}\n", e);
+ dev_err!(dev, "Failed to create BiosImage: {:?}\n", e);
})?;
Ok(image)
@@ -773,16 +761,16 @@ fn into_image(self) -> Result<BiosImage> {
}
/// Creates a new BiosImageBase from raw byte data.
- fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
+ fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
// Ensure we have enough data for the ROM header.
if data.len() < 26 {
- dev_err!(pdev.as_ref(), "Not enough data for ROM header\n");
+ dev_err!(dev, "Not enough data for ROM header\n");
return Err(EINVAL);
}
// Parse the ROM header.
- let rom_header = PciRomHeader::new(pdev, &data[0..26])
- .inspect_err(|e| dev_err!(pdev.as_ref(), "Failed to create PciRomHeader: {:?}\n", e))?;
+ let rom_header = PciRomHeader::new(dev, &data[0..26])
+ .inspect_err(|e| dev_err!(dev, "Failed to create PciRomHeader: {:?}\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;
@@ -791,22 +779,22 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
.ok_or(EINVAL)
.inspect_err(|_| {
dev_err!(
- pdev.as_ref(),
+ dev,
"PCIR offset {:#x} out of bounds (data length: {})\n",
pcir_offset,
data.len()
);
dev_err!(
- pdev.as_ref(),
+ dev,
"Consider reading more data for construction of BiosImage\n"
);
})?;
- let pcir = PcirStruct::new(pdev, pcir_data)
- .inspect_err(|e| dev_err!(pdev.as_ref(), "Failed to create PcirStruct: {:?}\n", e))?;
+ let pcir = PcirStruct::new(dev, pcir_data)
+ .inspect_err(|e| dev_err!(dev, "Failed to create PcirStruct: {:?}\n", e))?;
// Look for NPDE structure if this is not an NBSI image (type != 0x70).
- let npde = NpdeStruct::find_in_data(pdev, data, &rom_header, &pcir);
+ let npde = NpdeStruct::find_in_data(dev, data, &rom_header, &pcir);
// Create a copy of the data.
let mut data_copy = KVec::new();
@@ -848,7 +836,7 @@ fn get_bit_token(&self, token_id: u8) -> Result<BitToken> {
///
/// 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> {
+ fn falcon_data_ptr(&self, dev: &device::Device) -> Result<u32> {
let token = self.get_bit_token(BIT_TOKEN_ID_FALCON_DATA)?;
// Make sure we don't go out of bounds
@@ -859,14 +847,14 @@ fn falcon_data_ptr(&self, pdev: &pci::Device) -> Result<u32> {
// 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 to convert data slice to array");
+ dev_err!(dev, "Failed to convert data slice to array");
EINVAL
})?;
let data_ptr = u32::from_le_bytes(bytes);
if (data_ptr as usize) < self.base.data.len() {
- dev_err!(pdev.as_ref(), "Falcon data pointer out of bounds\n");
+ dev_err!(dev, "Falcon data pointer out of bounds\n");
return Err(EINVAL);
}
@@ -928,7 +916,7 @@ struct PmuLookupTable {
}
impl PmuLookupTable {
- fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
+ fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
if data.len() < 4 {
return Err(EINVAL);
}
@@ -940,10 +928,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
let required_bytes = header_len + (entry_count * entry_len);
if data.len() < required_bytes {
- dev_err!(
- pdev.as_ref(),
- "PmuLookupTable data length less than required\n"
- );
+ dev_err!(dev, "PmuLookupTable data length less than required\n");
return Err(EINVAL);
}
@@ -956,11 +941,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
// Debug logging of entries (dumps the table data to dmesg)
for i in (header_len..required_bytes).step_by(entry_len) {
- dev_dbg!(
- pdev.as_ref(),
- "PMU entry: {:02x?}\n",
- &data[i..][..entry_len]
- );
+ dev_dbg!(dev, "PMU entry: {:02x?}\n", &data[i..][..entry_len]);
}
Ok(PmuLookupTable {
@@ -997,11 +978,11 @@ fn find_entry_by_type(&self, entry_type: u8) -> Result<PmuLookupTableEntry> {
impl FwSecBiosBuilder {
fn setup_falcon_data(
&mut self,
- pdev: &pci::Device,
+ dev: &device::Device,
pci_at_image: &PciAtBiosImage,
first_fwsec: &FwSecBiosBuilder,
) -> Result {
- let mut offset = pci_at_image.falcon_data_ptr(pdev)? as usize;
+ let mut offset = pci_at_image.falcon_data_ptr(dev)? as usize;
let mut pmu_in_first_fwsec = false;
// The falcon data pointer assumes that the PciAt and FWSEC images
@@ -1025,9 +1006,9 @@ fn setup_falcon_data(
if pmu_in_first_fwsec {
self.pmu_lookup_table =
- Some(PmuLookupTable::new(pdev, &first_fwsec.base.data[offset..])?);
+ Some(PmuLookupTable::new(dev, &first_fwsec.base.data[offset..])?);
} else {
- self.pmu_lookup_table = Some(PmuLookupTable::new(pdev, &self.base.data[offset..])?);
+ self.pmu_lookup_table = Some(PmuLookupTable::new(dev, &self.base.data[offset..])?);
}
match self
@@ -1040,18 +1021,14 @@ fn setup_falcon_data(
let mut ucode_offset = entry.data as usize;
ucode_offset -= pci_at_image.base.data.len();
if ucode_offset < first_fwsec.base.data.len() {
- dev_err!(pdev.as_ref(), "Falcon Ucode offset not in second Fwsec.\n");
+ dev_err!(dev, "Falcon Ucode offset not in second Fwsec.\n");
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
- );
+ dev_err!(dev, "PmuLookupTableEntry not found, error: {:?}\n", e);
return Err(EINVAL);
}
}
@@ -1059,7 +1036,7 @@ fn setup_falcon_data(
}
/// Build the final FwSecBiosImage from this builder
- fn build(self, pdev: &pci::Device) -> Result<FwSecBiosImage> {
+ fn build(self, dev: &device::Device) -> Result<FwSecBiosImage> {
let ret = FwSecBiosImage {
base: self.base,
falcon_ucode_offset: self.falcon_ucode_offset.ok_or(EINVAL)?,
@@ -1067,8 +1044,8 @@ fn build(self, pdev: &pci::Device) -> Result<FwSecBiosImage> {
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);
+ let desc = ret.header(dev)?;
+ dev_dbg!(dev, "PmuLookupTableEntry desc: {:#?}\n", desc);
}
Ok(ret)
--
2.50.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] gpu: nova-core: vbios: store reference to Device where relevant
2025-08-08 2:46 [PATCH 0/2] gpu: nova-core: vbios: simplify device use Alexandre Courbot
2025-08-08 2:46 ` [PATCH 1/2] gpu: nova-core: vbios: replace pci::Device with device::Device Alexandre Courbot
@ 2025-08-08 2:46 ` Alexandre Courbot
2025-08-29 13:43 ` Joel Fernandes
2025-09-01 10:37 ` [PATCH 0/2] gpu: nova-core: vbios: simplify device use Danilo Krummrich
2 siblings, 1 reply; 7+ messages in thread
From: Alexandre Courbot @ 2025-08-08 2:46 UTC (permalink / raw)
To: Danilo Krummrich, David Airlie, Simona Vetter, Joel Fernandes
Cc: nouveau, dri-devel, rust-for-linux, linux-kernel,
Alexandre Courbot
Now that the vbios code uses a non-bound `Device` instance, store an
`ARef` to it at construction time so we can use it for logging without
having to carry an extra argument on every method for that sole purpose.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/nova-core/firmware/fwsec.rs | 8 ++--
drivers/gpu/nova-core/vbios.rs | 69 ++++++++++++++++++++-------------
2 files changed, 46 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/nova-core/firmware/fwsec.rs b/drivers/gpu/nova-core/firmware/fwsec.rs
index 0dff3cfa90afee0cd4c3348023c8bfd7edccdb29..d9b9d1f92880cbcd36dac84b9e86a84e6465cf5d 100644
--- a/drivers/gpu/nova-core/firmware/fwsec.rs
+++ b/drivers/gpu/nova-core/firmware/fwsec.rs
@@ -253,8 +253,8 @@ impl FalconFirmware for FwsecFirmware {
impl FirmwareDmaObject<FwsecFirmware, Unsigned> {
fn new_fwsec(dev: &Device<device::Bound>, bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
- let desc = bios.fwsec_image().header(dev)?;
- let ucode = bios.fwsec_image().ucode(dev, desc)?;
+ let desc = bios.fwsec_image().header()?;
+ let ucode = bios.fwsec_image().ucode(desc)?;
let mut dma_object = DmaObject::from_data(dev, ucode)?;
let hdr_offset = (desc.imem_load_size + desc.interface_offset) as usize;
@@ -343,7 +343,7 @@ pub(crate) fn new(
let ucode_dma = FirmwareDmaObject::<Self, _>::new_fwsec(dev, bios, cmd)?;
// Patch signature if needed.
- let desc = bios.fwsec_image().header(dev)?;
+ let desc = bios.fwsec_image().header()?;
let ucode_signed = if desc.signature_count != 0 {
let sig_base_img = (desc.imem_load_size + desc.pkc_data_offset) as usize;
let desc_sig_versions = u32::from(desc.signature_versions);
@@ -382,7 +382,7 @@ pub(crate) fn new(
dev_dbg!(dev, "patching signature with index {}\n", signature_idx);
let signature = bios
.fwsec_image()
- .sigs(dev, desc)
+ .sigs(desc)
.and_then(|sigs| sigs.get(signature_idx).ok_or(EINVAL))?;
ucode_dma.patch_signature(signature, sig_base_img)?
diff --git a/drivers/gpu/nova-core/vbios.rs b/drivers/gpu/nova-core/vbios.rs
index b5564b4d3e4758e77178aa403635e4780f0378cc..6fc06b1b83655a7dec00308880dbdfc32d7105ce 100644
--- a/drivers/gpu/nova-core/vbios.rs
+++ b/drivers/gpu/nova-core/vbios.rs
@@ -9,6 +9,7 @@
use kernel::device;
use kernel::error::Result;
use kernel::prelude::*;
+use kernel::types::ARef;
/// The offset of the VBIOS ROM in the BAR0 space.
const ROM_OFFSET: usize = 0x300000;
@@ -230,10 +231,10 @@ pub(crate) fn new(dev: &device::Device, bar0: &Bar0) -> Result<Vbios> {
(second_fwsec_image, first_fwsec_image, pci_at_image)
{
second
- .setup_falcon_data(dev, &pci_at, &first)
+ .setup_falcon_data(&pci_at, &first)
.inspect_err(|e| dev_err!(dev, "Falcon data setup failed: {:?}\n", e))?;
Ok(Vbios {
- fwsec_image: second.build(dev)?,
+ fwsec_image: second.build()?,
})
} else {
dev_err!(
@@ -742,9 +743,10 @@ fn try_from(base: BiosImageBase) -> Result<Self> {
///
/// 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 {
+ /// Used for logging.
+ dev: ARef<device::Device>,
/// PCI ROM Expansion Header
rom_header: PciRomHeader,
/// PCI Data Structure
@@ -801,6 +803,7 @@ fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
data_copy.extend_from_slice(data, GFP_KERNEL)?;
Ok(BiosImageBase {
+ dev: dev.into(),
rom_header,
pcir,
npde,
@@ -836,7 +839,7 @@ fn get_bit_token(&self, token_id: u8) -> Result<BitToken> {
///
/// This is just a 4 byte structure that contains a pointer to the Falcon data in the FWSEC
/// image.
- fn falcon_data_ptr(&self, dev: &device::Device) -> Result<u32> {
+ fn falcon_data_ptr(&self) -> Result<u32> {
let token = self.get_bit_token(BIT_TOKEN_ID_FALCON_DATA)?;
// Make sure we don't go out of bounds
@@ -847,14 +850,14 @@ fn falcon_data_ptr(&self, dev: &device::Device) -> Result<u32> {
// 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!(dev, "Failed to convert data slice to array");
+ dev_err!(self.base.dev, "Failed to convert data slice to array");
EINVAL
})?;
let data_ptr = u32::from_le_bytes(bytes);
if (data_ptr as usize) < self.base.data.len() {
- dev_err!(dev, "Falcon data pointer out of bounds\n");
+ dev_err!(self.base.dev, "Falcon data pointer out of bounds\n");
return Err(EINVAL);
}
@@ -978,11 +981,10 @@ fn find_entry_by_type(&self, entry_type: u8) -> Result<PmuLookupTableEntry> {
impl FwSecBiosBuilder {
fn setup_falcon_data(
&mut self,
- dev: &device::Device,
pci_at_image: &PciAtBiosImage,
first_fwsec: &FwSecBiosBuilder,
) -> Result {
- let mut offset = pci_at_image.falcon_data_ptr(dev)? as usize;
+ let mut offset = pci_at_image.falcon_data_ptr()? as usize;
let mut pmu_in_first_fwsec = false;
// The falcon data pointer assumes that the PciAt and FWSEC images
@@ -1005,10 +1007,15 @@ fn setup_falcon_data(
self.falcon_data_offset = Some(offset);
if pmu_in_first_fwsec {
- self.pmu_lookup_table =
- Some(PmuLookupTable::new(dev, &first_fwsec.base.data[offset..])?);
+ self.pmu_lookup_table = Some(PmuLookupTable::new(
+ &self.base.dev,
+ &first_fwsec.base.data[offset..],
+ )?);
} else {
- self.pmu_lookup_table = Some(PmuLookupTable::new(dev, &self.base.data[offset..])?);
+ self.pmu_lookup_table = Some(PmuLookupTable::new(
+ &self.base.dev,
+ &self.base.data[offset..],
+ )?);
}
match self
@@ -1021,14 +1028,18 @@ fn setup_falcon_data(
let mut ucode_offset = entry.data as usize;
ucode_offset -= pci_at_image.base.data.len();
if ucode_offset < first_fwsec.base.data.len() {
- dev_err!(dev, "Falcon Ucode offset not in second Fwsec.\n");
+ dev_err!(self.base.dev, "Falcon Ucode offset not in second Fwsec.\n");
return Err(EINVAL);
}
ucode_offset -= first_fwsec.base.data.len();
self.falcon_ucode_offset = Some(ucode_offset);
}
Err(e) => {
- dev_err!(dev, "PmuLookupTableEntry not found, error: {:?}\n", e);
+ dev_err!(
+ self.base.dev,
+ "PmuLookupTableEntry not found, error: {:?}\n",
+ e
+ );
return Err(EINVAL);
}
}
@@ -1036,7 +1047,7 @@ fn setup_falcon_data(
}
/// Build the final FwSecBiosImage from this builder
- fn build(self, dev: &device::Device) -> Result<FwSecBiosImage> {
+ fn build(self) -> Result<FwSecBiosImage> {
let ret = FwSecBiosImage {
base: self.base,
falcon_ucode_offset: self.falcon_ucode_offset.ok_or(EINVAL)?,
@@ -1044,8 +1055,8 @@ fn build(self, dev: &device::Device) -> Result<FwSecBiosImage> {
if cfg!(debug_assertions) {
// Print the desc header for debugging
- let desc = ret.header(dev)?;
- dev_dbg!(dev, "PmuLookupTableEntry desc: {:#?}\n", desc);
+ let desc = ret.header()?;
+ dev_dbg!(ret.base.dev, "PmuLookupTableEntry desc: {:#?}\n", desc);
}
Ok(ret)
@@ -1054,13 +1065,16 @@ fn build(self, dev: &device::Device) -> Result<FwSecBiosImage> {
impl FwSecBiosImage {
/// Get the FwSec header ([`FalconUCodeDescV3`]).
- pub(crate) fn header(&self, dev: &device::Device) -> Result<&FalconUCodeDescV3> {
+ pub(crate) fn header(&self) -> 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 falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>() > self.base.data.len() {
- dev_err!(dev, "fwsec-frts header not contained within BIOS bounds\n");
+ dev_err!(
+ self.base.dev,
+ "fwsec-frts header not contained within BIOS bounds\n"
+ );
return Err(ERANGE);
}
@@ -1072,7 +1086,7 @@ pub(crate) fn header(&self, dev: &device::Device) -> Result<&FalconUCodeDescV3>
let ver = (hdr & 0xff00) >> 8;
if ver != 3 {
- dev_err!(dev, "invalid fwsec firmware version: {:?}\n", ver);
+ dev_err!(self.base.dev, "invalid fwsec firmware version: {:?}\n", ver);
return Err(EINVAL);
}
@@ -1092,7 +1106,7 @@ pub(crate) fn header(&self, dev: &device::Device) -> Result<&FalconUCodeDescV3>
}
/// Get the ucode data as a byte slice
- pub(crate) fn ucode(&self, dev: &device::Device, desc: &FalconUCodeDescV3) -> Result<&[u8]> {
+ pub(crate) fn ucode(&self, desc: &FalconUCodeDescV3) -> Result<&[u8]> {
let falcon_ucode_offset = self.falcon_ucode_offset;
// The ucode data follows the descriptor.
@@ -1104,15 +1118,16 @@ pub(crate) fn ucode(&self, dev: &device::Device, desc: &FalconUCodeDescV3) -> Re
.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"))
+ .inspect_err(|_| {
+ dev_err!(
+ self.base.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]> {
+ pub(crate) fn sigs(&self, 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 =
@@ -1121,7 +1136,7 @@ pub(crate) fn sigs(
// Make sure the data is within bounds.
if sigs_data_offset + sigs_size > self.base.data.len() {
dev_err!(
- dev,
+ self.base.dev,
"fwsec signatures data not contained within BIOS bounds\n"
);
return Err(ERANGE);
--
2.50.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] gpu: nova-core: vbios: replace pci::Device with device::Device
2025-08-08 2:46 ` [PATCH 1/2] gpu: nova-core: vbios: replace pci::Device with device::Device Alexandre Courbot
@ 2025-08-29 13:43 ` Joel Fernandes
0 siblings, 0 replies; 7+ messages in thread
From: Joel Fernandes @ 2025-08-29 13:43 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Danilo Krummrich, David Airlie, Simona Vetter, nouveau, dri-devel,
rust-for-linux, linux-kernel
On Fri, Aug 08, 2025 at 11:46:41AM +0900, Alexandre Courbot wrote:
> The passed pci::Device is exclusively used for logging purposes, so it
> can be replaced by a regular device::Device, which allows us to remove
> the `as_ref()` indirections at each logging site.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
thanks,
- Joel
> ---
> drivers/gpu/nova-core/gpu.rs | 2 +-
> drivers/gpu/nova-core/vbios.rs | 135 +++++++++++++++++------------------------
> 2 files changed, 57 insertions(+), 80 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
> index 72d40b0124f0c1a2a381484172c289af523511df..33082ac45873ee4cf91d7d8af499efa984af4ba9 100644
> --- a/drivers/gpu/nova-core/gpu.rs
> +++ b/drivers/gpu/nova-core/gpu.rs
> @@ -298,7 +298,7 @@ pub(crate) fn new(
> let fb_layout = FbLayout::new(spec.chipset, bar)?;
> dev_dbg!(pdev.as_ref(), "{:#x?}\n", fb_layout);
>
> - let bios = Vbios::new(pdev, bar)?;
> + let bios = Vbios::new(pdev.as_ref(), bar)?;
>
> Self::run_fwsec_frts(pdev.as_ref(), &gsp_falcon, bar, &bios, &fb_layout)?;
>
> diff --git a/drivers/gpu/nova-core/vbios.rs b/drivers/gpu/nova-core/vbios.rs
> index 5b5d9f38cbb3a6b1c374c1e0eee2509eb8d5660c..b5564b4d3e4758e77178aa403635e4780f0378cc 100644
> --- a/drivers/gpu/nova-core/vbios.rs
> +++ b/drivers/gpu/nova-core/vbios.rs
> @@ -8,7 +8,6 @@
> use core::convert::TryFrom;
> use kernel::device;
> use kernel::error::Result;
> -use kernel::pci;
> use kernel::prelude::*;
>
> /// The offset of the VBIOS ROM in the BAR0 space.
> @@ -31,7 +30,7 @@
>
> /// Vbios Reader for constructing the VBIOS data.
> struct VbiosIterator<'a> {
> - pdev: &'a pci::Device,
> + dev: &'a device::Device,
> 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
> @@ -46,9 +45,9 @@ struct VbiosIterator<'a> {
> }
>
> impl<'a> VbiosIterator<'a> {
> - fn new(pdev: &'a pci::Device, bar0: &'a Bar0) -> Result<Self> {
> + fn new(dev: &'a device::Device, bar0: &'a Bar0) -> Result<Self> {
> Ok(Self {
> - pdev,
> + dev,
> bar0,
> data: KVec::new(),
> current_offset: 0,
> @@ -64,7 +63,7 @@ fn read_more(&mut self, len: usize) -> Result {
> // Ensure length is a multiple of 4 for 32-bit reads
> if len % core::mem::size_of::<u32>() != 0 {
> dev_err!(
> - self.pdev.as_ref(),
> + self.dev,
> "VBIOS read length {} is not a multiple of 4\n",
> len
> );
> @@ -89,7 +88,7 @@ fn read_more(&mut self, len: usize) -> Result {
> /// Read bytes at a specific offset, filling any gap.
> fn read_more_at_offset(&mut self, offset: usize, len: usize) -> Result {
> if offset > BIOS_MAX_SCAN_LEN {
> - dev_err!(self.pdev.as_ref(), "Error: exceeded BIOS scan limit.\n");
> + dev_err!(self.dev, "Error: exceeded BIOS scan limit.\n");
> return Err(EINVAL);
> }
>
> @@ -115,7 +114,7 @@ fn read_bios_image_at_offset(
> if offset + len > data_len {
> self.read_more_at_offset(offset, len).inspect_err(|e| {
> dev_err!(
> - self.pdev.as_ref(),
> + self.dev,
> "Failed to read more at offset {:#x}: {:?}\n",
> offset,
> e
> @@ -123,9 +122,9 @@ fn read_bios_image_at_offset(
> })?;
> }
>
> - BiosImage::new(self.pdev, &self.data[offset..offset + len]).inspect_err(|err| {
> + BiosImage::new(self.dev, &self.data[offset..offset + len]).inspect_err(|err| {
> dev_err!(
> - self.pdev.as_ref(),
> + self.dev,
> "Failed to {} at offset {:#x}: {:?}\n",
> context,
> offset,
> @@ -146,10 +145,7 @@ fn next(&mut self) -> Option<Self::Item> {
> }
>
> if self.current_offset > BIOS_MAX_SCAN_LEN {
> - dev_err!(
> - self.pdev.as_ref(),
> - "Error: exceeded BIOS scan limit, stopping scan\n"
> - );
> + dev_err!(self.dev, "Error: exceeded BIOS scan limit, stopping scan\n");
> return None;
> }
>
> @@ -192,18 +188,18 @@ impl 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::Device, bar0: &Bar0) -> Result<Vbios> {
> + pub(crate) fn new(dev: &device::Device, bar0: &Bar0) -> Result<Vbios> {
> // Images to extract from iteration
> let mut pci_at_image: Option<PciAtBiosImage> = None;
> let mut first_fwsec_image: Option<FwSecBiosBuilder> = None;
> let mut second_fwsec_image: Option<FwSecBiosBuilder> = None;
>
> // Parse all VBIOS images in the ROM
> - for image_result in VbiosIterator::new(pdev, bar0)? {
> + for image_result in VbiosIterator::new(dev, bar0)? {
> let full_image = image_result?;
>
> dev_dbg!(
> - pdev.as_ref(),
> + dev,
> "Found BIOS image: size: {:#x}, type: {}, last: {}\n",
> full_image.image_size_bytes(),
> full_image.image_type_str(),
> @@ -234,14 +230,14 @@ pub(crate) fn new(pdev: &pci::Device, bar0: &Bar0) -> Result<Vbios> {
> (second_fwsec_image, first_fwsec_image, pci_at_image)
> {
> second
> - .setup_falcon_data(pdev, &pci_at, &first)
> - .inspect_err(|e| dev_err!(pdev.as_ref(), "Falcon data setup failed: {:?}\n", e))?;
> + .setup_falcon_data(dev, &pci_at, &first)
> + .inspect_err(|e| dev_err!(dev, "Falcon data setup failed: {:?}\n", e))?;
> Ok(Vbios {
> - fwsec_image: second.build(pdev)?,
> + fwsec_image: second.build(dev)?,
> })
> } else {
> dev_err!(
> - pdev.as_ref(),
> + dev,
> "Missing required images for falcon data setup, skipping\n"
> );
> Err(EINVAL)
> @@ -284,9 +280,9 @@ struct PcirStruct {
> }
>
> impl PcirStruct {
> - fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
> + fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
> if data.len() < core::mem::size_of::<PcirStruct>() {
> - dev_err!(pdev.as_ref(), "Not enough data for PcirStruct\n");
> + dev_err!(dev, "Not enough data for PcirStruct\n");
> return Err(EINVAL);
> }
>
> @@ -295,11 +291,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
>
> // Signature should be "PCIR" (0x52494350) or "NPDS" (0x5344504e).
> if &signature != b"PCIR" && &signature != b"NPDS" {
> - dev_err!(
> - pdev.as_ref(),
> - "Invalid signature for PcirStruct: {:?}\n",
> - signature
> - );
> + dev_err!(dev, "Invalid signature for PcirStruct: {:?}\n", signature);
> return Err(EINVAL);
> }
>
> @@ -308,7 +300,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
>
> let image_len = u16::from_le_bytes([data[16], data[17]]);
> if image_len == 0 {
> - dev_err!(pdev.as_ref(), "Invalid image length: 0\n");
> + dev_err!(dev, "Invalid image length: 0\n");
> return Err(EINVAL);
> }
>
> @@ -467,7 +459,7 @@ struct PciRomHeader {
> }
>
> impl PciRomHeader {
> - fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
> + fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
> if data.len() < 26 {
> // Need at least 26 bytes to read pciDataStrucPtr and sizeOfBlock.
> return Err(EINVAL);
> @@ -479,7 +471,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
> match signature {
> 0xAA55 | 0xBB77 | 0x4E56 => {}
> _ => {
> - dev_err!(pdev.as_ref(), "ROM signature unknown {:#x}\n", signature);
> + dev_err!(dev, "ROM signature unknown {:#x}\n", signature);
> return Err(EINVAL);
> }
> }
> @@ -538,9 +530,9 @@ struct NpdeStruct {
> }
>
> impl NpdeStruct {
> - fn new(pdev: &pci::Device, data: &[u8]) -> Option<Self> {
> + fn new(dev: &device::Device, data: &[u8]) -> Option<Self> {
> if data.len() < core::mem::size_of::<Self>() {
> - dev_dbg!(pdev.as_ref(), "Not enough data for NpdeStruct\n");
> + dev_dbg!(dev, "Not enough data for NpdeStruct\n");
> return None;
> }
>
> @@ -549,17 +541,13 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Option<Self> {
>
> // Signature should be "NPDE" (0x4544504E).
> if &signature != b"NPDE" {
> - dev_dbg!(
> - pdev.as_ref(),
> - "Invalid signature for NpdeStruct: {:?}\n",
> - signature
> - );
> + dev_dbg!(dev, "Invalid signature for NpdeStruct: {:?}\n", signature);
> return None;
> }
>
> let subimage_len = u16::from_le_bytes([data[8], data[9]]);
> if subimage_len == 0 {
> - dev_dbg!(pdev.as_ref(), "Invalid subimage length: 0\n");
> + dev_dbg!(dev, "Invalid subimage length: 0\n");
> return None;
> }
>
> @@ -584,7 +572,7 @@ fn image_size_bytes(&self) -> usize {
>
> /// Try to find NPDE in the data, the NPDE is right after the PCIR.
> fn find_in_data(
> - pdev: &pci::Device,
> + dev: &device::Device,
> data: &[u8],
> rom_header: &PciRomHeader,
> pcir: &PcirStruct,
> @@ -596,12 +584,12 @@ fn find_in_data(
>
> // Check if we have enough data
> if npde_start + core::mem::size_of::<Self>() > data.len() {
> - dev_dbg!(pdev.as_ref(), "Not enough data for NPDE\n");
> + dev_dbg!(dev, "Not enough data for NPDE\n");
> return None;
> }
>
> // Try to create NPDE from the data
> - NpdeStruct::new(pdev, &data[npde_start..])
> + NpdeStruct::new(dev, &data[npde_start..])
> }
> }
>
> @@ -669,10 +657,10 @@ fn image_size_bytes(&self) -> usize {
>
> /// 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::Device, data: &[u8]) -> Result<Self> {
> - let base = BiosImageBase::new(pdev, data)?;
> + fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
> + let base = BiosImageBase::new(dev, data)?;
> let image = base.into_image().inspect_err(|e| {
> - dev_err!(pdev.as_ref(), "Failed to create BiosImage: {:?}\n", e);
> + dev_err!(dev, "Failed to create BiosImage: {:?}\n", e);
> })?;
>
> Ok(image)
> @@ -773,16 +761,16 @@ fn into_image(self) -> Result<BiosImage> {
> }
>
> /// Creates a new BiosImageBase from raw byte data.
> - fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
> + fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
> // Ensure we have enough data for the ROM header.
> if data.len() < 26 {
> - dev_err!(pdev.as_ref(), "Not enough data for ROM header\n");
> + dev_err!(dev, "Not enough data for ROM header\n");
> return Err(EINVAL);
> }
>
> // Parse the ROM header.
> - let rom_header = PciRomHeader::new(pdev, &data[0..26])
> - .inspect_err(|e| dev_err!(pdev.as_ref(), "Failed to create PciRomHeader: {:?}\n", e))?;
> + let rom_header = PciRomHeader::new(dev, &data[0..26])
> + .inspect_err(|e| dev_err!(dev, "Failed to create PciRomHeader: {:?}\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;
> @@ -791,22 +779,22 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
> .ok_or(EINVAL)
> .inspect_err(|_| {
> dev_err!(
> - pdev.as_ref(),
> + dev,
> "PCIR offset {:#x} out of bounds (data length: {})\n",
> pcir_offset,
> data.len()
> );
> dev_err!(
> - pdev.as_ref(),
> + dev,
> "Consider reading more data for construction of BiosImage\n"
> );
> })?;
>
> - let pcir = PcirStruct::new(pdev, pcir_data)
> - .inspect_err(|e| dev_err!(pdev.as_ref(), "Failed to create PcirStruct: {:?}\n", e))?;
> + let pcir = PcirStruct::new(dev, pcir_data)
> + .inspect_err(|e| dev_err!(dev, "Failed to create PcirStruct: {:?}\n", e))?;
>
> // Look for NPDE structure if this is not an NBSI image (type != 0x70).
> - let npde = NpdeStruct::find_in_data(pdev, data, &rom_header, &pcir);
> + let npde = NpdeStruct::find_in_data(dev, data, &rom_header, &pcir);
>
> // Create a copy of the data.
> let mut data_copy = KVec::new();
> @@ -848,7 +836,7 @@ fn get_bit_token(&self, token_id: u8) -> Result<BitToken> {
> ///
> /// 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> {
> + fn falcon_data_ptr(&self, dev: &device::Device) -> Result<u32> {
> let token = self.get_bit_token(BIT_TOKEN_ID_FALCON_DATA)?;
>
> // Make sure we don't go out of bounds
> @@ -859,14 +847,14 @@ fn falcon_data_ptr(&self, pdev: &pci::Device) -> Result<u32> {
> // 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 to convert data slice to array");
> + dev_err!(dev, "Failed to convert data slice to array");
> EINVAL
> })?;
>
> let data_ptr = u32::from_le_bytes(bytes);
>
> if (data_ptr as usize) < self.base.data.len() {
> - dev_err!(pdev.as_ref(), "Falcon data pointer out of bounds\n");
> + dev_err!(dev, "Falcon data pointer out of bounds\n");
> return Err(EINVAL);
> }
>
> @@ -928,7 +916,7 @@ struct PmuLookupTable {
> }
>
> impl PmuLookupTable {
> - fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
> + fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
> if data.len() < 4 {
> return Err(EINVAL);
> }
> @@ -940,10 +928,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
> let required_bytes = header_len + (entry_count * entry_len);
>
> if data.len() < required_bytes {
> - dev_err!(
> - pdev.as_ref(),
> - "PmuLookupTable data length less than required\n"
> - );
> + dev_err!(dev, "PmuLookupTable data length less than required\n");
> return Err(EINVAL);
> }
>
> @@ -956,11 +941,7 @@ fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
>
> // Debug logging of entries (dumps the table data to dmesg)
> for i in (header_len..required_bytes).step_by(entry_len) {
> - dev_dbg!(
> - pdev.as_ref(),
> - "PMU entry: {:02x?}\n",
> - &data[i..][..entry_len]
> - );
> + dev_dbg!(dev, "PMU entry: {:02x?}\n", &data[i..][..entry_len]);
> }
>
> Ok(PmuLookupTable {
> @@ -997,11 +978,11 @@ fn find_entry_by_type(&self, entry_type: u8) -> Result<PmuLookupTableEntry> {
> impl FwSecBiosBuilder {
> fn setup_falcon_data(
> &mut self,
> - pdev: &pci::Device,
> + dev: &device::Device,
> pci_at_image: &PciAtBiosImage,
> first_fwsec: &FwSecBiosBuilder,
> ) -> Result {
> - let mut offset = pci_at_image.falcon_data_ptr(pdev)? as usize;
> + let mut offset = pci_at_image.falcon_data_ptr(dev)? as usize;
> let mut pmu_in_first_fwsec = false;
>
> // The falcon data pointer assumes that the PciAt and FWSEC images
> @@ -1025,9 +1006,9 @@ fn setup_falcon_data(
>
> if pmu_in_first_fwsec {
> self.pmu_lookup_table =
> - Some(PmuLookupTable::new(pdev, &first_fwsec.base.data[offset..])?);
> + Some(PmuLookupTable::new(dev, &first_fwsec.base.data[offset..])?);
> } else {
> - self.pmu_lookup_table = Some(PmuLookupTable::new(pdev, &self.base.data[offset..])?);
> + self.pmu_lookup_table = Some(PmuLookupTable::new(dev, &self.base.data[offset..])?);
> }
>
> match self
> @@ -1040,18 +1021,14 @@ fn setup_falcon_data(
> let mut ucode_offset = entry.data as usize;
> ucode_offset -= pci_at_image.base.data.len();
> if ucode_offset < first_fwsec.base.data.len() {
> - dev_err!(pdev.as_ref(), "Falcon Ucode offset not in second Fwsec.\n");
> + dev_err!(dev, "Falcon Ucode offset not in second Fwsec.\n");
> 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
> - );
> + dev_err!(dev, "PmuLookupTableEntry not found, error: {:?}\n", e);
> return Err(EINVAL);
> }
> }
> @@ -1059,7 +1036,7 @@ fn setup_falcon_data(
> }
>
> /// Build the final FwSecBiosImage from this builder
> - fn build(self, pdev: &pci::Device) -> Result<FwSecBiosImage> {
> + fn build(self, dev: &device::Device) -> Result<FwSecBiosImage> {
> let ret = FwSecBiosImage {
> base: self.base,
> falcon_ucode_offset: self.falcon_ucode_offset.ok_or(EINVAL)?,
> @@ -1067,8 +1044,8 @@ fn build(self, pdev: &pci::Device) -> Result<FwSecBiosImage> {
>
> 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);
> + let desc = ret.header(dev)?;
> + dev_dbg!(dev, "PmuLookupTableEntry desc: {:#?}\n", desc);
> }
>
> Ok(ret)
>
> --
> 2.50.1
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] gpu: nova-core: vbios: store reference to Device where relevant
2025-08-08 2:46 ` [PATCH 2/2] gpu: nova-core: vbios: store reference to Device where relevant Alexandre Courbot
@ 2025-08-29 13:43 ` Joel Fernandes
0 siblings, 0 replies; 7+ messages in thread
From: Joel Fernandes @ 2025-08-29 13:43 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Danilo Krummrich, David Airlie, Simona Vetter, nouveau, dri-devel,
rust-for-linux, linux-kernel
On Fri, Aug 08, 2025 at 11:46:42AM +0900, Alexandre Courbot wrote:
> Now that the vbios code uses a non-bound `Device` instance, store an
> `ARef` to it at construction time so we can use it for logging without
> having to carry an extra argument on every method for that sole purpose.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
thanks,
- Joel
> ---
> drivers/gpu/nova-core/firmware/fwsec.rs | 8 ++--
> drivers/gpu/nova-core/vbios.rs | 69 ++++++++++++++++++++-------------
> 2 files changed, 46 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/firmware/fwsec.rs b/drivers/gpu/nova-core/firmware/fwsec.rs
> index 0dff3cfa90afee0cd4c3348023c8bfd7edccdb29..d9b9d1f92880cbcd36dac84b9e86a84e6465cf5d 100644
> --- a/drivers/gpu/nova-core/firmware/fwsec.rs
> +++ b/drivers/gpu/nova-core/firmware/fwsec.rs
> @@ -253,8 +253,8 @@ impl FalconFirmware for FwsecFirmware {
>
> impl FirmwareDmaObject<FwsecFirmware, Unsigned> {
> fn new_fwsec(dev: &Device<device::Bound>, bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
> - let desc = bios.fwsec_image().header(dev)?;
> - let ucode = bios.fwsec_image().ucode(dev, desc)?;
> + let desc = bios.fwsec_image().header()?;
> + let ucode = bios.fwsec_image().ucode(desc)?;
> let mut dma_object = DmaObject::from_data(dev, ucode)?;
>
> let hdr_offset = (desc.imem_load_size + desc.interface_offset) as usize;
> @@ -343,7 +343,7 @@ pub(crate) fn new(
> let ucode_dma = FirmwareDmaObject::<Self, _>::new_fwsec(dev, bios, cmd)?;
>
> // Patch signature if needed.
> - let desc = bios.fwsec_image().header(dev)?;
> + let desc = bios.fwsec_image().header()?;
> let ucode_signed = if desc.signature_count != 0 {
> let sig_base_img = (desc.imem_load_size + desc.pkc_data_offset) as usize;
> let desc_sig_versions = u32::from(desc.signature_versions);
> @@ -382,7 +382,7 @@ pub(crate) fn new(
> dev_dbg!(dev, "patching signature with index {}\n", signature_idx);
> let signature = bios
> .fwsec_image()
> - .sigs(dev, desc)
> + .sigs(desc)
> .and_then(|sigs| sigs.get(signature_idx).ok_or(EINVAL))?;
>
> ucode_dma.patch_signature(signature, sig_base_img)?
> diff --git a/drivers/gpu/nova-core/vbios.rs b/drivers/gpu/nova-core/vbios.rs
> index b5564b4d3e4758e77178aa403635e4780f0378cc..6fc06b1b83655a7dec00308880dbdfc32d7105ce 100644
> --- a/drivers/gpu/nova-core/vbios.rs
> +++ b/drivers/gpu/nova-core/vbios.rs
> @@ -9,6 +9,7 @@
> use kernel::device;
> use kernel::error::Result;
> use kernel::prelude::*;
> +use kernel::types::ARef;
>
> /// The offset of the VBIOS ROM in the BAR0 space.
> const ROM_OFFSET: usize = 0x300000;
> @@ -230,10 +231,10 @@ pub(crate) fn new(dev: &device::Device, bar0: &Bar0) -> Result<Vbios> {
> (second_fwsec_image, first_fwsec_image, pci_at_image)
> {
> second
> - .setup_falcon_data(dev, &pci_at, &first)
> + .setup_falcon_data(&pci_at, &first)
> .inspect_err(|e| dev_err!(dev, "Falcon data setup failed: {:?}\n", e))?;
> Ok(Vbios {
> - fwsec_image: second.build(dev)?,
> + fwsec_image: second.build()?,
> })
> } else {
> dev_err!(
> @@ -742,9 +743,10 @@ fn try_from(base: BiosImageBase) -> Result<Self> {
> ///
> /// 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 {
> + /// Used for logging.
> + dev: ARef<device::Device>,
> /// PCI ROM Expansion Header
> rom_header: PciRomHeader,
> /// PCI Data Structure
> @@ -801,6 +803,7 @@ fn new(dev: &device::Device, data: &[u8]) -> Result<Self> {
> data_copy.extend_from_slice(data, GFP_KERNEL)?;
>
> Ok(BiosImageBase {
> + dev: dev.into(),
> rom_header,
> pcir,
> npde,
> @@ -836,7 +839,7 @@ fn get_bit_token(&self, token_id: u8) -> Result<BitToken> {
> ///
> /// This is just a 4 byte structure that contains a pointer to the Falcon data in the FWSEC
> /// image.
> - fn falcon_data_ptr(&self, dev: &device::Device) -> Result<u32> {
> + fn falcon_data_ptr(&self) -> Result<u32> {
> let token = self.get_bit_token(BIT_TOKEN_ID_FALCON_DATA)?;
>
> // Make sure we don't go out of bounds
> @@ -847,14 +850,14 @@ fn falcon_data_ptr(&self, dev: &device::Device) -> Result<u32> {
> // 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!(dev, "Failed to convert data slice to array");
> + dev_err!(self.base.dev, "Failed to convert data slice to array");
> EINVAL
> })?;
>
> let data_ptr = u32::from_le_bytes(bytes);
>
> if (data_ptr as usize) < self.base.data.len() {
> - dev_err!(dev, "Falcon data pointer out of bounds\n");
> + dev_err!(self.base.dev, "Falcon data pointer out of bounds\n");
> return Err(EINVAL);
> }
>
> @@ -978,11 +981,10 @@ fn find_entry_by_type(&self, entry_type: u8) -> Result<PmuLookupTableEntry> {
> impl FwSecBiosBuilder {
> fn setup_falcon_data(
> &mut self,
> - dev: &device::Device,
> pci_at_image: &PciAtBiosImage,
> first_fwsec: &FwSecBiosBuilder,
> ) -> Result {
> - let mut offset = pci_at_image.falcon_data_ptr(dev)? as usize;
> + let mut offset = pci_at_image.falcon_data_ptr()? as usize;
> let mut pmu_in_first_fwsec = false;
>
> // The falcon data pointer assumes that the PciAt and FWSEC images
> @@ -1005,10 +1007,15 @@ fn setup_falcon_data(
> self.falcon_data_offset = Some(offset);
>
> if pmu_in_first_fwsec {
> - self.pmu_lookup_table =
> - Some(PmuLookupTable::new(dev, &first_fwsec.base.data[offset..])?);
> + self.pmu_lookup_table = Some(PmuLookupTable::new(
> + &self.base.dev,
> + &first_fwsec.base.data[offset..],
> + )?);
> } else {
> - self.pmu_lookup_table = Some(PmuLookupTable::new(dev, &self.base.data[offset..])?);
> + self.pmu_lookup_table = Some(PmuLookupTable::new(
> + &self.base.dev,
> + &self.base.data[offset..],
> + )?);
> }
>
> match self
> @@ -1021,14 +1028,18 @@ fn setup_falcon_data(
> let mut ucode_offset = entry.data as usize;
> ucode_offset -= pci_at_image.base.data.len();
> if ucode_offset < first_fwsec.base.data.len() {
> - dev_err!(dev, "Falcon Ucode offset not in second Fwsec.\n");
> + dev_err!(self.base.dev, "Falcon Ucode offset not in second Fwsec.\n");
> return Err(EINVAL);
> }
> ucode_offset -= first_fwsec.base.data.len();
> self.falcon_ucode_offset = Some(ucode_offset);
> }
> Err(e) => {
> - dev_err!(dev, "PmuLookupTableEntry not found, error: {:?}\n", e);
> + dev_err!(
> + self.base.dev,
> + "PmuLookupTableEntry not found, error: {:?}\n",
> + e
> + );
> return Err(EINVAL);
> }
> }
> @@ -1036,7 +1047,7 @@ fn setup_falcon_data(
> }
>
> /// Build the final FwSecBiosImage from this builder
> - fn build(self, dev: &device::Device) -> Result<FwSecBiosImage> {
> + fn build(self) -> Result<FwSecBiosImage> {
> let ret = FwSecBiosImage {
> base: self.base,
> falcon_ucode_offset: self.falcon_ucode_offset.ok_or(EINVAL)?,
> @@ -1044,8 +1055,8 @@ fn build(self, dev: &device::Device) -> Result<FwSecBiosImage> {
>
> if cfg!(debug_assertions) {
> // Print the desc header for debugging
> - let desc = ret.header(dev)?;
> - dev_dbg!(dev, "PmuLookupTableEntry desc: {:#?}\n", desc);
> + let desc = ret.header()?;
> + dev_dbg!(ret.base.dev, "PmuLookupTableEntry desc: {:#?}\n", desc);
> }
>
> Ok(ret)
> @@ -1054,13 +1065,16 @@ fn build(self, dev: &device::Device) -> Result<FwSecBiosImage> {
>
> impl FwSecBiosImage {
> /// Get the FwSec header ([`FalconUCodeDescV3`]).
> - pub(crate) fn header(&self, dev: &device::Device) -> Result<&FalconUCodeDescV3> {
> + pub(crate) fn header(&self) -> 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 falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>() > self.base.data.len() {
> - dev_err!(dev, "fwsec-frts header not contained within BIOS bounds\n");
> + dev_err!(
> + self.base.dev,
> + "fwsec-frts header not contained within BIOS bounds\n"
> + );
> return Err(ERANGE);
> }
>
> @@ -1072,7 +1086,7 @@ pub(crate) fn header(&self, dev: &device::Device) -> Result<&FalconUCodeDescV3>
> let ver = (hdr & 0xff00) >> 8;
>
> if ver != 3 {
> - dev_err!(dev, "invalid fwsec firmware version: {:?}\n", ver);
> + dev_err!(self.base.dev, "invalid fwsec firmware version: {:?}\n", ver);
> return Err(EINVAL);
> }
>
> @@ -1092,7 +1106,7 @@ pub(crate) fn header(&self, dev: &device::Device) -> Result<&FalconUCodeDescV3>
> }
>
> /// Get the ucode data as a byte slice
> - pub(crate) fn ucode(&self, dev: &device::Device, desc: &FalconUCodeDescV3) -> Result<&[u8]> {
> + pub(crate) fn ucode(&self, desc: &FalconUCodeDescV3) -> Result<&[u8]> {
> let falcon_ucode_offset = self.falcon_ucode_offset;
>
> // The ucode data follows the descriptor.
> @@ -1104,15 +1118,16 @@ pub(crate) fn ucode(&self, dev: &device::Device, desc: &FalconUCodeDescV3) -> Re
> .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"))
> + .inspect_err(|_| {
> + dev_err!(
> + self.base.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]> {
> + pub(crate) fn sigs(&self, 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 =
> @@ -1121,7 +1136,7 @@ pub(crate) fn sigs(
> // Make sure the data is within bounds.
> if sigs_data_offset + sigs_size > self.base.data.len() {
> dev_err!(
> - dev,
> + self.base.dev,
> "fwsec signatures data not contained within BIOS bounds\n"
> );
> return Err(ERANGE);
>
> --
> 2.50.1
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] gpu: nova-core: vbios: simplify device use
2025-08-08 2:46 [PATCH 0/2] gpu: nova-core: vbios: simplify device use Alexandre Courbot
2025-08-08 2:46 ` [PATCH 1/2] gpu: nova-core: vbios: replace pci::Device with device::Device Alexandre Courbot
2025-08-08 2:46 ` [PATCH 2/2] gpu: nova-core: vbios: store reference to Device where relevant Alexandre Courbot
@ 2025-09-01 10:37 ` Danilo Krummrich
2025-09-01 13:30 ` Alexandre Courbot
2 siblings, 1 reply; 7+ messages in thread
From: Danilo Krummrich @ 2025-09-01 10:37 UTC (permalink / raw)
To: Alexandre Courbot
Cc: David Airlie, Simona Vetter, Joel Fernandes, nouveau, dri-devel,
rust-for-linux, linux-kernel
On 8/8/25 4:46 AM, Alexandre Courbot wrote:
> This small cleanup series simplifies the use of `Device` in vbios
> methods.
>
> The device is used for logging purposes only; thus we don't need a
> pci::Device, neither do we need it to be bound. This latter property
> allows us to store an `ARef` to it into structures that require logging
> instead of having all their methods take an extra `dev` argument.
> Removing this argument streamlines the code a bit.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/2] gpu: nova-core: vbios: simplify device use
2025-09-01 10:37 ` [PATCH 0/2] gpu: nova-core: vbios: simplify device use Danilo Krummrich
@ 2025-09-01 13:30 ` Alexandre Courbot
0 siblings, 0 replies; 7+ messages in thread
From: Alexandre Courbot @ 2025-09-01 13:30 UTC (permalink / raw)
To: Danilo Krummrich
Cc: David Airlie, Simona Vetter, Joel Fernandes, nouveau, dri-devel,
rust-for-linux, linux-kernel
On Mon Sep 1, 2025 at 7:37 PM JST, Danilo Krummrich wrote:
> On 8/8/25 4:46 AM, Alexandre Courbot wrote:
>> This small cleanup series simplifies the use of `Device` in vbios
>> methods.
>>
>> The device is used for logging purposes only; thus we don't need a
>> pci::Device, neither do we need it to be bound. This latter property
>> allows us to store an `ARef` to it into structures that require logging
>> instead of having all their methods take an extra `dev` argument.
>> Removing this argument streamlines the code a bit.
>>
>> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
>
> Acked-by: Danilo Krummrich <dakr@kernel.org>
Thanks! Pushed into nova-next.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-09-01 13:30 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-08 2:46 [PATCH 0/2] gpu: nova-core: vbios: simplify device use Alexandre Courbot
2025-08-08 2:46 ` [PATCH 1/2] gpu: nova-core: vbios: replace pci::Device with device::Device Alexandre Courbot
2025-08-29 13:43 ` Joel Fernandes
2025-08-08 2:46 ` [PATCH 2/2] gpu: nova-core: vbios: store reference to Device where relevant Alexandre Courbot
2025-08-29 13:43 ` Joel Fernandes
2025-09-01 10:37 ` [PATCH 0/2] gpu: nova-core: vbios: simplify device use Danilo Krummrich
2025-09-01 13:30 ` Alexandre Courbot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).