On Wed Dec 3, 2025 at 5:59 AM GMT, John Hubbard wrote:
> On Hopper and Blackwell, FSP boots GSP with hardware lockdown enabled.
> After FSP Chain of Trust completes, the driver must poll for lockdown
> release before proceeding with GSP initialization. Add the register
> bit and helper functions needed for this polling.
>
> Signed-off-by: John Hubbard <[email protected]>
> ---
>  drivers/gpu/nova-core/gsp/boot.rs | 86 ++++++++++++++++++++++++++++++-
>  drivers/gpu/nova-core/regs.rs     |  1 +
>  2 files changed, 86 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/nova-core/gsp/boot.rs 
> b/drivers/gpu/nova-core/gsp/boot.rs
> index 315f84907b11..4d04135a700e 100644
> --- a/drivers/gpu/nova-core/gsp/boot.rs
> +++ b/drivers/gpu/nova-core/gsp/boot.rs
> @@ -15,7 +15,8 @@
>      falcon::{
>          gsp::Gsp,
>          sec2::Sec2,
> -        Falcon, //
> +        Falcon,
> +        FalconEngine, //
>      },
>      fb::FbLayout,
>      firmware::{
> @@ -154,6 +155,89 @@ fn run_booter(
>          Ok(())
>      }
>  
> +    /// Check if GSP lockdown has been released after FSP Chain of Trust
> +    fn gsp_lockdown_released(
> +        dev: &device::Device,
> +        gsp_falcon: &Falcon<Gsp>,
> +        bar: &Bar0,
> +        fmc_boot_params_addr: u64,
> +        mbox0: &mut u32,
> +    ) -> bool {
> +        // Read GSP falcon mailbox0
> +        *mbox0 = gsp_falcon.read_mailbox0(bar);
> +
> +        // Check 1: If mbox0 has 0xbadf4100 pattern, GSP is still locked down
> +        if *mbox0 != 0 && (*mbox0 & 0xffffff00) == 0xbadf4100 {
> +            return false;
> +        }
> +
> +        // Check 2: If mbox0 has a value, check if it's an error
> +        if *mbox0 != 0 {
> +            let mbox1 = gsp_falcon.read_mailbox1(bar);
> +
> +            let combined_addr = (u64::from(mbox1) << 32) | u64::from(*mbox0);
> +            if combined_addr != fmc_boot_params_addr {
> +                // Address doesn't match - GSP wrote an error code
> +                // Return TRUE (lockdown released) with error
> +                dev_dbg!(dev,
> +                    "GSP lockdown released with error: mbox0={:#x}, 
> combined_addr={:#x}, expected={:#x}",
> +                    *mbox0, combined_addr, fmc_boot_params_addr);
> +                return true;
> +            }
> +        }
> +
> +        // Check 3: Verify HWCFG2 RISCV_BR_PRIV_LOCKDOWN bit is clear
> +        let hwcfg2 = regs::NV_PFALCON_FALCON_HWCFG2::read(bar, 
> &crate::falcon::gsp::Gsp::ID);
> +        !hwcfg2.riscv_br_priv_lockdown()
> +    }
> +
> +    /// Wait for GSP lockdown to be released after FSP Chain of Trust
> +    #[expect(dead_code)]
> +    fn wait_for_gsp_lockdown_release(
> +        dev: &device::Device,
> +        bar: &Bar0,
> +        gsp_falcon: &Falcon<Gsp>,
> +        fmc_boot_params_addr: u64,
> +    ) -> Result<u32> {
> +        dev_dbg!(dev, "Waiting for GSP lockdown release\n");
> +
> +        let mut mbox0: u32 = 0;
> +
> +        read_poll_timeout(
> +            || {
> +                let released = Self::gsp_lockdown_released(
> +                    dev,
> +                    gsp_falcon,
> +                    bar,
> +                    fmc_boot_params_addr,
> +                    &mut mbox0,
> +                );
> +
> +                Ok((released, mbox0))
> +            },
> +            |(released, _)| *released,
> +            Delta::ZERO,
> +            Delta::from_millis(4000),
> +        )
> +        .inspect_err(|_| {
> +            dev_err!(dev, "GSP lockdown release timeout\n");
> +        })

Once you're done with the error, please just return early with `?` and not keep
chaining.

Best,
Gary

> +        .map(|(_, mbox0)| mbox0)
> +        .and_then(|mbox0| {
> +            // Check mbox0 for error after wait completion
> +            if mbox0 != 0 {
> +                dev_err!(dev, "GSP-FMC boot failed (mbox: {:#x})\n", mbox0);
> +                Err(EIO)
> +            } else {
> +                dev_dbg!(
> +                    dev,
> +                    "GSP hardware lockdown fully released, proceeding with 
> initialization\n"
> +                );
> +                Ok(mbox0)
> +            }
> +        })
> +    }
> +
>      /// Attempt to boot the GSP.
>      ///
>      /// This is a GPU-dependent and complex procedure that involves loading 
> firmware files from
> diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
> index 0d5c13f19073..a41d31449c65 100644
> --- a/drivers/gpu/nova-core/regs.rs
> +++ b/drivers/gpu/nova-core/regs.rs
> @@ -277,6 +277,7 @@ pub(crate) fn vga_workspace_addr(self) -> Option<u64> {
>  
>  register!(NV_PFALCON_FALCON_HWCFG2 @ PFalconBase[0x000000f4] {
>      10:10   riscv as bool;
> +    11:11   riscv_br_priv_lockdown as bool, "RISC-V branch privilege 
> lockdown bit";
>      12:12   mem_scrubbing as bool, "Set to 0 after memory scrubbing is 
> completed";
>      31:31   reset_ready as bool, "Signal indicating that reset is completed 
> (GA102+)";
>  });

Reply via email to