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 compatible(&self) -> &[&str] {
106 COMPATIBLE
107 }
108
109 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 fn shutdown(&mut self) -> Result<(), BusError> {
119 self.power_state = PowerState::Off;
120 Ok(())
121 }
122
123 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 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 fn children(&self) -> Vec<BusChild> {
142 self.children.clone()
143 }
144}