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