1use std::cmp::Ordering;
11use std::collections::btree_map::BTreeMap;
12use std::sync::{Arc, Barrier, Mutex, RwLock, Weak};
13use std::{error, fmt, result};
14
15#[allow(unused_variables)]
20pub trait BusDevice: Send {
21 fn read(&mut self, base: u64, offset: u64, data: &mut [u8]) {}
23 fn write(&mut self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
25 None
26 }
27}
28
29#[allow(unused_variables)]
31pub trait BusDeviceSync: Send + Sync {
32 fn read(&self, base: u64, offset: u64, data: &mut [u8]) {}
34 fn write(&self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
36 None
37 }
38}
39
40impl<B: BusDevice> BusDeviceSync for Mutex<B> {
41 fn read(&self, base: u64, offset: u64, data: &mut [u8]) {
43 self.lock()
44 .expect("Failed to acquire device lock")
45 .read(base, offset, data)
46 }
47 fn write(&self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
49 self.lock()
50 .expect("Failed to acquire device lock")
51 .write(base, offset, data)
52 }
53}
54
55#[derive(Debug)]
57pub enum BusError {
58 Overlap,
60 ZeroSizedRange,
62 MissingAddressRange,
64}
65
66pub type Result<T> = result::Result<T, BusError>;
68
69impl fmt::Display for BusError {
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 write!(f, "bus_error: {self:?}")
72 }
73}
74
75impl error::Error for BusError {}
76
77#[derive(Debug, Copy, Clone)]
82pub struct BusRange {
83 pub base: u64,
85 pub len: u64,
87}
88
89impl BusRange {
90 pub fn overlaps(&self, base: u64, len: u64) -> bool {
92 self.base < (base + len) && base < self.base + self.len
93 }
94}
95
96impl Eq for BusRange {}
97
98impl PartialEq for BusRange {
99 fn eq(&self, other: &BusRange) -> bool {
100 self.base == other.base
101 }
102}
103
104impl Ord for BusRange {
105 fn cmp(&self, other: &BusRange) -> Ordering {
106 self.base.cmp(&other.base)
107 }
108}
109
110impl PartialOrd for BusRange {
111 fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> {
112 Some(self.cmp(other))
113 }
114}
115
116#[derive(Default, Debug)]
121pub struct Bus {
122 devices: RwLock<BTreeMap<BusRange, Weak<dyn BusDeviceSync>>>,
123}
124
125impl Bus {
126 pub fn new() -> Bus {
128 Bus {
129 devices: RwLock::new(BTreeMap::new()),
130 }
131 }
132
133 fn first_before(&self, addr: u64) -> Option<(BusRange, Arc<dyn BusDeviceSync>)> {
134 let devices = self.devices.read().unwrap();
135 let (range, dev) = devices
136 .range(..=BusRange { base: addr, len: 1 })
137 .next_back()?;
138 dev.upgrade().map(|d| (*range, d.clone()))
139 }
140
141 #[allow(clippy::type_complexity)]
142 pub fn resolve(&self, addr: u64) -> Option<(u64, u64, Arc<dyn BusDeviceSync>)> {
144 if let Some((range, dev)) = self.first_before(addr) {
145 let offset = addr - range.base;
146 if offset < range.len {
147 return Some((range.base, offset, dev));
148 }
149 }
150 None
151 }
152
153 pub fn insert(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()> {
155 if len == 0 {
156 return Err(BusError::ZeroSizedRange);
157 }
158
159 if self
161 .devices
162 .read()
163 .unwrap()
164 .iter()
165 .any(|(range, _dev)| range.overlaps(base, len))
166 {
167 return Err(BusError::Overlap);
168 }
169
170 if self
171 .devices
172 .write()
173 .unwrap()
174 .insert(BusRange { base, len }, Arc::downgrade(&device))
175 .is_some()
176 {
177 return Err(BusError::Overlap);
178 }
179
180 Ok(())
181 }
182
183 pub fn remove(&self, base: u64, len: u64) -> Result<()> {
185 if len == 0 {
186 return Err(BusError::ZeroSizedRange);
187 }
188
189 let bus_range = BusRange { base, len };
190
191 if self.devices.write().unwrap().remove(&bus_range).is_none() {
192 return Err(BusError::MissingAddressRange);
193 }
194
195 Ok(())
196 }
197
198 pub fn remove_by_device(&self, device: &Arc<dyn BusDeviceSync>) -> Result<()> {
200 let mut device_list = self.devices.write().unwrap();
201 let mut remove_key_list = Vec::new();
202
203 for (key, value) in device_list.iter() {
204 if Arc::ptr_eq(&value.upgrade().unwrap(), device) {
205 remove_key_list.push(*key);
206 }
207 }
208
209 for key in remove_key_list.iter() {
210 device_list.remove(key);
211 }
212
213 Ok(())
214 }
215
216 pub fn update_range(
218 &self,
219 old_base: u64,
220 old_len: u64,
221 new_base: u64,
222 new_len: u64,
223 ) -> Result<()> {
224 let device = if let Some((_, _, dev)) = self.resolve(old_base) {
226 dev.clone()
227 } else {
228 return Err(BusError::MissingAddressRange);
229 };
230
231 self.remove(old_base, old_len)?;
233
234 self.insert(device, new_base, new_len)
236 }
237
238 pub fn read(&self, addr: u64, data: &mut [u8]) -> Result<()> {
242 if let Some((base, offset, dev)) = self.resolve(addr) {
243 dev.read(base, offset, data);
245 Ok(())
246 } else {
247 Err(BusError::MissingAddressRange)
248 }
249 }
250
251 pub fn write(&self, addr: u64, data: &[u8]) -> Result<Option<Arc<Barrier>>> {
255 if let Some((base, offset, dev)) = self.resolve(addr) {
256 Ok(dev.write(base, offset, data))
258 } else {
259 Err(BusError::MissingAddressRange)
260 }
261 }
262}
263
264#[cfg(test)]
265mod tests {
266 use super::*;
267
268 struct DummyDevice;
269 impl BusDeviceSync for DummyDevice {}
270
271 struct ConstantDevice;
272 impl BusDeviceSync for ConstantDevice {
273 #[allow(clippy::cast_possible_truncation)]
274 fn read(&self, _base: u64, offset: u64, data: &mut [u8]) {
275 for (i, v) in data.iter_mut().enumerate() {
276 *v = (offset as u8) + (i as u8);
277 }
278 }
279
280 #[allow(clippy::cast_possible_truncation)]
281 fn write(&self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> {
282 for (i, v) in data.iter().enumerate() {
283 assert_eq!(*v, (offset as u8) + (i as u8))
284 }
285
286 None
287 }
288 }
289
290 #[test]
291 fn bus_insert() {
292 let bus = Bus::new();
293 let dummy = Arc::new(DummyDevice);
294 bus.insert(dummy.clone(), 0x10, 0).unwrap_err();
295 bus.insert(dummy.clone(), 0x10, 0x10).unwrap();
296
297 let result = bus.insert(dummy.clone(), 0x0f, 0x10);
298 assert_eq!(format!("{result:?}"), "Err(Overlap)");
299
300 bus.insert(dummy.clone(), 0x10, 0x10).unwrap_err();
301 bus.insert(dummy.clone(), 0x10, 0x15).unwrap_err();
302 bus.insert(dummy.clone(), 0x12, 0x15).unwrap_err();
303 bus.insert(dummy.clone(), 0x12, 0x01).unwrap_err();
304 bus.insert(dummy.clone(), 0x0, 0x20).unwrap_err();
305 bus.insert(dummy.clone(), 0x20, 0x05).unwrap();
306 bus.insert(dummy.clone(), 0x25, 0x05).unwrap();
307 bus.insert(dummy, 0x0, 0x10).unwrap();
308 }
309
310 #[test]
311 fn bus_remove() {
312 let bus = Bus::new();
313 let dummy: Arc<dyn BusDeviceSync> = Arc::new(DummyDevice);
314
315 bus.remove(0x42, 0x0).unwrap_err();
316
317 bus.remove(0x13, 0x12).unwrap_err();
318
319 bus.insert(dummy.clone(), 0x13, 0x12).unwrap();
320 bus.remove(0x42, 0x42).unwrap_err();
321 bus.remove(0x13, 0x12).unwrap();
322
323 bus.insert(dummy.clone(), 0x16, 0x1).unwrap();
324 bus.remove_by_device(&dummy).unwrap();
325 bus.remove(0x16, 0x1).unwrap_err();
326 }
327
328 #[test]
329 #[allow(clippy::redundant_clone)]
330 fn bus_read_write() {
331 let bus = Bus::new();
332 let dummy = Arc::new(DummyDevice);
333 bus.insert(dummy.clone(), 0x10, 0x10).unwrap();
334 bus.read(0x10, &mut [0, 0, 0, 0]).unwrap();
335 bus.write(0x10, &[0, 0, 0, 0]).unwrap();
336 bus.read(0x11, &mut [0, 0, 0, 0]).unwrap();
337 bus.write(0x11, &[0, 0, 0, 0]).unwrap();
338 bus.read(0x16, &mut [0, 0, 0, 0]).unwrap();
339 bus.write(0x16, &[0, 0, 0, 0]).unwrap();
340 bus.read(0x20, &mut [0, 0, 0, 0]).unwrap_err();
341 bus.write(0x20, &[0, 0, 0, 0]).unwrap_err();
342 bus.read(0x06, &mut [0, 0, 0, 0]).unwrap_err();
343 bus.write(0x06, &[0, 0, 0, 0]).unwrap_err();
344 }
345
346 #[test]
347 #[allow(clippy::redundant_clone)]
348 fn bus_read_write_values() {
349 let bus = Bus::new();
350 let dummy = Arc::new(ConstantDevice);
351 bus.insert(dummy.clone(), 0x10, 0x10).unwrap();
352
353 let mut values = [0, 1, 2, 3];
354 bus.read(0x10, &mut values).unwrap();
355 assert_eq!(values, [0, 1, 2, 3]);
356 bus.write(0x10, &values).unwrap();
357 bus.read(0x15, &mut values).unwrap();
358 assert_eq!(values, [5, 6, 7, 8]);
359 bus.write(0x15, &values).unwrap();
360 }
361
362 #[test]
363 #[allow(clippy::redundant_clone)]
364 fn busrange_cmp() {
365 let range = BusRange { base: 0x10, len: 2 };
366 assert_eq!(range, BusRange { base: 0x10, len: 3 });
367 assert_eq!(range, BusRange { base: 0x10, len: 2 });
368
369 assert!(range < BusRange { base: 0x12, len: 1 });
370 assert!(range < BusRange { base: 0x12, len: 3 });
371
372 assert_eq!(range, range.clone());
373
374 let bus = Bus::new();
375 let mut data = [1, 2, 3, 4];
376 let device = Arc::new(DummyDevice);
377 bus.insert(device.clone(), 0x10, 0x10).unwrap();
378 bus.write(0x10, &data).unwrap();
379 bus.read(0x10, &mut data).unwrap();
380 assert_eq!(data, [1, 2, 3, 4]);
381 }
382
383 #[test]
384 fn bus_range_overlap() {
385 let a = BusRange {
386 base: 0x1000,
387 len: 0x400,
388 };
389 assert!(a.overlaps(0x1000, 0x400));
390 assert!(a.overlaps(0xf00, 0x400));
391 assert!(a.overlaps(0x1000, 0x01));
392 assert!(a.overlaps(0xfff, 0x02));
393 assert!(a.overlaps(0x1100, 0x100));
394 assert!(a.overlaps(0x13ff, 0x100));
395 assert!(!a.overlaps(0x1400, 0x100));
396 assert!(!a.overlaps(0xf00, 0x100));
397 }
398
399 #[test]
400 fn bus_update_range() {
401 let bus = Bus::new();
402 let dummy = Arc::new(DummyDevice);
403
404 bus.update_range(0x13, 0x12, 0x16, 0x1).unwrap_err();
405 bus.insert(dummy.clone(), 0x13, 12).unwrap();
406
407 bus.update_range(0x16, 0x1, 0x13, 0x12).unwrap_err();
408 bus.update_range(0x13, 0x12, 0x16, 0x1).unwrap();
409 }
410}