#[path = "../../../os-virtio-mmio-v2/src/lib.rs"] mod virtio_mmio_v2; use virtio_mmio_v2::{Error, Identity, Phase, Queue, Registry, Window}; fn identity() -> Identity { Identity {magic: virtio_mmio_v2::MAGIC, version: 2, device_id: 2, vendor_id: 0x554d_4551} } fn window(base: u64) -> Window { Window::new(base, 0x200, 0x4000_0000, 0x5000_0000).unwrap() } fn queue() -> Queue { Queue {maximum: 256, size: 128, desc: 0x4000_1000, available: 0x4000_2000, used: 0x4000_3000} } #[test] fn os_virtio_mmio_v2_positive() { let mut registry = Registry::<2>::new(); let claim = registry.claim(window(0x0a00_0000), identity()).unwrap(); registry.negotiate(claim, (1 << 5, 1), (1 << 5, 1)).unwrap(); assert_eq!(registry.phase(claim), Ok(Phase::FeaturesOk)); registry.queue_ready(claim, queue()).unwrap(); registry.driver_ok(claim).unwrap(); assert_eq!(registry.phase(claim), Ok(Phase::DriverOk)); registry.observe_reset(claim, 0, 0).unwrap(); registry.release(claim).unwrap(); assert_eq!(registry.count(), 0); let next = registry.claim(window(0x0a00_0000), identity()).unwrap(); assert!(next.generation > claim.generation); assert_eq!(registry.phase(claim), Err(Error::StaleClaim)); registry.release(next).unwrap(); } #[test] fn os_virtio_mmio_v2_negative() { assert_eq!(Window::new(0x0a00_0001, 0x200, 0x4000_0000, 0x5000_0000), Err(Error::InvalidWindow)); assert_eq!(Window::new(0x4000_0000, 0x200, 0x4000_0000, 0x5000_0000), Err(Error::InvalidWindow)); let mut registry = Registry::<1>::new(); let absent = Identity {device_id: 0, ..identity()}; assert_eq!(registry.claim(window(0x0a00_0000), absent), Err(Error::MissingDevice)); let legacy = Identity {version: 1, ..identity()}; assert_eq!(registry.claim(window(0x0a00_0000), legacy), Err(Error::WrongIdentity)); let claim = registry.claim(window(0x0a00_0000), identity()).unwrap(); let before = registry.snapshot(); assert_eq!(registry.claim(window(0x0a00_0000), identity()), Err(Error::DuplicateSlot)); assert_eq!(registry.negotiate(claim, (0, 1), (0, 0)), Err(Error::InvalidFeatures)); assert_eq!(registry.negotiate(claim, (0, 1), (1, 1)), Err(Error::InvalidFeatures)); assert_eq!(registry.queue_ready(claim, queue()), Err(Error::WrongPhase)); assert_eq!(registry.snapshot(), before); registry.negotiate(claim, (1 << 5, 1), (1 << 5, 1)).unwrap(); let features = registry.snapshot(); assert_eq!(registry.queue_ready(claim, Queue {size: 0, ..queue()}), Err(Error::InvalidQueue)); assert_eq!(registry.queue_ready(claim, Queue {size: 129, ..queue()}), Err(Error::InvalidQueue)); assert_eq!(registry.queue_ready(claim, Queue {desc: 0x4000_1001, ..queue()}), Err(Error::InvalidQueue)); assert_eq!(registry.snapshot(), features); registry.queue_ready(claim, queue()).unwrap(); let ready = registry.snapshot(); assert_eq!(registry.release(claim), Err(Error::StillReady)); assert_eq!(registry.observe_reset(claim, 0, 1), Err(Error::StillReady)); assert_eq!(registry.snapshot(), ready); registry.driver_ok(claim).unwrap(); assert_eq!(registry.release(claim), Err(Error::StillReady)); registry.observe_reset(claim, 0, 0).unwrap(); registry.release(claim).unwrap(); }