From: Alexandre Courbot <acourbot@nvidia.com>
To: Danilo Krummrich <dakr@kernel.org>,
Alice Ryhl <aliceryhl@google.com>,
David Airlie <airlied@gmail.com>,
Simona Vetter <simona@ffwll.ch>, Gary Guo <gary@garyguo.net>,
John Hubbard <jhubbard@nvidia.com>,
Alistair Popple <apopple@nvidia.com>,
Timur Tabi <ttabi@nvidia.com>,
Eliot Courtney <ecourtney@nvidia.com>,
Zhi Wang <zhiw@nvidia.com>
Cc: nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org,
linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
Alexandre Courbot <acourbot@nvidia.com>
Subject: [PATCH v3 04/12] gpu: nova-core: gsp: pass GspBootContext to unload methods
Date: Mon, 29 Jun 2026 21:31:47 +0900 [thread overview]
Message-ID: <20260629-nova-bootcontext-v3-4-26cb29ee8dee@nvidia.com> (raw)
In-Reply-To: <20260629-nova-bootcontext-v3-0-26cb29ee8dee@nvidia.com>
`GspBootContext` contains the resources required to boot the GSP. As it
turns out, this is also the context required for unloading it.
Reflect that fact by replacing the arguments of `Gsp::unload` and
`UnloadBundle::run` with the `GspBootContext`. This symmetry between
`Gsp::boot` and `Gsp::unload` will also be convenient when we want to
make these methods generic over the boot context corresponding to the
boot method used.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/nova-core/gpu.rs | 19 ++++++++++++++++---
drivers/gpu/nova-core/gsp/boot.rs | 28 +++++++++++++---------------
drivers/gpu/nova-core/gsp/hal.rs | 15 +--------------
drivers/gpu/nova-core/gsp/hal/gh100.rs | 13 +++----------
drivers/gpu/nova-core/gsp/hal/tu102.rs | 22 ++++++++++------------
5 files changed, 43 insertions(+), 54 deletions(-)
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index 4d76be429e75..4ee0a43ac4b6 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -269,7 +269,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
#[pin_data(PinnedDrop)]
struct GspResources<'gpu> {
/// Device owning the GPU.
- device: &'gpu device::Device<device::Bound>,
+ device: &'gpu pci::Device<device::Bound>,
+ /// Details about the chipset.
+ spec: Spec,
/// MMIO mapping of PCI BAR 0.
bar: Bar0<'gpu>,
/// GSP falcon instance, used for GSP boot up and cleanup.
@@ -312,7 +314,16 @@ fn drop(self: Pin<&mut Self>) {
.gsp
.as_ref()
.get_ref()
- .unload(device, bar, &*this.gsp_falcon, &*this.sec2_falcon, bundle)
+ .unload(
+ GspBootContext {
+ pdev: device,
+ bar,
+ chipset: this.spec.chipset,
+ gsp_falcon: &*this.gsp_falcon,
+ sec2_falcon: &*this.sec2_falcon,
+ },
+ bundle,
+ )
.inspect_err(|e| dev_err!(device, "failed to unload GSP: {:?}\n", e));
}
}
@@ -344,7 +355,9 @@ pub(crate) fn new(
sysmem_flush: SysmemFlush::register(pdev.as_ref(), bar, spec.chipset)?,
gsp_resources <- try_pin_init!(GspResources {
- device: pdev.as_ref(),
+ device: pdev,
+
+ spec: *spec,
bar,
diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs
index 0d2213fb1569..033b2ee2e2a0 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -3,7 +3,6 @@
use kernel::{
bits,
- device,
dma::Coherent,
io::poll::read_poll_timeout,
prelude::*,
@@ -15,7 +14,6 @@
driver::Bar0,
falcon::{
gsp::Gsp,
- sec2::Sec2,
Falcon, //
},
fb::FbLayout,
@@ -47,7 +45,6 @@ pub(crate) fn boot(
let bar = ctx.bar;
let chipset = ctx.chipset;
let gsp_falcon = ctx.gsp_falcon;
- let sec2_falcon = ctx.sec2_falcon;
let dev = pdev.as_ref();
let hal = super::hal::gsp_hal(chipset);
@@ -61,9 +58,11 @@ pub(crate) fn boot(
// Perform the chipset-specific boot sequence, and retrieve the unload bundle.
let unload_bundle = hal.boot(&self, &ctx, &fb_layout, &wpr_meta)?;
- let unload_guard = ScopeGuard::new_with_data(unload_bundle, |unload_bundle| {
- let _ = self.unload(dev, bar, gsp_falcon, sec2_falcon, unload_bundle);
- });
+ let unload_guard =
+ ScopeGuard::new_with_data((ctx, unload_bundle), |(ctx, unload_bundle)| {
+ let _ = self.unload(ctx, unload_bundle);
+ });
+ let ctx = &unload_guard.0;
gsp_falcon.write_os_version(bar, gsp_fw.bootloader.app_version);
@@ -82,12 +81,12 @@ pub(crate) fn boot(
self.cmdq
.send_command_no_wait(bar, commands::SetRegistry::new())?;
- hal.post_boot(&self, &ctx, &gsp_fw)?;
+ hal.post_boot(&self, ctx, &gsp_fw)?;
// Wait until GSP is fully initialized.
commands::wait_gsp_init_done(&self.cmdq)?;
- Ok(unload_guard.dismiss())
+ Ok(unload_guard.dismiss().1)
}
/// Shut down the GSP and wait until it is offline.
@@ -116,17 +115,16 @@ fn shutdown_gsp(
/// This stops all activity on the GSP.
pub(crate) fn unload(
&self,
- dev: &device::Device<device::Bound>,
- bar: Bar0<'_>,
- gsp_falcon: &Falcon<Gsp>,
- sec2_falcon: &Falcon<Sec2>,
+ ctx: super::GspBootContext<'_>,
unload_bundle: Option<super::UnloadBundle>,
) -> Result {
+ let dev = ctx.dev();
+
// Shut down the GSP. Keep going even in case of error.
let mut res = Self::shutdown_gsp(
&self.cmdq,
- bar,
- gsp_falcon,
+ ctx.bar,
+ ctx.gsp_falcon,
commands::PowerStateLevel::Level0,
)
.inspect_err(|e| dev_err!(dev, "GSP shutdown failed: {:?}\n", e));
@@ -136,7 +134,7 @@ pub(crate) fn unload(
res = res.and(
unload_bundle
.0
- .run(dev, bar, gsp_falcon, sec2_falcon)
+ .run(&ctx)
.inspect_err(|e| dev_err!(dev, "Unload bundle failed: {:?}\n", e)),
);
} else {
diff --git a/drivers/gpu/nova-core/gsp/hal.rs b/drivers/gpu/nova-core/gsp/hal.rs
index 0d65a32f9949..849ca224085b 100644
--- a/drivers/gpu/nova-core/gsp/hal.rs
+++ b/drivers/gpu/nova-core/gsp/hal.rs
@@ -5,18 +5,11 @@
mod tu102;
use kernel::{
- device,
dma::Coherent,
prelude::*, //
};
use crate::{
- driver::Bar0,
- falcon::{
- gsp::Gsp as GspEngine,
- sec2::Sec2,
- Falcon, //
- },
fb::FbLayout,
firmware::gsp::GspFirmware,
gpu::{
@@ -37,13 +30,7 @@
/// required for unloading is prepared at load time, and stored here until it needs to be run.
pub(super) trait UnloadBundle: Send {
/// Performs the steps required to properly reset the GSP after it has been stopped.
- fn run(
- &self,
- dev: &device::Device<device::Bound>,
- bar: Bar0<'_>,
- gsp_falcon: &Falcon<GspEngine>,
- sec2_falcon: &Falcon<Sec2>,
- ) -> Result;
+ fn run(&self, ctx: &GspBootContext<'_>) -> Result;
}
/// Trait implemented by GSP HALs.
diff --git a/drivers/gpu/nova-core/gsp/hal/gh100.rs b/drivers/gpu/nova-core/gsp/hal/gh100.rs
index bd15a3067ffe..8dfbc402c13b 100644
--- a/drivers/gpu/nova-core/gsp/hal/gh100.rs
+++ b/drivers/gpu/nova-core/gsp/hal/gh100.rs
@@ -14,7 +14,6 @@
driver::Bar0,
falcon::{
gsp::Gsp as GspEngine,
- sec2::Sec2,
Falcon, //
},
fb::FbLayout,
@@ -118,22 +117,16 @@ fn wait_for_gsp_lockdown_release(
struct FspUnloadBundle;
impl UnloadBundle for FspUnloadBundle {
- fn run(
- &self,
- dev: &device::Device<device::Bound>,
- bar: Bar0<'_>,
- gsp_falcon: &Falcon<GspEngine>,
- _sec2_falcon: &Falcon<Sec2>,
- ) -> Result {
+ fn run(&self, ctx: &GspBootContext<'_>) -> Result {
// GSP falcon does most of the work of resetting, so just wait for it to finish.
read_poll_timeout(
- || Ok(gsp_falcon.is_riscv_active(bar)),
+ || Ok(ctx.gsp_falcon.is_riscv_active(ctx.bar)),
|&active| !active,
Delta::from_millis(10),
Delta::from_secs(5),
)
.map(|_| ())
- .inspect_err(|_| dev_err!(dev, "GSP falcon failed to halt\n"))
+ .inspect_err(|_| dev_err!(ctx.dev(), "GSP falcon failed to halt\n"))
}
}
diff --git a/drivers/gpu/nova-core/gsp/hal/tu102.rs b/drivers/gpu/nova-core/gsp/hal/tu102.rs
index 8511cc647596..ed9a3d362090 100644
--- a/drivers/gpu/nova-core/gsp/hal/tu102.rs
+++ b/drivers/gpu/nova-core/gsp/hal/tu102.rs
@@ -124,18 +124,15 @@ fn build(
}
impl UnloadBundle for Sec2UnloadBundle {
- fn run(
- &self,
- dev: &device::Device<device::Bound>,
- bar: Bar0<'_>,
- gsp_falcon: &Falcon<GspEngine>,
- sec2_falcon: &Falcon<Sec2>,
- ) -> Result {
+ fn run(&self, ctx: &GspBootContext<'_>) -> Result {
+ let dev = ctx.dev();
+ let bar = ctx.bar;
+
// Run FWSEC-SB to reset the GSP falcon to its pre-libos state.
// Log errors but keep going if it fails.
let fwsec_sb_res = self
.fwsec_sb
- .run(dev, bar, gsp_falcon)
+ .run(dev, bar, ctx.gsp_falcon)
.inspect_err(|e| dev_err!(dev, "FWSEC-SB failed to run: {:?}\n", e));
// Remove WPR2 region if set.
@@ -145,13 +142,14 @@ fn run(
return Ok(());
}
- sec2_falcon.reset(bar)?;
- sec2_falcon.load(dev, bar, &self.booter_unloader)?;
+ ctx.sec2_falcon.reset(bar)?;
+ ctx.sec2_falcon.load(dev, bar, &self.booter_unloader)?;
// Sentinel value to confirm that Booter Unloader has run.
const MAILBOX_SENTINEL: u32 = 0xff;
let (mbox0, _) =
- sec2_falcon.boot(bar, Some(MAILBOX_SENTINEL), Some(MAILBOX_SENTINEL))?;
+ ctx.sec2_falcon
+ .boot(bar, Some(MAILBOX_SENTINEL), Some(MAILBOX_SENTINEL))?;
if mbox0 != 0 {
dev_err!(dev, "Booter Unloader returned error 0x{:x}\n", mbox0);
return Err(EINVAL);
@@ -299,7 +297,7 @@ fn boot(
// Run the unload bundle to try and recover the GSP if an error occurs.
let unload_guard = ScopeGuard::new_with_data(unload_bundle, |unload_bundle| {
if let Some(unload_bundle) = unload_bundle {
- let _ = unload_bundle.0.run(dev, bar, gsp_falcon, sec2_falcon);
+ let _ = unload_bundle.0.run(ctx);
}
});
--
2.54.0
next prev parent reply other threads:[~2026-06-29 12:32 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-29 12:31 [PATCH v3 00/12] gpu: nova-core: consolidate and streamline GSP boot process Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 01/12] gpu: nova-core: gsp: sequencer: use GspBootContext Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 02/12] gpu: nova-core: gsp: sequencer: do not store sequence into GspSequencer Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 03/12] gpu: nova-core: gsp: replace BootUnloadGuard with local handlers Alexandre Courbot
2026-06-29 12:31 ` Alexandre Courbot [this message]
2026-06-29 12:31 ` [PATCH v3 05/12] gpu: nova-core: gsp: centralize missing unload bundle warnings Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 06/12] gpu: nova-core: gsp: fold TU102 unload bundle construction into HAL method Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 07/12] gpu: nova-core: gsp: turn FWSEC execution " Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 08/12] gpu: nova-core: gsp: make use of FWSEC bootloader a property of the TU102 HAL Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 09/12] gpu: nova-core: introduce GspBootMethod Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 10/12] gpu: nova-core: avoid repeated calls to pci::Device::as_ref Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 11/12] gpu: nova-core: gsp: pass GspBootContext mutably Alexandre Courbot
2026-06-29 12:31 ` [PATCH v3 12/12] gpu: nova-core: store Fsp instance in Gpu Alexandre Courbot
2026-06-29 13:05 ` [PATCH v3 00/12] gpu: nova-core: consolidate and streamline GSP boot process 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=20260629-nova-bootcontext-v3-4-26cb29ee8dee@nvidia.com \
--to=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=aliceryhl@google.com \
--cc=apopple@nvidia.com \
--cc=dakr@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=ecourtney@nvidia.com \
--cc=gary@garyguo.net \
--cc=jhubbard@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=nova-gpu@lists.linux.dev \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--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