On Wed Feb 25, 2026 at 7:53 AM JST, Joel Fernandes wrote:
> +    /// Extract the first usable FB region from GSP firmware data.
> +    ///
> +    /// Returns the first region suitable for driver memory allocation as a 
> `(base, size)` tuple.
> +    /// Usable regions are those that:
> +    /// - Are not reserved for firmware internal use.
> +    /// - Are not protected (hardware-enforced access restrictions).
> +    /// - Support compression (can use GPU memory compression for bandwidth).
> +    /// - Support ISO (isochronous memory for display requiring guaranteed 
> bandwidth).
> +    pub(crate) fn first_usable_fb_region(&self) -> Option<(u64, u64)> {
> +        let fb_info = &self.0.fbRegionInfoParams;
> +        for i in 0..fb_info.numFBRegions.into_safe_cast() {
> +            if let Some(reg) = fb_info.fbRegion.get(i) {
> +                // Skip malformed regions where limit < base.
> +                if reg.limit < reg.base {
> +                    continue;
> +                }
> +
> +                // Filter: not reserved, not protected, supports compression 
> and ISO.
> +                if reg.reserved == 0
> +                    && reg.bProtected == 0
> +                    && reg.supportCompressed != 0
> +                    && reg.supportISO != 0
> +                {
> +                    let size = reg.limit - reg.base + 1;
> +                    return Some((reg.base, size));
> +                }
> +            }
> +        }
> +        None
> +    }

No need for an explicit index and two blocks here, and we have iterator
methods designed just to do just this:

    fb_info
        .fbRegion
        .iter()
        .take(fb_info.numFBRegions.into_safe_cast())
        // Skip malformed regions where limit < base.
        .filter(|reg| reg.limit >= reg.base)
        .find_map(|reg| {
            // Filter: not reserved, not protected, supports compression and 
ISO.
            if reg.reserved == 0
                && reg.bProtected == 0
                && reg.supportCompressed != 0
                && reg.supportISO != 0
            {
                let size = reg.limit - reg.base + 1;
                Some(reg.base..reg.base.saturating_add(size))
            } else {
                None
            }
        })

Another thing, although not too important for now: we only take
advantage of the first available region in this series. This is ok for
now, but Nouveau for instance does collect all regions - so we should at
least have a TODO to align Nova to at least the same capability.

But this doesn't need to be done for this series; actually I'd prefer if
we start simple and get the buddy allocator in place before thinking
about this.

Reply via email to