1 // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 // 4 // Portions Copyright 2017 The Chromium OS Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style license that can be 6 // found in the LICENSE-BSD-3-Clause file. 7 8 //! Handles routing to devices in an address space. 9 10 use std::cmp::{Ord, Ordering, PartialEq, PartialOrd}; 11 use std::collections::btree_map::BTreeMap; 12 use std::sync::{Arc, Barrier, Mutex, RwLock, Weak}; 13 use std::{convert, error, fmt, io, result}; 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 /// Reads at `offset` from this device 22 fn read(&mut self, base: u64, offset: u64, data: &mut [u8]) {} 23 /// Writes at `offset` into this device 24 fn write(&mut self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> { 25 None 26 } 27 } 28 29 #[derive(Debug)] 30 pub enum Error { 31 /// The insertion failed because the new device overlapped with an old device. 32 Overlap, 33 /// Failed to operate on zero sized range. 34 ZeroSizedRange, 35 /// Failed to find address range. 36 MissingAddressRange, 37 } 38 39 pub type Result<T> = result::Result<T, Error>; 40 41 impl fmt::Display for Error { 42 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 43 write!(f, "bus_error: {:?}", self) 44 } 45 } 46 47 impl error::Error for Error {} 48 49 impl convert::From<Error> for io::Error { 50 fn from(e: Error) -> Self { 51 io::Error::new(io::ErrorKind::Other, e) 52 } 53 } 54 55 /// Holds a base and length representing the address space occupied by a `BusDevice`. 56 /// 57 /// * base - The address at which the range start. 58 /// * len - The length of the range in bytes. 59 #[derive(Debug, Copy, Clone)] 60 pub struct BusRange { 61 pub base: u64, 62 pub len: u64, 63 } 64 65 impl BusRange { 66 /// Returns true if there is overlap with the given range. 67 pub fn overlaps(&self, base: u64, len: u64) -> bool { 68 self.base < (base + len) && base < self.base + self.len 69 } 70 } 71 72 impl Eq for BusRange {} 73 74 impl PartialEq for BusRange { 75 fn eq(&self, other: &BusRange) -> bool { 76 self.base == other.base 77 } 78 } 79 80 impl Ord for BusRange { 81 fn cmp(&self, other: &BusRange) -> Ordering { 82 self.base.cmp(&other.base) 83 } 84 } 85 86 impl PartialOrd for BusRange { 87 fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> { 88 self.base.partial_cmp(&other.base) 89 } 90 } 91 92 /// A device container for routing reads and writes over some address space. 93 /// 94 /// This doesn't have any restrictions on what kind of device or address space this applies to. The 95 /// only restriction is that no two devices can overlap in this address space. 96 #[derive(Default)] 97 pub struct Bus { 98 devices: RwLock<BTreeMap<BusRange, Weak<Mutex<dyn BusDevice>>>>, 99 } 100 101 impl Bus { 102 /// Constructs an a bus with an empty address space. 103 pub fn new() -> Bus { 104 Bus { 105 devices: RwLock::new(BTreeMap::new()), 106 } 107 } 108 109 fn first_before(&self, addr: u64) -> Option<(BusRange, Arc<Mutex<dyn BusDevice>>)> { 110 let devices = self.devices.read().unwrap(); 111 let (range, dev) = devices 112 .range(..=BusRange { base: addr, len: 1 }) 113 .rev() 114 .next()?; 115 dev.upgrade().map(|d| (*range, d.clone())) 116 } 117 118 #[allow(clippy::type_complexity)] 119 pub fn resolve(&self, addr: u64) -> Option<(u64, u64, Arc<Mutex<dyn BusDevice>>)> { 120 if let Some((range, dev)) = self.first_before(addr) { 121 let offset = addr - range.base; 122 if offset < range.len { 123 return Some((range.base, offset, dev)); 124 } 125 } 126 None 127 } 128 129 /// Puts the given device at the given address space. 130 pub fn insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()> { 131 if len == 0 { 132 return Err(Error::ZeroSizedRange); 133 } 134 135 // Reject all cases where the new device's range overlaps with an existing device. 136 if self 137 .devices 138 .read() 139 .unwrap() 140 .iter() 141 .any(|(range, _dev)| range.overlaps(base, len)) 142 { 143 return Err(Error::Overlap); 144 } 145 146 if self 147 .devices 148 .write() 149 .unwrap() 150 .insert(BusRange { base, len }, Arc::downgrade(&device)) 151 .is_some() 152 { 153 return Err(Error::Overlap); 154 } 155 156 Ok(()) 157 } 158 159 /// Removes the device at the given address space range. 160 pub fn remove(&self, base: u64, len: u64) -> Result<()> { 161 if len == 0 { 162 return Err(Error::ZeroSizedRange); 163 } 164 165 let bus_range = BusRange { base, len }; 166 167 if self.devices.write().unwrap().remove(&bus_range).is_none() { 168 return Err(Error::MissingAddressRange); 169 } 170 171 Ok(()) 172 } 173 174 /// Removes all entries referencing the given device. 175 pub fn remove_by_device(&self, device: &Arc<Mutex<dyn BusDevice>>) -> Result<()> { 176 let mut device_list = self.devices.write().unwrap(); 177 let mut remove_key_list = Vec::new(); 178 179 for (key, value) in device_list.iter() { 180 if Arc::ptr_eq(&value.upgrade().unwrap(), device) { 181 remove_key_list.push(*key); 182 } 183 } 184 185 for key in remove_key_list.iter() { 186 device_list.remove(key); 187 } 188 189 Ok(()) 190 } 191 192 /// Updates the address range for an existing device. 193 pub fn update_range( 194 &self, 195 old_base: u64, 196 old_len: u64, 197 new_base: u64, 198 new_len: u64, 199 ) -> Result<()> { 200 // Retrieve the device corresponding to the range 201 let device = if let Some((_, _, dev)) = self.resolve(old_base) { 202 dev.clone() 203 } else { 204 return Err(Error::MissingAddressRange); 205 }; 206 207 // Remove the old address range 208 self.remove(old_base, old_len)?; 209 210 // Insert the new address range 211 self.insert(device, new_base, new_len) 212 } 213 214 /// Reads data from the device that owns the range containing `addr` and puts it into `data`. 215 /// 216 /// Returns true on success, otherwise `data` is untouched. 217 pub fn read(&self, addr: u64, data: &mut [u8]) -> Result<()> { 218 if let Some((base, offset, dev)) = self.resolve(addr) { 219 // OK to unwrap as lock() failing is a serious error condition and should panic. 220 dev.lock() 221 .expect("Failed to acquire device lock") 222 .read(base, offset, data); 223 Ok(()) 224 } else { 225 Err(Error::MissingAddressRange) 226 } 227 } 228 229 /// Writes `data` to the device that owns the range containing `addr`. 230 /// 231 /// Returns true on success, otherwise `data` is untouched. 232 pub fn write(&self, addr: u64, data: &[u8]) -> Result<Option<Arc<Barrier>>> { 233 if let Some((base, offset, dev)) = self.resolve(addr) { 234 // OK to unwrap as lock() failing is a serious error condition and should panic. 235 Ok(dev 236 .lock() 237 .expect("Failed to acquire device lock") 238 .write(base, offset, data)) 239 } else { 240 Err(Error::MissingAddressRange) 241 } 242 } 243 } 244 245 #[cfg(test)] 246 mod tests { 247 use super::*; 248 249 struct DummyDevice; 250 impl BusDevice for DummyDevice {} 251 252 struct ConstantDevice; 253 impl BusDevice for ConstantDevice { 254 fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) { 255 for (i, v) in data.iter_mut().enumerate() { 256 *v = (offset as u8) + (i as u8); 257 } 258 } 259 260 fn write(&mut self, _base: u64, offset: u64, data: &[u8]) -> Option<Arc<Barrier>> { 261 for (i, v) in data.iter().enumerate() { 262 assert_eq!(*v, (offset as u8) + (i as u8)) 263 } 264 265 None 266 } 267 } 268 269 #[test] 270 fn bus_insert() { 271 let bus = Bus::new(); 272 let dummy = Arc::new(Mutex::new(DummyDevice)); 273 assert!(bus.insert(dummy.clone(), 0x10, 0).is_err()); 274 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 275 276 let result = bus.insert(dummy.clone(), 0x0f, 0x10); 277 assert!(result.is_err()); 278 assert_eq!(format!("{:?}", result), "Err(Overlap)"); 279 280 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err()); 281 assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err()); 282 assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err()); 283 assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err()); 284 assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err()); 285 assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok()); 286 assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok()); 287 assert!(bus.insert(dummy, 0x0, 0x10).is_ok()); 288 } 289 290 #[test] 291 #[allow(clippy::redundant_clone)] 292 fn bus_read_write() { 293 let bus = Bus::new(); 294 let dummy = Arc::new(Mutex::new(DummyDevice)); 295 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 296 assert!(bus.read(0x10, &mut [0, 0, 0, 0]).is_ok()); 297 assert!(bus.write(0x10, &[0, 0, 0, 0]).is_ok()); 298 assert!(bus.read(0x11, &mut [0, 0, 0, 0]).is_ok()); 299 assert!(bus.write(0x11, &[0, 0, 0, 0]).is_ok()); 300 assert!(bus.read(0x16, &mut [0, 0, 0, 0]).is_ok()); 301 assert!(bus.write(0x16, &[0, 0, 0, 0]).is_ok()); 302 assert!(bus.read(0x20, &mut [0, 0, 0, 0]).is_err()); 303 assert!(bus.write(0x20, &[0, 0, 0, 0]).is_err()); 304 assert!(bus.read(0x06, &mut [0, 0, 0, 0]).is_err()); 305 assert!(bus.write(0x06, &[0, 0, 0, 0]).is_err()); 306 } 307 308 #[test] 309 #[allow(clippy::redundant_clone)] 310 fn bus_read_write_values() { 311 let bus = Bus::new(); 312 let dummy = Arc::new(Mutex::new(ConstantDevice)); 313 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 314 315 let mut values = [0, 1, 2, 3]; 316 assert!(bus.read(0x10, &mut values).is_ok()); 317 assert_eq!(values, [0, 1, 2, 3]); 318 assert!(bus.write(0x10, &values).is_ok()); 319 assert!(bus.read(0x15, &mut values).is_ok()); 320 assert_eq!(values, [5, 6, 7, 8]); 321 assert!(bus.write(0x15, &values).is_ok()); 322 } 323 324 #[test] 325 #[allow(clippy::redundant_clone)] 326 fn busrange_cmp() { 327 let range = BusRange { base: 0x10, len: 2 }; 328 assert_eq!(range, BusRange { base: 0x10, len: 3 }); 329 assert_eq!(range, BusRange { base: 0x10, len: 2 }); 330 331 assert!(range < BusRange { base: 0x12, len: 1 }); 332 assert!(range < BusRange { base: 0x12, len: 3 }); 333 334 assert_eq!(range, range.clone()); 335 336 let bus = Bus::new(); 337 let mut data = [1, 2, 3, 4]; 338 let device = Arc::new(Mutex::new(DummyDevice)); 339 assert!(bus.insert(device.clone(), 0x10, 0x10).is_ok()); 340 assert!(bus.write(0x10, &data).is_ok()); 341 assert!(bus.read(0x10, &mut data).is_ok()); 342 assert_eq!(data, [1, 2, 3, 4]); 343 } 344 345 #[test] 346 fn bus_range_overlap() { 347 let a = BusRange { 348 base: 0x1000, 349 len: 0x400, 350 }; 351 assert!(a.overlaps(0x1000, 0x400)); 352 assert!(a.overlaps(0xf00, 0x400)); 353 assert!(a.overlaps(0x1000, 0x01)); 354 assert!(a.overlaps(0xfff, 0x02)); 355 assert!(a.overlaps(0x1100, 0x100)); 356 assert!(a.overlaps(0x13ff, 0x100)); 357 assert!(!a.overlaps(0x1400, 0x100)); 358 assert!(!a.overlaps(0xf00, 0x100)); 359 } 360 } 361