mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 08:15:07 -04:00
gpu: nova-core: gsp: turn FWSEC execution into HAL method
Turn the `run_fwsec_frts` function into a method of `Tu102`. A following patch will turn the "use FWSEC bootloader" property into a flag of the TU102 HAL itself, and making this a method will allow the code to access it instead of querying `Chipset`. Reviewed-by: Eliot Courtney <ecourtney@nvidia.com> Link: https://patch.msgid.link/20260709-nova-bootcontext-v6-7-520cbf8b9b50@nvidia.com Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
@@ -127,94 +127,95 @@ fn run(&self, ctx: &GspBootContext<'_>) -> Result {
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to load and run the FWSEC-FRTS firmware and confirm that it has properly
|
||||
/// created the WPR2 region.
|
||||
fn run_fwsec_frts(
|
||||
dev: &device::Device<device::Bound>,
|
||||
chipset: Chipset,
|
||||
falcon: &Falcon<'_, GspEngine>,
|
||||
bar: Bar0<'_>,
|
||||
bios: &Vbios,
|
||||
fb_layout: &FbLayout,
|
||||
) -> Result {
|
||||
// Check that the WPR2 region does not already exist - if it does, we cannot run
|
||||
// FWSEC-FRTS until the GPU is reset.
|
||||
if bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI).higher_bound() != 0 {
|
||||
dev_err!(
|
||||
dev,
|
||||
"WPR2 region already exists - GPU needs to be reset to proceed\n"
|
||||
);
|
||||
return Err(EBUSY);
|
||||
}
|
||||
|
||||
// FWSEC-FRTS will create the WPR2 region.
|
||||
let fwsec_frts = FwsecFirmware::new(
|
||||
dev,
|
||||
falcon,
|
||||
bios,
|
||||
FwsecCommand::Frts {
|
||||
frts_addr: fb_layout.frts.start,
|
||||
frts_size: fb_layout.frts.len(),
|
||||
},
|
||||
)?;
|
||||
|
||||
if chipset.needs_fwsec_bootloader() {
|
||||
let fwsec_frts_bl = FwsecFirmwareWithBl::new(fwsec_frts, dev, chipset)?;
|
||||
// Load and run the bootloader, which will load FWSEC-FRTS and run it.
|
||||
fwsec_frts_bl.run(dev, falcon, bar)?;
|
||||
} else {
|
||||
// Load and run FWSEC-FRTS directly.
|
||||
fwsec_frts.run(dev, falcon)?;
|
||||
}
|
||||
|
||||
// SCRATCH_E contains the error code for FWSEC-FRTS.
|
||||
let frts_status = bar
|
||||
.read(regs::NV_PBUS_SW_SCRATCH_0E_FRTS_ERR)
|
||||
.frts_err_code();
|
||||
if frts_status != 0 {
|
||||
dev_err!(
|
||||
dev,
|
||||
"FWSEC-FRTS returned with error code {:#x}\n",
|
||||
frts_status
|
||||
);
|
||||
|
||||
return Err(EIO);
|
||||
}
|
||||
|
||||
// Check that the WPR2 region has been created as we requested.
|
||||
let (wpr2_lo, wpr2_hi) = (
|
||||
bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO).lower_bound(),
|
||||
bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI).higher_bound(),
|
||||
);
|
||||
|
||||
match (wpr2_lo, wpr2_hi) {
|
||||
(_, 0) => {
|
||||
dev_err!(dev, "WPR2 region not created after running FWSEC-FRTS\n");
|
||||
|
||||
Err(EIO)
|
||||
}
|
||||
(wpr2_lo, _) if wpr2_lo != fb_layout.frts.start => {
|
||||
dev_err!(
|
||||
dev,
|
||||
"WPR2 region created at unexpected address {:#x}; expected {:#x}\n",
|
||||
wpr2_lo,
|
||||
fb_layout.frts.start,
|
||||
);
|
||||
|
||||
Err(EIO)
|
||||
}
|
||||
(wpr2_lo, wpr2_hi) => {
|
||||
dev_dbg!(dev, "WPR2: {:#x}-{:#x}\n", wpr2_lo, wpr2_hi);
|
||||
dev_dbg!(dev, "GPU instance built\n");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Tu102;
|
||||
|
||||
impl Tu102 {
|
||||
/// Helper method to load and run the FWSEC-FRTS firmware and confirm that it has properly
|
||||
/// created the WPR2 region.
|
||||
fn run_fwsec_frts(
|
||||
&self,
|
||||
dev: &device::Device<device::Bound>,
|
||||
chipset: Chipset,
|
||||
falcon: &Falcon<'_, GspEngine>,
|
||||
bar: Bar0<'_>,
|
||||
bios: &Vbios,
|
||||
fb_layout: &FbLayout,
|
||||
) -> Result {
|
||||
// Check that the WPR2 region does not already exist - if it does, we cannot run
|
||||
// FWSEC-FRTS until the GPU is reset.
|
||||
if bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI).higher_bound() != 0 {
|
||||
dev_err!(
|
||||
dev,
|
||||
"WPR2 region already exists - GPU needs to be reset to proceed\n"
|
||||
);
|
||||
return Err(EBUSY);
|
||||
}
|
||||
|
||||
// FWSEC-FRTS will create the WPR2 region.
|
||||
let fwsec_frts = FwsecFirmware::new(
|
||||
dev,
|
||||
falcon,
|
||||
bios,
|
||||
FwsecCommand::Frts {
|
||||
frts_addr: fb_layout.frts.start,
|
||||
frts_size: fb_layout.frts.len(),
|
||||
},
|
||||
)?;
|
||||
|
||||
if chipset.needs_fwsec_bootloader() {
|
||||
let fwsec_frts_bl = FwsecFirmwareWithBl::new(fwsec_frts, dev, chipset)?;
|
||||
// Load and run the bootloader, which will load FWSEC-FRTS and run it.
|
||||
fwsec_frts_bl.run(dev, falcon, bar)?;
|
||||
} else {
|
||||
// Load and run FWSEC-FRTS directly.
|
||||
fwsec_frts.run(dev, falcon)?;
|
||||
}
|
||||
|
||||
// SCRATCH_E contains the error code for FWSEC-FRTS.
|
||||
let frts_status = bar
|
||||
.read(regs::NV_PBUS_SW_SCRATCH_0E_FRTS_ERR)
|
||||
.frts_err_code();
|
||||
if frts_status != 0 {
|
||||
dev_err!(
|
||||
dev,
|
||||
"FWSEC-FRTS returned with error code {:#x}\n",
|
||||
frts_status
|
||||
);
|
||||
|
||||
return Err(EIO);
|
||||
}
|
||||
|
||||
// Check that the WPR2 region has been created as we requested.
|
||||
let (wpr2_lo, wpr2_hi) = (
|
||||
bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_LO).lower_bound(),
|
||||
bar.read(regs::NV_PFB_PRI_MMU_WPR2_ADDR_HI).higher_bound(),
|
||||
);
|
||||
|
||||
match (wpr2_lo, wpr2_hi) {
|
||||
(_, 0) => {
|
||||
dev_err!(dev, "WPR2 region not created after running FWSEC-FRTS\n");
|
||||
|
||||
Err(EIO)
|
||||
}
|
||||
(wpr2_lo, _) if wpr2_lo != fb_layout.frts.start => {
|
||||
dev_err!(
|
||||
dev,
|
||||
"WPR2 region created at unexpected address {:#x}; expected {:#x}\n",
|
||||
wpr2_lo,
|
||||
fb_layout.frts.start,
|
||||
);
|
||||
|
||||
Err(EIO)
|
||||
}
|
||||
(wpr2_lo, wpr2_hi) => {
|
||||
dev_dbg!(dev, "WPR2: {:#x}-{:#x}\n", wpr2_lo, wpr2_hi);
|
||||
dev_dbg!(dev, "GPU instance built\n");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Load and prepare the resources required to properly reset the GSP after it has been stopped.
|
||||
fn build_unload_bundle(
|
||||
&self,
|
||||
@@ -284,7 +285,7 @@ fn boot(
|
||||
|
||||
// FWSEC-FRTS is not executed on chips where the FRTS region size is 0 (e.g. GA100).
|
||||
if !fb_layout.frts.is_empty() {
|
||||
run_fwsec_frts(dev, chipset, gsp_falcon, bar, &bios, fb_layout)?;
|
||||
self.run_fwsec_frts(dev, chipset, gsp_falcon, bar, &bios, fb_layout)?;
|
||||
}
|
||||
|
||||
gsp_falcon.reset()?;
|
||||
|
||||
Reference in New Issue
Block a user