Skip to main content

strat9_bus_drivers/
stm32_etzpc.rs

1use crate::{
2    BusChild, BusDriver, BusError, PowerState,
3    mmio::MmioRegion,
4    stm32_firewall::{FirewallController, FirewallType},
5};
6use alloc::{string::String, vec::Vec};
7
8const ETZPC_DECPROT: usize = 0x10;
9const ETZPC_HWCFGR: usize = 0x3F0;
10
11const ETZPC_PROT_A7NS: u32 = 0x3;
12
13const HWCFGR_NUM_TZMA_MASK: u32 = 0xFF;
14const HWCFGR_NUM_PER_SEC_MASK: u32 = 0xFF00;
15const HWCFGR_NUM_PER_SEC_SHIFT: u32 = 8;
16const HWCFGR_NUM_AHB_SEC_MASK: u32 = 0xFF0000;
17const HWCFGR_NUM_AHB_SEC_SHIFT: u32 = 16;
18
19const COMPATIBLE: &[&str] = &["st,stm32-etzpc"];
20
21pub struct Stm32Etzpc {
22    regs: MmioRegion,
23    num_per: u32,
24    num_master: u32,
25    power_state: PowerState,
26    children: Vec<BusChild>,
27}
28
29impl Stm32Etzpc {
30    /// Creates a new instance.
31    pub fn new() -> Self {
32        Self {
33            regs: MmioRegion::new(),
34            num_per: 0,
35            num_master: 0,
36            power_state: PowerState::Off,
37            children: Vec::new(),
38        }
39    }
40
41    /// Reads hwcfg.
42    fn read_hwcfg(&mut self) {
43        let hwcfg = self.regs.read32(ETZPC_HWCFGR);
44        self.num_per = (hwcfg & HWCFGR_NUM_PER_SEC_MASK) >> HWCFGR_NUM_PER_SEC_SHIFT;
45        self.num_master = (hwcfg & HWCFGR_NUM_AHB_SEC_MASK) >> HWCFGR_NUM_AHB_SEC_SHIFT;
46    }
47
48    /// Reads decprot.
49    fn read_decprot(&self, id: u32) -> u32 {
50        let reg_idx = id / 16;
51        let bit_offset = (id % 16) * 2;
52        let val = self.regs.read32(ETZPC_DECPROT + (reg_idx as usize) * 4);
53        (val >> bit_offset) & 0x3
54    }
55
56    /// Performs the add child operation.
57    pub fn add_child(&mut self, child: BusChild) {
58        self.children.push(child);
59    }
60}
61
62impl FirewallController for Stm32Etzpc {
63    /// Performs the name operation.
64    fn name(&self) -> &str {
65        "stm32-etzpc"
66    }
67
68    /// Performs the firewall type operation.
69    fn firewall_type(&self) -> FirewallType {
70        FirewallType::Peripheral
71    }
72
73    /// Performs the max entries operation.
74    fn max_entries(&self) -> u32 {
75        self.num_per + self.num_master
76    }
77
78    /// Performs the grant access operation.
79    fn grant_access(&self, firewall_id: u32) -> Result<(), BusError> {
80        if firewall_id >= self.num_per + self.num_master {
81            return Err(BusError::InvalidArgument);
82        }
83
84        let decprot = self.read_decprot(firewall_id);
85        if decprot != ETZPC_PROT_A7NS {
86            return Err(BusError::PermissionDenied);
87        }
88
89        Ok(())
90    }
91
92    /// Performs the release access operation.
93    fn release_access(&self, _firewall_id: u32) -> Result<(), BusError> {
94        Ok(())
95    }
96}
97
98impl BusDriver for Stm32Etzpc {
99    /// Performs the name operation.
100    fn name(&self) -> &str {
101        "stm32-etzpc"
102    }
103
104    /// Performs the compatible operation.
105    fn compatible(&self) -> &[&str] {
106        COMPATIBLE
107    }
108
109    /// Performs the init operation.
110    fn init(&mut self, base: usize) -> Result<(), BusError> {
111        self.regs.init(base, 0x400);
112        self.read_hwcfg();
113        self.power_state = PowerState::On;
114        Ok(())
115    }
116
117    /// Performs the shutdown operation.
118    fn shutdown(&mut self) -> Result<(), BusError> {
119        self.power_state = PowerState::Off;
120        Ok(())
121    }
122
123    /// Reads reg.
124    fn read_reg(&self, offset: usize) -> Result<u32, BusError> {
125        if !self.regs.is_valid() {
126            return Err(BusError::InitFailed);
127        }
128        Ok(self.regs.read32(offset))
129    }
130
131    /// Writes reg.
132    fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
133        if !self.regs.is_valid() {
134            return Err(BusError::InitFailed);
135        }
136        self.regs.write32(offset, value);
137        Ok(())
138    }
139
140    /// Performs the children operation.
141    fn children(&self) -> Vec<BusChild> {
142        self.children.clone()
143    }
144}