• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //! Handles routing to devices in an address space.
6 
7 use std::cmp::{Ord, Ordering, PartialEq, PartialOrd};
8 use std::collections::btree_map::BTreeMap;
9 use std::fmt::{self, Display};
10 use std::result;
11 use std::sync::Arc;
12 
13 use sync::Mutex;
14 
15 /// Trait for devices that respond to reads or writes in an arbitrary address space.
16 ///
17 /// The device does not care where it exists in address space as each method is only given an offset
18 /// into its allocated portion of address space.
19 #[allow(unused_variables)]
20 pub trait BusDevice: Send {
21     /// Returns a label suitable for debug output.
debug_label(&self) -> String22     fn debug_label(&self) -> String;
23     /// Reads at `offset` from this device
read(&mut self, offset: u64, data: &mut [u8])24     fn read(&mut self, offset: u64, data: &mut [u8]) {}
25     /// Writes at `offset` into this device
write(&mut self, offset: u64, data: &[u8])26     fn write(&mut self, offset: u64, data: &[u8]) {}
27     /// Sets a register in the configuration space. Only used by PCI.
28     /// * `reg_idx` - The index of the config register to modify.
29     /// * `offset` - Offset in to the register.
config_register_write(&mut self, reg_idx: usize, offset: u64, data: &[u8])30     fn config_register_write(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {}
31     /// Gets a register from the configuration space. Only used by PCI.
32     /// * `reg_idx` - The index of the config register to read.
config_register_read(&self, reg_idx: usize) -> u3233     fn config_register_read(&self, reg_idx: usize) -> u32 {
34         0
35     }
36     /// Invoked when the device is sandboxed.
on_sandboxed(&mut self)37     fn on_sandboxed(&mut self) {}
38 }
39 
40 #[derive(Debug)]
41 pub enum Error {
42     /// The insertion failed because the new device overlapped with an old device.
43     Overlap,
44 }
45 
46 impl Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result47     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48         use self::Error::*;
49 
50         match self {
51             Overlap => write!(f, "new device overlaps with an old device"),
52         }
53     }
54 }
55 
56 pub type Result<T> = result::Result<T, Error>;
57 
58 /// Holds a base and length representing the address space occupied by a `BusDevice`.
59 ///
60 /// * base - The address at which the range start.
61 /// * len - The length of the range in bytes.
62 /// * full_addr - If true, return the full address from `get_device`, otherwise return the offset
63 ///               from `base`
64 #[derive(Debug, Copy, Clone)]
65 pub struct BusRange {
66     pub base: u64,
67     pub len: u64,
68     pub full_addr: bool,
69 }
70 
71 impl BusRange {
72     /// Returns true if `addr` is within the range.
contains(&self, addr: u64) -> bool73     pub fn contains(&self, addr: u64) -> bool {
74         self.base <= addr && addr < self.base + self.len
75     }
76 
77     /// Returns true if there is overlap with the given range.
overlaps(&self, base: u64, len: u64) -> bool78     pub fn overlaps(&self, base: u64, len: u64) -> bool {
79         self.base < (base + len) && base < self.base + self.len
80     }
81 }
82 
83 impl Eq for BusRange {}
84 
85 impl PartialEq for BusRange {
eq(&self, other: &BusRange) -> bool86     fn eq(&self, other: &BusRange) -> bool {
87         self.base == other.base
88     }
89 }
90 
91 impl Ord for BusRange {
cmp(&self, other: &BusRange) -> Ordering92     fn cmp(&self, other: &BusRange) -> Ordering {
93         self.base.cmp(&other.base)
94     }
95 }
96 
97 impl PartialOrd for BusRange {
partial_cmp(&self, other: &BusRange) -> Option<Ordering>98     fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> {
99         self.base.partial_cmp(&other.base)
100     }
101 }
102 
103 /// A device container for routing reads and writes over some address space.
104 ///
105 /// This doesn't have any restrictions on what kind of device or address space this applies to. The
106 /// only restriction is that no two devices can overlap in this address space.
107 #[derive(Clone)]
108 pub struct Bus {
109     devices: BTreeMap<BusRange, Arc<Mutex<dyn BusDevice>>>,
110 }
111 
112 impl Bus {
113     /// Constructs an a bus with an empty address space.
new() -> Bus114     pub fn new() -> Bus {
115         Bus {
116             devices: BTreeMap::new(),
117         }
118     }
119 
first_before(&self, addr: u64) -> Option<(BusRange, &Mutex<dyn BusDevice>)>120     fn first_before(&self, addr: u64) -> Option<(BusRange, &Mutex<dyn BusDevice>)> {
121         let (range, dev) = self
122             .devices
123             .range(
124                 ..=BusRange {
125                     base: addr,
126                     len: 1,
127                     full_addr: false,
128                 },
129             )
130             .rev()
131             .next()?;
132         Some((*range, dev))
133     }
134 
get_device(&self, addr: u64) -> Option<(u64, &Mutex<dyn BusDevice>)>135     fn get_device(&self, addr: u64) -> Option<(u64, &Mutex<dyn BusDevice>)> {
136         if let Some((range, dev)) = self.first_before(addr) {
137             let offset = addr - range.base;
138             if offset < range.len {
139                 if range.full_addr {
140                     return Some((addr, dev));
141                 } else {
142                     return Some((offset, dev));
143                 }
144             }
145         }
146         None
147     }
148 
149     /// Puts the given device at the given address space.
insert( &mut self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64, full_addr: bool, ) -> Result<()>150     pub fn insert(
151         &mut self,
152         device: Arc<Mutex<dyn BusDevice>>,
153         base: u64,
154         len: u64,
155         full_addr: bool,
156     ) -> Result<()> {
157         if len == 0 {
158             return Err(Error::Overlap);
159         }
160 
161         // Reject all cases where the new device's range overlaps with an existing device.
162         if self
163             .devices
164             .iter()
165             .any(|(range, _dev)| range.overlaps(base, len))
166         {
167             return Err(Error::Overlap);
168         }
169 
170         if self
171             .devices
172             .insert(
173                 BusRange {
174                     base,
175                     len,
176                     full_addr,
177                 },
178                 device,
179             )
180             .is_some()
181         {
182             return Err(Error::Overlap);
183         }
184 
185         Ok(())
186     }
187 
188     /// Reads data from the device that owns the range containing `addr` and puts it into `data`.
189     ///
190     /// Returns true on success, otherwise `data` is untouched.
read(&self, addr: u64, data: &mut [u8]) -> bool191     pub fn read(&self, addr: u64, data: &mut [u8]) -> bool {
192         if let Some((offset, dev)) = self.get_device(addr) {
193             dev.lock().read(offset, data);
194             true
195         } else {
196             false
197         }
198     }
199 
200     /// Writes `data` to the device that owns the range containing `addr`.
201     ///
202     /// Returns true on success, otherwise `data` is untouched.
write(&self, addr: u64, data: &[u8]) -> bool203     pub fn write(&self, addr: u64, data: &[u8]) -> bool {
204         if let Some((offset, dev)) = self.get_device(addr) {
205             dev.lock().write(offset, data);
206             true
207         } else {
208             false
209         }
210     }
211 }
212 
213 #[cfg(test)]
214 mod tests {
215     use super::*;
216 
217     struct DummyDevice;
218     impl BusDevice for DummyDevice {
debug_label(&self) -> String219         fn debug_label(&self) -> String {
220             "dummy device".to_owned()
221         }
222     }
223 
224     struct ConstantDevice;
225     impl BusDevice for ConstantDevice {
debug_label(&self) -> String226         fn debug_label(&self) -> String {
227             "constant device".to_owned()
228         }
229 
read(&mut self, offset: u64, data: &mut [u8])230         fn read(&mut self, offset: u64, data: &mut [u8]) {
231             for (i, v) in data.iter_mut().enumerate() {
232                 *v = (offset as u8) + (i as u8);
233             }
234         }
235 
write(&mut self, offset: u64, data: &[u8])236         fn write(&mut self, offset: u64, data: &[u8]) {
237             for (i, v) in data.iter().enumerate() {
238                 assert_eq!(*v, (offset as u8) + (i as u8))
239             }
240         }
241     }
242 
243     #[test]
bus_insert()244     fn bus_insert() {
245         let mut bus = Bus::new();
246         let dummy = Arc::new(Mutex::new(DummyDevice));
247         assert!(bus.insert(dummy.clone(), 0x10, 0, false).is_err());
248         assert!(bus.insert(dummy.clone(), 0x10, 0x10, false).is_ok());
249         assert!(bus.insert(dummy.clone(), 0x0f, 0x10, false).is_err());
250         assert!(bus.insert(dummy.clone(), 0x10, 0x10, false).is_err());
251         assert!(bus.insert(dummy.clone(), 0x10, 0x15, false).is_err());
252         assert!(bus.insert(dummy.clone(), 0x12, 0x15, false).is_err());
253         assert!(bus.insert(dummy.clone(), 0x12, 0x01, false).is_err());
254         assert!(bus.insert(dummy.clone(), 0x0, 0x20, false).is_err());
255         assert!(bus.insert(dummy.clone(), 0x20, 0x05, false).is_ok());
256         assert!(bus.insert(dummy.clone(), 0x25, 0x05, false).is_ok());
257         assert!(bus.insert(dummy.clone(), 0x0, 0x10, false).is_ok());
258     }
259 
260     #[test]
bus_insert_full_addr()261     fn bus_insert_full_addr() {
262         let mut bus = Bus::new();
263         let dummy = Arc::new(Mutex::new(DummyDevice));
264         assert!(bus.insert(dummy.clone(), 0x10, 0, true).is_err());
265         assert!(bus.insert(dummy.clone(), 0x10, 0x10, true).is_ok());
266         assert!(bus.insert(dummy.clone(), 0x0f, 0x10, true).is_err());
267         assert!(bus.insert(dummy.clone(), 0x10, 0x10, true).is_err());
268         assert!(bus.insert(dummy.clone(), 0x10, 0x15, true).is_err());
269         assert!(bus.insert(dummy.clone(), 0x12, 0x15, true).is_err());
270         assert!(bus.insert(dummy.clone(), 0x12, 0x01, true).is_err());
271         assert!(bus.insert(dummy.clone(), 0x0, 0x20, true).is_err());
272         assert!(bus.insert(dummy.clone(), 0x20, 0x05, true).is_ok());
273         assert!(bus.insert(dummy.clone(), 0x25, 0x05, true).is_ok());
274         assert!(bus.insert(dummy.clone(), 0x0, 0x10, true).is_ok());
275     }
276 
277     #[test]
bus_read_write()278     fn bus_read_write() {
279         let mut bus = Bus::new();
280         let dummy = Arc::new(Mutex::new(DummyDevice));
281         assert!(bus.insert(dummy.clone(), 0x10, 0x10, false).is_ok());
282         assert!(bus.read(0x10, &mut [0, 0, 0, 0]));
283         assert!(bus.write(0x10, &[0, 0, 0, 0]));
284         assert!(bus.read(0x11, &mut [0, 0, 0, 0]));
285         assert!(bus.write(0x11, &[0, 0, 0, 0]));
286         assert!(bus.read(0x16, &mut [0, 0, 0, 0]));
287         assert!(bus.write(0x16, &[0, 0, 0, 0]));
288         assert!(!bus.read(0x20, &mut [0, 0, 0, 0]));
289         assert!(!bus.write(0x20, &mut [0, 0, 0, 0]));
290         assert!(!bus.read(0x06, &mut [0, 0, 0, 0]));
291         assert!(!bus.write(0x06, &mut [0, 0, 0, 0]));
292     }
293 
294     #[test]
bus_read_write_values()295     fn bus_read_write_values() {
296         let mut bus = Bus::new();
297         let dummy = Arc::new(Mutex::new(ConstantDevice));
298         assert!(bus.insert(dummy.clone(), 0x10, 0x10, false).is_ok());
299 
300         let mut values = [0, 1, 2, 3];
301         assert!(bus.read(0x10, &mut values));
302         assert_eq!(values, [0, 1, 2, 3]);
303         assert!(bus.write(0x10, &values));
304         assert!(bus.read(0x15, &mut values));
305         assert_eq!(values, [5, 6, 7, 8]);
306         assert!(bus.write(0x15, &values));
307     }
308 
309     #[test]
bus_read_write_full_addr_values()310     fn bus_read_write_full_addr_values() {
311         let mut bus = Bus::new();
312         let dummy = Arc::new(Mutex::new(ConstantDevice));
313         assert!(bus.insert(dummy.clone(), 0x10, 0x10, true).is_ok());
314 
315         let mut values = [0u8; 4];
316         assert!(bus.read(0x10, &mut values));
317         assert_eq!(values, [0x10, 0x11, 0x12, 0x13]);
318         assert!(bus.write(0x10, &values));
319         assert!(bus.read(0x15, &mut values));
320         assert_eq!(values, [0x15, 0x16, 0x17, 0x18]);
321         assert!(bus.write(0x15, &values));
322     }
323 
324     #[test]
bus_range_contains()325     fn bus_range_contains() {
326         let a = BusRange {
327             base: 0x1000,
328             len: 0x400,
329             full_addr: false,
330         };
331         assert!(a.contains(0x1000));
332         assert!(a.contains(0x13ff));
333         assert!(!a.contains(0xfff));
334         assert!(!a.contains(0x1400));
335         assert!(a.contains(0x1200));
336     }
337 
338     #[test]
bus_range_overlap()339     fn bus_range_overlap() {
340         let a = BusRange {
341             base: 0x1000,
342             len: 0x400,
343             full_addr: false,
344         };
345         assert!(a.overlaps(0x1000, 0x400));
346         assert!(a.overlaps(0xf00, 0x400));
347         assert!(a.overlaps(0x1000, 0x01));
348         assert!(a.overlaps(0xfff, 0x02));
349         assert!(a.overlaps(0x1100, 0x100));
350         assert!(a.overlaps(0x13ff, 0x100));
351         assert!(!a.overlaps(0x1400, 0x100));
352         assert!(!a.overlaps(0xf00, 0x100));
353     }
354 }
355