`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 <[email protected]> --- 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
