1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2017 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker //! Handles routing to devices in an address space. 6*bb4ee6a4SAndroid Build Coastguard Worker 7*bb4ee6a4SAndroid Build Coastguard Worker use std::cmp::Ord; 8*bb4ee6a4SAndroid Build Coastguard Worker use std::cmp::Ordering; 9*bb4ee6a4SAndroid Build Coastguard Worker use std::cmp::PartialEq; 10*bb4ee6a4SAndroid Build Coastguard Worker use std::cmp::PartialOrd; 11*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap; 12*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeSet; 13*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt; 14*bb4ee6a4SAndroid Build Coastguard Worker use std::result; 15*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc; 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::anyhow; 18*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Context; 19*bb4ee6a4SAndroid Build Coastguard Worker use base::debug; 20*bb4ee6a4SAndroid Build Coastguard Worker use base::error; 21*bb4ee6a4SAndroid Build Coastguard Worker use base::Event; 22*bb4ee6a4SAndroid Build Coastguard Worker use base::SharedMemory; 23*bb4ee6a4SAndroid Build Coastguard Worker use remain::sorted; 24*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 25*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 26*bb4ee6a4SAndroid Build Coastguard Worker use sync::Mutex; 27*bb4ee6a4SAndroid Build Coastguard Worker use thiserror::Error; 28*bb4ee6a4SAndroid Build Coastguard Worker 29*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 30*bb4ee6a4SAndroid Build Coastguard Worker use crate::bus_stats::BusOperation; 31*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 32*bb4ee6a4SAndroid Build Coastguard Worker use crate::BusStatistics; 33*bb4ee6a4SAndroid Build Coastguard Worker use crate::DeviceId; 34*bb4ee6a4SAndroid Build Coastguard Worker use crate::PciAddress; 35*bb4ee6a4SAndroid Build Coastguard Worker use crate::PciDevice; 36*bb4ee6a4SAndroid Build Coastguard Worker use crate::Suspendable; 37*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] 38*bb4ee6a4SAndroid Build Coastguard Worker use crate::VfioPlatformDevice; 39*bb4ee6a4SAndroid Build Coastguard Worker use crate::VirtioMmioDevice; 40*bb4ee6a4SAndroid Build Coastguard Worker 41*bb4ee6a4SAndroid Build Coastguard Worker /// Information about how a device was accessed. 42*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] 43*bb4ee6a4SAndroid Build Coastguard Worker pub struct BusAccessInfo { 44*bb4ee6a4SAndroid Build Coastguard Worker /// Offset from base address that the device was accessed at. 45*bb4ee6a4SAndroid Build Coastguard Worker pub offset: u64, 46*bb4ee6a4SAndroid Build Coastguard Worker /// Absolute address of the device's access in its address space. 47*bb4ee6a4SAndroid Build Coastguard Worker pub address: u64, 48*bb4ee6a4SAndroid Build Coastguard Worker /// ID of the entity requesting a device access, usually the VCPU id. 49*bb4ee6a4SAndroid Build Coastguard Worker pub id: usize, 50*bb4ee6a4SAndroid Build Coastguard Worker } 51*bb4ee6a4SAndroid Build Coastguard Worker 52*bb4ee6a4SAndroid Build Coastguard Worker // Implement `Display` for `MinMax`. 53*bb4ee6a4SAndroid Build Coastguard Worker impl std::fmt::Display for BusAccessInfo { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result54*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 55*bb4ee6a4SAndroid Build Coastguard Worker write!(f, "{:?}", self) 56*bb4ee6a4SAndroid Build Coastguard Worker } 57*bb4ee6a4SAndroid Build Coastguard Worker } 58*bb4ee6a4SAndroid Build Coastguard Worker 59*bb4ee6a4SAndroid Build Coastguard Worker /// Result of a write to a device's PCI configuration space. 60*bb4ee6a4SAndroid Build Coastguard Worker /// This value represents the state change(s) that occurred due to the write. 61*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, Default, PartialEq, Eq)] 62*bb4ee6a4SAndroid Build Coastguard Worker pub struct ConfigWriteResult { 63*bb4ee6a4SAndroid Build Coastguard Worker /// The BusRange in the vector will be removed from mmio_bus 64*bb4ee6a4SAndroid Build Coastguard Worker pub mmio_remove: Vec<BusRange>, 65*bb4ee6a4SAndroid Build Coastguard Worker 66*bb4ee6a4SAndroid Build Coastguard Worker /// The BusRange in the vector will be added into mmio_bus 67*bb4ee6a4SAndroid Build Coastguard Worker pub mmio_add: Vec<BusRange>, 68*bb4ee6a4SAndroid Build Coastguard Worker 69*bb4ee6a4SAndroid Build Coastguard Worker /// The BusRange in the vector will be removed from io_bus 70*bb4ee6a4SAndroid Build Coastguard Worker pub io_remove: Vec<BusRange>, 71*bb4ee6a4SAndroid Build Coastguard Worker 72*bb4ee6a4SAndroid Build Coastguard Worker /// The BusRange in the vector will be added into io_bus 73*bb4ee6a4SAndroid Build Coastguard Worker pub io_add: Vec<BusRange>, 74*bb4ee6a4SAndroid Build Coastguard Worker 75*bb4ee6a4SAndroid Build Coastguard Worker /// Device specified at PciAddress will be removed after this config write 76*bb4ee6a4SAndroid Build Coastguard Worker /// - `Vec<PciAddress>>`: specified device will be removed after this config write 77*bb4ee6a4SAndroid Build Coastguard Worker pub removed_pci_devices: Vec<PciAddress>, 78*bb4ee6a4SAndroid Build Coastguard Worker } 79*bb4ee6a4SAndroid Build Coastguard Worker 80*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)] 81*bb4ee6a4SAndroid Build Coastguard Worker pub enum BusType { 82*bb4ee6a4SAndroid Build Coastguard Worker Mmio, 83*bb4ee6a4SAndroid Build Coastguard Worker Io, 84*bb4ee6a4SAndroid Build Coastguard Worker } 85*bb4ee6a4SAndroid Build Coastguard Worker 86*bb4ee6a4SAndroid Build Coastguard Worker /// Trait for devices that respond to reads or writes in an arbitrary address space. 87*bb4ee6a4SAndroid Build Coastguard Worker /// 88*bb4ee6a4SAndroid Build Coastguard Worker /// The device does not care where it exists in address space as each method is only given an offset 89*bb4ee6a4SAndroid Build Coastguard Worker /// into its allocated portion of address space. 90*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused_variables)] 91*bb4ee6a4SAndroid Build Coastguard Worker pub trait BusDevice: Send + Suspendable { 92*bb4ee6a4SAndroid Build Coastguard Worker /// Returns a label suitable for debug output. debug_label(&self) -> String93*bb4ee6a4SAndroid Build Coastguard Worker fn debug_label(&self) -> String; 94*bb4ee6a4SAndroid Build Coastguard Worker /// Returns a unique id per device type suitable for metrics gathering. device_id(&self) -> DeviceId95*bb4ee6a4SAndroid Build Coastguard Worker fn device_id(&self) -> DeviceId; 96*bb4ee6a4SAndroid Build Coastguard Worker /// Reads at `offset` from this device read(&mut self, offset: BusAccessInfo, data: &mut [u8])97*bb4ee6a4SAndroid Build Coastguard Worker fn read(&mut self, offset: BusAccessInfo, data: &mut [u8]) {} 98*bb4ee6a4SAndroid Build Coastguard Worker /// Writes at `offset` into this device write(&mut self, offset: BusAccessInfo, data: &[u8])99*bb4ee6a4SAndroid Build Coastguard Worker fn write(&mut self, offset: BusAccessInfo, data: &[u8]) {} 100*bb4ee6a4SAndroid Build Coastguard Worker /// Sets a register in the configuration space. Only used by PCI. 101*bb4ee6a4SAndroid Build Coastguard Worker /// * `reg_idx` - The index of the config register to modify. 102*bb4ee6a4SAndroid Build Coastguard Worker /// * `offset` - Offset in to the register. config_register_write( &mut self, reg_idx: usize, offset: u64, data: &[u8], ) -> ConfigWriteResult103*bb4ee6a4SAndroid Build Coastguard Worker fn config_register_write( 104*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 105*bb4ee6a4SAndroid Build Coastguard Worker reg_idx: usize, 106*bb4ee6a4SAndroid Build Coastguard Worker offset: u64, 107*bb4ee6a4SAndroid Build Coastguard Worker data: &[u8], 108*bb4ee6a4SAndroid Build Coastguard Worker ) -> ConfigWriteResult { 109*bb4ee6a4SAndroid Build Coastguard Worker ConfigWriteResult { 110*bb4ee6a4SAndroid Build Coastguard Worker ..Default::default() 111*bb4ee6a4SAndroid Build Coastguard Worker } 112*bb4ee6a4SAndroid Build Coastguard Worker } 113*bb4ee6a4SAndroid Build Coastguard Worker /// Gets a register from the configuration space. Only used by PCI. 114*bb4ee6a4SAndroid Build Coastguard Worker /// * `reg_idx` - The index of the config register to read. config_register_read(&self, reg_idx: usize) -> u32115*bb4ee6a4SAndroid Build Coastguard Worker fn config_register_read(&self, reg_idx: usize) -> u32 { 116*bb4ee6a4SAndroid Build Coastguard Worker 0 117*bb4ee6a4SAndroid Build Coastguard Worker } 118*bb4ee6a4SAndroid Build Coastguard Worker /// Provides a memory region to back MMIO access to the configuration 119*bb4ee6a4SAndroid Build Coastguard Worker /// space. If the device can keep the memory region up to date, then it 120*bb4ee6a4SAndroid Build Coastguard Worker /// should return true, after which no more calls to config_register_read 121*bb4ee6a4SAndroid Build Coastguard Worker /// will be made. Otherwise the device should return false. 122*bb4ee6a4SAndroid Build Coastguard Worker /// 123*bb4ee6a4SAndroid Build Coastguard Worker /// The device must set the header type register (0x0E) before returning 124*bb4ee6a4SAndroid Build Coastguard Worker /// from this function, and must make no further modifications to it 125*bb4ee6a4SAndroid Build Coastguard Worker /// after returning. This is to allow the caller to manage the multi- 126*bb4ee6a4SAndroid Build Coastguard Worker /// function device bit without worrying about race conditions. 127*bb4ee6a4SAndroid Build Coastguard Worker /// 128*bb4ee6a4SAndroid Build Coastguard Worker /// * `shmem` - The shared memory to use for the configuration space. 129*bb4ee6a4SAndroid Build Coastguard Worker /// * `base` - The base address of the memory region in shmem. 130*bb4ee6a4SAndroid Build Coastguard Worker /// * `len` - The length of the memory region. init_pci_config_mapping(&mut self, shmem: &SharedMemory, base: usize, len: usize) -> bool131*bb4ee6a4SAndroid Build Coastguard Worker fn init_pci_config_mapping(&mut self, shmem: &SharedMemory, base: usize, len: usize) -> bool { 132*bb4ee6a4SAndroid Build Coastguard Worker false 133*bb4ee6a4SAndroid Build Coastguard Worker } 134*bb4ee6a4SAndroid Build Coastguard Worker /// Sets a register in the virtual config space. Only used by PCI. 135*bb4ee6a4SAndroid Build Coastguard Worker /// * `reg_idx` - The index of the config register to modify. 136*bb4ee6a4SAndroid Build Coastguard Worker /// * `value` - The value to be written. virtual_config_register_write(&mut self, reg_idx: usize, value: u32)137*bb4ee6a4SAndroid Build Coastguard Worker fn virtual_config_register_write(&mut self, reg_idx: usize, value: u32) {} 138*bb4ee6a4SAndroid Build Coastguard Worker /// Gets a register from the virtual config space. Only used by PCI. 139*bb4ee6a4SAndroid Build Coastguard Worker /// * `reg_idx` - The index of the config register to read. virtual_config_register_read(&self, reg_idx: usize) -> u32140*bb4ee6a4SAndroid Build Coastguard Worker fn virtual_config_register_read(&self, reg_idx: usize) -> u32 { 141*bb4ee6a4SAndroid Build Coastguard Worker 0 142*bb4ee6a4SAndroid Build Coastguard Worker } 143*bb4ee6a4SAndroid Build Coastguard Worker /// Invoked when the device is sandboxed. on_sandboxed(&mut self)144*bb4ee6a4SAndroid Build Coastguard Worker fn on_sandboxed(&mut self) {} 145*bb4ee6a4SAndroid Build Coastguard Worker 146*bb4ee6a4SAndroid Build Coastguard Worker /// Gets a list of all ranges registered by this BusDevice. get_ranges(&self) -> Vec<(BusRange, BusType)>147*bb4ee6a4SAndroid Build Coastguard Worker fn get_ranges(&self) -> Vec<(BusRange, BusType)> { 148*bb4ee6a4SAndroid Build Coastguard Worker Vec::new() 149*bb4ee6a4SAndroid Build Coastguard Worker } 150*bb4ee6a4SAndroid Build Coastguard Worker 151*bb4ee6a4SAndroid Build Coastguard Worker /// Invoked when the device is destroyed destroy_device(&mut self)152*bb4ee6a4SAndroid Build Coastguard Worker fn destroy_device(&mut self) {} 153*bb4ee6a4SAndroid Build Coastguard Worker 154*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the secondary bus number if this bus device is pci bridge is_bridge(&self) -> Option<u8>155*bb4ee6a4SAndroid Build Coastguard Worker fn is_bridge(&self) -> Option<u8> { 156*bb4ee6a4SAndroid Build Coastguard Worker None 157*bb4ee6a4SAndroid Build Coastguard Worker } 158*bb4ee6a4SAndroid Build Coastguard Worker } 159*bb4ee6a4SAndroid Build Coastguard Worker 160*bb4ee6a4SAndroid Build Coastguard Worker pub trait BusDeviceSync: BusDevice + Sync { read(&self, offset: BusAccessInfo, data: &mut [u8])161*bb4ee6a4SAndroid Build Coastguard Worker fn read(&self, offset: BusAccessInfo, data: &mut [u8]); write(&self, offset: BusAccessInfo, data: &[u8])162*bb4ee6a4SAndroid Build Coastguard Worker fn write(&self, offset: BusAccessInfo, data: &[u8]); snapshot_sync(&self) -> anyhow::Result<serde_json::Value>163*bb4ee6a4SAndroid Build Coastguard Worker fn snapshot_sync(&self) -> anyhow::Result<serde_json::Value> { 164*bb4ee6a4SAndroid Build Coastguard Worker Err(anyhow!( 165*bb4ee6a4SAndroid Build Coastguard Worker "snapshot_sync not implemented for {}", 166*bb4ee6a4SAndroid Build Coastguard Worker std::any::type_name::<Self>() 167*bb4ee6a4SAndroid Build Coastguard Worker )) 168*bb4ee6a4SAndroid Build Coastguard Worker } 169*bb4ee6a4SAndroid Build Coastguard Worker /// Load a saved snapshot of an image. restore_sync(&self, _data: serde_json::Value) -> anyhow::Result<()>170*bb4ee6a4SAndroid Build Coastguard Worker fn restore_sync(&self, _data: serde_json::Value) -> anyhow::Result<()> { 171*bb4ee6a4SAndroid Build Coastguard Worker Err(anyhow!( 172*bb4ee6a4SAndroid Build Coastguard Worker "restore_sync not implemented for {}", 173*bb4ee6a4SAndroid Build Coastguard Worker std::any::type_name::<Self>() 174*bb4ee6a4SAndroid Build Coastguard Worker )) 175*bb4ee6a4SAndroid Build Coastguard Worker } 176*bb4ee6a4SAndroid Build Coastguard Worker /// Stop all threads related to the device. 177*bb4ee6a4SAndroid Build Coastguard Worker /// Sleep should be idempotent. sleep_sync(&self) -> anyhow::Result<()>178*bb4ee6a4SAndroid Build Coastguard Worker fn sleep_sync(&self) -> anyhow::Result<()> { 179*bb4ee6a4SAndroid Build Coastguard Worker Err(anyhow!( 180*bb4ee6a4SAndroid Build Coastguard Worker "sleep_sync not implemented for {}", 181*bb4ee6a4SAndroid Build Coastguard Worker std::any::type_name::<Self>() 182*bb4ee6a4SAndroid Build Coastguard Worker )) 183*bb4ee6a4SAndroid Build Coastguard Worker } 184*bb4ee6a4SAndroid Build Coastguard Worker /// Create/Resume all threads related to the device. 185*bb4ee6a4SAndroid Build Coastguard Worker /// Wake should be idempotent. wake_sync(&self) -> anyhow::Result<()>186*bb4ee6a4SAndroid Build Coastguard Worker fn wake_sync(&self) -> anyhow::Result<()> { 187*bb4ee6a4SAndroid Build Coastguard Worker Err(anyhow!( 188*bb4ee6a4SAndroid Build Coastguard Worker "wake_sync not implemented for {}", 189*bb4ee6a4SAndroid Build Coastguard Worker std::any::type_name::<Self>() 190*bb4ee6a4SAndroid Build Coastguard Worker )) 191*bb4ee6a4SAndroid Build Coastguard Worker } 192*bb4ee6a4SAndroid Build Coastguard Worker } 193*bb4ee6a4SAndroid Build Coastguard Worker 194*bb4ee6a4SAndroid Build Coastguard Worker pub trait BusResumeDevice: Send { 195*bb4ee6a4SAndroid Build Coastguard Worker /// notify the devices which are invoked 196*bb4ee6a4SAndroid Build Coastguard Worker /// before the VM resumes form suspend. resume_imminent(&mut self)197*bb4ee6a4SAndroid Build Coastguard Worker fn resume_imminent(&mut self) {} 198*bb4ee6a4SAndroid Build Coastguard Worker } 199*bb4ee6a4SAndroid Build Coastguard Worker 200*bb4ee6a4SAndroid Build Coastguard Worker /// The key to identify hotplug device from host view. 201*bb4ee6a4SAndroid Build Coastguard Worker /// like host sysfs path for vfio pci device, host disk file 202*bb4ee6a4SAndroid Build Coastguard Worker /// path for virtio block device 203*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 204*bb4ee6a4SAndroid Build Coastguard Worker pub enum HotPlugKey { 205*bb4ee6a4SAndroid Build Coastguard Worker HostUpstreamPort { host_addr: PciAddress }, 206*bb4ee6a4SAndroid Build Coastguard Worker HostDownstreamPort { host_addr: PciAddress }, 207*bb4ee6a4SAndroid Build Coastguard Worker HostVfio { host_addr: PciAddress }, 208*bb4ee6a4SAndroid Build Coastguard Worker GuestDevice { guest_addr: PciAddress }, 209*bb4ee6a4SAndroid Build Coastguard Worker } 210*bb4ee6a4SAndroid Build Coastguard Worker 211*bb4ee6a4SAndroid Build Coastguard Worker /// Trait for devices that notify hotplug event into guest 212*bb4ee6a4SAndroid Build Coastguard Worker pub trait HotPlugBus: Send { 213*bb4ee6a4SAndroid Build Coastguard Worker /// Request hot plug event. Returns error if the request is not sent. Upon success, optionally 214*bb4ee6a4SAndroid Build Coastguard Worker /// returns an event, which is triggerred once when the guest OS completes the request (by 215*bb4ee6a4SAndroid Build Coastguard Worker /// sending PCI_EXP_SLTCTL_CCIE). Returns None if no such mechanism is provided. 216*bb4ee6a4SAndroid Build Coastguard Worker /// * 'addr' - the guest pci address for hotplug in device hot_plug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>217*bb4ee6a4SAndroid Build Coastguard Worker fn hot_plug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>; 218*bb4ee6a4SAndroid Build Coastguard Worker /// Request hot unplug event. Returns error if the request is not sent. Upon success, optionally 219*bb4ee6a4SAndroid Build Coastguard Worker /// returns an event, which is triggerred once when the guest OS completes the request (by 220*bb4ee6a4SAndroid Build Coastguard Worker /// sending PCI_EXP_SLTCTL_CCIE). Returns None if no such mechanism is provided. 221*bb4ee6a4SAndroid Build Coastguard Worker /// * 'addr' - the guest pci address for hotplug out device hot_unplug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>222*bb4ee6a4SAndroid Build Coastguard Worker fn hot_unplug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>; 223*bb4ee6a4SAndroid Build Coastguard Worker /// Get a notification event when the HotPlugBus is ready for hot plug commands. If the port is 224*bb4ee6a4SAndroid Build Coastguard Worker /// already ready, then the notification event is triggerred immediately. get_ready_notification(&mut self) -> anyhow::Result<Event>225*bb4ee6a4SAndroid Build Coastguard Worker fn get_ready_notification(&mut self) -> anyhow::Result<Event>; 226*bb4ee6a4SAndroid Build Coastguard Worker /// Check whether the hotplug bus is available to add the new device 227*bb4ee6a4SAndroid Build Coastguard Worker /// 228*bb4ee6a4SAndroid Build Coastguard Worker /// - 'None': hotplug bus isn't match with host pci device 229*bb4ee6a4SAndroid Build Coastguard Worker /// - 'Some(bus_num)': hotplug bus is match and put the device at bus_num is_match(&self, host_addr: PciAddress) -> Option<u8>230*bb4ee6a4SAndroid Build Coastguard Worker fn is_match(&self, host_addr: PciAddress) -> Option<u8>; 231*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the upstream PCI Address of the hotplug bus get_address(&self) -> Option<PciAddress>232*bb4ee6a4SAndroid Build Coastguard Worker fn get_address(&self) -> Option<PciAddress>; 233*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the secondary bus number of this bus get_secondary_bus_number(&self) -> Option<u8>234*bb4ee6a4SAndroid Build Coastguard Worker fn get_secondary_bus_number(&self) -> Option<u8>; 235*bb4ee6a4SAndroid Build Coastguard Worker /// Add hotplug device into this bus 236*bb4ee6a4SAndroid Build Coastguard Worker /// * 'hotplug_key' - the key to identify hotplug device from host view 237*bb4ee6a4SAndroid Build Coastguard Worker /// * 'guest_addr' - the guest pci address for hotplug device add_hotplug_device(&mut self, hotplug_key: HotPlugKey, guest_addr: PciAddress)238*bb4ee6a4SAndroid Build Coastguard Worker fn add_hotplug_device(&mut self, hotplug_key: HotPlugKey, guest_addr: PciAddress); 239*bb4ee6a4SAndroid Build Coastguard Worker /// get guest pci address from the specified hotplug_key get_hotplug_device(&self, hotplug_key: HotPlugKey) -> Option<PciAddress>240*bb4ee6a4SAndroid Build Coastguard Worker fn get_hotplug_device(&self, hotplug_key: HotPlugKey) -> Option<PciAddress>; 241*bb4ee6a4SAndroid Build Coastguard Worker /// Check whether this hotplug bus is empty is_empty(&self) -> bool242*bb4ee6a4SAndroid Build Coastguard Worker fn is_empty(&self) -> bool; 243*bb4ee6a4SAndroid Build Coastguard Worker /// Get hotplug key of this hotplug bus get_hotplug_key(&self) -> Option<HotPlugKey>244*bb4ee6a4SAndroid Build Coastguard Worker fn get_hotplug_key(&self) -> Option<HotPlugKey>; 245*bb4ee6a4SAndroid Build Coastguard Worker } 246*bb4ee6a4SAndroid Build Coastguard Worker 247*bb4ee6a4SAndroid Build Coastguard Worker /// Trait for generic device abstraction, that is, all devices that reside on BusDevice and want 248*bb4ee6a4SAndroid Build Coastguard Worker /// to be converted back to its original type. Each new foo device must provide 249*bb4ee6a4SAndroid Build Coastguard Worker /// as_foo_device() + as_foo_device_mut() + into_foo_device(), default impl methods return None. 250*bb4ee6a4SAndroid Build Coastguard Worker pub trait BusDeviceObj { as_pci_device(&self) -> Option<&dyn PciDevice>251*bb4ee6a4SAndroid Build Coastguard Worker fn as_pci_device(&self) -> Option<&dyn PciDevice> { 252*bb4ee6a4SAndroid Build Coastguard Worker None 253*bb4ee6a4SAndroid Build Coastguard Worker } as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice>254*bb4ee6a4SAndroid Build Coastguard Worker fn as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice> { 255*bb4ee6a4SAndroid Build Coastguard Worker None 256*bb4ee6a4SAndroid Build Coastguard Worker } into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>>257*bb4ee6a4SAndroid Build Coastguard Worker fn into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>> { 258*bb4ee6a4SAndroid Build Coastguard Worker None 259*bb4ee6a4SAndroid Build Coastguard Worker } 260*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] as_platform_device(&self) -> Option<&VfioPlatformDevice>261*bb4ee6a4SAndroid Build Coastguard Worker fn as_platform_device(&self) -> Option<&VfioPlatformDevice> { 262*bb4ee6a4SAndroid Build Coastguard Worker None 263*bb4ee6a4SAndroid Build Coastguard Worker } 264*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] as_platform_device_mut(&mut self) -> Option<&mut VfioPlatformDevice>265*bb4ee6a4SAndroid Build Coastguard Worker fn as_platform_device_mut(&mut self) -> Option<&mut VfioPlatformDevice> { 266*bb4ee6a4SAndroid Build Coastguard Worker None 267*bb4ee6a4SAndroid Build Coastguard Worker } 268*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))] into_platform_device(self: Box<Self>) -> Option<Box<VfioPlatformDevice>>269*bb4ee6a4SAndroid Build Coastguard Worker fn into_platform_device(self: Box<Self>) -> Option<Box<VfioPlatformDevice>> { 270*bb4ee6a4SAndroid Build Coastguard Worker None 271*bb4ee6a4SAndroid Build Coastguard Worker } as_virtio_mmio_device(&self) -> Option<&VirtioMmioDevice>272*bb4ee6a4SAndroid Build Coastguard Worker fn as_virtio_mmio_device(&self) -> Option<&VirtioMmioDevice> { 273*bb4ee6a4SAndroid Build Coastguard Worker None 274*bb4ee6a4SAndroid Build Coastguard Worker } as_virtio_mmio_device_mut(&mut self) -> Option<&mut VirtioMmioDevice>275*bb4ee6a4SAndroid Build Coastguard Worker fn as_virtio_mmio_device_mut(&mut self) -> Option<&mut VirtioMmioDevice> { 276*bb4ee6a4SAndroid Build Coastguard Worker None 277*bb4ee6a4SAndroid Build Coastguard Worker } into_virtio_mmio_device(self: Box<Self>) -> Option<Box<VirtioMmioDevice>>278*bb4ee6a4SAndroid Build Coastguard Worker fn into_virtio_mmio_device(self: Box<Self>) -> Option<Box<VirtioMmioDevice>> { 279*bb4ee6a4SAndroid Build Coastguard Worker None 280*bb4ee6a4SAndroid Build Coastguard Worker } 281*bb4ee6a4SAndroid Build Coastguard Worker } 282*bb4ee6a4SAndroid Build Coastguard Worker 283*bb4ee6a4SAndroid Build Coastguard Worker #[sorted] 284*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Error, Debug)] 285*bb4ee6a4SAndroid Build Coastguard Worker pub enum Error { 286*bb4ee6a4SAndroid Build Coastguard Worker #[error("Bus Range not found")] 287*bb4ee6a4SAndroid Build Coastguard Worker Empty, 288*bb4ee6a4SAndroid Build Coastguard Worker /// The insertion failed because the new device overlapped with an old device. 289*bb4ee6a4SAndroid Build Coastguard Worker #[error("new device {base},{len} overlaps with an old device {other_base},{other_len}")] 290*bb4ee6a4SAndroid Build Coastguard Worker Overlap { 291*bb4ee6a4SAndroid Build Coastguard Worker base: u64, 292*bb4ee6a4SAndroid Build Coastguard Worker len: u64, 293*bb4ee6a4SAndroid Build Coastguard Worker other_base: u64, 294*bb4ee6a4SAndroid Build Coastguard Worker other_len: u64, 295*bb4ee6a4SAndroid Build Coastguard Worker }, 296*bb4ee6a4SAndroid Build Coastguard Worker } 297*bb4ee6a4SAndroid Build Coastguard Worker 298*bb4ee6a4SAndroid Build Coastguard Worker pub type Result<T> = result::Result<T, Error>; 299*bb4ee6a4SAndroid Build Coastguard Worker 300*bb4ee6a4SAndroid Build Coastguard Worker /// Holds a base and length representing the address space occupied by a `BusDevice`. 301*bb4ee6a4SAndroid Build Coastguard Worker /// 302*bb4ee6a4SAndroid Build Coastguard Worker /// * base - The address at which the range start. 303*bb4ee6a4SAndroid Build Coastguard Worker /// * len - The length of the range in bytes. 304*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Serialize, Deserialize)] 305*bb4ee6a4SAndroid Build Coastguard Worker pub struct BusRange { 306*bb4ee6a4SAndroid Build Coastguard Worker pub base: u64, 307*bb4ee6a4SAndroid Build Coastguard Worker pub len: u64, 308*bb4ee6a4SAndroid Build Coastguard Worker } 309*bb4ee6a4SAndroid Build Coastguard Worker 310*bb4ee6a4SAndroid Build Coastguard Worker impl BusRange { 311*bb4ee6a4SAndroid Build Coastguard Worker /// Returns true if `addr` is within the range. contains(&self, addr: u64) -> bool312*bb4ee6a4SAndroid Build Coastguard Worker pub fn contains(&self, addr: u64) -> bool { 313*bb4ee6a4SAndroid Build Coastguard Worker self.base <= addr && addr < self.base.saturating_add(self.len) 314*bb4ee6a4SAndroid Build Coastguard Worker } 315*bb4ee6a4SAndroid Build Coastguard Worker 316*bb4ee6a4SAndroid Build Coastguard Worker /// Returns true if there is overlap with the given range. overlaps(&self, base: u64, len: u64) -> bool317*bb4ee6a4SAndroid Build Coastguard Worker pub fn overlaps(&self, base: u64, len: u64) -> bool { 318*bb4ee6a4SAndroid Build Coastguard Worker self.base < base.saturating_add(len) && base < self.base.saturating_add(self.len) 319*bb4ee6a4SAndroid Build Coastguard Worker } 320*bb4ee6a4SAndroid Build Coastguard Worker } 321*bb4ee6a4SAndroid Build Coastguard Worker 322*bb4ee6a4SAndroid Build Coastguard Worker impl Eq for BusRange {} 323*bb4ee6a4SAndroid Build Coastguard Worker 324*bb4ee6a4SAndroid Build Coastguard Worker impl PartialEq for BusRange { eq(&self, other: &BusRange) -> bool325*bb4ee6a4SAndroid Build Coastguard Worker fn eq(&self, other: &BusRange) -> bool { 326*bb4ee6a4SAndroid Build Coastguard Worker self.base == other.base 327*bb4ee6a4SAndroid Build Coastguard Worker } 328*bb4ee6a4SAndroid Build Coastguard Worker } 329*bb4ee6a4SAndroid Build Coastguard Worker 330*bb4ee6a4SAndroid Build Coastguard Worker impl Ord for BusRange { cmp(&self, other: &BusRange) -> Ordering331*bb4ee6a4SAndroid Build Coastguard Worker fn cmp(&self, other: &BusRange) -> Ordering { 332*bb4ee6a4SAndroid Build Coastguard Worker self.base.cmp(&other.base) 333*bb4ee6a4SAndroid Build Coastguard Worker } 334*bb4ee6a4SAndroid Build Coastguard Worker } 335*bb4ee6a4SAndroid Build Coastguard Worker 336*bb4ee6a4SAndroid Build Coastguard Worker impl PartialOrd for BusRange { partial_cmp(&self, other: &BusRange) -> Option<Ordering>337*bb4ee6a4SAndroid Build Coastguard Worker fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> { 338*bb4ee6a4SAndroid Build Coastguard Worker Some(self.cmp(other)) 339*bb4ee6a4SAndroid Build Coastguard Worker } 340*bb4ee6a4SAndroid Build Coastguard Worker } 341*bb4ee6a4SAndroid Build Coastguard Worker 342*bb4ee6a4SAndroid Build Coastguard Worker impl std::fmt::Debug for BusRange { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result343*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 344*bb4ee6a4SAndroid Build Coastguard Worker write!(f, "{:#x}..+{:#x}", self.base, self.len) 345*bb4ee6a4SAndroid Build Coastguard Worker } 346*bb4ee6a4SAndroid Build Coastguard Worker } 347*bb4ee6a4SAndroid Build Coastguard Worker 348*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone)] 349*bb4ee6a4SAndroid Build Coastguard Worker struct BusEntry { 350*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 351*bb4ee6a4SAndroid Build Coastguard Worker index: usize, 352*bb4ee6a4SAndroid Build Coastguard Worker device: BusDeviceEntry, 353*bb4ee6a4SAndroid Build Coastguard Worker } 354*bb4ee6a4SAndroid Build Coastguard Worker 355*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone)] 356*bb4ee6a4SAndroid Build Coastguard Worker enum BusDeviceEntry { 357*bb4ee6a4SAndroid Build Coastguard Worker OuterSync(Arc<Mutex<dyn BusDevice>>), 358*bb4ee6a4SAndroid Build Coastguard Worker InnerSync(Arc<dyn BusDeviceSync>), 359*bb4ee6a4SAndroid Build Coastguard Worker } 360*bb4ee6a4SAndroid Build Coastguard Worker 361*bb4ee6a4SAndroid Build Coastguard Worker /// A device container for routing reads and writes over some address space. 362*bb4ee6a4SAndroid Build Coastguard Worker /// 363*bb4ee6a4SAndroid Build Coastguard Worker /// This doesn't have any restrictions on what kind of device or address space this applies to. The 364*bb4ee6a4SAndroid Build Coastguard Worker /// only restriction is that no two devices can overlap in this address space. 365*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone)] 366*bb4ee6a4SAndroid Build Coastguard Worker pub struct Bus { 367*bb4ee6a4SAndroid Build Coastguard Worker devices: Arc<Mutex<BTreeMap<BusRange, BusEntry>>>, 368*bb4ee6a4SAndroid Build Coastguard Worker access_id: usize, 369*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 370*bb4ee6a4SAndroid Build Coastguard Worker pub stats: Arc<Mutex<BusStatistics>>, 371*bb4ee6a4SAndroid Build Coastguard Worker bus_type: BusType, 372*bb4ee6a4SAndroid Build Coastguard Worker } 373*bb4ee6a4SAndroid Build Coastguard Worker 374*bb4ee6a4SAndroid Build Coastguard Worker impl Bus { 375*bb4ee6a4SAndroid Build Coastguard Worker /// Constructs an a bus with an empty address space. new(bus_type: BusType) -> Bus376*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(bus_type: BusType) -> Bus { 377*bb4ee6a4SAndroid Build Coastguard Worker Bus { 378*bb4ee6a4SAndroid Build Coastguard Worker devices: Arc::new(Mutex::new(BTreeMap::new())), 379*bb4ee6a4SAndroid Build Coastguard Worker access_id: 0, 380*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 381*bb4ee6a4SAndroid Build Coastguard Worker stats: Arc::new(Mutex::new(BusStatistics::new())), 382*bb4ee6a4SAndroid Build Coastguard Worker bus_type, 383*bb4ee6a4SAndroid Build Coastguard Worker } 384*bb4ee6a4SAndroid Build Coastguard Worker } 385*bb4ee6a4SAndroid Build Coastguard Worker 386*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the bus type get_bus_type(&self) -> BusType387*bb4ee6a4SAndroid Build Coastguard Worker pub fn get_bus_type(&self) -> BusType { 388*bb4ee6a4SAndroid Build Coastguard Worker self.bus_type 389*bb4ee6a4SAndroid Build Coastguard Worker } 390*bb4ee6a4SAndroid Build Coastguard Worker 391*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the id that will be used for BusAccessInfo. set_access_id(&mut self, id: usize)392*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_access_id(&mut self, id: usize) { 393*bb4ee6a4SAndroid Build Coastguard Worker self.access_id = id; 394*bb4ee6a4SAndroid Build Coastguard Worker } 395*bb4ee6a4SAndroid Build Coastguard Worker first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)>396*bb4ee6a4SAndroid Build Coastguard Worker fn first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)> { 397*bb4ee6a4SAndroid Build Coastguard Worker let devices = self.devices.lock(); 398*bb4ee6a4SAndroid Build Coastguard Worker let (range, entry) = devices 399*bb4ee6a4SAndroid Build Coastguard Worker .range(..=BusRange { base: addr, len: 1 }) 400*bb4ee6a4SAndroid Build Coastguard Worker .next_back()?; 401*bb4ee6a4SAndroid Build Coastguard Worker Some((*range, entry.clone())) 402*bb4ee6a4SAndroid Build Coastguard Worker } 403*bb4ee6a4SAndroid Build Coastguard Worker get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)>404*bb4ee6a4SAndroid Build Coastguard Worker fn get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)> { 405*bb4ee6a4SAndroid Build Coastguard Worker if let Some((range, entry)) = self.first_before(addr) { 406*bb4ee6a4SAndroid Build Coastguard Worker let offset = addr - range.base; 407*bb4ee6a4SAndroid Build Coastguard Worker if offset < range.len { 408*bb4ee6a4SAndroid Build Coastguard Worker return Some((offset, addr, entry)); 409*bb4ee6a4SAndroid Build Coastguard Worker } 410*bb4ee6a4SAndroid Build Coastguard Worker } 411*bb4ee6a4SAndroid Build Coastguard Worker None 412*bb4ee6a4SAndroid Build Coastguard Worker } 413*bb4ee6a4SAndroid Build Coastguard Worker 414*bb4ee6a4SAndroid Build Coastguard Worker /// There is no unique ID for device instances. For now we use the Arc pointers to dedup them. 415*bb4ee6a4SAndroid Build Coastguard Worker /// 416*bb4ee6a4SAndroid Build Coastguard Worker /// See virtio-gpu for an example of a single device instance with multiple bus entries. 417*bb4ee6a4SAndroid Build Coastguard Worker /// 418*bb4ee6a4SAndroid Build Coastguard Worker /// TODO: Add a unique ID to BusDevice and use that instead of pointers. unique_devices(&self) -> Vec<BusDeviceEntry>419*bb4ee6a4SAndroid Build Coastguard Worker fn unique_devices(&self) -> Vec<BusDeviceEntry> { 420*bb4ee6a4SAndroid Build Coastguard Worker let mut seen_ptrs = BTreeSet::new(); 421*bb4ee6a4SAndroid Build Coastguard Worker self.devices 422*bb4ee6a4SAndroid Build Coastguard Worker .lock() 423*bb4ee6a4SAndroid Build Coastguard Worker .iter() 424*bb4ee6a4SAndroid Build Coastguard Worker .map(|(_, bus_entry)| bus_entry.device.clone()) 425*bb4ee6a4SAndroid Build Coastguard Worker .filter(|dev| match dev { 426*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::OuterSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8), 427*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::InnerSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8), 428*bb4ee6a4SAndroid Build Coastguard Worker }) 429*bb4ee6a4SAndroid Build Coastguard Worker .collect() 430*bb4ee6a4SAndroid Build Coastguard Worker } 431*bb4ee6a4SAndroid Build Coastguard Worker 432*bb4ee6a4SAndroid Build Coastguard Worker /// Same as `unique_devices`, but also calculates the "snapshot key" for each device. 433*bb4ee6a4SAndroid Build Coastguard Worker /// 434*bb4ee6a4SAndroid Build Coastguard Worker /// The keys are used to associate a particular device with data in a serialized snapshot. The 435*bb4ee6a4SAndroid Build Coastguard Worker /// keys need to be stable across multiple runs of the same crosvm binary. 436*bb4ee6a4SAndroid Build Coastguard Worker /// 437*bb4ee6a4SAndroid Build Coastguard Worker /// It is most convienent to calculate all the snapshot keys at once, because the keys are 438*bb4ee6a4SAndroid Build Coastguard Worker /// dependant on the order of devices on the bus. unique_devices_with_snapshot_key(&self) -> Vec<(String, BusDeviceEntry)>439*bb4ee6a4SAndroid Build Coastguard Worker fn unique_devices_with_snapshot_key(&self) -> Vec<(String, BusDeviceEntry)> { 440*bb4ee6a4SAndroid Build Coastguard Worker let mut next_ids = BTreeMap::<String, usize>::new(); 441*bb4ee6a4SAndroid Build Coastguard Worker let mut choose_key = |debug_label: String| -> String { 442*bb4ee6a4SAndroid Build Coastguard Worker let label = debug_label.replace(char::is_whitespace, "-"); 443*bb4ee6a4SAndroid Build Coastguard Worker let id = next_ids.entry(label.clone()).or_default(); 444*bb4ee6a4SAndroid Build Coastguard Worker let key = format!("{}-{}", label, id); 445*bb4ee6a4SAndroid Build Coastguard Worker *id += 1; 446*bb4ee6a4SAndroid Build Coastguard Worker key 447*bb4ee6a4SAndroid Build Coastguard Worker }; 448*bb4ee6a4SAndroid Build Coastguard Worker 449*bb4ee6a4SAndroid Build Coastguard Worker let mut result = Vec::new(); 450*bb4ee6a4SAndroid Build Coastguard Worker for device_entry in self.unique_devices() { 451*bb4ee6a4SAndroid Build Coastguard Worker let key = match &device_entry { 452*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::OuterSync(d) => choose_key(d.lock().debug_label()), 453*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::InnerSync(d) => choose_key(d.debug_label()), 454*bb4ee6a4SAndroid Build Coastguard Worker }; 455*bb4ee6a4SAndroid Build Coastguard Worker result.push((key, device_entry)); 456*bb4ee6a4SAndroid Build Coastguard Worker } 457*bb4ee6a4SAndroid Build Coastguard Worker result 458*bb4ee6a4SAndroid Build Coastguard Worker } 459*bb4ee6a4SAndroid Build Coastguard Worker sleep_devices(&self) -> anyhow::Result<()>460*bb4ee6a4SAndroid Build Coastguard Worker pub fn sleep_devices(&self) -> anyhow::Result<()> { 461*bb4ee6a4SAndroid Build Coastguard Worker for device_entry in self.unique_devices() { 462*bb4ee6a4SAndroid Build Coastguard Worker match device_entry { 463*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::OuterSync(dev) => { 464*bb4ee6a4SAndroid Build Coastguard Worker let mut dev = (*dev).lock(); 465*bb4ee6a4SAndroid Build Coastguard Worker debug!("Sleep on device: {}", dev.debug_label()); 466*bb4ee6a4SAndroid Build Coastguard Worker dev.sleep() 467*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| format!("failed to sleep {}", dev.debug_label()))?; 468*bb4ee6a4SAndroid Build Coastguard Worker } 469*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::InnerSync(dev) => { 470*bb4ee6a4SAndroid Build Coastguard Worker debug!("Sleep on device: {}", dev.debug_label()); 471*bb4ee6a4SAndroid Build Coastguard Worker dev.sleep_sync() 472*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| format!("failed to sleep {}", dev.debug_label()))?; 473*bb4ee6a4SAndroid Build Coastguard Worker } 474*bb4ee6a4SAndroid Build Coastguard Worker } 475*bb4ee6a4SAndroid Build Coastguard Worker } 476*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 477*bb4ee6a4SAndroid Build Coastguard Worker } 478*bb4ee6a4SAndroid Build Coastguard Worker wake_devices(&self) -> anyhow::Result<()>479*bb4ee6a4SAndroid Build Coastguard Worker pub fn wake_devices(&self) -> anyhow::Result<()> { 480*bb4ee6a4SAndroid Build Coastguard Worker for device_entry in self.unique_devices() { 481*bb4ee6a4SAndroid Build Coastguard Worker match device_entry { 482*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::OuterSync(dev) => { 483*bb4ee6a4SAndroid Build Coastguard Worker let mut dev = dev.lock(); 484*bb4ee6a4SAndroid Build Coastguard Worker debug!("Wake on device: {}", dev.debug_label()); 485*bb4ee6a4SAndroid Build Coastguard Worker dev.wake() 486*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| format!("failed to wake {}", dev.debug_label()))?; 487*bb4ee6a4SAndroid Build Coastguard Worker } 488*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::InnerSync(dev) => { 489*bb4ee6a4SAndroid Build Coastguard Worker debug!("Wake on device: {}", dev.debug_label()); 490*bb4ee6a4SAndroid Build Coastguard Worker dev.wake_sync() 491*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| format!("failed to wake {}", dev.debug_label()))?; 492*bb4ee6a4SAndroid Build Coastguard Worker } 493*bb4ee6a4SAndroid Build Coastguard Worker } 494*bb4ee6a4SAndroid Build Coastguard Worker } 495*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 496*bb4ee6a4SAndroid Build Coastguard Worker } 497*bb4ee6a4SAndroid Build Coastguard Worker snapshot_devices( &self, snapshot_writer: &vm_control::SnapshotWriter, ) -> anyhow::Result<()>498*bb4ee6a4SAndroid Build Coastguard Worker pub fn snapshot_devices( 499*bb4ee6a4SAndroid Build Coastguard Worker &self, 500*bb4ee6a4SAndroid Build Coastguard Worker snapshot_writer: &vm_control::SnapshotWriter, 501*bb4ee6a4SAndroid Build Coastguard Worker ) -> anyhow::Result<()> { 502*bb4ee6a4SAndroid Build Coastguard Worker for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() { 503*bb4ee6a4SAndroid Build Coastguard Worker match device_entry { 504*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::OuterSync(dev) => { 505*bb4ee6a4SAndroid Build Coastguard Worker let mut dev = dev.lock(); 506*bb4ee6a4SAndroid Build Coastguard Worker debug!("Snapshot on device: {}", dev.debug_label()); 507*bb4ee6a4SAndroid Build Coastguard Worker snapshot_writer.write_fragment( 508*bb4ee6a4SAndroid Build Coastguard Worker &snapshot_key, 509*bb4ee6a4SAndroid Build Coastguard Worker &(*dev) 510*bb4ee6a4SAndroid Build Coastguard Worker .snapshot() 511*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?, 512*bb4ee6a4SAndroid Build Coastguard Worker )?; 513*bb4ee6a4SAndroid Build Coastguard Worker } 514*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::InnerSync(dev) => { 515*bb4ee6a4SAndroid Build Coastguard Worker debug!("Snapshot on device: {}", dev.debug_label()); 516*bb4ee6a4SAndroid Build Coastguard Worker snapshot_writer.write_fragment( 517*bb4ee6a4SAndroid Build Coastguard Worker &snapshot_key, 518*bb4ee6a4SAndroid Build Coastguard Worker &dev.snapshot_sync() 519*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?, 520*bb4ee6a4SAndroid Build Coastguard Worker )?; 521*bb4ee6a4SAndroid Build Coastguard Worker } 522*bb4ee6a4SAndroid Build Coastguard Worker } 523*bb4ee6a4SAndroid Build Coastguard Worker } 524*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 525*bb4ee6a4SAndroid Build Coastguard Worker } 526*bb4ee6a4SAndroid Build Coastguard Worker restore_devices( &self, snapshot_reader: &vm_control::SnapshotReader, ) -> anyhow::Result<()>527*bb4ee6a4SAndroid Build Coastguard Worker pub fn restore_devices( 528*bb4ee6a4SAndroid Build Coastguard Worker &self, 529*bb4ee6a4SAndroid Build Coastguard Worker snapshot_reader: &vm_control::SnapshotReader, 530*bb4ee6a4SAndroid Build Coastguard Worker ) -> anyhow::Result<()> { 531*bb4ee6a4SAndroid Build Coastguard Worker let mut unused_keys: BTreeSet<String> = 532*bb4ee6a4SAndroid Build Coastguard Worker snapshot_reader.list_fragments()?.into_iter().collect(); 533*bb4ee6a4SAndroid Build Coastguard Worker for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() { 534*bb4ee6a4SAndroid Build Coastguard Worker unused_keys.remove(&snapshot_key); 535*bb4ee6a4SAndroid Build Coastguard Worker match device_entry { 536*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::OuterSync(dev) => { 537*bb4ee6a4SAndroid Build Coastguard Worker let mut dev = dev.lock(); 538*bb4ee6a4SAndroid Build Coastguard Worker debug!("Restore on device: {}", dev.debug_label()); 539*bb4ee6a4SAndroid Build Coastguard Worker dev.restore(snapshot_reader.read_fragment(&snapshot_key)?) 540*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| { 541*bb4ee6a4SAndroid Build Coastguard Worker format!("restore failed for device {}", dev.debug_label()) 542*bb4ee6a4SAndroid Build Coastguard Worker })?; 543*bb4ee6a4SAndroid Build Coastguard Worker } 544*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::InnerSync(dev) => { 545*bb4ee6a4SAndroid Build Coastguard Worker debug!("Restore on device: {}", dev.debug_label()); 546*bb4ee6a4SAndroid Build Coastguard Worker dev.restore_sync(snapshot_reader.read_fragment(&snapshot_key)?) 547*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| { 548*bb4ee6a4SAndroid Build Coastguard Worker format!("restore failed for device {}", dev.debug_label()) 549*bb4ee6a4SAndroid Build Coastguard Worker })?; 550*bb4ee6a4SAndroid Build Coastguard Worker } 551*bb4ee6a4SAndroid Build Coastguard Worker } 552*bb4ee6a4SAndroid Build Coastguard Worker } 553*bb4ee6a4SAndroid Build Coastguard Worker 554*bb4ee6a4SAndroid Build Coastguard Worker if !unused_keys.is_empty() { 555*bb4ee6a4SAndroid Build Coastguard Worker error!( 556*bb4ee6a4SAndroid Build Coastguard Worker "unused restore data in bus, devices might be missing: {:?}", 557*bb4ee6a4SAndroid Build Coastguard Worker unused_keys 558*bb4ee6a4SAndroid Build Coastguard Worker ); 559*bb4ee6a4SAndroid Build Coastguard Worker } 560*bb4ee6a4SAndroid Build Coastguard Worker 561*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 562*bb4ee6a4SAndroid Build Coastguard Worker } 563*bb4ee6a4SAndroid Build Coastguard Worker 564*bb4ee6a4SAndroid Build Coastguard Worker /// Puts the given device at the given address space. insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()>565*bb4ee6a4SAndroid Build Coastguard Worker pub fn insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()> { 566*bb4ee6a4SAndroid Build Coastguard Worker if len == 0 { 567*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Overlap { 568*bb4ee6a4SAndroid Build Coastguard Worker base, 569*bb4ee6a4SAndroid Build Coastguard Worker len, 570*bb4ee6a4SAndroid Build Coastguard Worker other_base: 0, 571*bb4ee6a4SAndroid Build Coastguard Worker other_len: 0, 572*bb4ee6a4SAndroid Build Coastguard Worker }); 573*bb4ee6a4SAndroid Build Coastguard Worker } 574*bb4ee6a4SAndroid Build Coastguard Worker 575*bb4ee6a4SAndroid Build Coastguard Worker // Reject all cases where the new device's range overlaps with an existing device. 576*bb4ee6a4SAndroid Build Coastguard Worker let mut devices = self.devices.lock(); 577*bb4ee6a4SAndroid Build Coastguard Worker devices.iter().try_for_each(|(range, _dev)| { 578*bb4ee6a4SAndroid Build Coastguard Worker if range.overlaps(base, len) { 579*bb4ee6a4SAndroid Build Coastguard Worker Err(Error::Overlap { 580*bb4ee6a4SAndroid Build Coastguard Worker base, 581*bb4ee6a4SAndroid Build Coastguard Worker len, 582*bb4ee6a4SAndroid Build Coastguard Worker other_base: range.base, 583*bb4ee6a4SAndroid Build Coastguard Worker other_len: range.len, 584*bb4ee6a4SAndroid Build Coastguard Worker }) 585*bb4ee6a4SAndroid Build Coastguard Worker } else { 586*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 587*bb4ee6a4SAndroid Build Coastguard Worker } 588*bb4ee6a4SAndroid Build Coastguard Worker })?; 589*bb4ee6a4SAndroid Build Coastguard Worker 590*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 591*bb4ee6a4SAndroid Build Coastguard Worker let name = device.lock().debug_label(); 592*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 593*bb4ee6a4SAndroid Build Coastguard Worker let device_id = device.lock().device_id(); 594*bb4ee6a4SAndroid Build Coastguard Worker if devices 595*bb4ee6a4SAndroid Build Coastguard Worker .insert( 596*bb4ee6a4SAndroid Build Coastguard Worker BusRange { base, len }, 597*bb4ee6a4SAndroid Build Coastguard Worker BusEntry { 598*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 599*bb4ee6a4SAndroid Build Coastguard Worker index: self 600*bb4ee6a4SAndroid Build Coastguard Worker .stats 601*bb4ee6a4SAndroid Build Coastguard Worker .lock() 602*bb4ee6a4SAndroid Build Coastguard Worker .next_device_index(name, device_id.into(), base, len), 603*bb4ee6a4SAndroid Build Coastguard Worker device: BusDeviceEntry::OuterSync(device), 604*bb4ee6a4SAndroid Build Coastguard Worker }, 605*bb4ee6a4SAndroid Build Coastguard Worker ) 606*bb4ee6a4SAndroid Build Coastguard Worker .is_some() 607*bb4ee6a4SAndroid Build Coastguard Worker { 608*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Overlap { 609*bb4ee6a4SAndroid Build Coastguard Worker base, 610*bb4ee6a4SAndroid Build Coastguard Worker len, 611*bb4ee6a4SAndroid Build Coastguard Worker other_base: base, 612*bb4ee6a4SAndroid Build Coastguard Worker other_len: len, 613*bb4ee6a4SAndroid Build Coastguard Worker }); 614*bb4ee6a4SAndroid Build Coastguard Worker } 615*bb4ee6a4SAndroid Build Coastguard Worker 616*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 617*bb4ee6a4SAndroid Build Coastguard Worker } 618*bb4ee6a4SAndroid Build Coastguard Worker 619*bb4ee6a4SAndroid Build Coastguard Worker /// Puts the given device that implements BusDeviceSync at the given address space. Devices 620*bb4ee6a4SAndroid Build Coastguard Worker /// that implement BusDeviceSync manage thread safety internally, and thus can be written to 621*bb4ee6a4SAndroid Build Coastguard Worker /// by multiple threads simultaneously. insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()>622*bb4ee6a4SAndroid Build Coastguard Worker pub fn insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()> { 623*bb4ee6a4SAndroid Build Coastguard Worker if len == 0 { 624*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Overlap { 625*bb4ee6a4SAndroid Build Coastguard Worker base, 626*bb4ee6a4SAndroid Build Coastguard Worker len, 627*bb4ee6a4SAndroid Build Coastguard Worker other_base: 0, 628*bb4ee6a4SAndroid Build Coastguard Worker other_len: 0, 629*bb4ee6a4SAndroid Build Coastguard Worker }); 630*bb4ee6a4SAndroid Build Coastguard Worker } 631*bb4ee6a4SAndroid Build Coastguard Worker 632*bb4ee6a4SAndroid Build Coastguard Worker // Reject all cases where the new device's range overlaps with an existing device. 633*bb4ee6a4SAndroid Build Coastguard Worker let mut devices = self.devices.lock(); 634*bb4ee6a4SAndroid Build Coastguard Worker devices.iter().try_for_each(|(range, _dev)| { 635*bb4ee6a4SAndroid Build Coastguard Worker if range.overlaps(base, len) { 636*bb4ee6a4SAndroid Build Coastguard Worker Err(Error::Overlap { 637*bb4ee6a4SAndroid Build Coastguard Worker base, 638*bb4ee6a4SAndroid Build Coastguard Worker len, 639*bb4ee6a4SAndroid Build Coastguard Worker other_base: range.base, 640*bb4ee6a4SAndroid Build Coastguard Worker other_len: range.len, 641*bb4ee6a4SAndroid Build Coastguard Worker }) 642*bb4ee6a4SAndroid Build Coastguard Worker } else { 643*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 644*bb4ee6a4SAndroid Build Coastguard Worker } 645*bb4ee6a4SAndroid Build Coastguard Worker })?; 646*bb4ee6a4SAndroid Build Coastguard Worker 647*bb4ee6a4SAndroid Build Coastguard Worker if devices 648*bb4ee6a4SAndroid Build Coastguard Worker .insert( 649*bb4ee6a4SAndroid Build Coastguard Worker BusRange { base, len }, 650*bb4ee6a4SAndroid Build Coastguard Worker BusEntry { 651*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 652*bb4ee6a4SAndroid Build Coastguard Worker index: self.stats.lock().next_device_index( 653*bb4ee6a4SAndroid Build Coastguard Worker device.debug_label(), 654*bb4ee6a4SAndroid Build Coastguard Worker device.device_id().into(), 655*bb4ee6a4SAndroid Build Coastguard Worker base, 656*bb4ee6a4SAndroid Build Coastguard Worker len, 657*bb4ee6a4SAndroid Build Coastguard Worker ), 658*bb4ee6a4SAndroid Build Coastguard Worker device: BusDeviceEntry::InnerSync(device), 659*bb4ee6a4SAndroid Build Coastguard Worker }, 660*bb4ee6a4SAndroid Build Coastguard Worker ) 661*bb4ee6a4SAndroid Build Coastguard Worker .is_some() 662*bb4ee6a4SAndroid Build Coastguard Worker { 663*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Overlap { 664*bb4ee6a4SAndroid Build Coastguard Worker base, 665*bb4ee6a4SAndroid Build Coastguard Worker len, 666*bb4ee6a4SAndroid Build Coastguard Worker other_base: base, 667*bb4ee6a4SAndroid Build Coastguard Worker other_len: len, 668*bb4ee6a4SAndroid Build Coastguard Worker }); 669*bb4ee6a4SAndroid Build Coastguard Worker } 670*bb4ee6a4SAndroid Build Coastguard Worker 671*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 672*bb4ee6a4SAndroid Build Coastguard Worker } 673*bb4ee6a4SAndroid Build Coastguard Worker 674*bb4ee6a4SAndroid Build Coastguard Worker /// Remove the given device at the given address space. remove(&self, base: u64, len: u64) -> Result<()>675*bb4ee6a4SAndroid Build Coastguard Worker pub fn remove(&self, base: u64, len: u64) -> Result<()> { 676*bb4ee6a4SAndroid Build Coastguard Worker if len == 0 { 677*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::Overlap { 678*bb4ee6a4SAndroid Build Coastguard Worker base, 679*bb4ee6a4SAndroid Build Coastguard Worker len, 680*bb4ee6a4SAndroid Build Coastguard Worker other_base: 0, 681*bb4ee6a4SAndroid Build Coastguard Worker other_len: 0, 682*bb4ee6a4SAndroid Build Coastguard Worker }); 683*bb4ee6a4SAndroid Build Coastguard Worker } 684*bb4ee6a4SAndroid Build Coastguard Worker 685*bb4ee6a4SAndroid Build Coastguard Worker let mut devices = self.devices.lock(); 686*bb4ee6a4SAndroid Build Coastguard Worker if devices 687*bb4ee6a4SAndroid Build Coastguard Worker .iter() 688*bb4ee6a4SAndroid Build Coastguard Worker .any(|(range, _dev)| range.base == base && range.len == len) 689*bb4ee6a4SAndroid Build Coastguard Worker { 690*bb4ee6a4SAndroid Build Coastguard Worker let ret = devices.remove(&BusRange { base, len }); 691*bb4ee6a4SAndroid Build Coastguard Worker if ret.is_some() { 692*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 693*bb4ee6a4SAndroid Build Coastguard Worker } else { 694*bb4ee6a4SAndroid Build Coastguard Worker Err(Error::Empty) 695*bb4ee6a4SAndroid Build Coastguard Worker } 696*bb4ee6a4SAndroid Build Coastguard Worker } else { 697*bb4ee6a4SAndroid Build Coastguard Worker Err(Error::Empty) 698*bb4ee6a4SAndroid Build Coastguard Worker } 699*bb4ee6a4SAndroid Build Coastguard Worker } 700*bb4ee6a4SAndroid Build Coastguard Worker 701*bb4ee6a4SAndroid Build Coastguard Worker /// Reads data from the device that owns the range containing `addr` and puts it into `data`. 702*bb4ee6a4SAndroid Build Coastguard Worker /// 703*bb4ee6a4SAndroid Build Coastguard Worker /// Returns true on success, otherwise `data` is filled with zeroes. read(&self, addr: u64, data: &mut [u8]) -> bool704*bb4ee6a4SAndroid Build Coastguard Worker pub fn read(&self, addr: u64, data: &mut [u8]) -> bool { 705*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 706*bb4ee6a4SAndroid Build Coastguard Worker let start = self.stats.lock().start_stat(); 707*bb4ee6a4SAndroid Build Coastguard Worker 708*bb4ee6a4SAndroid Build Coastguard Worker // Initialize `data` with all zeroes to ensure consistent results even if device `read()` 709*bb4ee6a4SAndroid Build Coastguard Worker // implementations don't always fill every byte. 710*bb4ee6a4SAndroid Build Coastguard Worker data.fill(0); 711*bb4ee6a4SAndroid Build Coastguard Worker 712*bb4ee6a4SAndroid Build Coastguard Worker let device_index = if let Some((offset, address, entry)) = self.get_device(addr) { 713*bb4ee6a4SAndroid Build Coastguard Worker let io = BusAccessInfo { 714*bb4ee6a4SAndroid Build Coastguard Worker address, 715*bb4ee6a4SAndroid Build Coastguard Worker offset, 716*bb4ee6a4SAndroid Build Coastguard Worker id: self.access_id, 717*bb4ee6a4SAndroid Build Coastguard Worker }; 718*bb4ee6a4SAndroid Build Coastguard Worker 719*bb4ee6a4SAndroid Build Coastguard Worker match &entry.device { 720*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::OuterSync(dev) => dev.lock().read(io, data), 721*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::InnerSync(dev) => dev.read(io, data), 722*bb4ee6a4SAndroid Build Coastguard Worker } 723*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 724*bb4ee6a4SAndroid Build Coastguard Worker let index = Some(entry.index); 725*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(not(feature = "stats"))] 726*bb4ee6a4SAndroid Build Coastguard Worker let index = Some(()); 727*bb4ee6a4SAndroid Build Coastguard Worker index 728*bb4ee6a4SAndroid Build Coastguard Worker } else { 729*bb4ee6a4SAndroid Build Coastguard Worker None 730*bb4ee6a4SAndroid Build Coastguard Worker }; 731*bb4ee6a4SAndroid Build Coastguard Worker 732*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 733*bb4ee6a4SAndroid Build Coastguard Worker if let Some(device_index) = device_index { 734*bb4ee6a4SAndroid Build Coastguard Worker self.stats 735*bb4ee6a4SAndroid Build Coastguard Worker .lock() 736*bb4ee6a4SAndroid Build Coastguard Worker .end_stat(BusOperation::Write, start, device_index); 737*bb4ee6a4SAndroid Build Coastguard Worker return true; 738*bb4ee6a4SAndroid Build Coastguard Worker } 739*bb4ee6a4SAndroid Build Coastguard Worker 740*bb4ee6a4SAndroid Build Coastguard Worker device_index.is_some() 741*bb4ee6a4SAndroid Build Coastguard Worker } 742*bb4ee6a4SAndroid Build Coastguard Worker 743*bb4ee6a4SAndroid Build Coastguard Worker /// Writes `data` to the device that owns the range containing `addr`. 744*bb4ee6a4SAndroid Build Coastguard Worker /// 745*bb4ee6a4SAndroid Build Coastguard Worker /// Returns true on success, otherwise `data` is untouched. write(&self, addr: u64, data: &[u8]) -> bool746*bb4ee6a4SAndroid Build Coastguard Worker pub fn write(&self, addr: u64, data: &[u8]) -> bool { 747*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 748*bb4ee6a4SAndroid Build Coastguard Worker let start = self.stats.lock().start_stat(); 749*bb4ee6a4SAndroid Build Coastguard Worker 750*bb4ee6a4SAndroid Build Coastguard Worker let device_index = if let Some((offset, address, entry)) = self.get_device(addr) { 751*bb4ee6a4SAndroid Build Coastguard Worker let io = BusAccessInfo { 752*bb4ee6a4SAndroid Build Coastguard Worker address, 753*bb4ee6a4SAndroid Build Coastguard Worker offset, 754*bb4ee6a4SAndroid Build Coastguard Worker id: self.access_id, 755*bb4ee6a4SAndroid Build Coastguard Worker }; 756*bb4ee6a4SAndroid Build Coastguard Worker 757*bb4ee6a4SAndroid Build Coastguard Worker match &entry.device { 758*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::OuterSync(dev) => dev.lock().write(io, data), 759*bb4ee6a4SAndroid Build Coastguard Worker BusDeviceEntry::InnerSync(dev) => dev.write(io, data), 760*bb4ee6a4SAndroid Build Coastguard Worker } 761*bb4ee6a4SAndroid Build Coastguard Worker 762*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 763*bb4ee6a4SAndroid Build Coastguard Worker let index = Some(entry.index); 764*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(not(feature = "stats"))] 765*bb4ee6a4SAndroid Build Coastguard Worker let index = Some(()); 766*bb4ee6a4SAndroid Build Coastguard Worker index 767*bb4ee6a4SAndroid Build Coastguard Worker } else { 768*bb4ee6a4SAndroid Build Coastguard Worker None 769*bb4ee6a4SAndroid Build Coastguard Worker }; 770*bb4ee6a4SAndroid Build Coastguard Worker 771*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "stats")] 772*bb4ee6a4SAndroid Build Coastguard Worker if let Some(device_index) = device_index { 773*bb4ee6a4SAndroid Build Coastguard Worker self.stats 774*bb4ee6a4SAndroid Build Coastguard Worker .lock() 775*bb4ee6a4SAndroid Build Coastguard Worker .end_stat(BusOperation::Write, start, device_index); 776*bb4ee6a4SAndroid Build Coastguard Worker } 777*bb4ee6a4SAndroid Build Coastguard Worker device_index.is_some() 778*bb4ee6a4SAndroid Build Coastguard Worker } 779*bb4ee6a4SAndroid Build Coastguard Worker } 780*bb4ee6a4SAndroid Build Coastguard Worker 781*bb4ee6a4SAndroid Build Coastguard Worker impl Default for Bus { default() -> Self782*bb4ee6a4SAndroid Build Coastguard Worker fn default() -> Self { 783*bb4ee6a4SAndroid Build Coastguard Worker Self::new(BusType::Io) 784*bb4ee6a4SAndroid Build Coastguard Worker } 785*bb4ee6a4SAndroid Build Coastguard Worker } 786*bb4ee6a4SAndroid Build Coastguard Worker 787*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)] 788*bb4ee6a4SAndroid Build Coastguard Worker mod tests { 789*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Result as AnyhowResult; 790*bb4ee6a4SAndroid Build Coastguard Worker 791*bb4ee6a4SAndroid Build Coastguard Worker use super::*; 792*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::CrosvmDeviceId; 793*bb4ee6a4SAndroid Build Coastguard Worker use crate::suspendable::Suspendable; 794*bb4ee6a4SAndroid Build Coastguard Worker use crate::suspendable_tests; 795*bb4ee6a4SAndroid Build Coastguard Worker 796*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)] 797*bb4ee6a4SAndroid Build Coastguard Worker struct DummyDevice; 798*bb4ee6a4SAndroid Build Coastguard Worker 799*bb4ee6a4SAndroid Build Coastguard Worker impl BusDevice for DummyDevice { device_id(&self) -> DeviceId800*bb4ee6a4SAndroid Build Coastguard Worker fn device_id(&self) -> DeviceId { 801*bb4ee6a4SAndroid Build Coastguard Worker CrosvmDeviceId::Cmos.into() 802*bb4ee6a4SAndroid Build Coastguard Worker } debug_label(&self) -> String803*bb4ee6a4SAndroid Build Coastguard Worker fn debug_label(&self) -> String { 804*bb4ee6a4SAndroid Build Coastguard Worker "dummy device".to_owned() 805*bb4ee6a4SAndroid Build Coastguard Worker } 806*bb4ee6a4SAndroid Build Coastguard Worker } 807*bb4ee6a4SAndroid Build Coastguard Worker 808*bb4ee6a4SAndroid Build Coastguard Worker impl Suspendable for DummyDevice { snapshot(&mut self) -> AnyhowResult<serde_json::Value>809*bb4ee6a4SAndroid Build Coastguard Worker fn snapshot(&mut self) -> AnyhowResult<serde_json::Value> { 810*bb4ee6a4SAndroid Build Coastguard Worker serde_json::to_value(self).context("error serializing") 811*bb4ee6a4SAndroid Build Coastguard Worker } 812*bb4ee6a4SAndroid Build Coastguard Worker restore(&mut self, data: serde_json::Value) -> AnyhowResult<()>813*bb4ee6a4SAndroid Build Coastguard Worker fn restore(&mut self, data: serde_json::Value) -> AnyhowResult<()> { 814*bb4ee6a4SAndroid Build Coastguard Worker *self = serde_json::from_value(data).context("error deserializing")?; 815*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 816*bb4ee6a4SAndroid Build Coastguard Worker } 817*bb4ee6a4SAndroid Build Coastguard Worker sleep(&mut self) -> AnyhowResult<()>818*bb4ee6a4SAndroid Build Coastguard Worker fn sleep(&mut self) -> AnyhowResult<()> { 819*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 820*bb4ee6a4SAndroid Build Coastguard Worker } 821*bb4ee6a4SAndroid Build Coastguard Worker wake(&mut self) -> AnyhowResult<()>822*bb4ee6a4SAndroid Build Coastguard Worker fn wake(&mut self) -> AnyhowResult<()> { 823*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 824*bb4ee6a4SAndroid Build Coastguard Worker } 825*bb4ee6a4SAndroid Build Coastguard Worker } 826*bb4ee6a4SAndroid Build Coastguard Worker 827*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)] 828*bb4ee6a4SAndroid Build Coastguard Worker struct ConstantDevice { 829*bb4ee6a4SAndroid Build Coastguard Worker uses_full_addr: bool, 830*bb4ee6a4SAndroid Build Coastguard Worker } 831*bb4ee6a4SAndroid Build Coastguard Worker 832*bb4ee6a4SAndroid Build Coastguard Worker impl BusDevice for ConstantDevice { device_id(&self) -> DeviceId833*bb4ee6a4SAndroid Build Coastguard Worker fn device_id(&self) -> DeviceId { 834*bb4ee6a4SAndroid Build Coastguard Worker CrosvmDeviceId::Cmos.into() 835*bb4ee6a4SAndroid Build Coastguard Worker } 836*bb4ee6a4SAndroid Build Coastguard Worker debug_label(&self) -> String837*bb4ee6a4SAndroid Build Coastguard Worker fn debug_label(&self) -> String { 838*bb4ee6a4SAndroid Build Coastguard Worker "constant device".to_owned() 839*bb4ee6a4SAndroid Build Coastguard Worker } 840*bb4ee6a4SAndroid Build Coastguard Worker read(&mut self, info: BusAccessInfo, data: &mut [u8])841*bb4ee6a4SAndroid Build Coastguard Worker fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) { 842*bb4ee6a4SAndroid Build Coastguard Worker let addr = if self.uses_full_addr { 843*bb4ee6a4SAndroid Build Coastguard Worker info.address 844*bb4ee6a4SAndroid Build Coastguard Worker } else { 845*bb4ee6a4SAndroid Build Coastguard Worker info.offset 846*bb4ee6a4SAndroid Build Coastguard Worker }; 847*bb4ee6a4SAndroid Build Coastguard Worker for (i, v) in data.iter_mut().enumerate() { 848*bb4ee6a4SAndroid Build Coastguard Worker *v = (addr as u8) + (i as u8); 849*bb4ee6a4SAndroid Build Coastguard Worker } 850*bb4ee6a4SAndroid Build Coastguard Worker } 851*bb4ee6a4SAndroid Build Coastguard Worker write(&mut self, info: BusAccessInfo, data: &[u8])852*bb4ee6a4SAndroid Build Coastguard Worker fn write(&mut self, info: BusAccessInfo, data: &[u8]) { 853*bb4ee6a4SAndroid Build Coastguard Worker let addr = if self.uses_full_addr { 854*bb4ee6a4SAndroid Build Coastguard Worker info.address 855*bb4ee6a4SAndroid Build Coastguard Worker } else { 856*bb4ee6a4SAndroid Build Coastguard Worker info.offset 857*bb4ee6a4SAndroid Build Coastguard Worker }; 858*bb4ee6a4SAndroid Build Coastguard Worker for (i, v) in data.iter().enumerate() { 859*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(*v, (addr as u8) + (i as u8)) 860*bb4ee6a4SAndroid Build Coastguard Worker } 861*bb4ee6a4SAndroid Build Coastguard Worker } 862*bb4ee6a4SAndroid Build Coastguard Worker } 863*bb4ee6a4SAndroid Build Coastguard Worker 864*bb4ee6a4SAndroid Build Coastguard Worker impl Suspendable for ConstantDevice { snapshot(&mut self) -> AnyhowResult<serde_json::Value>865*bb4ee6a4SAndroid Build Coastguard Worker fn snapshot(&mut self) -> AnyhowResult<serde_json::Value> { 866*bb4ee6a4SAndroid Build Coastguard Worker serde_json::to_value(self).context("error serializing") 867*bb4ee6a4SAndroid Build Coastguard Worker } 868*bb4ee6a4SAndroid Build Coastguard Worker restore(&mut self, data: serde_json::Value) -> AnyhowResult<()>869*bb4ee6a4SAndroid Build Coastguard Worker fn restore(&mut self, data: serde_json::Value) -> AnyhowResult<()> { 870*bb4ee6a4SAndroid Build Coastguard Worker *self = serde_json::from_value(data).context("error deserializing")?; 871*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 872*bb4ee6a4SAndroid Build Coastguard Worker } 873*bb4ee6a4SAndroid Build Coastguard Worker sleep(&mut self) -> AnyhowResult<()>874*bb4ee6a4SAndroid Build Coastguard Worker fn sleep(&mut self) -> AnyhowResult<()> { 875*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 876*bb4ee6a4SAndroid Build Coastguard Worker } 877*bb4ee6a4SAndroid Build Coastguard Worker wake(&mut self) -> AnyhowResult<()>878*bb4ee6a4SAndroid Build Coastguard Worker fn wake(&mut self) -> AnyhowResult<()> { 879*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 880*bb4ee6a4SAndroid Build Coastguard Worker } 881*bb4ee6a4SAndroid Build Coastguard Worker } 882*bb4ee6a4SAndroid Build Coastguard Worker modify_constant_device(constant: &mut ConstantDevice)883*bb4ee6a4SAndroid Build Coastguard Worker fn modify_constant_device(constant: &mut ConstantDevice) { 884*bb4ee6a4SAndroid Build Coastguard Worker constant.uses_full_addr = !constant.uses_full_addr; 885*bb4ee6a4SAndroid Build Coastguard Worker } 886*bb4ee6a4SAndroid Build Coastguard Worker 887*bb4ee6a4SAndroid Build Coastguard Worker #[test] bus_insert()888*bb4ee6a4SAndroid Build Coastguard Worker fn bus_insert() { 889*bb4ee6a4SAndroid Build Coastguard Worker let bus = Bus::new(BusType::Io); 890*bb4ee6a4SAndroid Build Coastguard Worker let dummy = Arc::new(Mutex::new(DummyDevice)); 891*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x10, 0).is_err()); 892*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 893*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err()); 894*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err()); 895*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err()); 896*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err()); 897*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err()); 898*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err()); 899*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok()); 900*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok()); 901*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy, 0x0, 0x10).is_ok()); 902*bb4ee6a4SAndroid Build Coastguard Worker } 903*bb4ee6a4SAndroid Build Coastguard Worker 904*bb4ee6a4SAndroid Build Coastguard Worker #[test] bus_insert_full_addr()905*bb4ee6a4SAndroid Build Coastguard Worker fn bus_insert_full_addr() { 906*bb4ee6a4SAndroid Build Coastguard Worker let bus = Bus::new(BusType::Io); 907*bb4ee6a4SAndroid Build Coastguard Worker let dummy = Arc::new(Mutex::new(DummyDevice)); 908*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x10, 0).is_err()); 909*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok()); 910*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err()); 911*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err()); 912*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err()); 913*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err()); 914*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err()); 915*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err()); 916*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok()); 917*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok()); 918*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy, 0x0, 0x10).is_ok()); 919*bb4ee6a4SAndroid Build Coastguard Worker } 920*bb4ee6a4SAndroid Build Coastguard Worker 921*bb4ee6a4SAndroid Build Coastguard Worker #[test] bus_read_write()922*bb4ee6a4SAndroid Build Coastguard Worker fn bus_read_write() { 923*bb4ee6a4SAndroid Build Coastguard Worker let bus = Bus::new(BusType::Io); 924*bb4ee6a4SAndroid Build Coastguard Worker let dummy = Arc::new(Mutex::new(DummyDevice)); 925*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy, 0x10, 0x10).is_ok()); 926*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.read(0x10, &mut [0, 0, 0, 0])); 927*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.write(0x10, &[0, 0, 0, 0])); 928*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.read(0x11, &mut [0, 0, 0, 0])); 929*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.write(0x11, &[0, 0, 0, 0])); 930*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.read(0x16, &mut [0, 0, 0, 0])); 931*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.write(0x16, &[0, 0, 0, 0])); 932*bb4ee6a4SAndroid Build Coastguard Worker assert!(!bus.read(0x20, &mut [0, 0, 0, 0])); 933*bb4ee6a4SAndroid Build Coastguard Worker assert!(!bus.write(0x20, &[0, 0, 0, 0])); 934*bb4ee6a4SAndroid Build Coastguard Worker assert!(!bus.read(0x06, &mut [0, 0, 0, 0])); 935*bb4ee6a4SAndroid Build Coastguard Worker assert!(!bus.write(0x06, &[0, 0, 0, 0])); 936*bb4ee6a4SAndroid Build Coastguard Worker } 937*bb4ee6a4SAndroid Build Coastguard Worker 938*bb4ee6a4SAndroid Build Coastguard Worker #[test] bus_read_write_values()939*bb4ee6a4SAndroid Build Coastguard Worker fn bus_read_write_values() { 940*bb4ee6a4SAndroid Build Coastguard Worker let bus = Bus::new(BusType::Io); 941*bb4ee6a4SAndroid Build Coastguard Worker let dummy = Arc::new(Mutex::new(ConstantDevice { 942*bb4ee6a4SAndroid Build Coastguard Worker uses_full_addr: false, 943*bb4ee6a4SAndroid Build Coastguard Worker })); 944*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy, 0x10, 0x10).is_ok()); 945*bb4ee6a4SAndroid Build Coastguard Worker 946*bb4ee6a4SAndroid Build Coastguard Worker let mut values = [0, 1, 2, 3]; 947*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.read(0x10, &mut values)); 948*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(values, [0, 1, 2, 3]); 949*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.write(0x10, &values)); 950*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.read(0x15, &mut values)); 951*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(values, [5, 6, 7, 8]); 952*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.write(0x15, &values)); 953*bb4ee6a4SAndroid Build Coastguard Worker } 954*bb4ee6a4SAndroid Build Coastguard Worker 955*bb4ee6a4SAndroid Build Coastguard Worker #[test] bus_read_write_full_addr_values()956*bb4ee6a4SAndroid Build Coastguard Worker fn bus_read_write_full_addr_values() { 957*bb4ee6a4SAndroid Build Coastguard Worker let bus = Bus::new(BusType::Io); 958*bb4ee6a4SAndroid Build Coastguard Worker let dummy = Arc::new(Mutex::new(ConstantDevice { 959*bb4ee6a4SAndroid Build Coastguard Worker uses_full_addr: true, 960*bb4ee6a4SAndroid Build Coastguard Worker })); 961*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.insert(dummy, 0x10, 0x10).is_ok()); 962*bb4ee6a4SAndroid Build Coastguard Worker 963*bb4ee6a4SAndroid Build Coastguard Worker let mut values = [0u8; 4]; 964*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.read(0x10, &mut values)); 965*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(values, [0x10, 0x11, 0x12, 0x13]); 966*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.write(0x10, &values)); 967*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.read(0x15, &mut values)); 968*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(values, [0x15, 0x16, 0x17, 0x18]); 969*bb4ee6a4SAndroid Build Coastguard Worker assert!(bus.write(0x15, &values)); 970*bb4ee6a4SAndroid Build Coastguard Worker } 971*bb4ee6a4SAndroid Build Coastguard Worker 972*bb4ee6a4SAndroid Build Coastguard Worker #[test] bus_read_no_device()973*bb4ee6a4SAndroid Build Coastguard Worker fn bus_read_no_device() { 974*bb4ee6a4SAndroid Build Coastguard Worker let bus = Bus::new(BusType::Io); 975*bb4ee6a4SAndroid Build Coastguard Worker 976*bb4ee6a4SAndroid Build Coastguard Worker // read() should return false, since there is no device at address 0x10, but it should 977*bb4ee6a4SAndroid Build Coastguard Worker // also fill the data with 0s. 978*bb4ee6a4SAndroid Build Coastguard Worker let mut values = [1, 2, 3, 4]; 979*bb4ee6a4SAndroid Build Coastguard Worker assert!(!bus.read(0x10, &mut values)); 980*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(values, [0, 0, 0, 0]); 981*bb4ee6a4SAndroid Build Coastguard Worker } 982*bb4ee6a4SAndroid Build Coastguard Worker 983*bb4ee6a4SAndroid Build Coastguard Worker suspendable_tests!( 984*bb4ee6a4SAndroid Build Coastguard Worker constant_device_true, 985*bb4ee6a4SAndroid Build Coastguard Worker ConstantDevice { 986*bb4ee6a4SAndroid Build Coastguard Worker uses_full_addr: true, 987*bb4ee6a4SAndroid Build Coastguard Worker }, 988*bb4ee6a4SAndroid Build Coastguard Worker modify_constant_device 989*bb4ee6a4SAndroid Build Coastguard Worker ); 990*bb4ee6a4SAndroid Build Coastguard Worker 991*bb4ee6a4SAndroid Build Coastguard Worker suspendable_tests!( 992*bb4ee6a4SAndroid Build Coastguard Worker constant_device_false, 993*bb4ee6a4SAndroid Build Coastguard Worker ConstantDevice { 994*bb4ee6a4SAndroid Build Coastguard Worker uses_full_addr: false, 995*bb4ee6a4SAndroid Build Coastguard Worker }, 996*bb4ee6a4SAndroid Build Coastguard Worker modify_constant_device 997*bb4ee6a4SAndroid Build Coastguard Worker ); 998*bb4ee6a4SAndroid Build Coastguard Worker 999*bb4ee6a4SAndroid Build Coastguard Worker #[test] bus_range_contains()1000*bb4ee6a4SAndroid Build Coastguard Worker fn bus_range_contains() { 1001*bb4ee6a4SAndroid Build Coastguard Worker let a = BusRange { 1002*bb4ee6a4SAndroid Build Coastguard Worker base: 0x1000, 1003*bb4ee6a4SAndroid Build Coastguard Worker len: 0x400, 1004*bb4ee6a4SAndroid Build Coastguard Worker }; 1005*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.contains(0x1000)); 1006*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.contains(0x13ff)); 1007*bb4ee6a4SAndroid Build Coastguard Worker assert!(!a.contains(0xfff)); 1008*bb4ee6a4SAndroid Build Coastguard Worker assert!(!a.contains(0x1400)); 1009*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.contains(0x1200)); 1010*bb4ee6a4SAndroid Build Coastguard Worker } 1011*bb4ee6a4SAndroid Build Coastguard Worker 1012*bb4ee6a4SAndroid Build Coastguard Worker #[test] bus_range_overlap()1013*bb4ee6a4SAndroid Build Coastguard Worker fn bus_range_overlap() { 1014*bb4ee6a4SAndroid Build Coastguard Worker let a = BusRange { 1015*bb4ee6a4SAndroid Build Coastguard Worker base: 0x1000, 1016*bb4ee6a4SAndroid Build Coastguard Worker len: 0x400, 1017*bb4ee6a4SAndroid Build Coastguard Worker }; 1018*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.overlaps(0x1000, 0x400)); 1019*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.overlaps(0xf00, 0x400)); 1020*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.overlaps(0x1000, 0x01)); 1021*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.overlaps(0xfff, 0x02)); 1022*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.overlaps(0x1100, 0x100)); 1023*bb4ee6a4SAndroid Build Coastguard Worker assert!(a.overlaps(0x13ff, 0x100)); 1024*bb4ee6a4SAndroid Build Coastguard Worker assert!(!a.overlaps(0x1400, 0x100)); 1025*bb4ee6a4SAndroid Build Coastguard Worker assert!(!a.overlaps(0xf00, 0x100)); 1026*bb4ee6a4SAndroid Build Coastguard Worker } 1027*bb4ee6a4SAndroid Build Coastguard Worker } 1028