mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-27 23:23:09 +00:00
vfio_user: Make GPIO device more interesting
Every third read on the GPIO pin will return 1 and also trigger an interrupt in the guest. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
c8967fcc37
commit
1181fd21fd
@ -6,11 +6,12 @@
|
|||||||
use argh::FromArgs;
|
use argh::FromArgs;
|
||||||
use log::info;
|
use log::info;
|
||||||
use pci::PciBarConfiguration;
|
use pci::PciBarConfiguration;
|
||||||
use std::{fs::File, mem::size_of, path::PathBuf};
|
use std::{fs::File, io::Write, mem::size_of, num::Wrapping, path::PathBuf};
|
||||||
use vfio_bindings::bindings::vfio::{
|
use vfio_bindings::bindings::vfio::{
|
||||||
vfio_region_info, VFIO_IRQ_INFO_EVENTFD, VFIO_PCI_BAR2_REGION_INDEX,
|
vfio_region_info, VFIO_IRQ_INFO_EVENTFD, VFIO_IRQ_SET_ACTION_TRIGGER,
|
||||||
VFIO_PCI_CONFIG_REGION_INDEX, VFIO_PCI_INTX_IRQ_INDEX, VFIO_PCI_NUM_IRQS, VFIO_PCI_NUM_REGIONS,
|
VFIO_IRQ_SET_DATA_EVENTFD, VFIO_PCI_BAR2_REGION_INDEX, VFIO_PCI_CONFIG_REGION_INDEX,
|
||||||
VFIO_REGION_INFO_FLAG_READ, VFIO_REGION_INFO_FLAG_WRITE,
|
VFIO_PCI_INTX_IRQ_INDEX, VFIO_PCI_NUM_IRQS, VFIO_PCI_NUM_REGIONS, VFIO_REGION_INFO_FLAG_READ,
|
||||||
|
VFIO_REGION_INFO_FLAG_WRITE,
|
||||||
};
|
};
|
||||||
use vfio_user::{IrqInfo, Server, ServerBackend};
|
use vfio_user::{IrqInfo, Server, ServerBackend};
|
||||||
|
|
||||||
@ -35,6 +36,8 @@ struct Args {
|
|||||||
|
|
||||||
struct TestBackend {
|
struct TestBackend {
|
||||||
configuration: pci::PciConfiguration,
|
configuration: pci::PciConfiguration,
|
||||||
|
irq: Option<File>,
|
||||||
|
count: Wrapping<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestBackend {
|
impl TestBackend {
|
||||||
@ -65,7 +68,11 @@ impl TestBackend {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
configuration.set_irq(1, pci::PciInterruptPin::IntA);
|
configuration.set_irq(1, pci::PciInterruptPin::IntA);
|
||||||
TestBackend { configuration }
|
TestBackend {
|
||||||
|
configuration,
|
||||||
|
irq: None,
|
||||||
|
count: Wrapping(0),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +90,16 @@ impl ServerBackend for TestBackend {
|
|||||||
let v = self.configuration.read_config_register(reg_idx);
|
let v = self.configuration.read_config_register(reg_idx);
|
||||||
let reg_offset = offset as usize % 4;
|
let reg_offset = offset as usize % 4;
|
||||||
data.copy_from_slice(&v.to_le_bytes()[reg_offset..reg_offset + data.len()]);
|
data.copy_from_slice(&v.to_le_bytes()[reg_offset..reg_offset + data.len()]);
|
||||||
|
} else if region == VFIO_PCI_BAR2_REGION_INDEX && offset == 0 {
|
||||||
|
info!("gpio value read: count = {}", self.count);
|
||||||
|
self.count += 1;
|
||||||
|
if self.count.0 % 3 == 0 {
|
||||||
|
data[0] = 1;
|
||||||
|
if let Some(irq) = &mut self.irq {
|
||||||
|
info!("Triggering interrupt for count = {}", self.count);
|
||||||
|
irq.write_all(&1u64.to_le_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -139,6 +156,13 @@ impl ServerBackend for TestBackend {
|
|||||||
fds: Vec<File>,
|
fds: Vec<File>,
|
||||||
) -> Result<(), std::io::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
info!("set_irqs index = {index} flags = {flags} start = {start} count = {count} fds = {fds:?}");
|
info!("set_irqs index = {index} flags = {flags} start = {start} count = {count} fds = {fds:?}");
|
||||||
|
if flags & (VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER) > 0 {
|
||||||
|
if count == 1 {
|
||||||
|
self.irq = Some(fds[0].try_clone().unwrap());
|
||||||
|
} else {
|
||||||
|
self.irq = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user