The next patch aims at replacing the cumbersome `BootUnloadGuard` with a more local and less intrusive mechanism to run the GSP unload sequence upon GSP boot failure. Doing so requires running the boot code in a local closure, which changes its indentation and would make other changes difficult to track in the diff. Thus, this preparatory patch moves said boot code into a local closure that is run upon construction, so the next patch does not need to re-indent code that changes.
This is a mechanical preparatory patch to make the next patch easier to read. No functional change intended. Signed-off-by: Alexandre Courbot <[email protected]> --- drivers/gpu/nova-core/gsp/boot.rs | 42 ++++++++------- drivers/gpu/nova-core/gsp/hal/gh100.rs | 40 +++++++------- drivers/gpu/nova-core/gsp/hal/tu102.rs | 96 ++++++++++++++++++---------------- 3 files changed, 96 insertions(+), 82 deletions(-) diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs index bb2000b7a78b..9eccfd634b61 100644 --- a/drivers/gpu/nova-core/gsp/boot.rs +++ b/drivers/gpu/nova-core/gsp/boot.rs @@ -119,30 +119,36 @@ pub(crate) fn boot( // Perform the chipset-specific boot sequence, and retrieve the unload bundle. let unload_guard = hal.boot(&self, &ctx, &fb_layout, &wpr_meta)?; + // Run from a closure so we can retrieve the result, and run the unload sequence of the GSP + // in case of error. + let res = (|| { + gsp_falcon.write_os_version(bar, gsp_fw.bootloader.app_version); - gsp_falcon.write_os_version(bar, gsp_fw.bootloader.app_version); + // Poll for RISC-V to become active before continuing. + read_poll_timeout( + || Ok(gsp_falcon.is_riscv_active(bar)), + |val: &bool| *val, + Delta::from_millis(10), + Delta::from_secs(5), + )?; - // Poll for RISC-V to become active before continuing. - read_poll_timeout( - || Ok(gsp_falcon.is_riscv_active(bar)), - |val: &bool| *val, - Delta::from_millis(10), - Delta::from_secs(5), - )?; + dev_dbg!(pdev, "RISC-V active? {}\n", gsp_falcon.is_riscv_active(bar),); - dev_dbg!(pdev, "RISC-V active? {}\n", gsp_falcon.is_riscv_active(bar),); + self.cmdq + .send_command_no_wait(bar, commands::SetSystemInfo::new(pdev, chipset))?; + self.cmdq + .send_command_no_wait(bar, commands::SetRegistry::new())?; - self.cmdq - .send_command_no_wait(bar, commands::SetSystemInfo::new(pdev, chipset))?; - 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) + })(); - // Wait until GSP is fully initialized. - commands::wait_gsp_init_done(&self.cmdq)?; - - Ok(unload_guard.dismiss()) + match res { + Err(e) => Err(e), + Ok(()) => Ok(unload_guard.dismiss()), + } } /// Shut down the GSP and wait until it is offline. diff --git a/drivers/gpu/nova-core/gsp/hal/gh100.rs b/drivers/gpu/nova-core/gsp/hal/gh100.rs index c9fdc8cacedc..46e03f34bc74 100644 --- a/drivers/gpu/nova-core/gsp/hal/gh100.rs +++ b/drivers/gpu/nova-core/gsp/hal/gh100.rs @@ -162,31 +162,35 @@ fn boot<'a>( let gsp_falcon = ctx.gsp_falcon; let sec2_falcon = ctx.sec2_falcon; - let fsp_fw = FspFirmware::new(dev, chipset, FIRMWARE_VERSION)?; + let res = (|| { + let fsp_fw = FspFirmware::new(dev, chipset, FIRMWARE_VERSION)?; - let unload_bundle = crate::gsp::UnloadBundle( - KBox::new(FspUnloadBundle, GFP_KERNEL)? as KBox<dyn UnloadBundle> - ); + let unload_bundle = crate::gsp::UnloadBundle( + KBox::new(FspUnloadBundle, GFP_KERNEL)? as KBox<dyn UnloadBundle> + ); - // Wrap the unload bundle into a drop guard so it is automatically run upon failure. - let unload_guard = - BootUnloadGuard::new(gsp, dev, bar, gsp_falcon, sec2_falcon, Some(unload_bundle)); + // Wrap the unload bundle into a drop guard so it is automatically run upon failure. + let unload_guard = + BootUnloadGuard::new(gsp, dev, bar, gsp_falcon, sec2_falcon, Some(unload_bundle)); - let mut fsp = Fsp::wait_secure_boot(dev, bar, chipset, fsp_fw)?; + let mut fsp = Fsp::wait_secure_boot(dev, bar, chipset, fsp_fw)?; - let args = FmcBootArgs::new( - dev, - chipset, - wpr_meta.dma_handle(), - gsp.libos.dma_handle(), - false, - )?; + let args = FmcBootArgs::new( + dev, + chipset, + wpr_meta.dma_handle(), + gsp.libos.dma_handle(), + false, + )?; - fsp.boot_fmc(dev, bar, fb_layout, &args)?; + fsp.boot_fmc(dev, bar, fb_layout, &args)?; - wait_for_gsp_lockdown_release(dev, bar, gsp_falcon, args.boot_params_dma_handle())?; + wait_for_gsp_lockdown_release(dev, bar, gsp_falcon, args.boot_params_dma_handle())?; - Ok(unload_guard) + Ok(unload_guard) + })(); + + res } } diff --git a/drivers/gpu/nova-core/gsp/hal/tu102.rs b/drivers/gpu/nova-core/gsp/hal/tu102.rs index 6ed4ee268086..9b24361f924b 100644 --- a/drivers/gpu/nova-core/gsp/hal/tu102.rs +++ b/drivers/gpu/nova-core/gsp/hal/tu102.rs @@ -277,59 +277,63 @@ fn boot<'a>( let gsp_falcon = ctx.gsp_falcon; let sec2_falcon = ctx.sec2_falcon; - let bios = Vbios::new(dev, bar)?; + let res = (|| { + let bios = Vbios::new(dev, bar)?; - // Try and prepare the unload bundle. - // - // If the unload bundle creation fails, the GPU will need to be reset before the driver can - // be probed again. - let unload_bundle = - Sec2UnloadBundle::build(dev, bar, chipset, &bios, gsp_falcon, sec2_falcon) - .inspect_err(|e| { - dev_warn!(dev, "Failed to prepare unload firmware: {:?}\n", e); - dev_warn!(dev, "The GSP won't be able to unload properly on unbind.\n"); - dev_warn!( - dev, - "The GPU will need to be reset before the driver can bind again.\n" - ); - }) - .ok() - .map(crate::gsp::UnloadBundle); + // Try and prepare the unload bundle. + // + // If the unload bundle creation fails, the GPU will need to be reset before the driver + // can be probed again. + let unload_bundle = + Sec2UnloadBundle::build(dev, bar, chipset, &bios, gsp_falcon, sec2_falcon) + .inspect_err(|e| { + dev_warn!(dev, "Failed to prepare unload firmware: {:?}\n", e); + dev_warn!(dev, "The GSP won't be able to unload properly on unbind.\n"); + dev_warn!( + dev, + "The GPU will need to be reset before the driver can bind again.\n" + ); + }) + .ok() + .map(crate::gsp::UnloadBundle); - // Wrap the unload bundle into a drop guard so it is automatically run upon failure. - let unload_guard = - BootUnloadGuard::new(gsp, dev, bar, gsp_falcon, sec2_falcon, unload_bundle); + // Wrap the unload bundle into a drop guard so it is automatically run upon failure. + let unload_guard = + BootUnloadGuard::new(gsp, dev, bar, gsp_falcon, sec2_falcon, unload_bundle); - // FWSEC-FRTS is not executed on chips where the FRTS region size is 0 (e.g. GA100). - if !fb_layout.frts.is_empty() { - run_fwsec_frts(dev, chipset, gsp_falcon, bar, &bios, fb_layout)?; - } + // FWSEC-FRTS is not executed on chips where the FRTS region size is 0 (e.g. GA100). + if !fb_layout.frts.is_empty() { + run_fwsec_frts(dev, chipset, gsp_falcon, bar, &bios, fb_layout)?; + } - gsp_falcon.reset(bar)?; - let libos_handle = gsp.libos.dma_handle(); - let (mbox0, mbox1) = gsp_falcon.boot( - bar, - Some(libos_handle as u32), - Some((libos_handle >> 32) as u32), - )?; - dev_dbg!(dev, "GSP MBOX0: {:#x}, MBOX1: {:#x}\n", mbox0, mbox1); + gsp_falcon.reset(bar)?; + let libos_handle = gsp.libos.dma_handle(); + let (mbox0, mbox1) = gsp_falcon.boot( + bar, + Some(libos_handle as u32), + Some((libos_handle >> 32) as u32), + )?; + dev_dbg!(dev, "GSP MBOX0: {:#x}, MBOX1: {:#x}\n", mbox0, mbox1); - dev_dbg!( - dev, - "Using SEC2 to load and run the booter_load firmware...\n" - ); + dev_dbg!( + dev, + "Using SEC2 to load and run the booter_load firmware...\n" + ); - BooterFirmware::new( - dev, - BooterKind::Loader, - chipset, - FIRMWARE_VERSION, - sec2_falcon, - bar, - )? - .run(dev, bar, sec2_falcon, wpr_meta)?; + BooterFirmware::new( + dev, + BooterKind::Loader, + chipset, + FIRMWARE_VERSION, + sec2_falcon, + bar, + )? + .run(dev, bar, sec2_falcon, wpr_meta)?; - Ok(unload_guard) + Ok(unload_guard) + })(); + + res } fn post_boot(&self, gsp: &Gsp, ctx: &GspBootContext<'_>, gsp_fw: &GspFirmware) -> Result { -- 2.54.0
