1*82eaa14eSJohn Hubbard // SPDX-License-Identifier: GPL-2.0 2*82eaa14eSJohn Hubbard // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3*82eaa14eSJohn Hubbard 4*82eaa14eSJohn Hubbard //! FSP (Foundation Security Processor) interface for Hopper/Blackwell GPUs. 5*82eaa14eSJohn Hubbard //! 6*82eaa14eSJohn Hubbard //! Hopper/Blackwell use a simplified firmware boot sequence: FMC, then FSP, then GSP. 7*82eaa14eSJohn Hubbard //! Unlike Turing/Ampere/Ada, there is no SEC2 (Security Engine 2) usage. 8*82eaa14eSJohn Hubbard //! FSP handles secure boot directly using FMC firmware and Chain of Trust. 9*82eaa14eSJohn Hubbard 10*82eaa14eSJohn Hubbard use kernel::{ 11*82eaa14eSJohn Hubbard device, 12*82eaa14eSJohn Hubbard io::poll::read_poll_timeout, 13*82eaa14eSJohn Hubbard prelude::*, 14*82eaa14eSJohn Hubbard time::Delta, // 15*82eaa14eSJohn Hubbard }; 16*82eaa14eSJohn Hubbard 17*82eaa14eSJohn Hubbard use crate::{ 18*82eaa14eSJohn Hubbard driver::Bar0, 19*82eaa14eSJohn Hubbard falcon::{ 20*82eaa14eSJohn Hubbard fsp::Fsp as FspEngine, 21*82eaa14eSJohn Hubbard Falcon, // 22*82eaa14eSJohn Hubbard }, 23*82eaa14eSJohn Hubbard firmware::fsp::FspFirmware, 24*82eaa14eSJohn Hubbard gpu::Chipset, 25*82eaa14eSJohn Hubbard regs, // 26*82eaa14eSJohn Hubbard }; 27*82eaa14eSJohn Hubbard 28*82eaa14eSJohn Hubbard mod hal; 29*82eaa14eSJohn Hubbard 30*82eaa14eSJohn Hubbard /// FSP interface for Hopper/Blackwell GPUs. 31*82eaa14eSJohn Hubbard /// 32*82eaa14eSJohn Hubbard /// An `Fsp` is produced by [`Fsp::wait_secure_boot`], which only returns once FSP secure boot 33*82eaa14eSJohn Hubbard /// has completed. It owns the FSP falcon and the FMC firmware, which are used for the subsequent 34*82eaa14eSJohn Hubbard /// Chain of Trust boot. 35*82eaa14eSJohn Hubbard pub(crate) struct Fsp { 36*82eaa14eSJohn Hubbard #[expect(dead_code)] 37*82eaa14eSJohn Hubbard falcon: Falcon<FspEngine>, 38*82eaa14eSJohn Hubbard #[expect(dead_code)] 39*82eaa14eSJohn Hubbard fsp_fw: FspFirmware, 40*82eaa14eSJohn Hubbard } 41*82eaa14eSJohn Hubbard 42*82eaa14eSJohn Hubbard impl Fsp { 43*82eaa14eSJohn Hubbard /// Waits for FSP secure boot completion, then returns the [`Fsp`] interface. 44*82eaa14eSJohn Hubbard /// 45*82eaa14eSJohn Hubbard /// Polls the thermal scratch register until FSP signals boot completion or the timeout 46*82eaa14eSJohn Hubbard /// elapses. Returning an [`Fsp`] only on success guarantees, at the API level, that the 47*82eaa14eSJohn Hubbard /// interface is not used before secure boot has completed. 48*82eaa14eSJohn Hubbard pub(crate) fn wait_secure_boot( 49*82eaa14eSJohn Hubbard dev: &device::Device<device::Bound>, 50*82eaa14eSJohn Hubbard bar: &Bar0, 51*82eaa14eSJohn Hubbard chipset: Chipset, 52*82eaa14eSJohn Hubbard fsp_fw: FspFirmware, 53*82eaa14eSJohn Hubbard ) -> Result<Fsp> { 54*82eaa14eSJohn Hubbard /// FSP secure boot completion timeout in milliseconds. 55*82eaa14eSJohn Hubbard const FSP_SECURE_BOOT_TIMEOUT_MS: i64 = 5000; 56*82eaa14eSJohn Hubbard 57*82eaa14eSJohn Hubbard let hal = hal::fsp_hal(chipset).ok_or(ENOTSUPP)?; 58*82eaa14eSJohn Hubbard let falcon = Falcon::<FspEngine>::new(dev, chipset)?; 59*82eaa14eSJohn Hubbard 60*82eaa14eSJohn Hubbard read_poll_timeout( 61*82eaa14eSJohn Hubbard || Ok(hal.fsp_boot_status(bar)), 62*82eaa14eSJohn Hubbard |&status| status == regs::NV_THERM_I2CS_SCRATCH_FSP_BOOT_COMPLETE_STATUS_SUCCESS, 63*82eaa14eSJohn Hubbard Delta::from_millis(10), 64*82eaa14eSJohn Hubbard Delta::from_millis(FSP_SECURE_BOOT_TIMEOUT_MS), 65*82eaa14eSJohn Hubbard ) 66*82eaa14eSJohn Hubbard .inspect_err(|e| { 67*82eaa14eSJohn Hubbard dev_err!(dev, "FSP secure boot completion error: {:?}\n", e); 68*82eaa14eSJohn Hubbard })?; 69*82eaa14eSJohn Hubbard 70*82eaa14eSJohn Hubbard Ok(Fsp { falcon, fsp_fw }) 71*82eaa14eSJohn Hubbard } 72*82eaa14eSJohn Hubbard } 73