Skip to main content

strat9_bus_drivers/
moxtet.rs

1use crate::{BusChild, BusDriver, BusError, PowerState};
2use alloc::{string::String, vec::Vec};
3
4const MAX_MODULES: usize = 6;
5
6const COMPATIBLE: &[&str] = &["cznic,moxtet"];
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum MoxtetModuleId {
10    Sfp,
11    Pci,
12    Topaz,
13    Peridot,
14    Usb3,
15    PcieBridge,
16    Unknown(u8),
17}
18
19impl MoxtetModuleId {
20    /// Builds this from raw.
21    pub fn from_raw(raw: u8) -> Self {
22        match raw & 0x0F {
23            0x01 => MoxtetModuleId::Sfp,
24            0x02 => MoxtetModuleId::Pci,
25            0x03 => MoxtetModuleId::Topaz,
26            0x04 => MoxtetModuleId::Peridot,
27            0x05 => MoxtetModuleId::Usb3,
28            0x06 => MoxtetModuleId::PcieBridge,
29            other => MoxtetModuleId::Unknown(other),
30        }
31    }
32
33    /// Performs the name operation.
34    pub fn name(&self) -> &'static str {
35        match self {
36            MoxtetModuleId::Sfp => "sfp",
37            MoxtetModuleId::Pci => "pci",
38            MoxtetModuleId::Topaz => "topaz",
39            MoxtetModuleId::Peridot => "peridot",
40            MoxtetModuleId::Usb3 => "usb3",
41            MoxtetModuleId::PcieBridge => "pcie-bridge",
42            MoxtetModuleId::Unknown(_) => "unknown",
43        }
44    }
45}
46
47pub struct MoxtetModule {
48    pub id: MoxtetModuleId,
49    pub index: u8,
50}
51
52pub struct Moxtet {
53    modules: Vec<MoxtetModule>,
54    module_count: usize,
55    tx_buf: [u8; MAX_MODULES + 1],
56    rx_buf: [u8; MAX_MODULES + 1],
57    irq_mask: [bool; MAX_MODULES],
58    power_state: PowerState,
59}
60
61impl Moxtet {
62    /// Creates a new instance.
63    pub fn new() -> Self {
64        Self {
65            modules: Vec::new(),
66            module_count: 0,
67            tx_buf: [0; MAX_MODULES + 1],
68            rx_buf: [0; MAX_MODULES + 1],
69            irq_mask: [false; MAX_MODULES],
70            power_state: PowerState::Off,
71        }
72    }
73
74    /// Performs the discover topology operation.
75    pub fn discover_topology(&mut self, spi_data: &[u8]) {
76        self.modules.clear();
77        self.module_count = 0;
78
79        for (i, &byte) in spi_data.iter().enumerate().skip(1) {
80            if i > MAX_MODULES {
81                break;
82            }
83            let id = MoxtetModuleId::from_raw(byte);
84            self.modules.push(MoxtetModule {
85                id,
86                index: (i - 1) as u8,
87            });
88            self.module_count = i;
89        }
90    }
91
92    /// Performs the module read operation.
93    pub fn module_read(&self, index: usize) -> Result<u8, BusError> {
94        if index >= self.module_count {
95            return Err(BusError::DeviceNotFound);
96        }
97        Ok(self.rx_buf[index + 1])
98    }
99
100    /// Performs the module write operation.
101    pub fn module_write(&mut self, index: usize, value: u8) -> Result<(), BusError> {
102        if index >= self.module_count {
103            return Err(BusError::DeviceNotFound);
104        }
105        self.tx_buf[index + 1] = value;
106        Ok(())
107    }
108
109    /// Sets irq mask.
110    pub fn set_irq_mask(&mut self, index: usize, masked: bool) {
111        if index < MAX_MODULES {
112            self.irq_mask[index] = masked;
113        }
114    }
115}
116
117impl BusDriver for Moxtet {
118    /// Performs the name operation.
119    fn name(&self) -> &str {
120        "moxtet"
121    }
122
123    /// Performs the compatible operation.
124    fn compatible(&self) -> &[&str] {
125        COMPATIBLE
126    }
127
128    /// Performs the init operation.
129    fn init(&mut self, _base: usize) -> Result<(), BusError> {
130        self.power_state = PowerState::On;
131        Ok(())
132    }
133
134    /// Performs the shutdown operation.
135    fn shutdown(&mut self) -> Result<(), BusError> {
136        self.power_state = PowerState::Off;
137        Ok(())
138    }
139
140    /// Reads reg.
141    fn read_reg(&self, offset: usize) -> Result<u32, BusError> {
142        self.module_read(offset).map(|v| v as u32)
143    }
144
145    /// Writes reg.
146    fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
147        self.module_write(offset, value as u8)
148    }
149
150    /// Performs the children operation.
151    fn children(&self) -> Vec<BusChild> {
152        self.modules
153            .iter()
154            .map(|m| BusChild {
155                name: String::from(m.id.name()),
156                base_addr: m.index as u64,
157                size: 1,
158            })
159            .collect()
160    }
161
162    /// Handles irq.
163    fn handle_irq(&mut self) -> bool {
164        for i in 0..self.module_count {
165            if self.irq_mask[i] {
166                continue;
167            }
168            let status = self.rx_buf[i + 1];
169            if status & 0xF0 != 0 {
170                return true;
171            }
172        }
173        false
174    }
175}