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 falcon::{ 18 Falcon, 19 FalconEngine, 20 PFalcon2Base, 21 PFalconBase, // 22 }, 23 regs, 24 }; 25 26 /// Type specifying the `Gsp` falcon engine. Cannot be instantiated. 27 pub(crate) struct Gsp(()); 28 29 impl RegisterBase<PFalconBase> for Gsp { 30 const BASE: usize = 0x00110000; 31 } 32 33 impl RegisterBase<PFalcon2Base> for Gsp { 34 const BASE: usize = 0x00111000; 35 } 36 37 impl FalconEngine for Gsp {} 38 39 impl<'a> Falcon<'a, Gsp> { 40 /// Clears the SWGEN0 bit in the Falcon's IRQ status clear register to 41 /// allow GSP to signal CPU for processing new messages in message queue. 42 pub(crate) fn clear_swgen0_intr(&self) { 43 self.bar.write( 44 WithBase::of::<Gsp>(), 45 regs::NV_PFALCON_FALCON_IRQSCLR::zeroed().with_swgen0(true), 46 ); 47 } 48 49 /// Checks if GSP reload/resume has completed during the boot process. 50 pub(crate) fn check_reload_completed(&self, timeout: Delta) -> Result<bool> { 51 read_poll_timeout( 52 || Ok(self.bar.read(regs::NV_PGC6_BSI_SECURE_SCRATCH_14)), 53 |val| val.boot_stage_3_handoff(), 54 Delta::ZERO, 55 timeout, 56 ) 57 .map(|_| true) 58 } 59 60 /// Returns whether the RISC-V branch privilege lockdown bit is set. 61 pub(crate) fn riscv_branch_privilege_lockdown(&self) -> bool { 62 self.bar 63 .read(regs::NV_PFALCON_FALCON_HWCFG2::of::<Gsp>()) 64 .riscv_br_priv_lockdown() 65 } 66 67 /// Returns whether GSP registers can be read by the CPU. 68 pub(crate) fn priv_target_mask_released(&self) -> bool { 69 /// Pattern returned by GSP register reads while the PRIV target mask still blocks CPU 70 /// access. The low byte varies; the upper 24 bits are fixed. 71 const LOCKED_PATTERN: u32 = 0xbadf_4100; 72 const LOCKED_MASK: u32 = 0xffff_ff00; 73 74 let hwcfg2 = self 75 .bar 76 .read(regs::NV_PFALCON_FALCON_HWCFG2::of::<Gsp>()) 77 .into_raw(); 78 79 hwcfg2 != 0 && (hwcfg2 & LOCKED_MASK) != LOCKED_PATTERN 80 } 81 } 82