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