diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs index afbd75879d16..1475485bded3 100644 --- a/drivers/gpu/nova-core/fsp.rs +++ b/drivers/gpu/nova-core/fsp.rs @@ -40,7 +40,11 @@ FIRMWARE_VERSION, // }, gpu::Chipset, - gsp::GspFmcBootParams, + gsp::{ + GspFmcBootParams, + GspFwWprMeta, + LibosMemoryRegionInitArgument, // + }, mctp::{ MctpHeader, NvdmHeader, @@ -134,7 +138,7 @@ impl FspCotMessage { fn new<'a>( fb_layout: &FbLayout, fsp_fw: &'a FspFirmware, - args: &'a FmcBootArgs, + args: &'a FmcBootArgs<'_>, ) -> Result + 'a> { // frts_vidmem_offset is measured from the end of FB, so FRTS sits at // (end of FB) - frts_vidmem_offset. @@ -188,35 +192,39 @@ impl MessageToFsp for FspCotMessage { } /// Bundled arguments for FMC boot via FSP Chain of Trust. -pub(crate) struct FmcBootArgs { +pub(crate) struct FmcBootArgs<'a> { chipset: Chipset, fmc_boot_params: Coherent, resume: bool, + // Additional dependencies required to be kept alive for FMC boot. + _wpr_meta: &'a Coherent, + _libos: &'a Coherent<[LibosMemoryRegionInitArgument]>, } -impl FmcBootArgs { +impl<'a> FmcBootArgs<'a> { /// Builds FMC boot arguments, allocating the DMA-coherent boot parameter /// structure that FSP will read. pub(crate) fn new( dev: &device::Device, chipset: Chipset, - wpr_meta_addr: u64, - libos_addr: u64, + wpr_meta: &'a Coherent, + libos: &'a Coherent<[LibosMemoryRegionInitArgument]>, resume: bool, ) -> Result { - let init = GspFmcBootParams::new(wpr_meta_addr, libos_addr); + let init = GspFmcBootParams::new(wpr_meta.dma_handle(), libos.dma_handle()); Ok(Self { chipset, fmc_boot_params: Coherent::::init(dev, GFP_KERNEL, init)?, resume, + _wpr_meta: wpr_meta, + _libos: libos, }) } - /// DMA address of the FMC boot parameters, needed after boot for lockdown - /// release polling. - pub(crate) fn boot_params_dma_handle(&self) -> u64 { - self.fmc_boot_params.dma_handle() + /// Returns the FMC boot parameters allocation. + pub(crate) fn boot_params(&self) -> &Coherent { + &self.fmc_boot_params } } @@ -350,7 +358,7 @@ pub(crate) fn boot_fmc( &mut self, dev: &device::Device, fb_layout: &FbLayout, - args: &FmcBootArgs, + args: &FmcBootArgs<'_>, ) -> Result { dev_dbg!(dev, "Starting FSP boot sequence for {}\n", args.chipset); diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs index f38630026e5d..c7b18c44c03d 100644 --- a/drivers/gpu/nova-core/gsp.rs +++ b/drivers/gpu/nova-core/gsp.rs @@ -30,6 +30,7 @@ pub(crate) use fw::{ GspFmcBootParams, GspFwWprMeta, + LibosMemoryRegionInitArgument, LibosParams, // }; pub(crate) use hal::boot_firmware_files; @@ -45,10 +46,7 @@ gpu::Chipset, gsp::{ cmdq::Cmdq, - fw::{ - GspArgumentsPadded, - LibosMemoryRegionInitArgument, // - }, + fw::GspArgumentsPadded, // }, num, }; diff --git a/drivers/gpu/nova-core/gsp/hal/gh100.rs b/drivers/gpu/nova-core/gsp/hal/gh100.rs index ad04904b5af4..ee086f1c2876 100644 --- a/drivers/gpu/nova-core/gsp/hal/gh100.rs +++ b/drivers/gpu/nova-core/gsp/hal/gh100.rs @@ -25,6 +25,7 @@ }, Gsp, GspBootContext, + GspFmcBootParams, GspFwWprMeta, // }, }; @@ -56,13 +57,13 @@ fn combined_addr(&self) -> u64 { fn lockdown_released_or_error( &self, gsp_falcon: &Falcon<'_, GspEngine>, - fmc_boot_params_addr: u64, + fmc_boot_params: &Coherent, ) -> bool { // GSP-FMC normally clears the boot parameters address from the mailboxes early during // boot. If the address is still there, keep polling rather than treating it as an error. // Any other non-zero mailbox0 value is a GSP-FMC error code. if self.mbox0 != 0 { - return self.combined_addr() != fmc_boot_params_addr; + return self.combined_addr() != fmc_boot_params.dma_handle(); } !gsp_falcon.riscv_branch_privilege_lockdown() @@ -73,7 +74,7 @@ fn lockdown_released_or_error( fn wait_for_gsp_lockdown_release( dev: &device::Device, gsp_falcon: &Falcon<'_, GspEngine>, - fmc_boot_params_addr: u64, + fmc_boot_params: &Coherent, ) -> Result { dev_dbg!(dev, "Waiting for GSP lockdown release\n"); @@ -88,7 +89,7 @@ fn wait_for_gsp_lockdown_release( }, |mbox| match mbox { None => false, - Some(mbox) => mbox.lockdown_released_or_error(gsp_falcon, fmc_boot_params_addr), + Some(mbox) => mbox.lockdown_released_or_error(gsp_falcon, fmc_boot_params), }, Delta::from_millis(10), Delta::from_secs(30), @@ -147,13 +148,7 @@ fn boot( KBox::new(FspUnloadBundle, GFP_KERNEL)? as KBox ); - let args = FmcBootArgs::new( - dev, - chipset, - wpr_meta.dma_handle(), - gsp.libos.dma_handle(), - false, - )?; + let args = FmcBootArgs::new(dev, chipset, wpr_meta, &gsp.libos, false)?; // Wait for the GSP RISC-V core to halt in case of error. We create this guard after `args` // to make sure that boot args are kept alive until halt, in case they are still being @@ -169,7 +164,7 @@ fn boot( // Wait for GSP-FMC to release the GSP lockdown, indicating that `args` is not accessed // anymore. - wait_for_gsp_lockdown_release(dev, gsp_falcon, args.boot_params_dma_handle())?; + wait_for_gsp_lockdown_release(dev, gsp_falcon, args.boot_params())?; Ok(Some(unload_guard.dismiss().0)) }