mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Joel Fernandes <joelagnelf@nvidia.com>
To: "Lyude Paul" <lyude@redhat.com>,
	"Alexandre Courbot" <acourbot@nvidia.com>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Maxime Ripard" <mripard@kernel.org>,
	"Thomas Zimmermann" <tzimmermann@suse.de>
Cc: John Hubbard <jhubbard@nvidia.com>,
	Ben Skeggs <bskeggs@nvidia.com>, Timur Tabi <ttabi@nvidia.com>,
	Alistair Popple <apopple@nvidia.com>,
	linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
	nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
	Shirish Baskaran <sbaskaran@nvidia.com>
Subject: Re: [PATCH v4 16/20] nova-core: Add support for VBIOS ucode extraction for boot
Date: Thu, 5 Jun 2025 12:09:46 -0400	[thread overview]
Message-ID: <9de086d3-e441-439f-9ff5-aa66a99643ba@nvidia.com> (raw)
In-Reply-To: <f528cd2d491f15404f30317dd093cc7af5a00fa7.camel@redhat.com>

Hi Lyude,

>> +bios_image! {
>> +    PciAt PciAtBiosImage,   // PCI-AT compatible BIOS image
>> +    Efi EfiBiosImage,       // EFI (Extensible Firmware Interface)
>> +    Nbsi NbsiBiosImage,     // NBSI (Nvidia Bios System Interface)
>> +    FwSecPartial FwSecBiosPartial, // FWSEC (Firmware Security)
>> +}
> 
> Maybe add a colon to separate the two fields in this macro so it looks more
> like a struct declaration?

Sure, will do.

