The `Fsp` instance was only used in the Hopper+ boot path, and consequently built locally (and immediately dropped) in it.
This worked well as a temporary measure, but the FSP is a GPU sub-device, so its lifetime should match the GPU rather than a single boot invocation. It will also be needed in other parts of the driver, for instance vGPU. Thus, create the `Fsp` instance in the `Gpu` constructor and store it there, passing it to the GSP boot as a mutable reference using `GspBootContext`. This makes the `Fsp` available even after the GSP is booted. Signed-off-by: Alexandre Courbot <[email protected]> --- drivers/gpu/nova-core/gpu.rs | 15 ++++++++++++++- drivers/gpu/nova-core/gsp.rs | 2 ++ drivers/gpu/nova-core/gsp/hal/gh100.rs | 8 ++------ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index 663e61d0c023..c0c0c82e3e39 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -22,11 +22,13 @@ Falcon, // }, fb::SysmemFlush, + fsp::Fsp, gsp::{ self, commands::GetGspStaticInfoReply, Gsp, - GspBootContext, // + GspBootContext, + GspBootMethod, // }, regs, }; @@ -262,6 +264,10 @@ struct GspResources<'gpu> { gsp_falcon: Falcon<'gpu, GspFalcon>, /// SEC2 falcon instance, used for GSP boot up and cleanup. sec2_falcon: Falcon<'gpu, Sec2Falcon>, + /// FSP instance, if on an arch that supports it. + // TODO: use different resource types for each boot method, and make the relevant Gsp methods + // generic against them. + fsp: Option<Fsp<'gpu>>, /// GSP runtime data. #[pin] gsp: Gsp, @@ -305,6 +311,7 @@ fn drop(self: Pin<&mut Self>) { chipset: this.spec.chipset, gsp_falcon: &*this.gsp_falcon, sec2_falcon: &*this.sec2_falcon, + fsp: this.fsp.as_mut(), }, bundle, ) @@ -356,6 +363,11 @@ pub(crate) fn new( sec2_falcon: Falcon::new(dev, spec.chipset, bar)?, + fsp: match spec.chipset.gsp_boot_method() { + GspBootMethod::Sec2 { .. } => None, + GspBootMethod::Fsp => Some(Fsp::wait_secure_boot(dev, bar, spec.chipset)?), + }, + gsp <- Gsp::new(pdev), // This member must be initialized last, so the `UnloadBundle` can never be dropped @@ -367,6 +379,7 @@ pub(crate) fn new( chipset: spec.chipset, gsp_falcon, sec2_falcon, + fsp: fsp.as_mut(), })?, }), diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs index c2d7a557310a..e89366b425fb 100644 --- a/drivers/gpu/nova-core/gsp.rs +++ b/drivers/gpu/nova-core/gsp.rs @@ -38,6 +38,7 @@ sec2::Sec2 as Sec2Falcon, Falcon, // }, + fsp::Fsp, gpu::{ Architecture, Chipset, // @@ -67,6 +68,7 @@ pub(crate) struct GspBootContext<'ctx, 'gpu> { pub(crate) chipset: Chipset, pub(crate) gsp_falcon: &'ctx Falcon<'gpu, GspFalcon>, pub(crate) sec2_falcon: &'ctx Falcon<'gpu, Sec2Falcon>, + pub(crate) fsp: Option<&'ctx mut Fsp<'gpu>>, } impl<'ctx, 'gpu> GspBootContext<'ctx, 'gpu> { diff --git a/drivers/gpu/nova-core/gsp/hal/gh100.rs b/drivers/gpu/nova-core/gsp/hal/gh100.rs index 2805a35abb79..de786871c8ec 100644 --- a/drivers/gpu/nova-core/gsp/hal/gh100.rs +++ b/drivers/gpu/nova-core/gsp/hal/gh100.rs @@ -16,10 +16,7 @@ Falcon, // }, fb::FbLayout, - fsp::{ - FmcBootArgs, - Fsp, // - }, + fsp::FmcBootArgs, gsp::{ hal::{ GspHal, @@ -142,7 +139,6 @@ fn boot( wpr_meta: &Coherent<GspFwWprMeta>, ) -> Result<Option<crate::gsp::UnloadBundle>> { let dev = ctx.dev(); - let bar = ctx.bar; let chipset = ctx.chipset; let gsp_falcon = ctx.gsp_falcon; @@ -150,7 +146,7 @@ fn boot( KBox::new(FspUnloadBundle, GFP_KERNEL)? as KBox<dyn UnloadBundle> ); - let mut fsp = Fsp::wait_secure_boot(dev, bar, chipset)?; + let fsp = ctx.fsp.as_mut().ok_or(ENODEV)?; let args = FmcBootArgs::new( dev, -- 2.54.0
