All of lore.kernel.org
 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-10-06 20:48 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.