> 
>> +
>> +struct PciAtBiosImage {
>> +    base: BiosImageBase,
>> +    bit_header: BitHeader,
>> +    bit_offset: usize,
>> +}
>> +
>> +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 FwSecBiosPartial {
>> +    base: BiosImageBase,
>> +    // FWSEC-specific fields
>> +    // These are temporary fields that are used during the construction of
>> +    // the FwSecBiosPartial. Once FwSecBiosPartial 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<usize>,
>> +    // The PmuLookupTable starts at the offset of the falcon data pointer
>> +    pmu_lookup_table: Option<PmuLookupTable>,
>> +    // The offset of the Falcon ucode
>> +    falcon_ucode_offset: Option<usize>,
> 
> Shouldn't these last 3 comments be docstrings?

Sure, will change.

> 
>> +}
>> +
>> +struct FwSecBiosImage {
>> +    base: BiosImageBase,
>> +    // The offset of the Falcon ucode
> 
> Same here

Sure, will change.

> 
>> +    falcon_ucode_offset: usize,
>> +}
>> +
>> +// Convert from BiosImageBase to BiosImage
>> +impl TryFrom<BiosImageBase> for BiosImage {
>> +    type Error = Error;
>> +
>> +    fn try_from(base: BiosImageBase) -> Result<Self> {
>> +        match base.pcir.code_type {
>> +            0x00 => Ok(BiosImage::PciAt(base.try_into()?)),
>> +            0x03 => Ok(BiosImage::Efi(EfiBiosImage { base })),
>> +            0x70 => Ok(BiosImage::Nbsi(NbsiBiosImage { base })),
>> +            0xE0 => Ok(BiosImage::FwSecPartial(FwSecBiosPartial {
>> +                base,
>> +                falcon_data_offset: None,
>> +                pmu_lookup_table: None,
>> +                falcon_ucode_offset: None,
>> +            })),
>> +            _ => Err(EINVAL),
>> +        }
>> +    }
>> +}
>> +
>> +/// BIOS Image structure containing various headers and references
>> +/// fields base to all BIOS images. Each BiosImage type has a
>> +/// BiosImageBase type along with other image-specific fields.
>> +/// Note that Rust favors composition of types over inheritance.
>> +#[derive(Debug)]
>> +#[expect(dead_code)]
>> +struct BiosImageBase {
>> +    /// PCI ROM Expansion Header
>> +    rom_header: PciRomHeader,
>> +    /// PCI Data Structure
>> +    pcir: PcirStruct,
>> +    /// NVIDIA PCI Data Extension (optional)
>> +    npde: Option<NpdeStruct>,
>> +    /// Image data (includes ROM header and PCIR)
>> +    data: KVec<u8>,
>> +}
>> +
>> +impl BiosImageBase {
>> +    fn into_image(self) -> Result<BiosImage> {
>> +        BiosImage::try_from(self)
>> +    }
>> +
>> +    /// Creates a new BiosImageBase from raw byte data.
>> +    fn new(pdev: &pci::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");
>> +            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))?;
>> +
>> +        // Get the PCI Data Structure using the pointer from the ROM header
>> +        let pcir_offset = rom_header.pci_data_struct_offset as usize;
>> +        let pcir_data = data
>> +            .get(pcir_offset..pcir_offset + core::mem::size_of::<PcirStruct>())
>> +            .ok_or(EINVAL)
>> +            .inspect_err(|_| {
>> +                dev_err!(
>> +                    pdev.as_ref(),
>> +                    "PCIR offset {:#x} out of bounds (data length: {})\n",
>> +                    pcir_offset,
>> +                    data.len()
>> +                );
>> +                dev_err!(
>> +                    pdev.as_ref(),
>> +                    "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))?;
>> +
>> +        // Look for NPDE structure if this is not an NBSI image (type != 0x70)
>> +        let npde = NpdeStruct::find_in_data(pdev, data, &rom_header, &pcir);
>> +
>> +        // Create a copy of the data
>> +        let mut data_copy = KVec::new();
>> +        data_copy.extend_with(data.len(), 0, GFP_KERNEL)?;
>> +        data_copy.copy_from_slice(data);
>> +
>> +        Ok(BiosImageBase {
>> +            rom_header,
>> +            pcir,
>> +            npde,
>> +            data: data_copy,
>> +        })
>> +    }
>> +}
>> +
>> +/// 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.
>> +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<(BitHeader, usize)> {
>> +        let bit_pattern = [0xff, 0xb8, b'B', b'I', b'T', 0x00];
>> +        let bit_offset = Self::find_byte_pattern(data, &bit_pattern)?;
>> +        let bit_header = BitHeader::new(&data[bit_offset..])?;
>> +
>> +        Ok((bit_header, bit_offset))
>> +    }
>> +
>> +    /// Get a BIT token entry from the BIT table in the PciAtBiosImage
>> +    fn get_bit_token(&self, token_id: u8) -> Result<BitToken> {
>> +        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> {
>> +        let token = self.get_bit_token(BIT_TOKEN_ID_FALCON_DATA)?;
>> +
>> +        // Make sure we don't go out of bounds
>> +        if token.data_offset as usize + 4 > self.base.data.len() {
>> +            return Err(EINVAL);
>> +        }
>> +
>> +        // 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");
>> +            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");
>> +            return Err(EINVAL);
>> +        }
>> +
>> +        Ok(data_ptr)
> 
> Not 100% sure about this but maybe this should be data_offset and not
> data_ptr? It took me a bit to understand what was going on here since normally
> you can't tell if a pointer is valid just by comparing it to the raw length of
> a piece of data
> 

I understand it is a bit confusing, but is consistent with OpenRM code base
naming so I'll like to leave it alone for consistency.

>> +    }
>> +}
>> +
>> +impl TryFrom<BiosImageBase> for PciAtBiosImage {
>> +    type Error = Error;
>> +
>> +    fn try_from(base: BiosImageBase) -> Result<Self> {
>> +        let data_slice = &base.data;
>> +        let (bit_header, bit_offset) = PciAtBiosImage::find_bit_header(data_slice)?;
>> +
>> +        Ok(PciAtBiosImage {
>> +            base,
>> +            bit_header,
>> +            bit_offset,
>> +        })
>> +    }
>> +}
>> +
>> +/// The PmuLookupTableEntry structure is a single entry in the PmuLookupTable.
>> +/// See the PmuLookupTable description for more information.
>> +#[expect(dead_code)]
>> +struct PmuLookupTableEntry {
>> +    application_id: u8,
>> +    target_id: u8,
>> +    data: u32,
>> +}
>> +
>> +impl PmuLookupTableEntry {
>> +    fn new(data: &[u8]) -> Result<Self> {
>> +        if data.len() < 5 {
>> +            return Err(EINVAL);
>> +        }
>> +
>> +        Ok(PmuLookupTableEntry {
>> +            application_id: data[0],
>> +            target_id: data[1],
>> +            data: u32::from_le_bytes(data[2..6].try_into().map_err(|_| 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 PmuLookupTable {
>> +    version: u8,
>> +    header_len: u8,
>> +    entry_len: u8,
>> +    entry_count: u8,
>> +    table_data: KVec<u8>,
>> +}
>> +
>> +impl PmuLookupTable {
>> +    fn new(pdev: &pci::Device, data: &[u8]) -> Result<Self> {
>> +        if data.len() < 4 {
>> +            return Err(EINVAL);
>> +        }
>> +
>> +        let header_len = data[1] as usize;
>> +        let entry_len = data[2] as usize;
>> +        let entry_count = data[3] as usize;
>> +
>> +        let required_bytes = header_len + (entry_count * entry_len);
>> +
>> +        if data.len() < required_bytes {
>> +            dev_err!(
>> +                pdev.as_ref(),
>> +                "PmuLookupTable data length less than required\n"
>> +            );
>> +            return Err(EINVAL);
>> +        }
>> +
>> +        // Create a copy of only the table data
>> +        let table_data = {
>> +            let mut 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)
>> +        if cfg!(debug_assertions) {
>> +            for i in (header_len..required_bytes).step_by(entry_len) {
>> +                dev_dbg!(
>> +                    pdev.as_ref(),
>> +                    "PMU entry: {:02x?}\n",
>> +                    &data[i..][..entry_len]
>> +                );
>> +            }
>> +        }
> 
> Not sure this makes sense - debug_assertions is supposed to be about
> assertions, we probably shouldn't try to use it for other things (especially
> since we've already got dev_dbg! here)

This was suggested by Danilo. I don't really feel strongly either way, IMO I am
also Ok with running it in production.

> 
>> +
>> +        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,
>> +        })
>> +    }
>> +
>> +    fn lookup_index(&self, idx: u8) -> Result<PmuLookupTableEntry> {
>> +        if idx >= self.entry_count {
>> +            return Err(EINVAL);
>> +        }
>> +
>> +        let index = (idx as usize) * self.entry_len as usize;
>> +        PmuLookupTableEntry::new(&self.table_data[index..])
>> +    }
>> +
>> +    // find entry by type value
>> +    fn find_entry_by_type(&self, entry_type: u8) -> Result<PmuLookupTableEntry> {
>> +        for i in 0..self.entry_count {
>> +            let entry = self.lookup_index(i)?;
>> +            if entry.application_id == entry_type {
>> +                return Ok(entry);
>> +            }
>> +        }
>> +
>> +        Err(EINVAL)
>> +    }
>> +}
>> +
>> +/// 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.
>> +impl FwSecBiosPartial {
>> +    fn setup_falcon_data(
>> +        &mut self,
>> +        pdev: &pci::Device,
>> +        pci_at_image: &PciAtBiosImage,
>> +        first_fwsec: &FwSecBiosPartial,
>> +    ) -> Result {
>> +        let mut offset = pci_at_image.falcon_data_ptr(pdev)? as usize;
>> +        let mut pmu_in_first_fwsec = false;
>> +
>> +        // 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();
>> +
>> +        // The offset is now from the start of the first Fwsec image, however
>> +        // the offset points to a location in the second Fwsec image. Since
>> +        // the fwsec images are contiguous, subtract the length of the first Fwsec
>> +        // image from the offset to get the offset to the start of the second
>> +        // Fwsec image.
>> +        if offset < first_fwsec.base.data.len() {
>> +            pmu_in_first_fwsec = true;
>> +        } else {
>> +            offset -= first_fwsec.base.data.len();
>> +        }
>> +
>> +        self.falcon_data_offset = Some(offset);
>> +
>> +        if pmu_in_first_fwsec {
>> +            self.pmu_lookup_table =
>> +                Some(PmuLookupTable::new(pdev, &first_fwsec.base.data[offset..])?);
>> +        } else {
>> +            self.pmu_lookup_table = Some(PmuLookupTable::new(pdev, &self.base.data[offset..])?);
>> +        }
>> +
>> +        match self
>> +            .pmu_lookup_table
>> +            .as_ref()
>> +            .ok_or(EINVAL)?
>> +            .find_entry_by_type(FALCON_UCODE_ENTRY_APPID_FWSEC_PROD)
>> +        {
>> +            Ok(entry) => {
>> +                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");
>> +                    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(())
>> +    }
>> +}
>> +
>> +impl FwSecBiosImage {
>> +    fn new(pdev: &pci::Device, data: FwSecBiosPartial) -> Result<Self> {
>> +        let ret = FwSecBiosImage {
>> +            base: data.base,
>> +            falcon_ucode_offset: data.falcon_ucode_offset.ok_or(EINVAL)?,
>> +        };
>> +
>> +        if cfg!(debug_assertions) {
>> +            // Print the desc header for debugging
>> +            let desc = ret.fwsec_header(pdev.as_ref())?;
>> +            dev_dbg!(pdev.as_ref(), "PmuLookupTableEntry desc: {:#?}\n", desc);
>> +        }
> 
> Again - definitely don't think we should be using debug_assertions for this

Same comment reply above.

>> +
>> +        Ok(ret)
>> +    }
>> +
>> +    /// Get the FwSec header (FalconUCodeDescV3)
>> +    fn fwsec_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 falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>() > self.base.data.len() {
>> +            dev_err!(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()
>> +            .map_err(|_| EINVAL)?;
>> +        let 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);
>> +        }
>> +
>> +        // Return a reference to the FalconUCodeDescV3 structure SAFETY: we have checked that
>> +        // `falcon_ucode_offset + size_of::<FalconUCodeDescV3` is within the bounds of `data.`
> 
> The SAFETY comment here should start on its own line in the comment

Fixed.

> 
>> +        Ok(unsafe {
>> +            &*(self.base.data.as_ptr().add(falcon_ucode_offset) as *const FalconUCodeDescV3)
> 
> FWIW: I would use cast here, not as.

Ok, I'll kindly defer this to Alex since he wrote this line.

> Also though, I think you need to justify> in the safety comment here why it's
safe to be able to hold an immutable
> reference (e.g. why can we expect this data not to be mutated for the lifetime
> of the reference?)

This data vector is ROM, also 'data' in BiosImageBase is immutable after
construction. I'll update the comment.

> 
>> +        })
>> +    }
> 
> ^ missing a newline here

Fixed.

> 
>> +    /// Get the ucode data as a byte slice
>> +    fn fwsec_ucode(&self, dev: &device::Device, desc: &FalconUCodeDescV3) -> Result<&[u8]> {
>> +        let falcon_ucode_offset = self.falcon_ucode_offset;
> 
> I think we can drop this variable if we're only calling falcon_ucode_offset
> once
> 

Good point, fixed.

>> +
>> +        // The ucode data follows the descriptor
>> +        let ucode_data_offset = falcon_ucode_offset + desc.size();
>> +        let size = (desc.imem_load_size + desc.dmem_load_size) as usize;
>> +
>> +        // Get the data slice, checking bounds in a single operation
>> +        self.base
>> +            .data
>> +            .get(ucode_data_offset..ucode_data_offset + size)
>> +            .ok_or(ERANGE)
>> +            .inspect_err(|_| dev_err!(dev, "fwsec ucode data not contained within BIOS bounds\n"))
>> +    }
>> +
>> +    /// Get the signatures as a byte slice
>> +    fn fwsec_sigs(&self, dev: &device::Device, desc: &FalconUCodeDescV3) -> Result<&[u8]> {
>> +        const SIG_SIZE: usize = 96 * 4;
>> +
>> +        let falcon_ucode_offset = self.falcon_ucode_offset;
>> +
>> +        // The signatures data follows the descriptor
>> +        let sigs_data_offset = falcon_ucode_offset + core::mem::size_of::<FalconUCodeDescV3>();
>> +        let size = desc.signature_count as usize * SIG_SIZE;
>> +
>> +        // Make sure the data is within bounds
>> +        if sigs_data_offset + size > self.base.data.len() {
>> +            dev_err!(
>> +                dev,
>> +                "fwsec signatures data not contained within BIOS bounds\n"
>> +            );
>> +            return Err(ERANGE);
>> +        }
>> +
>> +        Ok(&self.base.data[sigs_data_offset..sigs_data_offset + size])
>> +    }
>> +}
>>
> 
> Would be nice to get other people's take on this but I feel like that we
> probably shouldn't make these methods conditional at this point,
> FwSecBiosImage as a type name with FwSecBiosPartial implies that we should
> have already figured out if it's a valid bios image and extracted the relevant
> data in ::new() right?
> 

Do you mean these things be computed at object construction time? I am not sure
if I agree with that, because maybe computing some of these will be optional in
the future. And it will also require additional fields/footprint in the struct
to store them. Probably more LOC too.

thanks,

 - Joel



  parent reply	other threads:[~2025-06-05 16:09 UTC|newest]

Thread overview: 109+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-21  6:44 [PATCH v4 00/20] nova-core: run FWSEC-FRTS to perform first stage of GSP initialization Alexandre Courbot
2025-05-21  6:44 ` [PATCH v4 01/20] rust: dma: expose the count and size of CoherentAllocation Alexandre Courbot
2025-05-21  8:00   ` Danilo Krummrich
2025-05-22  5:24     ` Alexandre Courbot
2025-05-21 12:43   ` Boqun Feng
2025-05-21 15:57     ` Joel Fernandes
2025-05-21 15:59       ` Joel Fernandes
2025-05-22  5:29     ` Alexandre Courbot
2025-06-02  9:24       ` Danilo Krummrich
2025-05-21  6:44 ` [PATCH v4 02/20] rust: make ETIMEDOUT error available Alexandre Courbot
2025-05-21  7:27   ` Benno Lossin
2025-05-21  6:44 ` [PATCH v4 03/20] rust: sizes: add constants up to SZ_2G Alexandre Courbot
2025-05-21 12:45   ` Boqun Feng
2025-05-21  6:44 ` [PATCH v4 04/20] rust: add new `num` module with useful integer operations Alexandre Courbot
2025-05-22  4:00   ` Alexandre Courbot
2025-05-22  8:44     ` Miguel Ojeda
2025-05-22  9:31       ` Alexandre Courbot
2025-05-28 19:56   ` Alice Ryhl
2025-05-29  1:35     ` Alexandre Courbot
2025-05-28 20:17   ` Benno Lossin
2025-05-29  1:18     ` Alexandre Courbot
2025-05-29  7:27       ` Benno Lossin
2025-06-02  9:39         ` Danilo Krummrich
2025-06-03 22:53           ` Benno Lossin
2025-06-03 23:54             ` Alexandre Courbot
2025-06-04  7:21               ` Benno Lossin
2025-06-02 13:09         ` Alexandre Courbot
2025-06-03 23:02           ` Benno Lossin
2025-06-04  0:05             ` Alexandre Courbot
2025-06-04  7:18               ` Benno Lossin
2025-06-12 13:17                 ` Alexandre Courbot
2025-06-12 13:27                   ` Alexandre Courbot
2025-06-12 14:49                     ` Benno Lossin
2025-06-13  5:31                       ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 05/20] gpu: nova-core: use absolute paths in register!() macro Alexandre Courbot
2025-05-30 21:38   ` Lyude Paul
2025-05-21  6:45 ` [PATCH v4 06/20] gpu: nova-core: add delimiter for helper rules " Alexandre Courbot
2025-05-30 21:39   ` Lyude Paul
2025-05-21  6:45 ` [PATCH v4 07/20] gpu: nova-core: expose the offset of each register as a type constant Alexandre Courbot
2025-05-30 21:40   ` Lyude Paul
2025-05-21  6:45 ` [PATCH v4 08/20] gpu: nova-core: allow register aliases Alexandre Courbot
2025-05-21  8:37   ` Danilo Krummrich
2025-05-22  5:14     ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 09/20] gpu: nova-core: increase BAR0 size to 16MB Alexandre Courbot
2025-05-30 21:46   ` Lyude Paul
2025-06-02 11:21     ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 10/20] gpu: nova-core: add helper function to wait on condition Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 11/20] gpu: nova-core: wait for GFW_BOOT completion Alexandre Courbot
2025-05-30 21:51   ` Lyude Paul
2025-05-31 14:09     ` Miguel Ojeda
2025-05-31 14:37       ` Danilo Krummrich
2025-05-31 14:45         ` Miguel Ojeda
2025-06-02 11:21         ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 12/20] gpu: nova-core: add DMA object struct Alexandre Courbot
2025-05-30 21:53   ` Lyude Paul
2025-05-21  6:45 ` [PATCH v4 13/20] gpu: nova-core: register sysmem flush page Alexandre Courbot
2025-05-30 21:57   ` Lyude Paul
2025-06-02 11:09     ` Danilo Krummrich
2025-06-02 11:20       ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 14/20] gpu: nova-core: add falcon register definitions and base code Alexandre Courbot
2025-05-30 22:22   ` Lyude Paul
2025-06-03  8:03     ` Alexandre Courbot
2025-06-02 12:06   ` Danilo Krummrich
2025-06-03  7:59     ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 15/20] gpu: nova-core: firmware: add ucode descriptor used by FWSEC-FRTS Alexandre Courbot
2025-05-30 22:23   ` Lyude Paul
2025-06-02 12:26   ` Danilo Krummrich
2025-06-04  3:58     ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 16/20] nova-core: Add support for VBIOS ucode extraction for boot Alexandre Courbot
2025-05-27 20:38   ` Joel Fernandes
2025-05-29  6:47     ` Alexandre Courbot
2025-06-03 21:15     ` Lyude Paul
2025-06-05 16:18       ` Joel Fernandes
2025-06-02 13:33   ` Danilo Krummrich
2025-06-02 15:15     ` Joel Fernandes
2025-06-03  8:12       ` Alexandre Courbot
2025-06-03 13:47         ` Joel Fernandes
2025-06-03 13:49           ` Danilo Krummrich
2025-06-03 14:29     ` Joel Fernandes
2025-06-04 18:23     ` Joel Fernandes
2025-06-03 21:05   ` Lyude Paul
2025-06-04 10:03     ` Miguel Ojeda
2025-06-05 16:09     ` Joel Fernandes [this message]
2025-06-05 16:21       ` Danilo Krummrich
2025-06-05 16:28         ` Joel Fernandes
2025-05-21  6:45 ` [PATCH v4 17/20] gpu: nova-core: compute layout of the FRTS region Alexandre Courbot
2025-06-03 21:14   ` Lyude Paul
2025-06-04  4:18     ` Alexandre Courbot
2025-06-04 10:24       ` Danilo Krummrich
2025-06-05 13:14         ` Alexandre Courbot
2025-06-04 10:23   ` Danilo Krummrich
2025-06-05 13:36     ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 18/20] gpu: nova-core: add types for patching firmware binaries Alexandre Courbot
2025-06-03 21:16   ` Lyude Paul
2025-06-04 10:28   ` Danilo Krummrich
2025-06-12  7:19     ` Alexandre Courbot
2025-06-12 10:54       ` Danilo Krummrich
2025-06-12 12:52         ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 19/20] gpu: nova-core: extract FWSEC from BIOS and patch it to run FWSEC-FRTS Alexandre Courbot
2025-06-03 21:32   ` Lyude Paul
2025-06-04  1:11     ` Alexandre Courbot
2025-06-04 10:42   ` Danilo Krummrich
2025-06-12  7:20     ` Alexandre Courbot
2025-05-21  6:45 ` [PATCH v4 20/20] gpu: nova-core: load and " Alexandre Courbot
2025-05-29 21:30   ` Timur Tabi
2025-05-30 22:32     ` Lyude Paul
2025-06-04  1:37     ` Alexandre Courbot
2025-06-03 21:45   ` Lyude Paul
2025-06-04  1:38     ` Alexandre Courbot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9de086d3-e441-439f-9ff5-aa66a99643ba@nvidia.com \
    --to=joelagnelf@nvidia.com \
    --cc=a.hindborg@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=airlied@gmail.com \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=apopple@nvidia.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=bskeggs@nvidia.com \
    --cc=dakr@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gary@garyguo.net \
    --cc=jhubbard@nvidia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lyude@redhat.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=nouveau@lists.freedesktop.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=sbaskaran@nvidia.com \
    --cc=simona@ffwll.ch \
    --cc=tmgross@umich.edu \
    --cc=ttabi@nvidia.com \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®