virtio: Merge the x86 and x86_64 platform specific code

This commit is contained in:
bjorn3
2024-06-15 21:56:25 +02:00
parent b6a75d0a16
commit 359f4482dd
2 changed files with 1 additions and 86 deletions
-81
View File
@@ -1,81 +0,0 @@
use crate::{legacy_transport::LegacyTransport, reinit, transport::Error, Device};
use pcid_interface::irq_helpers::{allocate_single_interrupt_vector_for_msi, read_bsp_apic_id};
use pcid_interface::msi::MsixTableEntry;
use std::{fs::File, ptr::NonNull};
use crate::{probe::MappedMsixRegs, MSIX_PRIMARY_VECTOR};
use pcid_interface::*;
pub fn enable_msix(pcid_handle: &mut PciFunctionHandle) -> Result<File, Error> {
let pci_config = pcid_handle.config();
// Extended message signaled interrupts.
let msix_info = match pcid_handle.feature_info(PciFeature::MsiX)? {
PciFeatureInfo::MsiX(capability) => capability,
_ => unreachable!(),
};
msix_info.validate(pci_config.func.bars);
let bar_address = unsafe { pcid_handle.map_bar(msix_info.table_bar)? }
.ptr
.as_ptr() as usize;
let virt_table_base = (bar_address + msix_info.table_offset as usize) as *mut MsixTableEntry;
let mut info = MappedMsixRegs {
virt_table_base: NonNull::new(virt_table_base).unwrap(),
info: msix_info,
};
// Allocate the primary MSI vector.
// FIXME allow the driver to register multiple MSI-X vectors
// FIXME move this MSI-X registering code into pcid_interface or pcid itself
let interrupt_handle = {
let table_entry_pointer = info.table_entry_pointer(MSIX_PRIMARY_VECTOR as usize);
let destination_id = read_bsp_apic_id().expect("virtio_core: `read_bsp_apic_id()` failed");
let (msg_addr_and_data, interrupt_handle) =
allocate_single_interrupt_vector_for_msi(destination_id);
table_entry_pointer.write_addr_and_data(msg_addr_and_data);
table_entry_pointer.unmask();
interrupt_handle
};
pcid_handle.enable_feature(PciFeature::MsiX)?;
log::info!("virtio: using MSI-X (interrupt_handle={interrupt_handle:?})");
Ok(interrupt_handle)
}
pub fn probe_legacy_port_transport(
pci_config: &SubdriverArguments,
pcid_handle: &mut PciFunctionHandle,
) -> Result<Device, Error> {
let port = pci_config.func.bars[0].expect_port();
common::acquire_port_io_rights().expect("virtio: failed to set I/O privilege level");
log::warn!("virtio: using legacy transport");
let transport = LegacyTransport::new(port);
// Setup interrupts.
let all_pci_features = pcid_handle.fetch_all_features()?;
let has_msix = all_pci_features.iter().any(|feature| feature.is_msix());
// According to the virtio specification, the device REQUIRED to support MSI-X.
assert!(has_msix, "virtio: device does not support MSI-X");
let irq_handle = enable_msix(pcid_handle)?;
let device = Device {
transport,
irq_handle,
device_space: core::ptr::null_mut(),
};
device.transport.reset();
reinit(&device)?;
Ok(device)
}
+1 -5
View File
@@ -10,14 +10,10 @@ mod probe;
#[path="arch/aarch64.rs"]
mod arch;
#[cfg(target_arch = "x86")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[path="arch/x86.rs"]
mod arch;
#[cfg(target_arch = "x86_64")]
#[path="arch/x86_64.rs"]
mod arch;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
mod legacy_transport;