Blackwell GPU identification, including ELF .fwsignature_* items.
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
drivers/gpu/nova-core/falcon/hal.rs | 3 ++-
drivers/gpu/nova-core/fb/hal.rs | 5 ++---
drivers/gpu/nova-core/firmware/gsp.rs | 16 ++++++++++++++++
drivers/gpu/nova-core/gpu.rs | 17 +++++++++++++++++
4 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/nova-core/falcon/hal.rs b/drivers/gpu/nova-core/falcon/hal.rs
index 2e1fcd7ac813..7ba8ba856c72 100644
--- a/drivers/gpu/nova-core/falcon/hal.rs
+++ b/drivers/gpu/nova-core/falcon/hal.rs
@@ -44,7 +44,8 @@ pub(super) fn falcon_hal<E: FalconEngine + 'static>(
use Chipset::*;
let hal = match chipset {
- GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107 => {
+ GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
+ | GB100 | GB102 | GB202 | GB203 | GB205 | GB206 | GB207 => {
KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
}
_ => return Err(ENOTSUPP),
diff --git a/drivers/gpu/nova-core/fb/hal.rs b/drivers/gpu/nova-core/fb/hal.rs
index c8e86193317d..30fde2487d8b 100644
--- a/drivers/gpu/nova-core/fb/hal.rs
+++ b/drivers/gpu/nova-core/fb/hal.rs
@@ -32,8 +32,7 @@ pub(super) fn fb_hal(chipset: Chipset) -> &'static dyn FbHal {
match chipset {
TU102 | TU104 | TU106 | TU117 | TU116 => tu102::TU102_HAL,
GA100 => ga100::GA100_HAL,
- GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107 => {
- ga102::GA102_HAL
- }
+ GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
+ | GB100 | GB102 | GB202 | GB203 | GB205 | GB206 | GB207 => ga102::GA102_HAL,
}
}
diff --git a/drivers/gpu/nova-core/firmware/gsp.rs b/drivers/gpu/nova-core/firmware/gsp.rs
index f824863ad551..ed2dea2cd144 100644
--- a/drivers/gpu/nova-core/firmware/gsp.rs
+++ b/drivers/gpu/nova-core/firmware/gsp.rs
@@ -153,6 +153,22 @@ pub(crate) fn new<'a, 'b>(
Architecture::Ampere => ".fwsignature_ga10x",
Architecture::Hopper => ".fwsignature_gh10x",
Architecture::Ada => ".fwsignature_ad10x",
+ Architecture::Blackwell => {
+ // Distinguish between GB10x and GB20x series
+ match chipset {
+ // GB10x series: GB100, GB102
+ Chipset::GB100 | Chipset::GB102 => ".fwsignature_gb10x",
+ // GB20x series: GB202, GB203, GB205, GB206, GB207
+ Chipset::GB202
+ | Chipset::GB203
+ | Chipset::GB205
+ | Chipset::GB206
+ | Chipset::GB207 => ".fwsignature_gb20x",
+ // Unsupported Blackwell chips
+ _ => return Err(ENOTSUPP),
+ }
+ }
+
_ => return Err(ENOTSUPP),
};
let signatures = elf::elf64_section(fw.data(), sigs_section)
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 678577cd8c9c..024bd4d6e092 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -78,6 +78,14 @@ fn try_from(value: u32) -> Result<Self, Self::Error> {
AD104 = 0x194,
AD106 = 0x196,
AD107 = 0x197,
+ // Blackwell
+ GB100 = 0x1a0,
+ GB102 = 0x1a2,
+ GB202 = 0x1b2,
+ GB203 = 0x1b3,
+ GB205 = 0x1b5,
+ GB206 = 0x1b6,
+ GB207 = 0x1b7,
});
impl Chipset {
@@ -93,6 +101,13 @@ pub(crate) fn arch(&self) -> Architecture {
Self::AD102 | Self::AD103 | Self::AD104 | Self::AD106 | Self::AD107 => {
Architecture::Ada
}
+ Self::GB100
+ | Self::GB102
+ | Self::GB202
+ | Self::GB203
+ | Self::GB205
+ | Self::GB206
+ | Self::GB207 => Architecture::Blackwell,
}
}
}
@@ -120,6 +135,7 @@ pub(crate) enum Architecture {
Ampere = 0x17,
Hopper = 0x18,
Ada = 0x19,
+ Blackwell = 0x1b,
}
impl TryFrom<u8> for Architecture {
@@ -131,6 +147,7 @@ fn try_from(value: u8) -> Result<Self> {
0x17 => Ok(Self::Ampere),
0x18 => Ok(Self::Hopper),
0x19 => Ok(Self::Ada),
+ 0x1b => Ok(Self::Blackwell),
_ => Err(ENODEV),
}
}
--
2.51.2
On Wed, 2025-11-05 at 19:54 -0800, John Hubbard wrote:
> let hal = match chipset {
> - GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
> => {
> + GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
> + | GB100 | GB102 | GB202 | GB203 | GB205 | GB206 | GB207 => {
> KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
> }
Maybe combine patches 2 and 3? Also, maybe this should be a range check, instead of listing
every since version? It seems like everything past GA100 uses the GA102 HAL.
On 11/6/25 6:44 AM, Timur Tabi wrote:
> On Wed, 2025-11-05 at 19:54 -0800, John Hubbard wrote:
>> let hal = match chipset {
>> - GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
>> => {
>> + GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
>> + | GB100 | GB102 | GB202 | GB203 | GB205 | GB206 | GB207 => {
>> KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
>> }
>
> Maybe combine patches 2 and 3? Also, maybe this should be a range check, instead of listing
> every since version? It seems like everything past GA100 uses the GA102 HAL.
>
Sure, I can combine the patches.
I'm not sure why I've been wary of using ranges for these arch's.
I'll try it out.
thanks,
John Hubbard
On 11/6/25 2:24 PM, John Hubbard wrote:
> On 11/6/25 6:44 AM, Timur Tabi wrote:
>> On Wed, 2025-11-05 at 19:54 -0800, John Hubbard wrote:
>>> let hal = match chipset {
>>> - GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
>>> => {
>>> + GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
>>> + | GB100 | GB102 | GB202 | GB203 | GB205 | GB206 | GB207 => {
>>> KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
>>> }
>>
>> Maybe combine patches 2 and 3? Also, maybe this should be a range check, instead of listing
>> every since version? It seems like everything past GA100 uses the GA102 HAL.
>>
>
> Sure, I can combine the patches.
>
> I'm not sure why I've been wary of using ranges for these arch's.
> I'll try it out.
Now I know. :) Unlike C, Rust does *not* like it when we try to
treat enums as integers. Casting or other (messier) approaches are
required, and in no case is the end result a more readable on-screen
experience. At least not so far.
It is possible to mix in Architecture (Turing, Ampere, etc) checks,
but I'm not sure that is worth the additional clutter.
Maybe let's just do the long lists of chipsets for now...?
thanks,
--
John Hubbard
On Wed Nov 19, 2025 at 10:46 AM JST, John Hubbard wrote:
> On 11/6/25 2:24 PM, John Hubbard wrote:
>> On 11/6/25 6:44 AM, Timur Tabi wrote:
>>> On Wed, 2025-11-05 at 19:54 -0800, John Hubbard wrote:
>>>> let hal = match chipset {
>>>> - GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
>>>> => {
>>>> + GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
>>>> + | GB100 | GB102 | GB202 | GB203 | GB205 | GB206 | GB207 => {
>>>> KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
>>>> }
>>>
>>> Maybe combine patches 2 and 3? Also, maybe this should be a range check, instead of listing
>>> every since version? It seems like everything past GA100 uses the GA102 HAL.
>>>
>>
>> Sure, I can combine the patches.
>>
>> I'm not sure why I've been wary of using ranges for these arch's.
>> I'll try it out.
>
> Now I know. :) Unlike C, Rust does *not* like it when we try to
> treat enums as integers. Casting or other (messier) approaches are
> required, and in no case is the end result a more readable on-screen
> experience. At least not so far.
>
> It is possible to mix in Architecture (Turing, Ampere, etc) checks,
> but I'm not sure that is worth the additional clutter.
>
> Maybe let's just do the long lists of chipsets for now...?
Yeah, I've hit this issue as well. The compiler might remove that
limitation in the future, or maybe we can craft a `chipset_range!()`
macro that hides the messy casting, but this exhaustive listing also has
the benefit of forcing us to consider every critical site whenever we
support a new chipset so I'm actually not too bothered by it.
On Wed, 19 Nov 2025 at 12:46, Alexandre Courbot <acourbot@nvidia.com> wrote:
>
> On Wed Nov 19, 2025 at 10:46 AM JST, John Hubbard wrote:
> > On 11/6/25 2:24 PM, John Hubbard wrote:
> >> On 11/6/25 6:44 AM, Timur Tabi wrote:
> >>> On Wed, 2025-11-05 at 19:54 -0800, John Hubbard wrote:
> >>>> let hal = match chipset {
> >>>> - GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
> >>>> => {
> >>>> + GA102 | GA103 | GA104 | GA106 | GA107 | GH100 | AD102 | AD103 | AD104 | AD106 | AD107
> >>>> + | GB100 | GB102 | GB202 | GB203 | GB205 | GB206 | GB207 => {
> >>>> KBox::new(ga102::Ga102::<E>::new(), GFP_KERNEL)? as KBox<dyn FalconHal<E>>
> >>>> }
> >>>
> >>> Maybe combine patches 2 and 3? Also, maybe this should be a range check, instead of listing
> >>> every since version? It seems like everything past GA100 uses the GA102 HAL.
> >>>
> >>
> >> Sure, I can combine the patches.
> >>
> >> I'm not sure why I've been wary of using ranges for these arch's.
> >> I'll try it out.
> >
> > Now I know. :) Unlike C, Rust does *not* like it when we try to
> > treat enums as integers. Casting or other (messier) approaches are
> > required, and in no case is the end result a more readable on-screen
> > experience. At least not so far.
> >
> > It is possible to mix in Architecture (Turing, Ampere, etc) checks,
> > but I'm not sure that is worth the additional clutter.
> >
> > Maybe let's just do the long lists of chipsets for now...?
>
> Yeah, I've hit this issue as well. The compiler might remove that
> limitation in the future, or maybe we can craft a `chipset_range!()`
> macro that hides the messy casting, but this exhaustive listing also has
> the benefit of forcing us to consider every critical site whenever we
> support a new chipset so I'm actually not too bothered by it.
I wrote some macros in my nova-core-experiments, had
chipset_before/after/range I think
Dave.
On 11/18/25 7:15 PM, Dave Airlie wrote:
> On Wed, 19 Nov 2025 at 12:46, Alexandre Courbot <acourbot@nvidia.com> wrote:
...
>>> Maybe let's just do the long lists of chipsets for now...?
>>
>> Yeah, I've hit this issue as well. The compiler might remove that
>> limitation in the future, or maybe we can craft a `chipset_range!()`
>> macro that hides the messy casting, but this exhaustive listing also has
>> the benefit of forcing us to consider every critical site whenever we
>> support a new chipset so I'm actually not too bothered by it.
>
> I wrote some macros in my nova-core-experiments, had
> chipset_before/after/range I think
>
aha, I was afraid someone was going to say "macros" out loud, at some
point. And now you've gone and done it. :)
Well, I think we probably want:
a) The ability to clearly specify a chipset range, and
b) For extra credit, maybe: also be able to specify entire GPU
architectures, and architecture ranges.
...again, without too much extraneous noise at the call sites: the goal is
to read it easily:
GA102..=GA104 | Architecture::Blackwell
for example. Macros are going to require that to be less clean, but
let me poke around and see.
thanks,
--
John Hubbard
On Wed, 19 Nov 2025 at 17:08, John Hubbard <jhubbard@nvidia.com> wrote: > > On 11/18/25 7:15 PM, Dave Airlie wrote: > > On Wed, 19 Nov 2025 at 12:46, Alexandre Courbot <acourbot@nvidia.com> wrote: > ... > >>> Maybe let's just do the long lists of chipsets for now...? > >> > >> Yeah, I've hit this issue as well. The compiler might remove that > >> limitation in the future, or maybe we can craft a `chipset_range!()` > >> macro that hides the messy casting, but this exhaustive listing also has > >> the benefit of forcing us to consider every critical site whenever we > >> support a new chipset so I'm actually not too bothered by it. > > > > I wrote some macros in my nova-core-experiments, had > > chipset_before/after/range I think > > > > aha, I was afraid someone was going to say "macros" out loud, at some > point. And now you've gone and done it. :) > > Well, I think we probably want: > > a) The ability to clearly specify a chipset range, and > > b) For extra credit, maybe: also be able to specify entire GPU > architectures, and architecture ranges. > > ...again, without too much extraneous noise at the call sites: the goal is > to read it easily: > > GA102..=GA104 | Architecture::Blackwell > > > for example. Macros are going to require that to be less clean, but > let me poke around and see. https://gitlab.freedesktop.org/nouvelles/kernel/-/blob/nova-core-experiments-fsp-boot/drivers/gpu/nova-core/gpu.rs?ref_type=heads#L96 is what I did, but yeah probably not going to get nice ranges like that. Dave.
On 11/18/25 11:15 PM, Dave Airlie wrote: > On Wed, 19 Nov 2025 at 17:08, John Hubbard <jhubbard@nvidia.com> wrote: >> >> On 11/18/25 7:15 PM, Dave Airlie wrote: >>> On Wed, 19 Nov 2025 at 12:46, Alexandre Courbot <acourbot@nvidia.com> wrote: >> ... >> GA102..=GA104 | Architecture::Blackwell >> >> >> for example. Macros are going to require that to be less clean, but >> let me poke around and see. > > https://gitlab.freedesktop.org/nouvelles/kernel/-/blob/nova-core-experiments-fsp-boot/drivers/gpu/nova-core/gpu.rs?ref_type=heads#L96 > > is what I did, but yeah probably not going to get nice ranges like that. > Thanks for the pointer, I was wondering where that was (I didn't see it in https://github.com/airlied/linux.git, and forgot about the freedesktop.org repo). Yes, I see we can really only go so far here. thanks, -- John Hubbard
© 2016 - 2025 Red Hat, Inc.