* [PATCH v5 1/3] gpu: nova-core: prepare Spec and Revision types for boot0/boot42
2025-11-06 1:27 [PATCH v5 0/3] gpu: nova: add boot42 support for next-gen GPUs John Hubbard
@ 2025-11-06 1:27 ` John Hubbard
2025-11-06 7:45 ` Alexandre Courbot
2025-11-06 1:27 ` [PATCH v5 2/3] gpu: nova-core: make Architecture behave as a u8 type John Hubbard
2025-11-06 1:27 ` [PATCH v5 3/3] gpu: nova-core: add boot42 support for next-gen GPUs John Hubbard
2 siblings, 1 reply; 9+ messages in thread
From: John Hubbard @ 2025-11-06 1:27 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Alexandre Courbot, Joel Fernandes, Timur Tabi, Alistair Popple,
Edwin Peer, Zhi Wang, David Airlie, Simona Vetter, Bjorn Helgaas,
Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, nouveau, rust-for-linux, LKML, John Hubbard
1) Implement Display for Spec. This simplifies the dev_info!() code for
printing banners such as:
NVIDIA (Chipset: GA104, Architecture: Ampere, Revision: a.1)
2) Decouple Revision from boot0.
3) Enhance Revision, which in turn simplifies Spec::new().
4) Also, slightly enhance the comment about Spec, to be more precise.
Cc: Alexandre Courbot <acourbot@nvidia.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Timur Tabi <ttabi@nvidia.com>
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
drivers/gpu/nova-core/gpu.rs | 45 +++++++++++++++++++----------------
drivers/gpu/nova-core/regs.rs | 8 +++++++
2 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 9d182bffe8b4..8173cdcd8378 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -130,16 +130,18 @@ fn try_from(value: u8) -> Result<Self> {
}
pub(crate) struct Revision {
- major: u8,
- minor: u8,
+ pub(crate) major: u8,
+ pub(crate) minor: u8,
}
-impl Revision {
- fn from_boot0(boot0: regs::NV_PMC_BOOT_0) -> Self {
- Self {
- major: boot0.major_revision(),
- minor: boot0.minor_revision(),
- }
+impl TryFrom<regs::NV_PMC_BOOT_0> for Spec {
+ type Error = Error;
+
+ fn try_from(boot0: regs::NV_PMC_BOOT_0) -> Result<Self> {
+ Ok(Self {
+ chipset: boot0.chipset()?,
+ revision: boot0.revision(),
+ })
}
}
@@ -149,7 +151,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
-/// Structure holding the metadata of the GPU.
+/// Structure holding a basic description of the GPU: Architecture, Chipset and Revision.
pub(crate) struct Spec {
chipset: Chipset,
/// The revision of the chipset.
@@ -160,10 +162,19 @@ impl Spec {
fn new(bar: &Bar0) -> Result<Spec> {
let boot0 = regs::NV_PMC_BOOT_0::read(bar);
- Ok(Self {
- chipset: boot0.chipset()?,
- revision: Revision::from_boot0(boot0),
- })
+ Spec::try_from(boot0)
+ }
+}
+
+impl fmt::Display for Spec {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "Chipset: {}, Architecture: {:?}, Revision: {}",
+ self.chipset,
+ self.chipset.arch(),
+ self.revision
+ )
}
}
@@ -193,13 +204,7 @@ pub(crate) fn new<'a>(
) -> impl PinInit<Self, Error> + 'a {
try_pin_init!(Self {
spec: Spec::new(bar).inspect(|spec| {
- dev_info!(
- pdev.as_ref(),
- "NVIDIA (Chipset: {}, Architecture: {:?}, Revision: {})\n",
- spec.chipset,
- spec.chipset.arch(),
- spec.revision
- );
+ dev_info!(pdev.as_ref(),"NVIDIA ({})\n", spec);
})?,
// We must wait for GFW_BOOT completion before doing any significant setup on the GPU.
diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
index 206dab2e1335..207b865335af 100644
--- a/drivers/gpu/nova-core/regs.rs
+++ b/drivers/gpu/nova-core/regs.rs
@@ -41,6 +41,14 @@ pub(crate) fn chipset(self) -> Result<Chipset> {
})
.and_then(Chipset::try_from)
}
+
+ /// Returns the revision information of the chip.
+ pub(crate) fn revision(self) -> crate::gpu::Revision {
+ crate::gpu::Revision {
+ major: self.major_revision(),
+ minor: self.minor_revision(),
+ }
+ }
}
// PBUS
--
2.51.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v5 1/3] gpu: nova-core: prepare Spec and Revision types for boot0/boot42
2025-11-06 1:27 ` [PATCH v5 1/3] gpu: nova-core: prepare Spec and Revision types for boot0/boot42 John Hubbard
@ 2025-11-06 7:45 ` Alexandre Courbot
2025-11-06 21:12 ` John Hubbard
0 siblings, 1 reply; 9+ messages in thread
From: Alexandre Courbot @ 2025-11-06 7:45 UTC (permalink / raw)
To: John Hubbard, Danilo Krummrich
Cc: Alexandre Courbot, Joel Fernandes, Timur Tabi, Alistair Popple,
Edwin Peer, Zhi Wang, David Airlie, Simona Vetter, Bjorn Helgaas,
Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, nouveau, rust-for-linux, LKML, Nouveau
On Thu Nov 6, 2025 at 10:27 AM JST, John Hubbard wrote:
> 1) Implement Display for Spec. This simplifies the dev_info!() code for
> printing banners such as:
>
> NVIDIA (Chipset: GA104, Architecture: Ampere, Revision: a.1)
>
> 2) Decouple Revision from boot0.
>
> 3) Enhance Revision, which in turn simplifies Spec::new().
>
> 4) Also, slightly enhance the comment about Spec, to be more precise.
A bullet-list in a patch description is a sure sign you will be asked to
split things up. :)
And in this case I think it makes all the more sense, since all these
things taken separately ought to be simple, but having them in the same
diff makes it confusing to review.
Although it's mostly the `Display` implementation that at the very least
should be its own patch, the rest can probably be kept together as it is
related, and adding an intermediate patch would require temporary code
to build Revision. The diff becomes much clearer once the impl blocks
are moved where they should be (please see below).
The comment update can be squashed together with the Revision/Spec
patch.
>
> Cc: Alexandre Courbot <acourbot@nvidia.com>
> Cc: Danilo Krummrich <dakr@kernel.org>
> Cc: Timur Tabi <ttabi@nvidia.com>
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
> ---
> drivers/gpu/nova-core/gpu.rs | 45 +++++++++++++++++++----------------
> drivers/gpu/nova-core/regs.rs | 8 +++++++
> 2 files changed, 33 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
> index 9d182bffe8b4..8173cdcd8378 100644
> --- a/drivers/gpu/nova-core/gpu.rs
> +++ b/drivers/gpu/nova-core/gpu.rs
> @@ -130,16 +130,18 @@ fn try_from(value: u8) -> Result<Self> {
> }
>
> pub(crate) struct Revision {
> - major: u8,
> - minor: u8,
> + pub(crate) major: u8,
> + pub(crate) minor: u8,
> }
>
> -impl Revision {
> - fn from_boot0(boot0: regs::NV_PMC_BOOT_0) -> Self {
> - Self {
> - major: boot0.major_revision(),
> - minor: boot0.minor_revision(),
> - }
> +impl TryFrom<regs::NV_PMC_BOOT_0> for Spec {
> + type Error = Error;
> +
> + fn try_from(boot0: regs::NV_PMC_BOOT_0) -> Result<Self> {
> + Ok(Self {
> + chipset: boot0.chipset()?,
> + revision: boot0.revision(),
> + })
This impl block for `Revision` gets replaced by a block for `Spec`,
which is only declared later. Can you move it (and the one for BOOT_42
in the third patch) to the right place, next to the other impl blocks
for `Spec`?
> }
> }
>
> @@ -149,7 +151,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
> }
> }
>
> -/// Structure holding the metadata of the GPU.
> +/// Structure holding a basic description of the GPU: Architecture, Chipset and Revision.
> pub(crate) struct Spec {
> chipset: Chipset,
> /// The revision of the chipset.
> @@ -160,10 +162,19 @@ impl Spec {
> fn new(bar: &Bar0) -> Result<Spec> {
> let boot0 = regs::NV_PMC_BOOT_0::read(bar);
>
> - Ok(Self {
> - chipset: boot0.chipset()?,
> - revision: Revision::from_boot0(boot0),
> - })
> + Spec::try_from(boot0)
> + }
> +}
> +
> +impl fmt::Display for Spec {
> + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
> + write!(
> + f,
> + "Chipset: {}, Architecture: {:?}, Revision: {}",
> + self.chipset,
> + self.chipset.arch(),
> + self.revision
> + )
> }
> }
>
> @@ -193,13 +204,7 @@ pub(crate) fn new<'a>(
> ) -> impl PinInit<Self, Error> + 'a {
> try_pin_init!(Self {
> spec: Spec::new(bar).inspect(|spec| {
> - dev_info!(
> - pdev.as_ref(),
> - "NVIDIA (Chipset: {}, Architecture: {:?}, Revision: {})\n",
> - spec.chipset,
> - spec.chipset.arch(),
> - spec.revision
> - );
> + dev_info!(pdev.as_ref(),"NVIDIA ({})\n", spec);
> })?,
>
> // We must wait for GFW_BOOT completion before doing any significant setup on the GPU.
> diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
> index 206dab2e1335..207b865335af 100644
> --- a/drivers/gpu/nova-core/regs.rs
> +++ b/drivers/gpu/nova-core/regs.rs
> @@ -41,6 +41,14 @@ pub(crate) fn chipset(self) -> Result<Chipset> {
> })
> .and_then(Chipset::try_from)
> }
> +
> + /// Returns the revision information of the chip.
> + pub(crate) fn revision(self) -> crate::gpu::Revision {
> + crate::gpu::Revision {
nit: let's import `Revision`, or at least `gpu`, to align with what we
do with the other structures.
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH v5 1/3] gpu: nova-core: prepare Spec and Revision types for boot0/boot42
2025-11-06 7:45 ` Alexandre Courbot
@ 2025-11-06 21:12 ` John Hubbard
0 siblings, 0 replies; 9+ messages in thread
From: John Hubbard @ 2025-11-06 21:12 UTC (permalink / raw)
To: Alexandre Courbot, Danilo Krummrich
Cc: Joel Fernandes, Timur Tabi, Alistair Popple, Edwin Peer, Zhi Wang,
David Airlie, Simona Vetter, Bjorn Helgaas, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, nouveau,
rust-for-linux, LKML, Nouveau
On 11/5/25 11:45 PM, Alexandre Courbot wrote:
> On Thu Nov 6, 2025 at 10:27 AM JST, John Hubbard wrote:
>> 1) Implement Display for Spec. This simplifies the dev_info!() code for
>> printing banners such as:
>>
>> NVIDIA (Chipset: GA104, Architecture: Ampere, Revision: a.1)
>>
>> 2) Decouple Revision from boot0.
>>
>> 3) Enhance Revision, which in turn simplifies Spec::new().
>>
>> 4) Also, slightly enhance the comment about Spec, to be more precise.
>
> A bullet-list in a patch description is a sure sign you will be asked to
> split things up. :)
Yes. That is an eternal truth, which I foolishly ignored here. haha
>
> And in this case I think it makes all the more sense, since all these
> things taken separately ought to be simple, but having them in the same
> diff makes it confusing to review.
>
> Although it's mostly the `Display` implementation that at the very least
> should be its own patch, the rest can probably be kept together as it is
> related, and adding an intermediate patch would require temporary code
> to build Revision. The diff becomes much clearer once the impl blocks
> are moved where they should be (please see below).
>
> The comment update can be squashed together with the Revision/Spec
> patch.
>
Will do.
>>
>> Cc: Alexandre Courbot <acourbot@nvidia.com>
>> Cc: Danilo Krummrich <dakr@kernel.org>
>> Cc: Timur Tabi <ttabi@nvidia.com>
>> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
>> ---
>> drivers/gpu/nova-core/gpu.rs | 45 +++++++++++++++++++----------------
>> drivers/gpu/nova-core/regs.rs | 8 +++++++
>> 2 files changed, 33 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
>> index 9d182bffe8b4..8173cdcd8378 100644
>> --- a/drivers/gpu/nova-core/gpu.rs
>> +++ b/drivers/gpu/nova-core/gpu.rs
>> @@ -130,16 +130,18 @@ fn try_from(value: u8) -> Result<Self> {
>> }
>>
>> pub(crate) struct Revision {
>> - major: u8,
>> - minor: u8,
>> + pub(crate) major: u8,
>> + pub(crate) minor: u8,
>> }
>>
>> -impl Revision {
>> - fn from_boot0(boot0: regs::NV_PMC_BOOT_0) -> Self {
>> - Self {
>> - major: boot0.major_revision(),
>> - minor: boot0.minor_revision(),
>> - }
>> +impl TryFrom<regs::NV_PMC_BOOT_0> for Spec {
>> + type Error = Error;
>> +
>> + fn try_from(boot0: regs::NV_PMC_BOOT_0) -> Result<Self> {
>> + Ok(Self {
>> + chipset: boot0.chipset()?,
>> + revision: boot0.revision(),
>> + })
>
> This impl block for `Revision` gets replaced by a block for `Spec`,
> which is only declared later. Can you move it (and the one for BOOT_42
> in the third patch) to the right place, next to the other impl blocks
> for `Spec`?
Yes.
>
>> }
>> }
>>
>> @@ -149,7 +151,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
>> }
>> }
>>
>> -/// Structure holding the metadata of the GPU.
>> +/// Structure holding a basic description of the GPU: Architecture, Chipset and Revision.
>> pub(crate) struct Spec {
>> chipset: Chipset,
>> /// The revision of the chipset.
>> @@ -160,10 +162,19 @@ impl Spec {
>> fn new(bar: &Bar0) -> Result<Spec> {
>> let boot0 = regs::NV_PMC_BOOT_0::read(bar);
>>
>> - Ok(Self {
>> - chipset: boot0.chipset()?,
>> - revision: Revision::from_boot0(boot0),
>> - })
>> + Spec::try_from(boot0)
>> + }
>> +}
>> +
>> +impl fmt::Display for Spec {
>> + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
>> + write!(
>> + f,
>> + "Chipset: {}, Architecture: {:?}, Revision: {}",
>> + self.chipset,
>> + self.chipset.arch(),
>> + self.revision
>> + )
>> }
>> }
>>
>> @@ -193,13 +204,7 @@ pub(crate) fn new<'a>(
>> ) -> impl PinInit<Self, Error> + 'a {
>> try_pin_init!(Self {
>> spec: Spec::new(bar).inspect(|spec| {
>> - dev_info!(
>> - pdev.as_ref(),
>> - "NVIDIA (Chipset: {}, Architecture: {:?}, Revision: {})\n",
>> - spec.chipset,
>> - spec.chipset.arch(),
>> - spec.revision
>> - );
>> + dev_info!(pdev.as_ref(),"NVIDIA ({})\n", spec);
>> })?,
>>
>> // We must wait for GFW_BOOT completion before doing any significant setup on the GPU.
>> diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
>> index 206dab2e1335..207b865335af 100644
>> --- a/drivers/gpu/nova-core/regs.rs
>> +++ b/drivers/gpu/nova-core/regs.rs
>> @@ -41,6 +41,14 @@ pub(crate) fn chipset(self) -> Result<Chipset> {
>> })
>> .and_then(Chipset::try_from)
>> }
>> +
>> + /// Returns the revision information of the chip.
>> + pub(crate) fn revision(self) -> crate::gpu::Revision {
>> + crate::gpu::Revision {
>
> nit: let's import `Revision`, or at least `gpu`, to align with what we
> do with the other structures.
Yes.
thanks,
--
John Hubbard
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v5 2/3] gpu: nova-core: make Architecture behave as a u8 type
2025-11-06 1:27 [PATCH v5 0/3] gpu: nova: add boot42 support for next-gen GPUs John Hubbard
2025-11-06 1:27 ` [PATCH v5 1/3] gpu: nova-core: prepare Spec and Revision types for boot0/boot42 John Hubbard
@ 2025-11-06 1:27 ` John Hubbard
2025-11-06 1:27 ` [PATCH v5 3/3] gpu: nova-core: add boot42 support for next-gen GPUs John Hubbard
2 siblings, 0 replies; 9+ messages in thread
From: John Hubbard @ 2025-11-06 1:27 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Alexandre Courbot, Joel Fernandes, Timur Tabi, Alistair Popple,
Edwin Peer, Zhi Wang, David Airlie, Simona Vetter, Bjorn Helgaas,
Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, nouveau, rust-for-linux, LKML, John Hubbard
This allows Architecture to be passed into register!() and bitfield!()
macro calls. That in turn requires a default implementation for
Architecture.
This simplifies transforming BOOT0 (and later, BOOT42) register values
into GPU architectures.
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Timur Tabi <ttabi@nvidia.com>
Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
drivers/gpu/nova-core/gpu.rs | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 8173cdcd8378..27b8926977da 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -109,8 +109,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
/// Enum representation of the GPU generation.
-#[derive(fmt::Debug)]
+#[derive(fmt::Debug, Default)]
+#[repr(u8)]
pub(crate) enum Architecture {
+ #[default]
Turing = 0x16,
Ampere = 0x17,
Ada = 0x19,
@@ -129,6 +131,13 @@ fn try_from(value: u8) -> Result<Self> {
}
}
+impl From<Architecture> for u8 {
+ fn from(value: Architecture) -> Self {
+ // CAST: `Architecture` is `repr(u8)`, so this cast is always lossless.
+ value as u8
+ }
+}
+
pub(crate) struct Revision {
pub(crate) major: u8,
pub(crate) minor: u8,
--
2.51.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v5 3/3] gpu: nova-core: add boot42 support for next-gen GPUs
2025-11-06 1:27 [PATCH v5 0/3] gpu: nova: add boot42 support for next-gen GPUs John Hubbard
2025-11-06 1:27 ` [PATCH v5 1/3] gpu: nova-core: prepare Spec and Revision types for boot0/boot42 John Hubbard
2025-11-06 1:27 ` [PATCH v5 2/3] gpu: nova-core: make Architecture behave as a u8 type John Hubbard
@ 2025-11-06 1:27 ` John Hubbard
2025-11-06 7:24 ` Alexandre Courbot
2 siblings, 1 reply; 9+ messages in thread
From: John Hubbard @ 2025-11-06 1:27 UTC (permalink / raw)
To: Danilo Krummrich
Cc: Alexandre Courbot, Joel Fernandes, Timur Tabi, Alistair Popple,
Edwin Peer, Zhi Wang, David Airlie, Simona Vetter, Bjorn Helgaas,
Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, nouveau, rust-for-linux, LKML, John Hubbard
NVIDIA GPUs are moving away from using NV_PMC_BOOT_0 to contain
architecture and revision details, and will instead use NV_PMC_BOOT_42
in the future. NV_PMC_BOOT_0 will contain a specific set of values
that will mean "go read NV_PMC_BOOT_42 instead".
Change the selection logic in Nova so that it will claim Turing and
later GPUs. This will work for the foreseeable future, without any
further code changes here, because all NVIDIA GPUs are considered, from
the oldest supported on Linux (NV04), through the future GPUs.
Add some comment documentation to explain, chronologically, how boot0
and boot42 change with the GPU eras, and how that affects the selection
logic.
Cc: Alexandre Courbot <acourbot@nvidia.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Timur Tabi <ttabi@nvidia.com>
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
drivers/gpu/nova-core/gpu.rs | 38 ++++++++++++++++++++++++++++++++++-
drivers/gpu/nova-core/regs.rs | 33 ++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 27b8926977da..8d2bad0e27d1 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -154,6 +154,17 @@ fn try_from(boot0: regs::NV_PMC_BOOT_0) -> Result<Self> {
}
}
+impl TryFrom<regs::NV_PMC_BOOT_42> for Spec {
+ type Error = Error;
+
+ fn try_from(boot42: regs::NV_PMC_BOOT_42) -> Result<Self> {
+ Ok(Self {
+ chipset: boot42.chipset()?,
+ revision: boot42.revision(),
+ })
+ }
+}
+
impl fmt::Display for Revision {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:x}.{:x}", self.major, self.minor)
@@ -169,9 +180,34 @@ pub(crate) struct Spec {
impl Spec {
fn new(bar: &Bar0) -> Result<Spec> {
+ // Some brief notes about boot0 and boot42, in chronological order:
+ //
+ // NV04 through Volta:
+ //
+ // Not supported by Nova. boot0 is necessary and sufficient to identify these GPUs.
+ // boot42 may not even exist on some of these GPUs.
+ //
+ // Turing through Blackwell:
+ //
+ // Supported by both Nouveau and Nova. boot0 is still necessary and sufficient to
+ // identify these GPUs. boot42 exists on these GPUs but we don't need to use it.
+ //
+ // Rubin:
+ //
+ // Only supported by Nova. Need to use boot42 to fully identify these GPUs.
+ //
+ // "Future" (after Rubin) GPUs:
+ //
+ // Only supported by Nova. NV_PMC_BOOT's ARCH_0 (bits 28:24) will be zeroed out, and
+ // ARCH_1 (bit 8:8) will be set to 1, which will mean, "refer to NV_PMC_BOOT_42".
+
let boot0 = regs::NV_PMC_BOOT_0::read(bar);
- Spec::try_from(boot0)
+ if boot0.use_boot42_instead() {
+ Spec::try_from(regs::NV_PMC_BOOT_42::read(bar))
+ } else {
+ Spec::try_from(boot0)
+ }
}
}
diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
index 207b865335af..8b5ff3858210 100644
--- a/drivers/gpu/nova-core/regs.rs
+++ b/drivers/gpu/nova-core/regs.rs
@@ -25,6 +25,13 @@
});
impl NV_PMC_BOOT_0 {
+ pub(crate) fn use_boot42_instead(self) -> bool {
+ // "Future" GPUs (some time after Rubin) will set `architecture_0`
+ // to 0, and `architecture_1` to 1, and put the architecture details in
+ // boot42 instead.
+ self.architecture_0() == 0 && self.architecture_1() == 1
+ }
+
/// Combines `architecture_0` and `architecture_1` to obtain the architecture of the chip.
pub(crate) fn architecture(self) -> Result<Architecture> {
Architecture::try_from(
@@ -51,6 +58,32 @@ pub(crate) fn revision(self) -> crate::gpu::Revision {
}
}
+register!(NV_PMC_BOOT_42 @ 0x00000108, "Extended architecture information" {
+ 7:0 implementation as u8, "Implementation version of the architecture";
+ 15:8 architecture as u8 ?=> Architecture, "Architecture value";
+ 19:16 minor_revision as u8, "Minor revision of the chip";
+ 23:20 major_revision as u8, "Major revision of the chip";
+});
+
+impl NV_PMC_BOOT_42 {
+ pub(crate) fn chipset(self) -> Result<Chipset> {
+ self.architecture()
+ .map(|arch| {
+ ((arch as u32) << Self::IMPLEMENTATION_RANGE.len())
+ | u32::from(self.implementation())
+ })
+ .and_then(Chipset::try_from)
+ }
+
+ /// Returns the revision information of the chip.
+ pub(crate) fn revision(self) -> crate::gpu::Revision {
+ crate::gpu::Revision {
+ major: self.major_revision(),
+ minor: self.minor_revision(),
+ }
+ }
+}
+
// PBUS
register!(NV_PBUS_SW_SCRATCH @ 0x00001400[64] {});
--
2.51.2
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v5 3/3] gpu: nova-core: add boot42 support for next-gen GPUs
2025-11-06 1:27 ` [PATCH v5 3/3] gpu: nova-core: add boot42 support for next-gen GPUs John Hubbard
@ 2025-11-06 7:24 ` Alexandre Courbot
2025-11-06 21:27 ` John Hubbard
0 siblings, 1 reply; 9+ messages in thread
From: Alexandre Courbot @ 2025-11-06 7:24 UTC (permalink / raw)
To: John Hubbard, Danilo Krummrich
Cc: Alexandre Courbot, Joel Fernandes, Timur Tabi, Alistair Popple,
Edwin Peer, Zhi Wang, David Airlie, Simona Vetter, Bjorn Helgaas,
Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, nouveau, rust-for-linux, LKML, Nouveau
On Thu Nov 6, 2025 at 10:27 AM JST, John Hubbard wrote:
> NVIDIA GPUs are moving away from using NV_PMC_BOOT_0 to contain
> architecture and revision details, and will instead use NV_PMC_BOOT_42
> in the future. NV_PMC_BOOT_0 will contain a specific set of values
> that will mean "go read NV_PMC_BOOT_42 instead".
>
> Change the selection logic in Nova so that it will claim Turing and
> later GPUs. This will work for the foreseeable future, without any
> further code changes here, because all NVIDIA GPUs are considered, from
> the oldest supported on Linux (NV04), through the future GPUs.
>
> Add some comment documentation to explain, chronologically, how boot0
> and boot42 change with the GPU eras, and how that affects the selection
> logic.
>
> Cc: Alexandre Courbot <acourbot@nvidia.com>
> Cc: Danilo Krummrich <dakr@kernel.org>
> Cc: Timur Tabi <ttabi@nvidia.com>
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
> ---
> drivers/gpu/nova-core/gpu.rs | 38 ++++++++++++++++++++++++++++++++++-
> drivers/gpu/nova-core/regs.rs | 33 ++++++++++++++++++++++++++++++
> 2 files changed, 70 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
> index 27b8926977da..8d2bad0e27d1 100644
> --- a/drivers/gpu/nova-core/gpu.rs
> +++ b/drivers/gpu/nova-core/gpu.rs
> @@ -154,6 +154,17 @@ fn try_from(boot0: regs::NV_PMC_BOOT_0) -> Result<Self> {
> }
> }
>
> +impl TryFrom<regs::NV_PMC_BOOT_42> for Spec {
> + type Error = Error;
> +
> + fn try_from(boot42: regs::NV_PMC_BOOT_42) -> Result<Self> {
> + Ok(Self {
> + chipset: boot42.chipset()?,
> + revision: boot42.revision(),
> + })
> + }
> +}
> +
> impl fmt::Display for Revision {
> fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
> write!(f, "{:x}.{:x}", self.major, self.minor)
> @@ -169,9 +180,34 @@ pub(crate) struct Spec {
>
> impl Spec {
> fn new(bar: &Bar0) -> Result<Spec> {
> + // Some brief notes about boot0 and boot42, in chronological order:
> + //
> + // NV04 through Volta:
> + //
> + // Not supported by Nova. boot0 is necessary and sufficient to identify these GPUs.
> + // boot42 may not even exist on some of these GPUs.
> + //
> + // Turing through Blackwell:
> + //
> + // Supported by both Nouveau and Nova. boot0 is still necessary and sufficient to
> + // identify these GPUs. boot42 exists on these GPUs but we don't need to use it.
> + //
> + // Rubin:
> + //
> + // Only supported by Nova. Need to use boot42 to fully identify these GPUs.
> + //
> + // "Future" (after Rubin) GPUs:
> + //
> + // Only supported by Nova. NV_PMC_BOOT's ARCH_0 (bits 28:24) will be zeroed out, and
> + // ARCH_1 (bit 8:8) will be set to 1, which will mean, "refer to NV_PMC_BOOT_42".
From the code it looks like Rubin and "Future" GPUs are handled exactly
the same - do we need two paragraphs to describe them, or can we just
have one for "Rubing and future GPUs"?
> +
> let boot0 = regs::NV_PMC_BOOT_0::read(bar);
>
> - Spec::try_from(boot0)
> + if boot0.use_boot42_instead() {
> + Spec::try_from(regs::NV_PMC_BOOT_42::read(bar))
> + } else {
> + Spec::try_from(boot0)
> + }
> }
> }
>
> diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
> index 207b865335af..8b5ff3858210 100644
> --- a/drivers/gpu/nova-core/regs.rs
> +++ b/drivers/gpu/nova-core/regs.rs
> @@ -25,6 +25,13 @@
> });
>
> impl NV_PMC_BOOT_0 {
> + pub(crate) fn use_boot42_instead(self) -> bool {
> + // "Future" GPUs (some time after Rubin) will set `architecture_0`
> + // to 0, and `architecture_1` to 1, and put the architecture details in
> + // boot42 instead.
If this is "some time after Rubin", how do we infer that we must use
boot42 for Rubin, as the previous comment suggests?
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH v5 3/3] gpu: nova-core: add boot42 support for next-gen GPUs
2025-11-06 7:24 ` Alexandre Courbot
@ 2025-11-06 21:27 ` John Hubbard
2025-11-07 0:15 ` John Hubbard
0 siblings, 1 reply; 9+ messages in thread
From: John Hubbard @ 2025-11-06 21:27 UTC (permalink / raw)
To: Alexandre Courbot, Danilo Krummrich
Cc: Joel Fernandes, Timur Tabi, Alistair Popple, Edwin Peer, Zhi Wang,
David Airlie, Simona Vetter, Bjorn Helgaas, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, nouveau,
rust-for-linux, LKML, Nouveau
On 11/5/25 11:24 PM, Alexandre Courbot wrote:
> On Thu Nov 6, 2025 at 10:27 AM JST, John Hubbard wrote:
>> NVIDIA GPUs are moving away from using NV_PMC_BOOT_0 to contain
>> architecture and revision details, and will instead use NV_PMC_BOOT_42
>> in the future. NV_PMC_BOOT_0 will contain a specific set of values
>> that will mean "go read NV_PMC_BOOT_42 instead".
>>
>> Change the selection logic in Nova so that it will claim Turing and
>> later GPUs. This will work for the foreseeable future, without any
>> further code changes here, because all NVIDIA GPUs are considered, from
>> the oldest supported on Linux (NV04), through the future GPUs.
>>
>> Add some comment documentation to explain, chronologically, how boot0
>> and boot42 change with the GPU eras, and how that affects the selection
>> logic.
>>
>> Cc: Alexandre Courbot <acourbot@nvidia.com>
>> Cc: Danilo Krummrich <dakr@kernel.org>
>> Cc: Timur Tabi <ttabi@nvidia.com>
>> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
>> ---
>> drivers/gpu/nova-core/gpu.rs | 38 ++++++++++++++++++++++++++++++++++-
>> drivers/gpu/nova-core/regs.rs | 33 ++++++++++++++++++++++++++++++
>> 2 files changed, 70 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
>> index 27b8926977da..8d2bad0e27d1 100644
>> --- a/drivers/gpu/nova-core/gpu.rs
>> +++ b/drivers/gpu/nova-core/gpu.rs
>> @@ -154,6 +154,17 @@ fn try_from(boot0: regs::NV_PMC_BOOT_0) -> Result<Self> {
>> }
>> }
>>
>> +impl TryFrom<regs::NV_PMC_BOOT_42> for Spec {
>> + type Error = Error;
>> +
>> + fn try_from(boot42: regs::NV_PMC_BOOT_42) -> Result<Self> {
>> + Ok(Self {
>> + chipset: boot42.chipset()?,
>> + revision: boot42.revision(),
>> + })
>> + }
>> +}
>> +
>> impl fmt::Display for Revision {
>> fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
>> write!(f, "{:x}.{:x}", self.major, self.minor)
>> @@ -169,9 +180,34 @@ pub(crate) struct Spec {
>>
>> impl Spec {
>> fn new(bar: &Bar0) -> Result<Spec> {
>> + // Some brief notes about boot0 and boot42, in chronological order:
>> + //
>> + // NV04 through Volta:
>> + //
>> + // Not supported by Nova. boot0 is necessary and sufficient to identify these GPUs.
>> + // boot42 may not even exist on some of these GPUs.
>> + //
>> + // Turing through Blackwell:
>> + //
>> + // Supported by both Nouveau and Nova. boot0 is still necessary and sufficient to
>> + // identify these GPUs. boot42 exists on these GPUs but we don't need to use it.
>> + //
>> + // Rubin:
>> + //
>> + // Only supported by Nova. Need to use boot42 to fully identify these GPUs.
Ohh, I scrambled the comment when I added Rubin to the discussion. Actually,
the first sentence is correct, but the second is dead wrong. :)
Rubin will still key off of boot0.
I'll fix this up.
>> + //
>> + // "Future" (after Rubin) GPUs:
>> + //
>> + // Only supported by Nova. NV_PMC_BOOT's ARCH_0 (bits 28:24) will be zeroed out, and
>> + // ARCH_1 (bit 8:8) will be set to 1, which will mean, "refer to NV_PMC_BOOT_42".
>
> From the code it looks like Rubin and "Future" GPUs are handled exactly
> the same - do we need two paragraphs to describe them, or can we just
> have one for "Rubing and future GPUs"?
They are not. The code is correct but the comment is wrong.
>
>> +
>> let boot0 = regs::NV_PMC_BOOT_0::read(bar);
>>
>> - Spec::try_from(boot0)
>> + if boot0.use_boot42_instead() {
>> + Spec::try_from(regs::NV_PMC_BOOT_42::read(bar))
>> + } else {
>> + Spec::try_from(boot0)
>> + }
>> }
>> }
>>
>> diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
>> index 207b865335af..8b5ff3858210 100644
>> --- a/drivers/gpu/nova-core/regs.rs
>> +++ b/drivers/gpu/nova-core/regs.rs
>> @@ -25,6 +25,13 @@
>> });
>>
>> impl NV_PMC_BOOT_0 {
>> + pub(crate) fn use_boot42_instead(self) -> bool {
>> + // "Future" GPUs (some time after Rubin) will set `architecture_0`
>> + // to 0, and `architecture_1` to 1, and put the architecture details in
>> + // boot42 instead.
>
> If this is "some time after Rubin", how do we infer that we must use
> boot42 for Rubin, as the previous comment suggests?
Right, we will actually use boot0 for Rubin. Thanks for catching
the inconsistency!
thanks,
--
John Hubbard
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH v5 3/3] gpu: nova-core: add boot42 support for next-gen GPUs
2025-11-06 21:27 ` John Hubbard
@ 2025-11-07 0:15 ` John Hubbard
0 siblings, 0 replies; 9+ messages in thread
From: John Hubbard @ 2025-11-07 0:15 UTC (permalink / raw)
To: Alexandre Courbot, Danilo Krummrich
Cc: Joel Fernandes, Timur Tabi, Alistair Popple, Edwin Peer, Zhi Wang,
David Airlie, Simona Vetter, Bjorn Helgaas, Miguel Ojeda,
Alex Gaynor, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, nouveau,
rust-for-linux, LKML, Nouveau
On 11/6/25 1:27 PM, John Hubbard wrote:
> On 11/5/25 11:24 PM, Alexandre Courbot wrote:
>> On Thu Nov 6, 2025 at 10:27 AM JST, John Hubbard wrote:
>>> + // Rubin:
>>> + //
>>> + // Only supported by Nova. Need to use boot42 to fully identify these GPUs.
>
> Ohh, I scrambled the comment when I added Rubin to the discussion. Actually,
> the first sentence is correct, but the second is dead wrong. :)
>
> Rubin will still key off of boot0.
>
Correction, the dividing line for when this changes over turns out to
be mid-Rubin. So I'm looking at going back to "if later than
Fermi, use boot42" after all (Timur was advocating for that, earlier,
too.)
thanks,
--
John Hubbard
^ permalink raw reply [flat|nested] 9+ messages in thread