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