Skip to content

Commit 031fb88

Browse files
committed
pci: add test for device initialization
Add a unit test that ensures the device initialization process works properly. Signed-off-by: Babis Chalios <[email protected]>
1 parent 0ca3666 commit 031fb88

File tree

1 file changed

+136
-0
lines changed
  • src/vmm/src/devices/virtio/transport/pci

1 file changed

+136
-0
lines changed

src/vmm/src/devices/virtio/transport/pci/device.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,8 @@ mod tests {
10161016
use crate::arch::MEM_64BIT_DEVICES_START;
10171017
use crate::builder::tests::default_vmm;
10181018
use crate::devices::virtio::device::VirtioDevice;
1019+
use crate::devices::virtio::device_status::{ACKNOWLEDGE, DRIVER, DRIVER_OK, FEATURES_OK};
1020+
use crate::devices::virtio::generated::virtio_config::VIRTIO_F_VERSION_1;
10191021
use crate::devices::virtio::generated::virtio_ids;
10201022
use crate::devices::virtio::rng::Entropy;
10211023
use crate::devices::virtio::transport::pci::device::{
@@ -1513,4 +1515,138 @@ mod tests {
15131515
locked_virtio_pci_device.read_bar(0, NOTIFICATION_BAR_OFFSET, &mut buffer);
15141516
assert_eq!(buffer, [0u8; u64_to_usize(NOTIFICATION_SIZE)]);
15151517
}
1518+
1519+
fn write_driver_status(device: &mut VirtioPciDevice, status: u8) {
1520+
device.write_bar(0, COMMON_CONFIG_BAR_OFFSET + 0x14, status.as_slice());
1521+
}
1522+
1523+
fn read_driver_status(device: &mut VirtioPciDevice) -> u8 {
1524+
let mut status = 0u8;
1525+
device.read_bar(0, COMMON_CONFIG_BAR_OFFSET + 0x14, status.as_mut_slice());
1526+
status
1527+
}
1528+
1529+
fn read_device_features(device: &mut VirtioPciDevice) -> u64 {
1530+
let mut features_lo = 0u32;
1531+
device.write_bar(0, COMMON_CONFIG_BAR_OFFSET, 0u32.as_slice());
1532+
device.read_bar(
1533+
0,
1534+
COMMON_CONFIG_BAR_OFFSET + 0x4,
1535+
features_lo.as_mut_slice(),
1536+
);
1537+
let mut features_hi = 0u32;
1538+
device.write_bar(0, COMMON_CONFIG_BAR_OFFSET, 1u32.as_slice());
1539+
device.read_bar(
1540+
0,
1541+
COMMON_CONFIG_BAR_OFFSET + 0x4,
1542+
features_hi.as_mut_slice(),
1543+
);
1544+
1545+
features_lo as u64 | ((features_hi as u64) << 32)
1546+
}
1547+
1548+
fn write_driver_features(device: &mut VirtioPciDevice, features: u64) {
1549+
device.write_bar(0, COMMON_CONFIG_BAR_OFFSET + 0x8, 0u32.as_slice());
1550+
device.write_bar(
1551+
0,
1552+
COMMON_CONFIG_BAR_OFFSET + 0xc,
1553+
((features & 0xffff_ffff) as u32).as_slice(),
1554+
);
1555+
device.write_bar(0, COMMON_CONFIG_BAR_OFFSET + 0x8, 1u32.as_slice());
1556+
device.write_bar(
1557+
0,
1558+
COMMON_CONFIG_BAR_OFFSET + 0xc,
1559+
(((features >> 32) & 0xffff_ffff) as u32).as_slice(),
1560+
);
1561+
}
1562+
1563+
fn setup_queues(device: &mut VirtioPciDevice) {
1564+
device.write_bar(
1565+
0,
1566+
COMMON_CONFIG_BAR_OFFSET + 0x20,
1567+
0x8000_0000u64.as_slice(),
1568+
);
1569+
device.write_bar(
1570+
0,
1571+
COMMON_CONFIG_BAR_OFFSET + 0x28,
1572+
0x8000_1000u64.as_slice(),
1573+
);
1574+
device.write_bar(
1575+
0,
1576+
COMMON_CONFIG_BAR_OFFSET + 0x30,
1577+
0x8000_2000u64.as_slice(),
1578+
);
1579+
device.write_bar(0, COMMON_CONFIG_BAR_OFFSET + 0x1c, 1u16.as_slice());
1580+
}
1581+
1582+
#[test]
1583+
fn test_device_initialization() {
1584+
let mut vmm = create_vmm_with_virtio_pci_device();
1585+
let device = get_virtio_device(&vmm);
1586+
let mut locked_virtio_pci_device = device.lock().unwrap();
1587+
1588+
assert!(locked_virtio_pci_device.is_driver_init());
1589+
assert!(!locked_virtio_pci_device.is_driver_ready());
1590+
assert!(
1591+
!locked_virtio_pci_device
1592+
.device_activated
1593+
.load(std::sync::atomic::Ordering::SeqCst)
1594+
);
1595+
1596+
write_driver_status(
1597+
&mut locked_virtio_pci_device,
1598+
ACKNOWLEDGE.try_into().unwrap(),
1599+
);
1600+
write_driver_status(
1601+
&mut locked_virtio_pci_device,
1602+
(ACKNOWLEDGE | DRIVER).try_into().unwrap(),
1603+
);
1604+
assert!(!locked_virtio_pci_device.is_driver_init());
1605+
assert!(!locked_virtio_pci_device.is_driver_ready());
1606+
assert!(
1607+
!locked_virtio_pci_device
1608+
.device_activated
1609+
.load(std::sync::atomic::Ordering::SeqCst)
1610+
);
1611+
1612+
let status = read_driver_status(&mut locked_virtio_pci_device);
1613+
assert_eq!(status as u32, ACKNOWLEDGE | DRIVER);
1614+
1615+
// Entropy device just offers VIRTIO_F_VERSION_1
1616+
let offered_features = read_device_features(&mut locked_virtio_pci_device);
1617+
assert_eq!(offered_features, 1 << VIRTIO_F_VERSION_1);
1618+
// ACK features
1619+
write_driver_features(&mut locked_virtio_pci_device, offered_features);
1620+
write_driver_status(
1621+
&mut locked_virtio_pci_device,
1622+
(ACKNOWLEDGE | DRIVER | FEATURES_OK).try_into().unwrap(),
1623+
);
1624+
let status = read_driver_status(&mut locked_virtio_pci_device);
1625+
assert!((status & u8::try_from(FEATURES_OK).unwrap()) != 0);
1626+
1627+
assert!(!locked_virtio_pci_device.is_driver_init());
1628+
assert!(!locked_virtio_pci_device.is_driver_ready());
1629+
assert!(
1630+
!locked_virtio_pci_device
1631+
.device_activated
1632+
.load(std::sync::atomic::Ordering::SeqCst)
1633+
);
1634+
1635+
setup_queues(&mut locked_virtio_pci_device);
1636+
1637+
write_driver_status(
1638+
&mut locked_virtio_pci_device,
1639+
(ACKNOWLEDGE | DRIVER | FEATURES_OK | DRIVER_OK)
1640+
.try_into()
1641+
.unwrap(),
1642+
);
1643+
1644+
assert!(!locked_virtio_pci_device.is_driver_init());
1645+
assert!(locked_virtio_pci_device.is_driver_ready());
1646+
assert!(
1647+
locked_virtio_pci_device
1648+
.device_activated
1649+
.load(std::sync::atomic::Ordering::SeqCst)
1650+
);
1651+
}
15161652
}

0 commit comments

Comments
 (0)