diff --git a/src/drivers/virtio/transport/pci.rs b/src/drivers/virtio/transport/pci.rs index 4f1a660d4a..bcccb2900f 100644 --- a/src/drivers/virtio/transport/pci.rs +++ b/src/drivers/virtio/transport/pci.rs @@ -32,54 +32,6 @@ use crate::drivers::pci::{DeviceHeader, Masks, PciDevice}; use crate::drivers::virtio::env::memory::{MemLen, MemOff, VirtMemAddr}; use crate::drivers::virtio::error::VirtioError; -/// Virtio's cfg_type constants; indicating type of structure in capabilities list -/// See Virtio specification v1.1 - 4.1.4 -// -// WARN: Upon changes in the set of the enum variants -// one MUST adjust the associated From -// implementation, in order catch all cases correctly, -// as this function uses the catch-all "_" case! -#[allow(dead_code, non_camel_case_types, clippy::upper_case_acronyms)] -#[derive(Copy, Clone, PartialEq, Eq)] -#[repr(u8)] -pub enum CfgType { - INVALID = 0, - VIRTIO_PCI_CAP_COMMON_CFG = 1, - VIRTIO_PCI_CAP_NOTIFY_CFG = 2, - VIRTIO_PCI_CAP_ISR_CFG = 3, - VIRTIO_PCI_CAP_DEVICE_CFG = 4, - VIRTIO_PCI_CAP_PCI_CFG = 5, - VIRTIO_PCI_CAP_SHARED_MEMORY_CFG = 8, -} - -impl From for u8 { - fn from(val: CfgType) -> u8 { - match val { - CfgType::INVALID => 0, - CfgType::VIRTIO_PCI_CAP_COMMON_CFG => 1, - CfgType::VIRTIO_PCI_CAP_NOTIFY_CFG => 2, - CfgType::VIRTIO_PCI_CAP_ISR_CFG => 3, - CfgType::VIRTIO_PCI_CAP_DEVICE_CFG => 4, - CfgType::VIRTIO_PCI_CAP_PCI_CFG => 5, - CfgType::VIRTIO_PCI_CAP_SHARED_MEMORY_CFG => 8, - } - } -} - -impl From for CfgType { - fn from(val: u8) -> Self { - match val { - 1 => CfgType::VIRTIO_PCI_CAP_COMMON_CFG, - 2 => CfgType::VIRTIO_PCI_CAP_NOTIFY_CFG, - 3 => CfgType::VIRTIO_PCI_CAP_ISR_CFG, - 4 => CfgType::VIRTIO_PCI_CAP_DEVICE_CFG, - 5 => CfgType::VIRTIO_PCI_CAP_PCI_CFG, - 8 => CfgType::VIRTIO_PCI_CAP_SHARED_MEMORY_CFG, - _ => CfgType::INVALID, - } - } -} - /// Public structure to allow drivers to read the configuration space /// safely #[derive(Clone)] @@ -92,7 +44,7 @@ pub struct Origin { /// Maps a given device specific pci configuration structure and /// returns a static reference to it. pub fn map_dev_cfg(cap: &PciCap) -> Option<&'static mut T> { - if cap.cfg_type != CfgType::VIRTIO_PCI_CAP_DEVICE_CFG { + if cap.cfg_type != virtio_spec::pci::Cap::DeviceCfg { error!("Capability of device config has wrong id. Mapping not possible..."); return None; }; @@ -131,10 +83,10 @@ pub fn map_dev_cfg(cap: &PciCap) -> Option<&'static mut T> { /// as it is not directly mapped into address space from PCI device /// configuration space. /// Therefore the struct only contains necessary information to map -/// corresponding [CfgType] into address space. +/// corresponding config type (`pci::Cap`) into address space. #[derive(Clone)] pub struct PciCap { - cfg_type: CfgType, + cfg_type: virtio_spec::pci::Cap, bar: PciBar, id: u8, offset: MemOff, @@ -262,7 +214,7 @@ impl PartialEq for PciCapRaw { /// a given Virtio PCI device. /// /// As Virtio's PCI devices are allowed to present multiple capability -/// structures of the same [CfgType], the structure +/// structures of the same config type (`pci::Cap`), the structure /// provides a driver with all capabilities, sorted in descending priority, /// allowing the driver to choose. /// The structure contains a special dev_cfg_list field, a vector holding @@ -1064,7 +1016,7 @@ fn read_caps( }; cap_list.push(PciCap { - cfg_type: CfgType::from(cap_raw.cfg_type), + cfg_type: virtio_spec::pci::Cap::from(cap_raw.cfg_type), bar: cap_bar, id: cap_raw.id, offset: MemOff::from(cap_raw.offset), @@ -1155,36 +1107,36 @@ pub(crate) fn map_caps(device: &PciDevice) -> Result match pci_cap.map_common_cfg() { + virtio_spec::pci::Cap::CommonCfg => match pci_cap.map_common_cfg() { Some(cap) => caps.add_cfg_common(ComCfg::new(cap, pci_cap.id)), None => error!( "Common config capability with id {}, of device {:x}, could not be mapped!", pci_cap.id, device_id ), }, - CfgType::VIRTIO_PCI_CAP_NOTIFY_CFG => match NotifCfg::new(&pci_cap) { + virtio_spec::pci::Cap::NotifyCfg => match NotifCfg::new(&pci_cap) { Some(notif) => caps.add_cfg_notif(notif), None => error!( "Notification config capability with id {}, of device {:x} could not be used!", pci_cap.id, device_id ), }, - CfgType::VIRTIO_PCI_CAP_ISR_CFG => match pci_cap.map_isr_status() { + virtio_spec::pci::Cap::IsrCfg => match pci_cap.map_isr_status() { Some(isr_stat) => caps.add_cfg_isr(IsrStatus::new(isr_stat, pci_cap.id)), None => error!( "ISR status config capability with id {}, of device {:x} could not be used!", pci_cap.id, device_id ), }, - CfgType::VIRTIO_PCI_CAP_PCI_CFG => caps.add_cfg_alt(PciCfgAlt::new(&pci_cap)), - CfgType::VIRTIO_PCI_CAP_SHARED_MEMORY_CFG => match ShMemCfg::new(&pci_cap) { + virtio_spec::pci::Cap::PciCfg => caps.add_cfg_alt(PciCfgAlt::new(&pci_cap)), + virtio_spec::pci::Cap::SharedMemoryCfg => match ShMemCfg::new(&pci_cap) { Some(sh_mem) => caps.add_cfg_sh_mem(sh_mem), None => error!( "Shared Memory config capability with id {}, of device {:x} could not be used!", pci_cap.id, device_id ), }, - CfgType::VIRTIO_PCI_CAP_DEVICE_CFG => caps.add_cfg_dev(pci_cap), + virtio_spec::pci::Cap::DeviceCfg => caps.add_cfg_dev(pci_cap), // PCI's configuration space is allowed to hold other structures, which are not virtio specific and are therefore ignored // in the following diff --git a/virtio-spec/src/pci.rs b/virtio-spec/src/pci.rs index b486f4fb7d..245fca4fd1 100644 --- a/virtio-spec/src/pci.rs +++ b/virtio-spec/src/pci.rs @@ -1,5 +1,6 @@ //! Definitions for Virtio over PCI bus. +use num_enum::{FromPrimitive, IntoPrimitive}; use volatile::access::{ReadOnly, ReadWrite, RestrictAccess}; use volatile::{VolatileFieldAccess, VolatilePtr}; @@ -9,6 +10,8 @@ use crate::{le16, le32, DeviceStatus}; /// Common configuration structure /// /// The common configuration structure is found at the bar and offset within the [`VIRTIO_PCI_CAP_COMMON_CFG`] capability. +/// +/// [`VIRTIO_PCI_CAP_COMMON_CFG`]: Cap::CommonCfg #[doc(alias = "virtio_pci_common_cfg")] #[cfg_attr( feature = "zerocopy", @@ -151,3 +154,41 @@ virtio_bitflags! { const DEVICE_CONFIGURATION_INTERRUPT = 1 << 1; } } + +/// PCI Capability Configuration Type +#[derive(IntoPrimitive, FromPrimitive, PartialEq, Eq, Clone, Copy, Debug)] +#[non_exhaustive] +#[repr(u8)] +pub enum Cap { + /// Common configuration + #[doc(alias = "VIRTIO_PCI_CAP_COMMON_CFG")] + CommonCfg = 1, + + /// Notifications + #[doc(alias = "VIRTIO_PCI_CAP_NOTIFY_CFG")] + NotifyCfg = 2, + + /// ISR Status + #[doc(alias = "VIRTIO_PCI_CAP_ISR_CFG")] + IsrCfg = 3, + + /// Device specific configuration + #[doc(alias = "VIRTIO_PCI_CAP_DEVICE_CFG")] + DeviceCfg = 4, + + /// PCI configuration access + #[doc(alias = "VIRTIO_PCI_CAP_PCI_CFG")] + PciCfg = 5, + + /// Shared memory region + #[doc(alias = "VIRTIO_PCI_CAP_SHARED_MEMORY_CFG")] + SharedMemoryCfg = 8, + + /// Vendor-specific data + #[doc(alias = "VIRTIO_PCI_CAP_VENDOR_CFG")] + VencodCfg = 9, + + /// Unknown device + #[num_enum(catch_all)] + Unknown(u8), +}