warpshell/cores/
axi_firewall.rs

1//! # AXI firewall
2
3use crate::{BasedCtrlOps, Error as BasedError};
4use enum_iterator::Sequence;
5use thiserror::Error;
6
7const MI_BLOCK_MASK: u32 = 0x0100_0100;
8
9pub type Result<T> = std::result::Result<T, Error>;
10
11#[derive(Error, Debug)]
12pub enum Error {
13    #[error("Based access error: {0}")]
14    BasedError(#[from] BasedError),
15}
16
17/// AXI firewall registers
18#[derive(Copy, Clone, Debug, Sequence, PartialEq)]
19#[repr(u64)]
20pub enum AxiFirewallReg {
21    MiSideFaultStatus = 0x0,
22    MiSideSoftFaultControl = 0x4,
23    MiSideUnblockControl = 0x8,
24    IpVersion = 0x10,
25    SiSideFaultStatus = 0x100,
26    SiSideSoftFaultControl = 0x104,
27    SiSideUnblockControl = 0x108,
28}
29
30pub trait AxiFirewallOps: BasedCtrlOps {
31    /// Reads the value of an AXI firewall register
32    fn get_axi_firewall_reg(&self, reg: AxiFirewallReg) -> Result<u32> {
33        Ok(self.based_ctrl_read_u32(reg as u64)?)
34    }
35
36    /// Writes the value of an AXI firewall register
37    fn set_axi_firewall_reg(&self, reg: AxiFirewallReg, value: u32) -> Result<()> {
38        Ok(self.based_ctrl_write_u32(reg as u64, value)?)
39    }
40
41    fn get_mi_fault_status(&self) -> Result<u32> {
42        self.get_axi_firewall_reg(AxiFirewallReg::MiSideFaultStatus)
43    }
44
45    fn mi_is_blocked(&self) -> Result<bool> {
46        Ok(self.get_mi_fault_status()? != 0)
47    }
48
49    fn block_mi(&self) -> Result<()> {
50        self.set_axi_firewall_reg(AxiFirewallReg::MiSideSoftFaultControl, MI_BLOCK_MASK)
51    }
52
53    fn unblock_mi(&self) -> Result<()> {
54        self.set_axi_firewall_reg(AxiFirewallReg::MiSideSoftFaultControl, 0)?;
55        self.set_axi_firewall_reg(AxiFirewallReg::MiSideUnblockControl, 1)
56    }
57
58    fn get_ip_version(&self) -> Result<u32> {
59        self.get_axi_firewall_reg(AxiFirewallReg::IpVersion)
60    }
61}