Skip to main content

strat9_bus_drivers/
stm32_rifsc.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 RIFSC_RISC_SECCFGR0: usize = 0x10;
9const RIFSC_RISC_PRIVCFGR0: usize = 0x30;
10const RIFSC_RISC_PER0_CIDCFGR: usize = 0x100;
11const RIFSC_RISC_PER0_SEMCR: usize = 0x104;
12const RIFSC_RISC_HWCFGR2: usize = 0xFEC;
13
14const CIDCFGR_STRIDE: usize = 0x08;
15const CIDCFGR_CFEN: u32 = 1 << 0;
16const CIDCFGR_SEMEN: u32 = 1 << 1;
17const CIDCFGR_SEMWL_MASK: u32 = 0xFF << 16;
18const CIDCFGR_SCID_MASK: u32 = 0x7 << 4;
19const CIDCFGR_SCID_SHIFT: u32 = 4;
20
21const SEMCR_MUTEX: u32 = 1 << 0;
22
23const HWCFGR2_CONF1_MASK: u32 = 0xFFFF;
24const HWCFGR2_CONF2_MASK: u32 = 0xFF << 16;
25const HWCFGR2_CONF2_SHIFT: u32 = 16;
26const HWCFGR2_CONF3_MASK: u32 = 0xFF << 24;
27const HWCFGR2_CONF3_SHIFT: u32 = 24;
28
29const EXPECTED_CID: u32 = 1;
30
31const COMPATIBLE: &[&str] = &["st,stm32mp25-rifsc", "st,stm32mp21-rifsc"];
32
33pub struct Stm32Rifsc {
34    regs: MmioRegion,
35    nb_risup: u32,
36    nb_rimu: u32,
37    nb_risal: u32,
38    power_state: PowerState,
39    children: Vec<BusChild>,
40}
41
42impl Stm32Rifsc {
43    /// Creates a new instance.
44    pub fn new() -> Self {
45        Self {
46            regs: MmioRegion::new(),
47            nb_risup: 0,
48            nb_rimu: 0,
49            nb_risal: 0,
50            power_state: PowerState::Off,
51            children: Vec::new(),
52        }
53    }
54
55    /// Reads hwcfg.
56    fn read_hwcfg(&mut self) {
57        let hwcfg = self.regs.read32(RIFSC_RISC_HWCFGR2);
58        self.nb_risup = hwcfg & HWCFGR2_CONF1_MASK;
59        self.nb_rimu = (hwcfg & HWCFGR2_CONF2_MASK) >> HWCFGR2_CONF2_SHIFT;
60        self.nb_risal = (hwcfg & HWCFGR2_CONF3_MASK) >> HWCFGR2_CONF3_SHIFT;
61    }
62
63    /// Returns whether secure.
64    fn is_secure(&self, id: u32) -> bool {
65        let reg_idx = id / 32;
66        let bit = id % 32;
67        let val = self
68            .regs
69            .read32(RIFSC_RISC_SECCFGR0 + (reg_idx as usize) * 4);
70        (val & (1 << bit)) != 0
71    }
72
73    /// Returns whether privileged.
74    fn is_privileged(&self, id: u32) -> bool {
75        let reg_idx = id / 32;
76        let bit = id % 32;
77        let val = self
78            .regs
79            .read32(RIFSC_RISC_PRIVCFGR0 + (reg_idx as usize) * 4);
80        (val & (1 << bit)) != 0
81    }
82
83    /// Performs the cidcfgr offset operation.
84    fn cidcfgr_offset(id: u32) -> usize {
85        RIFSC_RISC_PER0_CIDCFGR + (id as usize) * CIDCFGR_STRIDE
86    }
87
88    /// Performs the semcr offset operation.
89    fn semcr_offset(id: u32) -> usize {
90        RIFSC_RISC_PER0_SEMCR + (id as usize) * CIDCFGR_STRIDE
91    }
92
93    /// Performs the acquire semaphore operation.
94    fn acquire_semaphore(&self, id: u32) -> Result<(), BusError> {
95        let offset = Self::semcr_offset(id);
96        self.regs.write32(offset, SEMCR_MUTEX);
97        let val = self.regs.read32(offset);
98        if val & SEMCR_MUTEX != 0 {
99            Ok(())
100        } else {
101            Err(BusError::PermissionDenied)
102        }
103    }
104
105    /// Performs the release semaphore operation.
106    fn release_semaphore(&self, id: u32) {
107        let offset = Self::semcr_offset(id);
108        self.regs.write32(offset, 0);
109    }
110
111    /// Performs the add child operation.
112    pub fn add_child(&mut self, child: BusChild) {
113        self.children.push(child);
114    }
115}
116
117impl FirewallController for Stm32Rifsc {
118    /// Performs the name operation.
119    fn name(&self) -> &str {
120        "stm32-rifsc"
121    }
122
123    /// Performs the firewall type operation.
124    fn firewall_type(&self) -> FirewallType {
125        FirewallType::Peripheral
126    }
127
128    /// Performs the max entries operation.
129    fn max_entries(&self) -> u32 {
130        self.nb_risup
131    }
132
133    /// Performs the grant access operation.
134    fn grant_access(&self, firewall_id: u32) -> Result<(), BusError> {
135        if firewall_id >= self.nb_risup {
136            return Err(BusError::InvalidArgument);
137        }
138
139        if self.is_secure(firewall_id) {
140            return Err(BusError::PermissionDenied);
141        }
142
143        let cidcfgr = self.regs.read32(Self::cidcfgr_offset(firewall_id));
144
145        if cidcfgr & CIDCFGR_CFEN != 0 {
146            let scid = (cidcfgr & CIDCFGR_SCID_MASK) >> CIDCFGR_SCID_SHIFT;
147
148            if cidcfgr & CIDCFGR_SEMEN != 0 {
149                let semwl = (cidcfgr & CIDCFGR_SEMWL_MASK) >> 16;
150                if semwl & (1 << EXPECTED_CID) == 0 {
151                    return Err(BusError::PermissionDenied);
152                }
153                return self.acquire_semaphore(firewall_id);
154            }
155
156            if scid != EXPECTED_CID {
157                return Err(BusError::PermissionDenied);
158            }
159        }
160
161        Ok(())
162    }
163
164    /// Performs the release access operation.
165    fn release_access(&self, firewall_id: u32) -> Result<(), BusError> {
166        if firewall_id >= self.nb_risup {
167            return Err(BusError::InvalidArgument);
168        }
169
170        let cidcfgr = self.regs.read32(Self::cidcfgr_offset(firewall_id));
171        if cidcfgr & CIDCFGR_CFEN != 0 && cidcfgr & CIDCFGR_SEMEN != 0 {
172            self.release_semaphore(firewall_id);
173        }
174
175        Ok(())
176    }
177}
178
179impl BusDriver for Stm32Rifsc {
180    /// Performs the name operation.
181    fn name(&self) -> &str {
182        "stm32-rifsc"
183    }
184
185    /// Performs the compatible operation.
186    fn compatible(&self) -> &[&str] {
187        COMPATIBLE
188    }
189
190    /// Performs the init operation.
191    fn init(&mut self, base: usize) -> Result<(), BusError> {
192        self.regs.init(base, 0x1000);
193        self.read_hwcfg();
194        self.power_state = PowerState::On;
195        Ok(())
196    }
197
198    /// Performs the shutdown operation.
199    fn shutdown(&mut self) -> Result<(), BusError> {
200        self.power_state = PowerState::Off;
201        Ok(())
202    }
203
204    /// Reads reg.
205    fn read_reg(&self, offset: usize) -> Result<u32, BusError> {
206        if !self.regs.is_valid() {
207            return Err(BusError::InitFailed);
208        }
209        Ok(self.regs.read32(offset))
210    }
211
212    /// Writes reg.
213    fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
214        if !self.regs.is_valid() {
215            return Err(BusError::InitFailed);
216        }
217        self.regs.write32(offset, value);
218        Ok(())
219    }
220
221    /// Performs the children operation.
222    fn children(&self) -> Vec<BusChild> {
223        self.children.clone()
224    }
225}