strat9_bus_drivers/
stm32_etzpc.rs1use 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 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 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 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 pub fn add_child(&mut self, child: BusChild) {
58 self.children.push(child);
59 }
60}
61
62impl FirewallController for Stm32Etzpc {
63 fn name(&self) -> &str {
65 "stm32-etzpc"
66 }
67
68 fn firewall_type(&self) -> FirewallType {
70 FirewallType::Peripheral
71 }
72
73 fn max_entries(&self) -> u32 {
75 self.num_per + self.num_master
76 }
77
78 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 fn release_access(&self, _firewall_id: u32) -> Result<(), BusError> {
94 Ok(())
95 }
96}
97
98impl BusDriver for Stm32Etzpc {
99 fn name(&self) -> &str {
101 "stm32-etzpc"
102 }
103
104 fn as_firewall(&self) -> Option<&dyn FirewallController> {
106 Some(self)
107 }
108
109 fn compatible(&self) -> &[&str] {
111 COMPATIBLE
112 }
113
114 fn init(&mut self, base: usize) -> Result<(), BusError> {
116 self.regs.init(base, 0x400);
117 self.read_hwcfg();
118 self.power_state = PowerState::On;
119 Ok(())
120 }
121
122 fn shutdown(&mut self) -> Result<(), BusError> {
124 self.power_state = PowerState::Off;
125 Ok(())
126 }
127
128 fn read_reg(&self, offset: usize) -> Result<u32, BusError> {
130 if !self.regs.is_valid() {
131 return Err(BusError::InitFailed);
132 }
133 self.regs.check_user_offset(offset)?;
134 Ok(self.regs.read32(offset))
135 }
136
137 fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
139 if !self.regs.is_valid() {
140 return Err(BusError::InitFailed);
141 }
142 self.regs.check_user_offset(offset)?;
143 self.regs.write32(offset, value);
144 Ok(())
145 }
146
147 fn children(&self) -> Vec<BusChild> {
149 self.children.clone()
150 }
151}