mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-03 11:25:20 +00:00
pci: vfio: Refactor code that reads PCI config from VFIO device
By splitting this into a trait with common code extracted then this will allow extensive reuse of logic in the vfio-user version. This commit also changed the order of parameters on ::write_config_dword() to place offset first to match the other functions. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
349dbb9aac
commit
a0e48a87b8
@ -246,19 +246,34 @@ pub struct MmioRegion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trait VfioPciConfig {
|
trait VfioPciConfig {
|
||||||
fn read_config_byte(&self, _offset: u32) -> u8 {
|
fn read_config_byte(&self, offset: u32) -> u8 {
|
||||||
|
let mut data: [u8; 1] = [0];
|
||||||
|
self.read_config(offset, &mut data);
|
||||||
|
data[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_config_word(&self, offset: u32) -> u16 {
|
||||||
|
let mut data: [u8; 2] = [0, 0];
|
||||||
|
self.read_config(offset, &mut data);
|
||||||
|
u16::from_le_bytes(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_config_dword(&self, offset: u32) -> u32 {
|
||||||
|
let mut data: [u8; 4] = [0, 0, 0, 0];
|
||||||
|
self.read_config(offset, &mut data);
|
||||||
|
u32::from_le_bytes(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_config_dword(&self, offset: u32, buf: u32) {
|
||||||
|
let data: [u8; 4] = buf.to_le_bytes();
|
||||||
|
self.write_config(offset, &data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_config(&self, _offset: u32, _data: &mut [u8]) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_config_word(&self, _offset: u32) -> u16 {
|
fn write_config(&self, _offset: u32, _data: &[u8]) {
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_config_dword(&self, _offset: u32) -> u32 {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_config_dword(&self, _buf: u32, _offset: u32) {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,32 +289,12 @@ impl VfioPciDeviceConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VfioPciConfig for VfioPciDeviceConfig {
|
impl VfioPciConfig for VfioPciDeviceConfig {
|
||||||
fn read_config_byte(&self, offset: u32) -> u8 {
|
fn read_config(&self, offset: u32, data: &mut [u8]) {
|
||||||
let mut data: [u8; 1] = [0];
|
|
||||||
self.device
|
self.device
|
||||||
.region_read(VFIO_PCI_CONFIG_REGION_INDEX, data.as_mut(), offset.into());
|
.region_read(VFIO_PCI_CONFIG_REGION_INDEX, data.as_mut(), offset.into());
|
||||||
|
|
||||||
data[0]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_config_word(&self, offset: u32) -> u16 {
|
fn write_config(&self, offset: u32, data: &[u8]) {
|
||||||
let mut data: [u8; 2] = [0, 0];
|
|
||||||
self.device
|
|
||||||
.region_read(VFIO_PCI_CONFIG_REGION_INDEX, data.as_mut(), offset.into());
|
|
||||||
|
|
||||||
u16::from_le_bytes(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_config_dword(&self, offset: u32) -> u32 {
|
|
||||||
let mut data: [u8; 4] = [0, 0, 0, 0];
|
|
||||||
self.device
|
|
||||||
.region_read(VFIO_PCI_CONFIG_REGION_INDEX, data.as_mut(), offset.into());
|
|
||||||
|
|
||||||
u32::from_le_bytes(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_config_dword(&self, buf: u32, offset: u32) {
|
|
||||||
let data: [u8; 4] = buf.to_le_bytes();
|
|
||||||
self.device
|
self.device
|
||||||
.region_write(VFIO_PCI_CONFIG_REGION_INDEX, &data, offset.into())
|
.region_write(VFIO_PCI_CONFIG_REGION_INDEX, &data, offset.into())
|
||||||
}
|
}
|
||||||
@ -869,7 +864,7 @@ impl PciDevice for VfioPciDevice {
|
|||||||
|
|
||||||
// To get size write all 1s
|
// To get size write all 1s
|
||||||
self.vfio_pci_configuration
|
self.vfio_pci_configuration
|
||||||
.write_config_dword(0xffff_ffff, bar_offset);
|
.write_config_dword(bar_offset, 0xffff_ffff);
|
||||||
|
|
||||||
// And read back BAR value. The device will write zeros for bits it doesn't care about
|
// And read back BAR value. The device will write zeros for bits it doesn't care about
|
||||||
let mut lower = self.vfio_pci_configuration.read_config_dword(bar_offset);
|
let mut lower = self.vfio_pci_configuration.read_config_dword(bar_offset);
|
||||||
@ -906,7 +901,7 @@ impl PciDevice for VfioPciDevice {
|
|||||||
// Query size of upper BAR of 64-bit BAR
|
// Query size of upper BAR of 64-bit BAR
|
||||||
let upper_offset: u32 = PCI_CONFIG_BAR_OFFSET + (bar_id + 1) * 4;
|
let upper_offset: u32 = PCI_CONFIG_BAR_OFFSET + (bar_id + 1) * 4;
|
||||||
self.vfio_pci_configuration
|
self.vfio_pci_configuration
|
||||||
.write_config_dword(0xffff_ffff, upper_offset);
|
.write_config_dword(upper_offset, 0xffff_ffff);
|
||||||
let upper = self.vfio_pci_configuration.read_config_dword(upper_offset);
|
let upper = self.vfio_pci_configuration.read_config_dword(upper_offset);
|
||||||
|
|
||||||
let mut combined_size = u64::from(upper) << 32 | u64::from(lower);
|
let mut combined_size = u64::from(upper) << 32 | u64::from(lower);
|
||||||
@ -1062,8 +1057,8 @@ impl PciDevice for VfioPciDevice {
|
|||||||
// enabling this bit, we first need to enable the MSI interrupts with
|
// enabling this bit, we first need to enable the MSI interrupts with
|
||||||
// VFIO through VFIO_DEVICE_SET_IRQS ioctl, and only after we can write
|
// VFIO through VFIO_DEVICE_SET_IRQS ioctl, and only after we can write
|
||||||
// to the device region to update the MSI Enable bit.
|
// to the device region to update the MSI Enable bit.
|
||||||
self.device
|
self.vfio_pci_configuration
|
||||||
.region_write(VFIO_PCI_CONFIG_REGION_INDEX, data, reg + offset);
|
.write_config((reg + offset) as u32, data);
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user