1use std::cmp::Ord;
8use std::cmp::Ordering;
9use std::cmp::PartialEq;
10use std::cmp::PartialOrd;
11use std::collections::BTreeMap;
12use std::collections::BTreeSet;
13use std::fmt;
14use std::result;
15use std::sync::Arc;
16
17use anyhow::anyhow;
18use anyhow::Context;
19use base::debug;
20use base::error;
21use base::Event;
22use base::SharedMemory;
23use remain::sorted;
24use serde::Deserialize;
25use serde::Serialize;
26use snapshot::AnySnapshot;
27use sync::Mutex;
28use thiserror::Error;
29
30#[cfg(feature = "stats")]
31use crate::bus_stats::BusOperation;
32#[cfg(feature = "stats")]
33use crate::BusStatistics;
34use crate::DeviceId;
35use crate::PciAddress;
36use crate::PciDevice;
37use crate::Suspendable;
38#[cfg(any(target_os = "android", target_os = "linux"))]
39use crate::VfioPlatformDevice;
40
41#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
43pub struct BusAccessInfo {
44 pub offset: u64,
46 pub address: u64,
48 pub id: usize,
50}
51
52impl std::fmt::Display for BusAccessInfo {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 write!(f, "{self:?}")
56 }
57}
58
59#[derive(Clone, Debug, Default, PartialEq, Eq)]
62pub struct ConfigWriteResult {
63 pub mmio_remove: Vec<BusRange>,
65
66 pub mmio_add: Vec<BusRange>,
68
69 pub io_remove: Vec<BusRange>,
71
72 pub io_add: Vec<BusRange>,
74
75 pub removed_pci_devices: Vec<PciAddress>,
78}
79
80#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
81pub enum BusType {
82 Mmio,
83 Io,
84}
85
86#[allow(unused_variables)]
91pub trait BusDevice: Send + Suspendable {
92 fn debug_label(&self) -> String;
94 fn device_id(&self) -> DeviceId;
96 fn read(&mut self, offset: BusAccessInfo, data: &mut [u8]) {}
98 fn write(&mut self, offset: BusAccessInfo, data: &[u8]) {}
100 fn config_register_write(
104 &mut self,
105 reg_idx: usize,
106 offset: u64,
107 data: &[u8],
108 ) -> ConfigWriteResult {
109 ConfigWriteResult {
110 ..Default::default()
111 }
112 }
113 fn config_register_read(&self, reg_idx: usize) -> u32 {
116 0
117 }
118 fn init_pci_config_mapping(&mut self, shmem: &SharedMemory, base: usize, len: usize) -> bool {
132 false
133 }
134 fn virtual_config_register_write(&mut self, reg_idx: usize, value: u32) {}
138 fn virtual_config_register_read(&self, reg_idx: usize) -> u32 {
141 0
142 }
143 fn on_sandboxed(&mut self) {}
145
146 fn get_ranges(&self) -> Vec<(BusRange, BusType)> {
148 Vec::new()
149 }
150
151 fn destroy_device(&mut self) {}
153
154 fn is_bridge(&self) -> Option<u8> {
156 None
157 }
158}
159
160pub trait BusDeviceSync: BusDevice + Sync {
161 fn read(&self, offset: BusAccessInfo, data: &mut [u8]);
162 fn write(&self, offset: BusAccessInfo, data: &[u8]);
163 fn snapshot_sync(&self) -> anyhow::Result<AnySnapshot> {
164 Err(anyhow!(
165 "snapshot_sync not implemented for {}",
166 std::any::type_name::<Self>()
167 ))
168 }
169 fn restore_sync(&self, _data: AnySnapshot) -> anyhow::Result<()> {
171 Err(anyhow!(
172 "restore_sync not implemented for {}",
173 std::any::type_name::<Self>()
174 ))
175 }
176 fn sleep_sync(&self) -> anyhow::Result<()> {
179 Err(anyhow!(
180 "sleep_sync not implemented for {}",
181 std::any::type_name::<Self>()
182 ))
183 }
184 fn wake_sync(&self) -> anyhow::Result<()> {
187 Err(anyhow!(
188 "wake_sync not implemented for {}",
189 std::any::type_name::<Self>()
190 ))
191 }
192}
193
194pub trait BusResumeDevice: Send {
195 fn resume_imminent(&mut self) {}
198}
199
200#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
204pub enum HotPlugKey {
205 HostUpstreamPort { host_addr: PciAddress },
206 HostDownstreamPort { host_addr: PciAddress },
207 HostVfio { host_addr: PciAddress },
208 GuestDevice { guest_addr: PciAddress },
209}
210
211pub trait HotPlugBus: Send {
213 fn hot_plug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>;
218 fn hot_unplug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>;
223 fn get_ready_notification(&mut self) -> anyhow::Result<Event>;
226 fn is_match(&self, host_addr: PciAddress) -> Option<u8>;
231 fn get_address(&self) -> Option<PciAddress>;
233 fn get_secondary_bus_number(&self) -> Option<u8>;
235 fn add_hotplug_device(&mut self, hotplug_key: HotPlugKey, guest_addr: PciAddress);
239 fn get_hotplug_device(&self, hotplug_key: HotPlugKey) -> Option<PciAddress>;
241 fn is_empty(&self) -> bool;
243 fn get_hotplug_key(&self) -> Option<HotPlugKey>;
245}
246
247pub trait BusDeviceObj {
251 fn as_pci_device(&self) -> Option<&dyn PciDevice> {
252 None
253 }
254 fn as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice> {
255 None
256 }
257 fn into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>> {
258 None
259 }
260 #[cfg(any(target_os = "android", target_os = "linux"))]
261 fn as_platform_device(&self) -> Option<&VfioPlatformDevice> {
262 None
263 }
264 #[cfg(any(target_os = "android", target_os = "linux"))]
265 fn as_platform_device_mut(&mut self) -> Option<&mut VfioPlatformDevice> {
266 None
267 }
268 #[cfg(any(target_os = "android", target_os = "linux"))]
269 fn into_platform_device(self: Box<Self>) -> Option<Box<VfioPlatformDevice>> {
270 None
271 }
272}
273
274#[sorted]
275#[derive(Error, Debug)]
276pub enum Error {
277 #[error("Bus Range not found")]
278 Empty,
279 #[error("new device {base},{len} overlaps with an old device {other_base},{other_len}")]
281 Overlap {
282 base: u64,
283 len: u64,
284 other_base: u64,
285 other_len: u64,
286 },
287}
288
289pub type Result<T> = result::Result<T, Error>;
290
291#[derive(Copy, Clone, Serialize, Deserialize)]
296pub struct BusRange {
297 pub base: u64,
298 pub len: u64,
299}
300
301impl BusRange {
302 pub fn contains(&self, addr: u64) -> bool {
304 self.base <= addr && addr < self.base.saturating_add(self.len)
305 }
306
307 pub fn overlaps(&self, base: u64, len: u64) -> bool {
309 self.base < base.saturating_add(len) && base < self.base.saturating_add(self.len)
310 }
311}
312
313impl Eq for BusRange {}
314
315impl PartialEq for BusRange {
316 fn eq(&self, other: &BusRange) -> bool {
317 self.base == other.base
318 }
319}
320
321impl Ord for BusRange {
322 fn cmp(&self, other: &BusRange) -> Ordering {
323 self.base.cmp(&other.base)
324 }
325}
326
327impl PartialOrd for BusRange {
328 fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> {
329 Some(self.cmp(other))
330 }
331}
332
333impl std::fmt::Debug for BusRange {
334 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
335 write!(f, "{:#x}..+{:#x}", self.base, self.len)
336 }
337}
338
339#[derive(Clone)]
340struct BusEntry {
341 #[cfg(feature = "stats")]
342 index: usize,
343 device: BusDeviceEntry,
344}
345
346#[derive(Clone)]
347enum BusDeviceEntry {
348 OuterSync(Arc<Mutex<dyn BusDevice>>),
349 InnerSync(Arc<dyn BusDeviceSync>),
350}
351
352#[derive(Clone)]
357pub struct Bus {
358 devices: Arc<Mutex<BTreeMap<BusRange, BusEntry>>>,
359 access_id: usize,
360 #[cfg(feature = "stats")]
361 pub stats: Arc<Mutex<BusStatistics>>,
362 bus_type: BusType,
363}
364
365impl Bus {
366 pub fn new(bus_type: BusType) -> Bus {
368 Bus {
369 devices: Arc::new(Mutex::new(BTreeMap::new())),
370 access_id: 0,
371 #[cfg(feature = "stats")]
372 stats: Arc::new(Mutex::new(BusStatistics::new())),
373 bus_type,
374 }
375 }
376
377 pub fn get_bus_type(&self) -> BusType {
379 self.bus_type
380 }
381
382 pub fn set_access_id(&mut self, id: usize) {
384 self.access_id = id;
385 }
386
387 fn first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)> {
388 let devices = self.devices.lock();
389 let (range, entry) = devices
390 .range(..=BusRange { base: addr, len: 1 })
391 .next_back()?;
392 Some((*range, entry.clone()))
393 }
394
395 fn get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)> {
396 if let Some((range, entry)) = self.first_before(addr) {
397 let offset = addr - range.base;
398 if offset < range.len {
399 return Some((offset, addr, entry));
400 }
401 }
402 None
403 }
404
405 fn unique_devices(&self) -> Vec<BusDeviceEntry> {
411 let mut seen_ptrs = BTreeSet::new();
412 self.devices
413 .lock()
414 .values()
415 .map(|bus_entry| bus_entry.device.clone())
416 .filter(|dev| match dev {
417 BusDeviceEntry::OuterSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8),
418 BusDeviceEntry::InnerSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8),
419 })
420 .collect()
421 }
422
423 fn unique_devices_with_snapshot_key(&self) -> Vec<(String, BusDeviceEntry)> {
431 let mut next_ids = BTreeMap::<String, usize>::new();
432 let mut choose_key = |debug_label: String| -> String {
433 let label = debug_label.replace(char::is_whitespace, "-");
434 let id = next_ids.entry(label.clone()).or_default();
435 let key = format!("{label}-{id}");
436 *id += 1;
437 key
438 };
439
440 let mut result = Vec::new();
441 for device_entry in self.unique_devices() {
442 let key = match &device_entry {
443 BusDeviceEntry::OuterSync(d) => choose_key(d.lock().debug_label()),
444 BusDeviceEntry::InnerSync(d) => choose_key(d.debug_label()),
445 };
446 result.push((key, device_entry));
447 }
448 result
449 }
450
451 pub fn sleep_devices(&self) -> anyhow::Result<()> {
452 for device_entry in self.unique_devices() {
453 match device_entry {
454 BusDeviceEntry::OuterSync(dev) => {
455 let mut dev = (*dev).lock();
456 debug!("Sleep on device: {}", dev.debug_label());
457 dev.sleep()
458 .with_context(|| format!("failed to sleep {}", dev.debug_label()))?;
459 }
460 BusDeviceEntry::InnerSync(dev) => {
461 debug!("Sleep on device: {}", dev.debug_label());
462 dev.sleep_sync()
463 .with_context(|| format!("failed to sleep {}", dev.debug_label()))?;
464 }
465 }
466 }
467 Ok(())
468 }
469
470 pub fn wake_devices(&self) -> anyhow::Result<()> {
471 for device_entry in self.unique_devices() {
472 match device_entry {
473 BusDeviceEntry::OuterSync(dev) => {
474 let mut dev = dev.lock();
475 debug!("Wake on device: {}", dev.debug_label());
476 dev.wake()
477 .with_context(|| format!("failed to wake {}", dev.debug_label()))?;
478 }
479 BusDeviceEntry::InnerSync(dev) => {
480 debug!("Wake on device: {}", dev.debug_label());
481 dev.wake_sync()
482 .with_context(|| format!("failed to wake {}", dev.debug_label()))?;
483 }
484 }
485 }
486 Ok(())
487 }
488
489 pub fn snapshot_devices(
490 &self,
491 snapshot_writer: &snapshot::SnapshotWriter,
492 ) -> anyhow::Result<()> {
493 for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() {
494 match device_entry {
495 BusDeviceEntry::OuterSync(dev) => {
496 let mut dev = dev.lock();
497 debug!("Snapshot on device: {}", dev.debug_label());
498 snapshot_writer.write_fragment(
499 &snapshot_key,
500 &(*dev)
501 .snapshot()
502 .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?,
503 )?;
504 }
505 BusDeviceEntry::InnerSync(dev) => {
506 debug!("Snapshot on device: {}", dev.debug_label());
507 snapshot_writer.write_fragment(
508 &snapshot_key,
509 &dev.snapshot_sync()
510 .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?,
511 )?;
512 }
513 }
514 }
515 Ok(())
516 }
517
518 pub fn restore_devices(
519 &self,
520 snapshot_reader: &snapshot::SnapshotReader,
521 ) -> anyhow::Result<()> {
522 let mut unused_keys: BTreeSet<String> =
523 snapshot_reader.list_fragments()?.into_iter().collect();
524 for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() {
525 unused_keys.remove(&snapshot_key);
526 match device_entry {
527 BusDeviceEntry::OuterSync(dev) => {
528 let mut dev = dev.lock();
529 debug!("Restore on device: {}", dev.debug_label());
530 dev.restore(snapshot_reader.read_fragment(&snapshot_key)?)
531 .with_context(|| {
532 format!("restore failed for device {}", dev.debug_label())
533 })?;
534 }
535 BusDeviceEntry::InnerSync(dev) => {
536 debug!("Restore on device: {}", dev.debug_label());
537 dev.restore_sync(snapshot_reader.read_fragment(&snapshot_key)?)
538 .with_context(|| {
539 format!("restore failed for device {}", dev.debug_label())
540 })?;
541 }
542 }
543 }
544
545 if !unused_keys.is_empty() {
546 error!(
547 "unused restore data in bus, devices might be missing: {:?}",
548 unused_keys
549 );
550 }
551
552 Ok(())
553 }
554
555 pub fn insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()> {
557 if len == 0 {
558 return Err(Error::Overlap {
559 base,
560 len,
561 other_base: 0,
562 other_len: 0,
563 });
564 }
565
566 let mut devices = self.devices.lock();
568 devices.iter().try_for_each(|(range, _dev)| {
569 if range.overlaps(base, len) {
570 Err(Error::Overlap {
571 base,
572 len,
573 other_base: range.base,
574 other_len: range.len,
575 })
576 } else {
577 Ok(())
578 }
579 })?;
580
581 #[cfg(feature = "stats")]
582 let name = device.lock().debug_label();
583 #[cfg(feature = "stats")]
584 let device_id = device.lock().device_id();
585 if devices
586 .insert(
587 BusRange { base, len },
588 BusEntry {
589 #[cfg(feature = "stats")]
590 index: self
591 .stats
592 .lock()
593 .next_device_index(name, device_id.into(), base, len),
594 device: BusDeviceEntry::OuterSync(device),
595 },
596 )
597 .is_some()
598 {
599 return Err(Error::Overlap {
600 base,
601 len,
602 other_base: base,
603 other_len: len,
604 });
605 }
606
607 Ok(())
608 }
609
610 pub fn insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()> {
614 if len == 0 {
615 return Err(Error::Overlap {
616 base,
617 len,
618 other_base: 0,
619 other_len: 0,
620 });
621 }
622
623 let mut devices = self.devices.lock();
625 devices.iter().try_for_each(|(range, _dev)| {
626 if range.overlaps(base, len) {
627 Err(Error::Overlap {
628 base,
629 len,
630 other_base: range.base,
631 other_len: range.len,
632 })
633 } else {
634 Ok(())
635 }
636 })?;
637
638 if devices
639 .insert(
640 BusRange { base, len },
641 BusEntry {
642 #[cfg(feature = "stats")]
643 index: self.stats.lock().next_device_index(
644 device.debug_label(),
645 device.device_id().into(),
646 base,
647 len,
648 ),
649 device: BusDeviceEntry::InnerSync(device),
650 },
651 )
652 .is_some()
653 {
654 return Err(Error::Overlap {
655 base,
656 len,
657 other_base: base,
658 other_len: len,
659 });
660 }
661
662 Ok(())
663 }
664
665 pub fn remove(&self, base: u64, len: u64) -> Result<()> {
667 if len == 0 {
668 return Err(Error::Overlap {
669 base,
670 len,
671 other_base: 0,
672 other_len: 0,
673 });
674 }
675
676 let mut devices = self.devices.lock();
677 if devices
678 .iter()
679 .any(|(range, _dev)| range.base == base && range.len == len)
680 {
681 let ret = devices.remove(&BusRange { base, len });
682 if ret.is_some() {
683 Ok(())
684 } else {
685 Err(Error::Empty)
686 }
687 } else {
688 Err(Error::Empty)
689 }
690 }
691
692 pub fn read(&self, addr: u64, data: &mut [u8]) -> bool {
696 #[cfg(feature = "stats")]
697 let start = self.stats.lock().start_stat();
698
699 data.fill(0);
702
703 let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
704 let io = BusAccessInfo {
705 address,
706 offset,
707 id: self.access_id,
708 };
709
710 match &entry.device {
711 BusDeviceEntry::OuterSync(dev) => dev.lock().read(io, data),
712 BusDeviceEntry::InnerSync(dev) => dev.read(io, data),
713 }
714 #[cfg(feature = "stats")]
715 let index = Some(entry.index);
716 #[cfg(not(feature = "stats"))]
717 let index = Some(());
718 index
719 } else {
720 None
721 };
722
723 #[cfg(feature = "stats")]
724 if let Some(device_index) = device_index {
725 self.stats
726 .lock()
727 .end_stat(BusOperation::Write, start, device_index);
728 return true;
729 }
730
731 device_index.is_some()
732 }
733
734 pub fn write(&self, addr: u64, data: &[u8]) -> bool {
738 #[cfg(feature = "stats")]
739 let start = self.stats.lock().start_stat();
740
741 let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
742 let io = BusAccessInfo {
743 address,
744 offset,
745 id: self.access_id,
746 };
747
748 match &entry.device {
749 BusDeviceEntry::OuterSync(dev) => dev.lock().write(io, data),
750 BusDeviceEntry::InnerSync(dev) => dev.write(io, data),
751 }
752
753 #[cfg(feature = "stats")]
754 let index = Some(entry.index);
755 #[cfg(not(feature = "stats"))]
756 let index = Some(());
757 index
758 } else {
759 None
760 };
761
762 #[cfg(feature = "stats")]
763 if let Some(device_index) = device_index {
764 self.stats
765 .lock()
766 .end_stat(BusOperation::Write, start, device_index);
767 }
768 device_index.is_some()
769 }
770}
771
772impl Default for Bus {
773 fn default() -> Self {
774 Self::new(BusType::Io)
775 }
776}
777
778#[cfg(test)]
779mod tests {
780 use anyhow::Result as AnyhowResult;
781
782 use super::*;
783 use crate::pci::CrosvmDeviceId;
784 use crate::suspendable::Suspendable;
785 use crate::suspendable_tests;
786
787 #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
788 struct DummyDevice;
789
790 impl BusDevice for DummyDevice {
791 fn device_id(&self) -> DeviceId {
792 CrosvmDeviceId::Cmos.into()
793 }
794 fn debug_label(&self) -> String {
795 "dummy device".to_owned()
796 }
797 }
798
799 impl Suspendable for DummyDevice {
800 fn snapshot(&mut self) -> AnyhowResult<AnySnapshot> {
801 AnySnapshot::to_any(self).context("error serializing")
802 }
803
804 fn restore(&mut self, data: AnySnapshot) -> AnyhowResult<()> {
805 *self = AnySnapshot::from_any(data).context("error deserializing")?;
806 Ok(())
807 }
808
809 fn sleep(&mut self) -> AnyhowResult<()> {
810 Ok(())
811 }
812
813 fn wake(&mut self) -> AnyhowResult<()> {
814 Ok(())
815 }
816 }
817
818 #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
819 struct ConstantDevice {
820 uses_full_addr: bool,
821 }
822
823 impl BusDevice for ConstantDevice {
824 fn device_id(&self) -> DeviceId {
825 CrosvmDeviceId::Cmos.into()
826 }
827
828 fn debug_label(&self) -> String {
829 "constant device".to_owned()
830 }
831
832 fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
833 let addr = if self.uses_full_addr {
834 info.address
835 } else {
836 info.offset
837 };
838 for (i, v) in data.iter_mut().enumerate() {
839 *v = (addr as u8) + (i as u8);
840 }
841 }
842
843 fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
844 let addr = if self.uses_full_addr {
845 info.address
846 } else {
847 info.offset
848 };
849 for (i, v) in data.iter().enumerate() {
850 assert_eq!(*v, (addr as u8) + (i as u8))
851 }
852 }
853 }
854
855 impl Suspendable for ConstantDevice {
856 fn snapshot(&mut self) -> AnyhowResult<AnySnapshot> {
857 AnySnapshot::to_any(self).context("error serializing")
858 }
859
860 fn restore(&mut self, data: AnySnapshot) -> AnyhowResult<()> {
861 *self = AnySnapshot::from_any(data).context("error deserializing")?;
862 Ok(())
863 }
864
865 fn sleep(&mut self) -> AnyhowResult<()> {
866 Ok(())
867 }
868
869 fn wake(&mut self) -> AnyhowResult<()> {
870 Ok(())
871 }
872 }
873
874 fn modify_constant_device(constant: &mut ConstantDevice) {
875 constant.uses_full_addr = !constant.uses_full_addr;
876 }
877
878 #[test]
879 fn bus_insert() {
880 let bus = Bus::new(BusType::Io);
881 let dummy = Arc::new(Mutex::new(DummyDevice));
882 assert!(bus.insert(dummy.clone(), 0x10, 0).is_err());
883 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
884 assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err());
885 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err());
886 assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err());
887 assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err());
888 assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err());
889 assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err());
890 assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok());
891 assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok());
892 assert!(bus.insert(dummy, 0x0, 0x10).is_ok());
893 }
894
895 #[test]
896 fn bus_insert_full_addr() {
897 let bus = Bus::new(BusType::Io);
898 let dummy = Arc::new(Mutex::new(DummyDevice));
899 assert!(bus.insert(dummy.clone(), 0x10, 0).is_err());
900 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
901 assert!(bus.insert(dummy.clone(), 0x0f, 0x10).is_err());
902 assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_err());
903 assert!(bus.insert(dummy.clone(), 0x10, 0x15).is_err());
904 assert!(bus.insert(dummy.clone(), 0x12, 0x15).is_err());
905 assert!(bus.insert(dummy.clone(), 0x12, 0x01).is_err());
906 assert!(bus.insert(dummy.clone(), 0x0, 0x20).is_err());
907 assert!(bus.insert(dummy.clone(), 0x20, 0x05).is_ok());
908 assert!(bus.insert(dummy.clone(), 0x25, 0x05).is_ok());
909 assert!(bus.insert(dummy, 0x0, 0x10).is_ok());
910 }
911
912 #[test]
913 fn bus_read_write() {
914 let bus = Bus::new(BusType::Io);
915 let dummy = Arc::new(Mutex::new(DummyDevice));
916 assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
917 assert!(bus.read(0x10, &mut [0, 0, 0, 0]));
918 assert!(bus.write(0x10, &[0, 0, 0, 0]));
919 assert!(bus.read(0x11, &mut [0, 0, 0, 0]));
920 assert!(bus.write(0x11, &[0, 0, 0, 0]));
921 assert!(bus.read(0x16, &mut [0, 0, 0, 0]));
922 assert!(bus.write(0x16, &[0, 0, 0, 0]));
923 assert!(!bus.read(0x20, &mut [0, 0, 0, 0]));
924 assert!(!bus.write(0x20, &[0, 0, 0, 0]));
925 assert!(!bus.read(0x06, &mut [0, 0, 0, 0]));
926 assert!(!bus.write(0x06, &[0, 0, 0, 0]));
927 }
928
929 #[test]
930 fn bus_read_write_values() {
931 let bus = Bus::new(BusType::Io);
932 let dummy = Arc::new(Mutex::new(ConstantDevice {
933 uses_full_addr: false,
934 }));
935 assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
936
937 let mut values = [0, 1, 2, 3];
938 assert!(bus.read(0x10, &mut values));
939 assert_eq!(values, [0, 1, 2, 3]);
940 assert!(bus.write(0x10, &values));
941 assert!(bus.read(0x15, &mut values));
942 assert_eq!(values, [5, 6, 7, 8]);
943 assert!(bus.write(0x15, &values));
944 }
945
946 #[test]
947 fn bus_read_write_full_addr_values() {
948 let bus = Bus::new(BusType::Io);
949 let dummy = Arc::new(Mutex::new(ConstantDevice {
950 uses_full_addr: true,
951 }));
952 assert!(bus.insert(dummy, 0x10, 0x10).is_ok());
953
954 let mut values = [0u8; 4];
955 assert!(bus.read(0x10, &mut values));
956 assert_eq!(values, [0x10, 0x11, 0x12, 0x13]);
957 assert!(bus.write(0x10, &values));
958 assert!(bus.read(0x15, &mut values));
959 assert_eq!(values, [0x15, 0x16, 0x17, 0x18]);
960 assert!(bus.write(0x15, &values));
961 }
962
963 #[test]
964 fn bus_read_no_device() {
965 let bus = Bus::new(BusType::Io);
966
967 let mut values = [1, 2, 3, 4];
970 assert!(!bus.read(0x10, &mut values));
971 assert_eq!(values, [0, 0, 0, 0]);
972 }
973
974 suspendable_tests!(
975 constant_device_true,
976 ConstantDevice {
977 uses_full_addr: true,
978 },
979 modify_constant_device
980 );
981
982 suspendable_tests!(
983 constant_device_false,
984 ConstantDevice {
985 uses_full_addr: false,
986 },
987 modify_constant_device
988 );
989
990 #[test]
991 fn bus_range_contains() {
992 let a = BusRange {
993 base: 0x1000,
994 len: 0x400,
995 };
996 assert!(a.contains(0x1000));
997 assert!(a.contains(0x13ff));
998 assert!(!a.contains(0xfff));
999 assert!(!a.contains(0x1400));
1000 assert!(a.contains(0x1200));
1001 }
1002
1003 #[test]
1004 fn bus_range_overlap() {
1005 let a = BusRange {
1006 base: 0x1000,
1007 len: 0x400,
1008 };
1009 assert!(a.overlaps(0x1000, 0x400));
1010 assert!(a.overlaps(0xf00, 0x400));
1011 assert!(a.overlaps(0x1000, 0x01));
1012 assert!(a.overlaps(0xfff, 0x02));
1013 assert!(a.overlaps(0x1100, 0x100));
1014 assert!(a.overlaps(0x13ff, 0x100));
1015 assert!(!a.overlaps(0x1400, 0x100));
1016 assert!(!a.overlaps(0xf00, 0x100));
1017 }
1018}