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 hypervisor::HypercallAbi;
24use remain::sorted;
25use serde::Deserialize;
26use serde::Serialize;
27use snapshot::AnySnapshot;
28use sync::Mutex;
29use thiserror::Error;
30use vm_control::DeviceId;
31
32#[cfg(feature = "stats")]
33use crate::bus_stats::BusOperation;
34#[cfg(feature = "stats")]
35use crate::BusStatistics;
36use crate::PciAddress;
37use crate::PciDevice;
38use crate::Suspendable;
39#[cfg(any(target_os = "android", target_os = "linux"))]
40use crate::VfioPlatformDevice;
41
42#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
44pub struct BusAccessInfo {
45 pub offset: u64,
47 pub address: u64,
49 pub id: usize,
51}
52
53impl std::fmt::Display for BusAccessInfo {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 write!(f, "{self:?}")
57 }
58}
59
60#[derive(Clone, Debug, Default, PartialEq, Eq)]
63pub struct ConfigWriteResult {
64 pub mmio_remove: Vec<BusRange>,
66
67 pub mmio_add: Vec<BusRange>,
69
70 pub io_remove: Vec<BusRange>,
72
73 pub io_add: Vec<BusRange>,
75
76 pub removed_pci_devices: Vec<PciAddress>,
79}
80
81#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
82pub enum BusType {
83 Mmio,
84 Io,
85 Hypercall,
86}
87
88#[allow(unused_variables)]
90pub trait BusDevice: Send + Suspendable {
91 fn debug_label(&self) -> String;
93 fn device_id(&self) -> DeviceId;
95 fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {}
97 fn write(&mut self, info: BusAccessInfo, data: &[u8]) {}
99 fn config_register_write(
103 &mut self,
104 reg_idx: usize,
105 offset: u64,
106 data: &[u8],
107 ) -> ConfigWriteResult {
108 ConfigWriteResult {
109 ..Default::default()
110 }
111 }
112 fn config_register_read(&self, reg_idx: usize) -> u32 {
115 0
116 }
117 fn init_pci_config_mapping(&mut self, shmem: &SharedMemory, base: usize, len: usize) -> bool {
131 false
132 }
133 fn virtual_config_register_write(&mut self, reg_idx: usize, value: u32) {}
137 fn virtual_config_register_read(&self, reg_idx: usize) -> u32 {
140 0
141 }
142 fn on_sandboxed(&mut self) {}
144
145 fn get_ranges(&self) -> Vec<(BusRange, BusType)> {
147 Vec::new()
148 }
149
150 fn destroy_device(&mut self) {}
152
153 fn supports_power_management(&self) -> anyhow::Result<bool> {
155 Ok(false)
156 }
157
158 fn initial_power_state(&self) -> bool {
160 true
162 }
163
164 fn power_on(&mut self) -> anyhow::Result<()> {
166 Err(anyhow!(
167 "power_on not implemented for {}",
168 std::any::type_name::<Self>()
169 ))
170 }
171
172 fn power_off(&mut self) -> anyhow::Result<()> {
174 Err(anyhow!(
175 "power_off not implemented for {}",
176 std::any::type_name::<Self>()
177 ))
178 }
179
180 fn is_bridge(&self) -> Option<u8> {
182 None
183 }
184
185 fn handle_hypercall(&self, abi: &mut HypercallAbi) -> anyhow::Result<()> {
191 Err(anyhow!(
192 "handle_hypercall not implemented for {}",
193 std::any::type_name::<Self>()
194 ))
195 }
196}
197
198pub trait BusDeviceSync: BusDevice + Sync {
199 fn read(&self, offset: BusAccessInfo, data: &mut [u8]);
200 fn write(&self, offset: BusAccessInfo, data: &[u8]);
201 fn snapshot_sync(&self) -> anyhow::Result<AnySnapshot> {
202 Err(anyhow!(
203 "snapshot_sync not implemented for {}",
204 std::any::type_name::<Self>()
205 ))
206 }
207 fn restore_sync(&self, _data: AnySnapshot) -> anyhow::Result<()> {
209 Err(anyhow!(
210 "restore_sync not implemented for {}",
211 std::any::type_name::<Self>()
212 ))
213 }
214 fn sleep_sync(&self) -> anyhow::Result<()> {
217 Err(anyhow!(
218 "sleep_sync not implemented for {}",
219 std::any::type_name::<Self>()
220 ))
221 }
222 fn wake_sync(&self) -> anyhow::Result<()> {
225 Err(anyhow!(
226 "wake_sync not implemented for {}",
227 std::any::type_name::<Self>()
228 ))
229 }
230}
231
232pub trait BusResumeDevice: Send {
233 fn resume_imminent(&mut self) {}
236}
237
238#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
242pub enum HotPlugKey {
243 HostUpstreamPort { host_addr: PciAddress },
244 HostDownstreamPort { host_addr: PciAddress },
245 HostVfio { host_addr: PciAddress },
246 GuestDevice { guest_addr: PciAddress },
247}
248
249pub trait HotPlugBus: Send {
251 fn hot_plug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>;
256 fn hot_unplug(&mut self, addr: PciAddress) -> anyhow::Result<Option<Event>>;
261 fn get_ready_notification(&mut self) -> anyhow::Result<Event>;
264 fn is_match(&self, host_addr: PciAddress) -> Option<u8>;
269 fn get_address(&self) -> Option<PciAddress>;
271 fn get_secondary_bus_number(&self) -> Option<u8>;
273 fn add_hotplug_device(&mut self, hotplug_key: HotPlugKey, guest_addr: PciAddress);
277 fn get_hotplug_device(&self, hotplug_key: HotPlugKey) -> Option<PciAddress>;
279 fn is_empty(&self) -> bool;
281 fn get_hotplug_key(&self) -> Option<HotPlugKey>;
283}
284
285pub trait BusDeviceObj {
289 fn as_pci_device(&self) -> Option<&dyn PciDevice> {
290 None
291 }
292 fn as_pci_device_mut(&mut self) -> Option<&mut dyn PciDevice> {
293 None
294 }
295 fn into_pci_device(self: Box<Self>) -> Option<Box<dyn PciDevice>> {
296 None
297 }
298 #[cfg(any(target_os = "android", target_os = "linux"))]
299 fn as_platform_device(&self) -> Option<&VfioPlatformDevice> {
300 None
301 }
302 #[cfg(any(target_os = "android", target_os = "linux"))]
303 fn as_platform_device_mut(&mut self) -> Option<&mut VfioPlatformDevice> {
304 None
305 }
306 #[cfg(any(target_os = "android", target_os = "linux"))]
307 fn into_platform_device(self: Box<Self>) -> Option<Box<VfioPlatformDevice>> {
308 None
309 }
310}
311
312#[sorted]
313#[derive(Error, Debug, PartialEq)]
314pub enum Error {
315 #[error("Bus Range not found")]
316 Empty,
317 #[error("new device {base},{len} overlaps with an old device {other_base},{other_len}")]
319 Overlap {
320 base: u64,
321 len: u64,
322 other_base: u64,
323 other_len: u64,
324 },
325}
326
327pub type Result<T> = result::Result<T, Error>;
328
329#[derive(Copy, Clone, Serialize, Deserialize)]
334pub struct BusRange {
335 pub base: u64,
336 pub len: u64,
337}
338
339impl BusRange {
340 pub fn contains(&self, addr: u64) -> bool {
342 self.base <= addr && addr < self.base.saturating_add(self.len)
343 }
344
345 pub fn overlaps(&self, base: u64, len: u64) -> bool {
347 self.base < base.saturating_add(len) && base < self.base.saturating_add(self.len)
348 }
349}
350
351impl Eq for BusRange {}
352
353impl PartialEq for BusRange {
354 fn eq(&self, other: &BusRange) -> bool {
355 self.base == other.base
356 }
357}
358
359impl Ord for BusRange {
360 fn cmp(&self, other: &BusRange) -> Ordering {
361 self.base.cmp(&other.base)
362 }
363}
364
365impl PartialOrd for BusRange {
366 fn partial_cmp(&self, other: &BusRange) -> Option<Ordering> {
367 Some(self.cmp(other))
368 }
369}
370
371impl std::fmt::Debug for BusRange {
372 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
373 write!(f, "{:#x}..+{:#x}", self.base, self.len)
374 }
375}
376
377#[derive(Clone)]
378struct BusEntry {
379 #[cfg(feature = "stats")]
380 index: usize,
381 device: BusDeviceEntry,
382}
383
384#[derive(Clone)]
385enum BusDeviceEntry {
386 OuterSync(Arc<Mutex<dyn BusDevice>>),
387 InnerSync(Arc<dyn BusDeviceSync>),
388}
389
390#[derive(Clone)]
395pub struct Bus {
396 devices: Arc<Mutex<BTreeMap<BusRange, BusEntry>>>,
397 access_id: usize,
398 #[cfg(feature = "stats")]
399 pub stats: Arc<Mutex<BusStatistics>>,
400 bus_type: BusType,
401}
402
403impl Bus {
404 pub fn new(bus_type: BusType) -> Bus {
406 Bus {
407 devices: Arc::new(Mutex::new(BTreeMap::new())),
408 access_id: 0,
409 #[cfg(feature = "stats")]
410 stats: Arc::new(Mutex::new(BusStatistics::new())),
411 bus_type,
412 }
413 }
414
415 pub fn get_bus_type(&self) -> BusType {
417 self.bus_type
418 }
419
420 pub fn set_access_id(&mut self, id: usize) {
422 self.access_id = id;
423 }
424
425 fn first_before(&self, addr: u64) -> Option<(BusRange, BusEntry)> {
426 let devices = self.devices.lock();
427 let (range, entry) = devices
428 .range(..=BusRange { base: addr, len: 1 })
429 .next_back()?;
430 Some((*range, entry.clone()))
431 }
432
433 fn get_device(&self, addr: u64) -> Option<(u64, u64, BusEntry)> {
434 if let Some((range, entry)) = self.first_before(addr) {
435 let offset = addr - range.base;
436 if offset < range.len {
437 return Some((offset, addr, entry));
438 }
439 }
440 None
441 }
442
443 fn unique_devices(&self) -> Vec<BusDeviceEntry> {
449 let mut seen_ptrs = BTreeSet::new();
450 self.devices
451 .lock()
452 .values()
453 .map(|bus_entry| bus_entry.device.clone())
454 .filter(|dev| match dev {
455 BusDeviceEntry::OuterSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8),
456 BusDeviceEntry::InnerSync(dev) => seen_ptrs.insert(Arc::as_ptr(dev) as *const u8),
457 })
458 .collect()
459 }
460
461 fn unique_devices_with_snapshot_key(&self) -> Vec<(String, BusDeviceEntry)> {
469 let mut next_ids = BTreeMap::<String, usize>::new();
470 let mut choose_key = |debug_label: String| -> String {
471 let label = debug_label.replace(char::is_whitespace, "-");
472 let id = next_ids.entry(label.clone()).or_default();
473 let key = format!("{label}-{id}");
474 *id += 1;
475 key
476 };
477
478 let mut result = Vec::new();
479 for device_entry in self.unique_devices() {
480 let key = match &device_entry {
481 BusDeviceEntry::OuterSync(d) => choose_key(d.lock().debug_label()),
482 BusDeviceEntry::InnerSync(d) => choose_key(d.debug_label()),
483 };
484 result.push((key, device_entry));
485 }
486 result
487 }
488
489 pub fn sleep_devices(&self) -> anyhow::Result<()> {
490 for device_entry in self.unique_devices() {
491 match device_entry {
492 BusDeviceEntry::OuterSync(dev) => {
493 let mut dev = (*dev).lock();
494 debug!("Sleep on device: {}", dev.debug_label());
495 dev.sleep()
496 .with_context(|| format!("failed to sleep {}", dev.debug_label()))?;
497 }
498 BusDeviceEntry::InnerSync(dev) => {
499 debug!("Sleep on device: {}", dev.debug_label());
500 dev.sleep_sync()
501 .with_context(|| format!("failed to sleep {}", dev.debug_label()))?;
502 }
503 }
504 }
505 Ok(())
506 }
507
508 pub fn wake_devices(&self) -> anyhow::Result<()> {
509 for device_entry in self.unique_devices() {
510 match device_entry {
511 BusDeviceEntry::OuterSync(dev) => {
512 let mut dev = dev.lock();
513 debug!("Wake on device: {}", dev.debug_label());
514 dev.wake()
515 .with_context(|| format!("failed to wake {}", dev.debug_label()))?;
516 }
517 BusDeviceEntry::InnerSync(dev) => {
518 debug!("Wake on device: {}", dev.debug_label());
519 dev.wake_sync()
520 .with_context(|| format!("failed to wake {}", dev.debug_label()))?;
521 }
522 }
523 }
524 Ok(())
525 }
526
527 pub fn snapshot_devices(
528 &self,
529 snapshot_writer: &snapshot::SnapshotWriter,
530 ) -> anyhow::Result<()> {
531 for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() {
532 match device_entry {
533 BusDeviceEntry::OuterSync(dev) => {
534 let mut dev = dev.lock();
535 debug!("Snapshot on device: {}", dev.debug_label());
536 snapshot_writer.write_fragment(
537 &snapshot_key,
538 &(*dev)
539 .snapshot()
540 .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?,
541 )?;
542 }
543 BusDeviceEntry::InnerSync(dev) => {
544 debug!("Snapshot on device: {}", dev.debug_label());
545 snapshot_writer.write_fragment(
546 &snapshot_key,
547 &dev.snapshot_sync()
548 .with_context(|| format!("failed to snapshot {}", dev.debug_label()))?,
549 )?;
550 }
551 }
552 }
553 Ok(())
554 }
555
556 pub fn restore_devices(
557 &self,
558 snapshot_reader: &snapshot::SnapshotReader,
559 ) -> anyhow::Result<()> {
560 let mut unused_keys: BTreeSet<String> =
561 snapshot_reader.list_fragments()?.into_iter().collect();
562 for (snapshot_key, device_entry) in self.unique_devices_with_snapshot_key() {
563 unused_keys.remove(&snapshot_key);
564 match device_entry {
565 BusDeviceEntry::OuterSync(dev) => {
566 let mut dev = dev.lock();
567 debug!("Restore on device: {}", dev.debug_label());
568 dev.restore(snapshot_reader.read_fragment(&snapshot_key)?)
569 .with_context(|| {
570 format!("restore failed for device {}", dev.debug_label())
571 })?;
572 }
573 BusDeviceEntry::InnerSync(dev) => {
574 debug!("Restore on device: {}", dev.debug_label());
575 dev.restore_sync(snapshot_reader.read_fragment(&snapshot_key)?)
576 .with_context(|| {
577 format!("restore failed for device {}", dev.debug_label())
578 })?;
579 }
580 }
581 }
582
583 if !unused_keys.is_empty() {
584 error!(
585 "unused restore data in bus, devices might be missing: {:?}",
586 unused_keys
587 );
588 }
589
590 Ok(())
591 }
592
593 pub fn insert(&self, device: Arc<Mutex<dyn BusDevice>>, base: u64, len: u64) -> Result<()> {
595 if len == 0 {
596 return Err(Error::Overlap {
597 base,
598 len,
599 other_base: 0,
600 other_len: 0,
601 });
602 }
603
604 let mut devices = self.devices.lock();
606 devices.iter().try_for_each(|(range, _dev)| {
607 if range.overlaps(base, len) {
608 Err(Error::Overlap {
609 base,
610 len,
611 other_base: range.base,
612 other_len: range.len,
613 })
614 } else {
615 Ok(())
616 }
617 })?;
618
619 #[cfg(feature = "stats")]
620 let name = device.lock().debug_label();
621 #[cfg(feature = "stats")]
622 let device_id = device.lock().device_id();
623 if devices
624 .insert(
625 BusRange { base, len },
626 BusEntry {
627 #[cfg(feature = "stats")]
628 index: self.stats.lock().next_device_index(
629 name,
630 device_id.metrics_id(),
631 base,
632 len,
633 ),
634 device: BusDeviceEntry::OuterSync(device),
635 },
636 )
637 .is_some()
638 {
639 return Err(Error::Overlap {
640 base,
641 len,
642 other_base: base,
643 other_len: len,
644 });
645 }
646
647 Ok(())
648 }
649
650 pub fn insert_sync(&self, device: Arc<dyn BusDeviceSync>, base: u64, len: u64) -> Result<()> {
654 if len == 0 {
655 return Err(Error::Overlap {
656 base,
657 len,
658 other_base: 0,
659 other_len: 0,
660 });
661 }
662
663 let mut devices = self.devices.lock();
665 devices.iter().try_for_each(|(range, _dev)| {
666 if range.overlaps(base, len) {
667 Err(Error::Overlap {
668 base,
669 len,
670 other_base: range.base,
671 other_len: range.len,
672 })
673 } else {
674 Ok(())
675 }
676 })?;
677
678 if devices
679 .insert(
680 BusRange { base, len },
681 BusEntry {
682 #[cfg(feature = "stats")]
683 index: self.stats.lock().next_device_index(
684 device.debug_label(),
685 device.device_id().metrics_id(),
686 base,
687 len,
688 ),
689 device: BusDeviceEntry::InnerSync(device),
690 },
691 )
692 .is_some()
693 {
694 return Err(Error::Overlap {
695 base,
696 len,
697 other_base: base,
698 other_len: len,
699 });
700 }
701
702 Ok(())
703 }
704
705 pub fn remove(&self, base: u64, len: u64) -> Result<()> {
707 if len == 0 {
708 return Err(Error::Overlap {
709 base,
710 len,
711 other_base: 0,
712 other_len: 0,
713 });
714 }
715
716 let mut devices = self.devices.lock();
717 if devices
718 .iter()
719 .any(|(range, _dev)| range.base == base && range.len == len)
720 {
721 let ret = devices.remove(&BusRange { base, len });
722 if ret.is_some() {
723 Ok(())
724 } else {
725 Err(Error::Empty)
726 }
727 } else {
728 Err(Error::Empty)
729 }
730 }
731
732 pub fn read(&self, addr: u64, data: &mut [u8]) -> bool {
736 #[cfg(feature = "stats")]
737 let start = self.stats.lock().start_stat();
738
739 data.fill(0);
742
743 let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
744 let io = BusAccessInfo {
745 address,
746 offset,
747 id: self.access_id,
748 };
749
750 match &entry.device {
751 BusDeviceEntry::OuterSync(dev) => dev.lock().read(io, data),
752 BusDeviceEntry::InnerSync(dev) => dev.read(io, data),
753 }
754 #[cfg(feature = "stats")]
755 let index = Some(entry.index);
756 #[cfg(not(feature = "stats"))]
757 let index = Some(());
758 index
759 } else {
760 None
761 };
762
763 #[cfg(feature = "stats")]
764 if let Some(device_index) = device_index {
765 self.stats
766 .lock()
767 .end_stat(BusOperation::Write, start, device_index);
768 return true;
769 }
770
771 device_index.is_some()
772 }
773
774 pub fn write(&self, addr: u64, data: &[u8]) -> bool {
778 #[cfg(feature = "stats")]
779 let start = self.stats.lock().start_stat();
780
781 let device_index = if let Some((offset, address, entry)) = self.get_device(addr) {
782 let io = BusAccessInfo {
783 address,
784 offset,
785 id: self.access_id,
786 };
787
788 match &entry.device {
789 BusDeviceEntry::OuterSync(dev) => dev.lock().write(io, data),
790 BusDeviceEntry::InnerSync(dev) => dev.write(io, data),
791 }
792
793 #[cfg(feature = "stats")]
794 let index = Some(entry.index);
795 #[cfg(not(feature = "stats"))]
796 let index = Some(());
797 index
798 } else {
799 None
800 };
801
802 #[cfg(feature = "stats")]
803 if let Some(device_index) = device_index {
804 self.stats
805 .lock()
806 .end_stat(BusOperation::Write, start, device_index);
807 }
808 device_index.is_some()
809 }
810
811 pub fn handle_hypercall(&self, abi: &mut HypercallAbi) -> anyhow::Result<()> {
817 let id = abi.hypercall_id().try_into().unwrap();
818 let (_, _, entry) = self
819 .get_device(id)
820 .with_context(|| format!("Unknown hypercall {id:#x}"))?;
821 match &entry.device {
822 BusDeviceEntry::OuterSync(dev) => dev.lock().handle_hypercall(abi),
823 BusDeviceEntry::InnerSync(dev) => dev.handle_hypercall(abi),
824 }
825 }
826}
827
828impl Default for Bus {
829 fn default() -> Self {
830 Self::new(BusType::Io)
831 }
832}
833
834#[cfg(test)]
835mod tests {
836 use anyhow::Result as AnyhowResult;
837 use vm_control::PlatformDeviceId;
838
839 use super::*;
840 use crate::suspendable::Suspendable;
841 use crate::suspendable_tests;
842 use crate::MockDevice;
843
844 #[derive(Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
845 struct ConstantDevice {
846 uses_full_addr: bool,
847 }
848
849 impl BusDevice for ConstantDevice {
850 fn device_id(&self) -> DeviceId {
851 PlatformDeviceId::Cmos.into()
852 }
853
854 fn debug_label(&self) -> String {
855 "constant device".to_owned()
856 }
857
858 fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
859 let addr = if self.uses_full_addr {
860 info.address
861 } else {
862 info.offset
863 };
864 for (i, v) in data.iter_mut().enumerate() {
865 *v = (addr as u8) + (i as u8);
866 }
867 }
868
869 fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
870 let addr = if self.uses_full_addr {
871 info.address
872 } else {
873 info.offset
874 };
875 for (i, v) in data.iter().enumerate() {
876 assert_eq!(*v, (addr as u8) + (i as u8))
877 }
878 }
879 }
880
881 impl Suspendable for ConstantDevice {
882 fn snapshot(&mut self) -> AnyhowResult<AnySnapshot> {
883 AnySnapshot::to_any(self).context("error serializing")
884 }
885
886 fn restore(&mut self, data: AnySnapshot) -> AnyhowResult<()> {
887 *self = AnySnapshot::from_any(data).context("error deserializing")?;
888 Ok(())
889 }
890
891 fn sleep(&mut self) -> AnyhowResult<()> {
892 Ok(())
893 }
894
895 fn wake(&mut self) -> AnyhowResult<()> {
896 Ok(())
897 }
898 }
899
900 fn modify_constant_device(constant: &mut ConstantDevice) {
901 constant.uses_full_addr = !constant.uses_full_addr;
902 }
903
904 #[test]
905 fn bus_insert() {
906 let bus = Bus::new(BusType::Io);
907 let dev = Arc::new(Mutex::new(MockDevice::new()));
908 assert_eq!(
909 bus.insert(dev.clone(), 0x10, 0),
910 Err(Error::Overlap {
911 base: 0x10,
912 len: 0,
913 other_base: 0,
914 other_len: 0
915 })
916 );
917 assert_eq!(bus.insert(dev.clone(), 0x10, 0x10), Ok(()));
918 assert_eq!(
919 bus.insert(dev.clone(), 0x0f, 0x10),
920 Err(Error::Overlap {
921 base: 0x0f,
922 len: 0x10,
923 other_base: 0x10,
924 other_len: 0x10
925 })
926 );
927 assert_eq!(
928 bus.insert(dev.clone(), 0x10, 0x10),
929 Err(Error::Overlap {
930 base: 0x10,
931 len: 0x10,
932 other_base: 0x10,
933 other_len: 0x10
934 })
935 );
936 assert_eq!(
937 bus.insert(dev.clone(), 0x10, 0x15),
938 Err(Error::Overlap {
939 base: 0x10,
940 len: 0x15,
941 other_base: 0x10,
942 other_len: 0x10
943 })
944 );
945 assert_eq!(
946 bus.insert(dev.clone(), 0x12, 0x15),
947 Err(Error::Overlap {
948 base: 0x12,
949 len: 0x15,
950 other_base: 0x10,
951 other_len: 0x10
952 })
953 );
954 assert_eq!(
955 bus.insert(dev.clone(), 0x12, 0x01),
956 Err(Error::Overlap {
957 base: 0x12,
958 len: 0x01,
959 other_base: 0x10,
960 other_len: 0x10
961 })
962 );
963 assert_eq!(
964 bus.insert(dev.clone(), 0x0, 0x20),
965 Err(Error::Overlap {
966 base: 0x0,
967 len: 0x20,
968 other_base: 0x10,
969 other_len: 0x10
970 })
971 );
972 assert_eq!(bus.insert(dev.clone(), 0x20, 0x05), Ok(()));
973 assert_eq!(bus.insert(dev.clone(), 0x25, 0x05), Ok(()));
974 assert_eq!(bus.insert(dev, 0x0, 0x10), Ok(()));
975 }
976
977 #[test]
978 fn bus_insert_full_addr() {
979 let bus = Bus::new(BusType::Io);
980 let dev = Arc::new(Mutex::new(MockDevice::new()));
981 assert_eq!(
982 bus.insert(dev.clone(), 0x10, 0),
983 Err(Error::Overlap {
984 base: 0x10,
985 len: 0,
986 other_base: 0,
987 other_len: 0
988 })
989 );
990 assert_eq!(bus.insert(dev.clone(), 0x10, 0x10), Ok(()));
991 assert_eq!(
992 bus.insert(dev.clone(), 0x0f, 0x10),
993 Err(Error::Overlap {
994 base: 0x0f,
995 len: 0x10,
996 other_base: 0x10,
997 other_len: 0x10
998 })
999 );
1000 assert_eq!(
1001 bus.insert(dev.clone(), 0x10, 0x10),
1002 Err(Error::Overlap {
1003 base: 0x10,
1004 len: 0x10,
1005 other_base: 0x10,
1006 other_len: 0x10
1007 })
1008 );
1009 assert_eq!(
1010 bus.insert(dev.clone(), 0x10, 0x15),
1011 Err(Error::Overlap {
1012 base: 0x10,
1013 len: 0x15,
1014 other_base: 0x10,
1015 other_len: 0x10
1016 })
1017 );
1018 assert_eq!(
1019 bus.insert(dev.clone(), 0x12, 0x15),
1020 Err(Error::Overlap {
1021 base: 0x12,
1022 len: 0x15,
1023 other_base: 0x10,
1024 other_len: 0x10
1025 })
1026 );
1027 assert_eq!(
1028 bus.insert(dev.clone(), 0x12, 0x01),
1029 Err(Error::Overlap {
1030 base: 0x12,
1031 len: 0x01,
1032 other_base: 0x10,
1033 other_len: 0x10
1034 })
1035 );
1036 assert_eq!(
1037 bus.insert(dev.clone(), 0x0, 0x20),
1038 Err(Error::Overlap {
1039 base: 0x0,
1040 len: 0x20,
1041 other_base: 0x10,
1042 other_len: 0x10
1043 })
1044 );
1045 assert_eq!(bus.insert(dev.clone(), 0x20, 0x05), Ok(()));
1046 assert_eq!(bus.insert(dev.clone(), 0x25, 0x05), Ok(()));
1047 assert_eq!(bus.insert(dev, 0x0, 0x10), Ok(()));
1048 }
1049
1050 #[test]
1051 fn bus_read_write() {
1052 let bus = Bus::new(BusType::Io);
1053 let dev = Arc::new(Mutex::new(MockDevice::new()));
1054 assert_eq!(bus.insert(dev, 0x10, 0x10), Ok(()));
1055 assert!(bus.read(0x10, &mut [0, 0, 0, 0]));
1056 assert!(bus.write(0x10, &[0, 0, 0, 0]));
1057 assert!(bus.read(0x11, &mut [0, 0, 0, 0]));
1058 assert!(bus.write(0x11, &[0, 0, 0, 0]));
1059 assert!(bus.read(0x16, &mut [0, 0, 0, 0]));
1060 assert!(bus.write(0x16, &[0, 0, 0, 0]));
1061 assert!(!bus.read(0x20, &mut [0, 0, 0, 0]));
1062 assert!(!bus.write(0x20, &[0, 0, 0, 0]));
1063 assert!(!bus.read(0x06, &mut [0, 0, 0, 0]));
1064 assert!(!bus.write(0x06, &[0, 0, 0, 0]));
1065 }
1066
1067 #[test]
1068 fn bus_read_write_values() {
1069 let bus = Bus::new(BusType::Io);
1070 let dev = Arc::new(Mutex::new(ConstantDevice {
1071 uses_full_addr: false,
1072 }));
1073 assert_eq!(bus.insert(dev, 0x10, 0x10), Ok(()));
1074
1075 let mut values = [0, 1, 2, 3];
1076 assert!(bus.read(0x10, &mut values));
1077 assert_eq!(values, [0, 1, 2, 3]);
1078 assert!(bus.write(0x10, &values));
1079 assert!(bus.read(0x15, &mut values));
1080 assert_eq!(values, [5, 6, 7, 8]);
1081 assert!(bus.write(0x15, &values));
1082 }
1083
1084 #[test]
1085 fn bus_read_write_full_addr_values() {
1086 let bus = Bus::new(BusType::Io);
1087 let dev = Arc::new(Mutex::new(ConstantDevice {
1088 uses_full_addr: true,
1089 }));
1090 assert_eq!(bus.insert(dev, 0x10, 0x10), Ok(()));
1091
1092 let mut values = [0u8; 4];
1093 assert!(bus.read(0x10, &mut values));
1094 assert_eq!(values, [0x10, 0x11, 0x12, 0x13]);
1095 assert!(bus.write(0x10, &values));
1096 assert!(bus.read(0x15, &mut values));
1097 assert_eq!(values, [0x15, 0x16, 0x17, 0x18]);
1098 assert!(bus.write(0x15, &values));
1099 }
1100
1101 #[test]
1102 fn bus_read_no_device() {
1103 let bus = Bus::new(BusType::Io);
1104
1105 let mut values = [1, 2, 3, 4];
1108 assert!(!bus.read(0x10, &mut values));
1109 assert_eq!(values, [0, 0, 0, 0]);
1110 }
1111
1112 suspendable_tests!(
1113 constant_device_true,
1114 ConstantDevice {
1115 uses_full_addr: true,
1116 },
1117 modify_constant_device
1118 );
1119
1120 suspendable_tests!(
1121 constant_device_false,
1122 ConstantDevice {
1123 uses_full_addr: false,
1124 },
1125 modify_constant_device
1126 );
1127
1128 #[test]
1129 fn bus_range_contains() {
1130 let a = BusRange {
1131 base: 0x1000,
1132 len: 0x400,
1133 };
1134 assert!(a.contains(0x1000));
1135 assert!(a.contains(0x13ff));
1136 assert!(!a.contains(0xfff));
1137 assert!(!a.contains(0x1400));
1138 assert!(a.contains(0x1200));
1139 }
1140
1141 #[test]
1142 fn bus_range_overlap() {
1143 let a = BusRange {
1144 base: 0x1000,
1145 len: 0x400,
1146 };
1147 assert!(a.overlaps(0x1000, 0x400));
1148 assert!(a.overlaps(0xf00, 0x400));
1149 assert!(a.overlaps(0x1000, 0x01));
1150 assert!(a.overlaps(0xfff, 0x02));
1151 assert!(a.overlaps(0x1100, 0x100));
1152 assert!(a.overlaps(0x13ff, 0x100));
1153 assert!(!a.overlaps(0x1400, 0x100));
1154 assert!(!a.overlaps(0xf00, 0x100));
1155 }
1156}