1 // SPDX-License-Identifier: GPL-2.0 2 3 use kernel::{ 4 io::{ 5 poll::read_poll_timeout, 6 register::{ 7 RegisterBase, 8 WithBase, // 9 }, 10 Io, 11 }, 12 prelude::*, 13 time::Delta, // 14 }; 15 16 use crate::{ 17 driver::Bar0, 18 falcon::{ 19 Falcon, 20 FalconEngine, 21 PFalcon2Base, 22 PFalconBase, // 23 }, 24 regs, 25 }; 26 27 /// Pattern returned by GSP register reads while the PRIV target mask still blocks CPU access. 28 const GSP_TARGET_MASK_LOCKED_PATTERN: u32 = 0xbadf_4100; 29 const GSP_TARGET_MASK_LOCKED_MASK: u32 = 0xffff_ff00; 30 31 /// Type specifying the `Gsp` falcon engine. Cannot be instantiated. 32 pub(crate) struct Gsp(()); 33 34 impl RegisterBase<PFalconBase> for Gsp { 35 const BASE: usize = 0x00110000; 36 } 37 38 impl RegisterBase<PFalcon2Base> for Gsp { 39 const BASE: usize = 0x00111000; 40 } 41 42 impl FalconEngine for Gsp {} 43 44 impl Falcon<Gsp> { 45 /// Clears the SWGEN0 bit in the Falcon's IRQ status clear register to 46 /// allow GSP to signal CPU for processing new messages in message queue. 47 pub(crate) fn clear_swgen0_intr(&self, bar: Bar0<'_>) { 48 bar.write( 49 WithBase::of::<Gsp>(), 50 regs::NV_PFALCON_FALCON_IRQSCLR::zeroed().with_swgen0(true), 51 ); 52 } 53 54 /// Checks if GSP reload/resume has completed during the boot process. 55 pub(crate) fn check_reload_completed(&self, bar: Bar0<'_>, timeout: Delta) -> Result<bool> { 56 read_poll_timeout( 57 || Ok(bar.read(regs::NV_PGC6_BSI_SECURE_SCRATCH_14)), 58 |val| val.boot_stage_3_handoff(), 59 Delta::ZERO, 60 timeout, 61 ) 62 .map(|_| true) 63 } 64 65 /// Returns whether the RISC-V branch privilege lockdown bit is set. 66 pub(crate) fn riscv_branch_privilege_lockdown(&self, bar: Bar0<'_>) -> bool { 67 bar.read(regs::NV_PFALCON_FALCON_HWCFG2::of::<Gsp>()) 68 .riscv_br_priv_lockdown() 69 } 70 71 /// Returns whether GSP registers can be read by the CPU. 72 pub(crate) fn priv_target_mask_released(&self, bar: Bar0<'_>) -> bool { 73 let hwcfg2 = bar 74 .read(regs::NV_PFALCON_FALCON_HWCFG2::of::<Gsp>()) 75 .into_raw(); 76 77 hwcfg2 != 0 && (hwcfg2 & GSP_TARGET_MASK_LOCKED_MASK) != GSP_TARGET_MASK_LOCKED_PATTERN 78 } 79 } 80