From: John Hubbard <jhubbard@nvidia.com>
To: Danilo Krummrich <dakr@kernel.org>,
Alexandre Courbot <acourbot@nvidia.com>
Cc: "Joel Fernandes" <joelagnelf@nvidia.com>,
"Timur Tabi" <ttabi@nvidia.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Eliot Courtney" <ecourtney@nvidia.com>,
"Zhi Wang" <zhiw@nvidia.com>, "David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Bjorn Helgaas" <bhelgaas@google.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" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
nouveau@lists.freedesktop.org, rust-for-linux@vger.kernel.org,
LKML <linux-kernel@vger.kernel.org>,
"John Hubbard" <jhubbard@nvidia.com>
Subject: [PATCH v4 30/33] gpu: nova-core: Hopper/Blackwell: add FSP Chain of Trust boot path
Date: Mon, 9 Feb 2026 18:45:57 -0800 [thread overview]
Message-ID: <20260210024601.593248-31-jhubbard@nvidia.com> (raw)
In-Reply-To: <20260210024601.593248-1-jhubbard@nvidia.com>
Add the FSP-based boot path for Hopper and Blackwell GPUs. Unlike
Turing/Ampere/Ada which use SEC2 to load the booter firmware, Hopper
and Blackwell use FSP (Firmware System Processor) with FMC firmware
to establish a Chain of Trust and boot GSP directly.
The boot() function now dispatches to either run_booter() (SEC2 path)
or run_fsp() (FSP path) based on the GPU architecture. The cmdq
commands are moved to after GSP boot, and the GSP sequencer is only
run for SEC2-based architectures.
Cc: Gary Guo <gary@garyguo.net>
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
drivers/gpu/nova-core/fb.rs | 1 -
drivers/gpu/nova-core/firmware/fsp.rs | 2 -
drivers/gpu/nova-core/fsp.rs | 6 +-
drivers/gpu/nova-core/gsp/boot.rs | 158 ++++++++++++++++++++------
4 files changed, 123 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index 7c502f15622c..a860f43ec5af 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -180,7 +180,6 @@ pub(crate) struct FbLayout {
pub(crate) heap: FbRange,
pub(crate) vf_partition_count: u8,
/// Total reserved size (heap + PMU reserved), aligned to 2MB.
- #[expect(unused)]
pub(crate) total_reserved_size: u32,
}
diff --git a/drivers/gpu/nova-core/firmware/fsp.rs b/drivers/gpu/nova-core/firmware/fsp.rs
index edcc173c2fa6..e10954aa146a 100644
--- a/drivers/gpu/nova-core/firmware/fsp.rs
+++ b/drivers/gpu/nova-core/firmware/fsp.rs
@@ -14,7 +14,6 @@
gpu::Chipset, //
};
-#[expect(dead_code)]
pub(crate) struct FspFirmware {
/// FMC firmware image data (only the .image section) - submitted to hardware
pub(crate) fmc_image: DmaObject,
@@ -23,7 +22,6 @@ pub(crate) struct FspFirmware {
}
impl FspFirmware {
- #[expect(dead_code)]
pub(crate) fn new(
dev: &device::Device<device::Bound>,
chipset: Chipset,
diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs
index 35169f3bc446..5e3c15a71e2d 100644
--- a/drivers/gpu/nova-core/fsp.rs
+++ b/drivers/gpu/nova-core/fsp.rs
@@ -1,8 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
-// TODO: remove this once the code is fully functional
-#![expect(dead_code)]
-
//! FSP (Firmware System Processor) interface for Hopper/Blackwell GPUs.
//!
//! Hopper/Blackwell use a simplified firmware boot sequence: FMC --> FSP --> GSP.
@@ -11,6 +8,7 @@
use kernel::{
device,
+ dma::CoherentAllocation,
io::poll::read_poll_timeout,
prelude::*,
ptr::{
@@ -352,8 +350,6 @@ pub(crate) fn create_fmc_boot_params(
wpr_meta_size: u32,
libos_addr: u64,
) -> Result<kernel::dma::CoherentAllocation<GspFmcBootParams>> {
- use kernel::dma::CoherentAllocation;
-
const GSP_DMA_TARGET_COHERENT_SYSTEM: u32 = 1;
const GSP_DMA_TARGET_NONCOHERENT_SYSTEM: u32 = 2;
diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs
index 1e8a7306e078..80d57a54c0c9 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -13,6 +13,7 @@
use crate::{
driver::Bar0,
falcon::{
+ fsp::Fsp as FspEngine,
gsp::Gsp,
sec2::Sec2,
Falcon,
@@ -24,6 +25,7 @@
BooterFirmware,
BooterKind, //
},
+ fsp::FspFirmware,
fwsec::{
FwsecCommand,
FwsecFirmware, //
@@ -31,9 +33,14 @@
gsp::GspFirmware,
FIRMWARE_VERSION, //
},
- gpu::Chipset,
+ fsp::Fsp,
+ gpu::{
+ Architecture,
+ Chipset, //
+ },
gsp::{
commands,
+ fw::LibosMemoryRegionInitArgument,
sequencer::{
GspSequencer,
GspSequencerParams, //
@@ -155,6 +162,55 @@ fn run_booter(
Ok(())
}
+ fn run_fsp(
+ dev: &device::Device<device::Bound>,
+ bar: &Bar0,
+ chipset: Chipset,
+ gsp_falcon: &Falcon<Gsp>,
+ wpr_meta: &CoherentAllocation<GspFwWprMeta>,
+ libos: &CoherentAllocation<LibosMemoryRegionInitArgument>,
+ fb_layout: &FbLayout,
+ ) -> Result {
+ let fsp_falcon = Falcon::<FspEngine>::new(dev, chipset)?;
+
+ Fsp::wait_secure_boot(dev, bar, chipset.arch())?;
+
+ let fsp_fw = FspFirmware::new(dev, chipset, FIRMWARE_VERSION)?;
+
+ // fmc_full is a KVec<u8> for CPU-side signature extraction only.
+ // A separate buffer, fsp_fw.fmc_image, is what gets submitted to the hardware.
+ let signatures = Fsp::extract_fmc_signatures_static(dev, &fsp_fw.fmc_full)?;
+
+ // Create FMC boot parameters
+ let fmc_boot_params = Fsp::create_fmc_boot_params(
+ dev,
+ wpr_meta.dma_handle(),
+ core::mem::size_of::<GspFwWprMeta>() as u32,
+ libos.dma_handle(),
+ )?;
+
+ // Execute FSP Chain of Trust
+ // NOTE: FSP Chain of Trust handles GSP boot internally - we do NOT reset or boot GSP
+ Fsp::boot_gsp_fmc_with_signatures(
+ dev,
+ bar,
+ chipset,
+ &fsp_fw.fmc_image,
+ &fmc_boot_params,
+ u64::from(fb_layout.total_reserved_size),
+ false, // not resuming
+ &fsp_falcon,
+ &signatures,
+ )?;
+
+ // Wait for GSP lockdown to be released
+ let fmc_boot_params_addr = fmc_boot_params.dma_handle();
+ let _mbox0 =
+ Self::wait_for_gsp_lockdown_release(dev, bar, gsp_falcon, fmc_boot_params_addr)?;
+
+ Ok(())
+ }
+
/// Check if GSP lockdown has been released after FSP Chain of Trust
fn gsp_lockdown_released(
dev: &device::Device,
@@ -196,7 +252,6 @@ fn gsp_lockdown_released(
}
/// Wait for GSP lockdown to be released after FSP Chain of Trust
- #[expect(dead_code)]
fn wait_for_gsp_lockdown_release(
dev: &device::Device,
bar: &Bar0,
@@ -257,43 +312,63 @@ pub(crate) fn boot(
) -> Result {
let dev = pdev.as_ref();
- let bios = Vbios::new(dev, bar)?;
-
let gsp_fw = KBox::pin_init(GspFirmware::new(dev, chipset, FIRMWARE_VERSION), GFP_KERNEL)?;
let fb_layout = FbLayout::new(chipset, bar, &gsp_fw)?;
dev_dbg!(dev, "{:#x?}\n", fb_layout);
- Self::run_fwsec_frts(dev, gsp_falcon, bar, &bios, &fb_layout)?;
+ if matches!(
+ chipset.arch(),
+ Architecture::Turing | Architecture::Ampere | Architecture::Ada
+ ) {
+ let bios = Vbios::new(dev, bar)?;
+ Self::run_fwsec_frts(dev, gsp_falcon, bar, &bios, &fb_layout)?;
+ }
let wpr_meta =
CoherentAllocation::<GspFwWprMeta>::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?;
dma_write!(wpr_meta[0] = GspFwWprMeta::new(&gsp_fw, &fb_layout))?;
- self.cmdq
- .send_command(bar, commands::SetSystemInfo::new(pdev))?;
- self.cmdq.send_command(bar, commands::SetRegistry::new())?;
+ // For SEC2-based architectures, reset GSP and boot it before SEC2
+ if matches!(
+ chipset.arch(),
+ Architecture::Turing | Architecture::Ampere | Architecture::Ada
+ ) {
+ gsp_falcon.reset(bar)?;
+ let libos_handle = self.libos.dma_handle();
+ let (mbox0, mbox1) = gsp_falcon.boot(
+ bar,
+ Some(libos_handle as u32),
+ Some((libos_handle >> 32) as u32),
+ )?;
+ dev_dbg!(
+ pdev,
+ "GSP MBOX0: {:#x}, MBOX1: {:#x}\n",
+ mbox0,
+ mbox1
+ );
- gsp_falcon.reset(bar)?;
- let libos_handle = self.libos.dma_handle();
- let (mbox0, mbox1) = gsp_falcon.boot(
- bar,
- Some(libos_handle as u32),
- Some((libos_handle >> 32) as u32),
- )?;
- dev_dbg!(
- pdev,
- "GSP MBOX0: {:#x}, MBOX1: {:#x}\n",
- mbox0,
- mbox1
- );
+ dev_dbg!(
+ pdev,
+ "Using SEC2 to load and run the booter_load firmware...\n"
+ );
+ }
- dev_dbg!(
- pdev,
- "Using SEC2 to load and run the booter_load firmware...\n"
- );
+ match chipset.arch() {
+ Architecture::Turing | Architecture::Ampere | Architecture::Ada => {
+ Self::run_booter(dev, bar, chipset, sec2_falcon, &wpr_meta)?
+ }
- Self::run_booter(dev, bar, chipset, sec2_falcon, &wpr_meta)?;
+ Architecture::Hopper | Architecture::Blackwell => Self::run_fsp(
+ dev,
+ bar,
+ chipset,
+ gsp_falcon,
+ &wpr_meta,
+ &self.libos,
+ &fb_layout,
+ )?,
+ }
gsp_falcon.write_os_version(bar, gsp_fw.bootloader.app_version);
@@ -311,16 +386,27 @@ pub(crate) fn boot(
gsp_falcon.is_riscv_active(bar),
);
- // Create and run the GSP sequencer.
- let seq_params = GspSequencerParams {
- bootloader_app_version: gsp_fw.bootloader.app_version,
- libos_dma_handle: libos_handle,
- gsp_falcon,
- sec2_falcon,
- dev: pdev.as_ref().into(),
- bar,
- };
- GspSequencer::run(&mut self.cmdq, seq_params)?;
+ // Now that GSP is active, send system info and registry
+ self.cmdq
+ .send_command(bar, commands::SetSystemInfo::new(pdev))?;
+ self.cmdq.send_command(bar, commands::SetRegistry::new())?;
+
+ if matches!(
+ chipset.arch(),
+ Architecture::Turing | Architecture::Ampere | Architecture::Ada
+ ) {
+ let libos_handle = self.libos.dma_handle();
+ // Create and run the GSP sequencer.
+ let seq_params = GspSequencerParams {
+ bootloader_app_version: gsp_fw.bootloader.app_version,
+ libos_dma_handle: libos_handle,
+ gsp_falcon,
+ sec2_falcon,
+ dev: pdev.as_ref().into(),
+ bar,
+ };
+ GspSequencer::run(&mut self.cmdq, seq_params)?;
+ }
// Wait until GSP is fully initialized.
commands::wait_gsp_init_done(&mut self.cmdq)?;
--
2.53.0
next prev parent reply other threads:[~2026-02-10 2:47 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-10 2:45 [PATCH v4 00/33] gpu: nova-core: firmware: Hopper/Blackwell support John Hubbard
2026-02-10 2:45 ` [PATCH v4 01/33] gpu: nova-core: pass pdev directly to dev_* logging macros John Hubbard
2026-02-11 10:06 ` Danilo Krummrich
2026-02-11 18:48 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 02/33] gpu: nova-core: print FB sizes, along with ranges John Hubbard
2026-02-10 2:45 ` [PATCH v4 03/33] gpu: nova-core: add FbRange.len() and use it in boot.rs John Hubbard
2026-02-10 2:45 ` [PATCH v4 04/33] gpu: nova-core: Hopper/Blackwell: basic GPU identification John Hubbard
2026-02-10 2:45 ` [PATCH v4 05/33] gpu: nova-core: factor .fwsignature* selection into a new get_gsp_sigs_section() John Hubbard
2026-02-11 10:16 ` Danilo Krummrich
2026-02-12 0:39 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 06/33] gpu: nova-core: use GPU Architecture to simplify HAL selections John Hubbard
2026-02-10 2:45 ` [PATCH v4 07/33] gpu: nova-core: apply the one "use" item per line policy to commands.rs John Hubbard
2026-02-10 2:45 ` [PATCH v4 08/33] gpu: nova-core: set DMA mask width based on GPU architecture John Hubbard
2026-02-11 10:28 ` Danilo Krummrich
2026-02-12 2:06 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 09/33] gpu: nova-core: Hopper/Blackwell: skip GFW boot waiting John Hubbard
2026-02-11 10:09 ` Danilo Krummrich
2026-02-12 1:49 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 10/33] gpu: nova-core: move firmware image parsing code to firmware.rs John Hubbard
2026-02-10 2:45 ` [PATCH v4 11/33] gpu: nova-core: factor out a section_name_eq() function John Hubbard
2026-02-10 2:45 ` [PATCH v4 12/33] gpu: nova-core: don't assume 64-bit firmware images John Hubbard
2026-02-10 2:45 ` [PATCH v4 13/33] gpu: nova-core: add support for 32-bit " John Hubbard
2026-02-10 2:45 ` [PATCH v4 14/33] gpu: nova-core: add auto-detection of 32-bit, 64-bit " John Hubbard
2026-02-10 2:45 ` [PATCH v4 15/33] gpu: nova-core: Hopper/Blackwell: add FMC firmware image, in support of FSP John Hubbard
2026-02-10 2:45 ` [PATCH v4 16/33] gpu: nova-core: Hopper/Blackwell: add FSP falcon engine stub John Hubbard
2026-02-10 2:45 ` [PATCH v4 17/33] gpu: nova-core: Hopper/Blackwell: add FSP falcon EMEM operations John Hubbard
2026-02-11 10:57 ` Danilo Krummrich
2026-02-12 2:09 ` John Hubbard
2026-02-17 15:43 ` Danilo Krummrich
2026-02-19 2:54 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 18/33] gpu: nova-core: Hopper/Blackwell: add FSP message infrastructure John Hubbard
2026-02-17 16:28 ` Danilo Krummrich
2026-02-20 22:05 ` Tegra notes for Nova: " John Hubbard
2026-02-23 3:36 ` Alexandre Courbot
2026-02-10 2:45 ` [PATCH v4 19/33] gpu: nova-core: Hopper/Blackwell: calculate reserved FB heap size John Hubbard
2026-02-17 16:39 ` Danilo Krummrich
2026-02-19 3:01 ` John Hubbard
2026-02-19 9:01 ` Miguel Ojeda
2026-02-20 22:08 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 20/33] gpu: nova-core: Hopper/Blackwell: add FSP secure boot completion waiting John Hubbard
2026-02-17 17:13 ` Danilo Krummrich
2026-02-20 23:26 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 21/33] gpu: nova-core: Hopper/Blackwell: add FSP message structures John Hubbard
2026-02-10 2:45 ` [PATCH v4 22/33] gpu: nova-core: Hopper/Blackwell: add FMC signature extraction John Hubbard
2026-02-10 2:45 ` [PATCH v4 23/33] gpu: nova-core: Hopper/Blackwell: add FSP send/receive messaging John Hubbard
2026-02-10 2:45 ` [PATCH v4 24/33] gpu: nova-core: Hopper/Blackwell: add FSP Chain of Trust boot John Hubbard
2026-02-17 18:16 ` Danilo Krummrich
2026-02-20 23:35 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 25/33] gpu: nova-core: Hopper/Blackwell: larger non-WPR heap John Hubbard
2026-02-17 20:04 ` Danilo Krummrich
2026-02-20 23:57 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 26/33] gpu: nova-core: Blackwell: use correct sysmem flush registers John Hubbard
2026-02-10 2:45 ` [PATCH v4 27/33] gpu: nova-core: Hopper/Blackwell: larger WPR2 (GSP) heap John Hubbard
2026-02-17 20:10 ` Danilo Krummrich
2026-02-21 1:01 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 28/33] gpu: nova-core: refactor SEC2 booter loading into run_booter() helper John Hubbard
2026-02-17 20:12 ` Danilo Krummrich
2026-02-21 1:03 ` John Hubbard
2026-02-10 2:45 ` [PATCH v4 29/33] gpu: nova-core: Hopper/Blackwell: add GSP lockdown release polling John Hubbard
2026-02-17 20:20 ` Danilo Krummrich
2026-02-21 1:06 ` John Hubbard
2026-02-10 2:45 ` John Hubbard [this message]
2026-02-10 2:45 ` [PATCH v4 31/33] gpu: nova-core: Hopper/Blackwell: new location for PCI config mirror John Hubbard
2026-02-10 2:45 ` [PATCH v4 32/33] gpu: nova-core: clarify the GPU firmware boot steps John Hubbard
2026-02-10 2:46 ` [PATCH v4 33/33] gpu: nova-core: fix aux device registration for multi-GPU systems John Hubbard
2026-02-10 22:27 ` [PATCH v4 00/33] gpu: nova-core: firmware: Hopper/Blackwell support John Hubbard
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=20260210024601.593248-31-jhubbard@nvidia.com \
--to=jhubbard@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=bhelgaas@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=ecourtney@nvidia.com \
--cc=gary@garyguo.net \
--cc=joelagnelf@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
--cc=ttabi@nvidia.com \
--cc=zhiw@nvidia.com \
/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