diff --git a/virtio-core/src/arch/aarch64.rs b/virtio-core/src/arch/aarch64.rs index 29e3b5855a..5d855258ca 100644 --- a/virtio-core/src/arch/aarch64.rs +++ b/virtio-core/src/arch/aarch64.rs @@ -7,10 +7,3 @@ use crate::{transport::Error, Device}; pub fn enable_msix(pcid_handle: &mut PcidServerHandle) -> Result { unimplemented!("virtio_core: aarch64 enable_msix") } - -pub fn probe_legacy_port_transport( - pci_config: &SubdriverArguments, - pcid_handle: &mut PcidServerHandle, -) -> Result { - panic!("virtio-core: aarch64 doesn't support legacy port I/O") -} \ No newline at end of file diff --git a/virtio-core/src/arch/x86.rs b/virtio-core/src/arch/x86.rs index edb85ab942..ebea0f9aa7 100644 --- a/virtio-core/src/arch/x86.rs +++ b/virtio-core/src/arch/x86.rs @@ -1,4 +1,4 @@ -use crate::{legacy_transport::LegacyTransport, reinit, transport::Error, Device}; +use crate::transport::Error; use pcid_interface::irq_helpers::{allocate_single_interrupt_vector_for_msi, read_bsp_apic_id}; use pcid_interface::msi::MsixTableEntry; @@ -48,34 +48,3 @@ pub fn enable_msix(pcid_handle: &mut PciFunctionHandle) -> Result { 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 { - 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) -} diff --git a/virtio-core/src/legacy_transport.rs b/virtio-core/src/legacy_transport.rs deleted file mode 100644 index 45341b103f..0000000000 --- a/virtio-core/src/legacy_transport.rs +++ /dev/null @@ -1,187 +0,0 @@ -use std::{sync::{Weak, atomic::{AtomicU16, Ordering}, Arc}, mem::size_of, fs::File}; - -use common::dma::Dma; -use syscall::{Pio, Io}; - -use crate::{transport::{NotifyBell, Transport, Queue, Error, Available, Used, queue_part_sizes, spawn_irq_thread, Mem, Borrowed}, spec::{Descriptor, DeviceStatusFlags}}; - - -pub enum LegacyRegister { - DeviceFeatures = 0, // u32 - - QueueAddress = 8, // u32 - QueueSize = 12, // u16 - QueueSelect = 14, // u16 - QueueNotify = 16, // u16 - - DeviceStatus = 18, // u8 - - ConfigMsixVector = 20, // u16 - QueueMsixVector = 22, // u16 -} - -struct LegacyBell(Weak); - -impl NotifyBell for LegacyBell { - #[inline] - fn ring(&self, queue_index: u16) { - let transport = self.0.upgrade().expect("bell: transport dropped"); - transport.write::(LegacyRegister::QueueNotify, queue_index) - } -} - -pub struct LegacyTransport(u16, AtomicU16, Weak); - -impl LegacyTransport { - pub(super) fn new(port: u16) -> Arc { - Arc::new_cyclic(|sref| Self(port, AtomicU16::new(0), sref.clone())) - } - - unsafe fn read_raw(&self, offset: usize) -> V - where - V: Sized + TryFrom, - >::Error: std::fmt::Debug, - { - let port = self.0 + offset as u16; - - if size_of::() == size_of::() { - V::try_from(Pio::::new(port).read() as u64).unwrap() - } else if size_of::() == size_of::() { - V::try_from(Pio::::new(port).read() as u64).unwrap() - } else if size_of::() == size_of::() { - V::try_from(Pio::::new(port).read() as u64).unwrap() - } else if size_of::() == size_of::() { - let lower = Pio::::new(port).read() as u64; - let upper = Pio::::new(port + size_of::() as u16).read() as u64; - - V::try_from(lower | (upper << 32)).unwrap() - } else { - unreachable!() - } - } - - fn read(&self, register: LegacyRegister) -> V - where - V: Sized + TryFrom, - >::Error: std::fmt::Debug, - { - unsafe { self.read_raw(register as usize) } - } - - fn write(&self, register: LegacyRegister, value: V) - where - V: Sized + TryInto, - >::Error: std::fmt::Debug, - { - if size_of::() == size_of::() { - Pio::::new(self.0 + register as u16).write(value.try_into().unwrap() as u8); - } else if size_of::() == size_of::() { - Pio::::new(self.0 + register as u16).write(value.try_into().unwrap() as u16); - } else if size_of::() == size_of::() { - Pio::::new(self.0 + register as u16).write(value.try_into().unwrap() as u32); - } else { - unreachable!() - } - } -} - -impl Transport for LegacyTransport { - fn reset(&self) { - self.write(LegacyRegister::DeviceStatus, 0u8); - - let status = self.read::(LegacyRegister::DeviceStatus); - assert_eq!(status, 0); - } - - fn check_device_feature(&self, feature: u32) -> bool { - assert!( - feature < 32, - "virtio: cannot query feature {feature} on a legacy device" - ); - self.read::(LegacyRegister::DeviceFeatures) & (1 << feature) == (1 << feature) - } - - fn ack_driver_feature(&self, feature: u32) { - assert!( - feature < 32, - "virtio: cannot ack feature {feature} on a legacy device" - ); - - let current = self.read::(LegacyRegister::DeviceFeatures); - self.write::(LegacyRegister::DeviceFeatures, current | (1 << feature)); - } - - fn setup_queue(&self, vector: u16, irq_handle: &File) -> Result, Error> { - let queue_index = self.1.fetch_add(1, Ordering::SeqCst); - self.write(LegacyRegister::QueueSelect, queue_index); - - let queue_size = self.read::(LegacyRegister::QueueSize) as usize; - let (desc_size, avail_size, used_size) = queue_part_sizes(queue_size); - - let descriptor = unsafe { - Dma::<[Descriptor]>::zeroed_slice(queue_size)?.assume_init() - }; - - let avail_addr = descriptor.physical() + desc_size; - let avail_virt = (descriptor.as_ptr() as usize) + desc_size; - let avail = unsafe { Available::from_raw(Mem::Borrowed(Borrowed::new(avail_addr, avail_virt, avail_size)), queue_size)? }; - - let used_addr = avail_addr + avail_size; - let used_virt = avail_virt + desc_size; - let used = unsafe { Used::from_raw(Mem::Borrowed(Borrowed::new(used_addr, used_virt, used_size)), queue_size)? }; - - self.write::(LegacyRegister::QueueMsixVector, vector); - self.write::(LegacyRegister::QueueAddress, (descriptor.physical() as u32) >> 12); - - log::info!("virtio-core: enabled queue #{queue_index} (size={queue_size})"); - - let queue = Queue::new( - descriptor, - avail, - used, - LegacyBell(self.2.clone()), - queue_index, - vector, - ); - - spawn_irq_thread(irq_handle, &queue); - Ok(queue) - } - - fn load_config(&self, offset: u8, size: u8) -> u64 { - // We always enable MSI-X. So, the device configuration space offset will - // always be 0x18. - // - // Checkout 4.1.4.8 Legacy Interfaces: A Note on PCI Device Layout - const DEVICE_SPACE_OFFSET: usize = 0x18; - - let size = size as usize; - let offset = DEVICE_SPACE_OFFSET + offset as usize; - - unsafe { - if size == size_of::() { - self.read_raw::(offset) as u64 - } else if size == size_of::() { - self.read_raw::(offset) as u64 - } else if size == size_of::() { - self.read_raw::(offset) as u64 - } else if size == size_of::() { - self.read_raw::(offset) as u64 - } else { - unreachable!() - } - } - } - - fn insert_status(&self, status: DeviceStatusFlags) { - let old = self.read::(LegacyRegister::DeviceStatus); - self.write(LegacyRegister::DeviceStatus, old | status.bits()); - } - - fn reinit_queue(&self, _queue: Arc) { - todo!() - } - - // Legacy devices do not have the `FEATURES_OK` bit. - fn finalize_features(&self) {} -} diff --git a/virtio-core/src/lib.rs b/virtio-core/src/lib.rs index 8dfd9a676f..817caaf913 100644 --- a/virtio-core/src/lib.rs +++ b/virtio-core/src/lib.rs @@ -14,8 +14,5 @@ mod arch; #[path="arch/x86.rs"] mod arch; -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -mod legacy_transport; - pub use probe::{probe_device, reinit, Device, MSIX_PRIMARY_VECTOR}; diff --git a/virtio-core/src/probe.rs b/virtio-core/src/probe.rs index 984acd88d2..9ecdd01ab4 100644 --- a/virtio-core/src/probe.rs +++ b/virtio-core/src/probe.rs @@ -131,48 +131,46 @@ pub fn probe_device(pcid_handle: &mut PciFunctionHandle) -> Result Result<(), Error> { diff --git a/virtio-core/src/transport.rs b/virtio-core/src/transport.rs index 14150cb279..c679dd8699 100644 --- a/virtio-core/src/transport.rs +++ b/virtio-core/src/transport.rs @@ -463,7 +463,7 @@ pub trait Transport: Sync + Send { fn ack_driver_feature(&self, feature: u32); /// Finalizes the acknowledged features by setting the `FEATURES_OK` bit in the - /// device status flags. No-op on a legacy device. + /// device status flags. fn finalize_features(&self); /// Runs the device.