• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use zerocopy::{FromBytes, Immutable, IntoBytes};
2 
3 use super::{mmio::MmioTransport, pci::PciTransport, DeviceStatus, DeviceType, Transport};
4 use crate::{PhysAddr, Result};
5 
6 /// A wrapper for an arbitrary VirtIO transport, either MMIO or PCI.
7 #[derive(Debug)]
8 pub enum SomeTransport {
9     /// An MMIO transport.
10     Mmio(MmioTransport),
11     /// A PCI transport.
12     Pci(PciTransport),
13     /// An x86-64 pKVM PCI transport.
14     #[cfg(target_arch = "x86_64")]
15     HypPci(super::x86_64::HypPciTransport),
16 }
17 
18 impl From<MmioTransport> for SomeTransport {
from(mmio: MmioTransport) -> Self19     fn from(mmio: MmioTransport) -> Self {
20         Self::Mmio(mmio)
21     }
22 }
23 
24 impl From<PciTransport> for SomeTransport {
from(pci: PciTransport) -> Self25     fn from(pci: PciTransport) -> Self {
26         Self::Pci(pci)
27     }
28 }
29 
30 impl Transport for SomeTransport {
device_type(&self) -> DeviceType31     fn device_type(&self) -> DeviceType {
32         match self {
33             Self::Mmio(mmio) => mmio.device_type(),
34             Self::Pci(pci) => pci.device_type(),
35             #[cfg(target_arch = "x86_64")]
36             Self::HypPci(pci) => pci.device_type(),
37         }
38     }
39 
read_device_features(&mut self) -> u6440     fn read_device_features(&mut self) -> u64 {
41         match self {
42             Self::Mmio(mmio) => mmio.read_device_features(),
43             Self::Pci(pci) => pci.read_device_features(),
44             #[cfg(target_arch = "x86_64")]
45             Self::HypPci(pci) => pci.read_device_features(),
46         }
47     }
48 
write_driver_features(&mut self, driver_features: u64)49     fn write_driver_features(&mut self, driver_features: u64) {
50         match self {
51             Self::Mmio(mmio) => mmio.write_driver_features(driver_features),
52             Self::Pci(pci) => pci.write_driver_features(driver_features),
53             #[cfg(target_arch = "x86_64")]
54             Self::HypPci(pci) => pci.write_driver_features(driver_features),
55         }
56     }
57 
max_queue_size(&mut self, queue: u16) -> u3258     fn max_queue_size(&mut self, queue: u16) -> u32 {
59         match self {
60             Self::Mmio(mmio) => mmio.max_queue_size(queue),
61             Self::Pci(pci) => pci.max_queue_size(queue),
62             #[cfg(target_arch = "x86_64")]
63             Self::HypPci(pci) => pci.max_queue_size(queue),
64         }
65     }
66 
notify(&mut self, queue: u16)67     fn notify(&mut self, queue: u16) {
68         match self {
69             Self::Mmio(mmio) => mmio.notify(queue),
70             Self::Pci(pci) => pci.notify(queue),
71             #[cfg(target_arch = "x86_64")]
72             Self::HypPci(pci) => pci.notify(queue),
73         }
74     }
75 
get_status(&self) -> DeviceStatus76     fn get_status(&self) -> DeviceStatus {
77         match self {
78             Self::Mmio(mmio) => mmio.get_status(),
79             Self::Pci(pci) => pci.get_status(),
80             #[cfg(target_arch = "x86_64")]
81             Self::HypPci(pci) => pci.get_status(),
82         }
83     }
84 
set_status(&mut self, status: DeviceStatus)85     fn set_status(&mut self, status: DeviceStatus) {
86         match self {
87             Self::Mmio(mmio) => mmio.set_status(status),
88             Self::Pci(pci) => pci.set_status(status),
89             #[cfg(target_arch = "x86_64")]
90             Self::HypPci(pci) => pci.set_status(status),
91         }
92     }
93 
set_guest_page_size(&mut self, guest_page_size: u32)94     fn set_guest_page_size(&mut self, guest_page_size: u32) {
95         match self {
96             Self::Mmio(mmio) => mmio.set_guest_page_size(guest_page_size),
97             Self::Pci(pci) => pci.set_guest_page_size(guest_page_size),
98             #[cfg(target_arch = "x86_64")]
99             Self::HypPci(pci) => pci.set_guest_page_size(guest_page_size),
100         }
101     }
102 
requires_legacy_layout(&self) -> bool103     fn requires_legacy_layout(&self) -> bool {
104         match self {
105             Self::Mmio(mmio) => mmio.requires_legacy_layout(),
106             Self::Pci(pci) => pci.requires_legacy_layout(),
107             #[cfg(target_arch = "x86_64")]
108             Self::HypPci(pci) => pci.requires_legacy_layout(),
109         }
110     }
111 
queue_set( &mut self, queue: u16, size: u32, descriptors: PhysAddr, driver_area: PhysAddr, device_area: PhysAddr, )112     fn queue_set(
113         &mut self,
114         queue: u16,
115         size: u32,
116         descriptors: PhysAddr,
117         driver_area: PhysAddr,
118         device_area: PhysAddr,
119     ) {
120         match self {
121             Self::Mmio(mmio) => mmio.queue_set(queue, size, descriptors, driver_area, device_area),
122             Self::Pci(pci) => pci.queue_set(queue, size, descriptors, driver_area, device_area),
123             #[cfg(target_arch = "x86_64")]
124             Self::HypPci(pci) => pci.queue_set(queue, size, descriptors, driver_area, device_area),
125         }
126     }
127 
queue_unset(&mut self, queue: u16)128     fn queue_unset(&mut self, queue: u16) {
129         match self {
130             Self::Mmio(mmio) => mmio.queue_unset(queue),
131             Self::Pci(pci) => pci.queue_unset(queue),
132             #[cfg(target_arch = "x86_64")]
133             Self::HypPci(pci) => pci.queue_unset(queue),
134         }
135     }
136 
queue_used(&mut self, queue: u16) -> bool137     fn queue_used(&mut self, queue: u16) -> bool {
138         match self {
139             Self::Mmio(mmio) => mmio.queue_used(queue),
140             Self::Pci(pci) => pci.queue_used(queue),
141             #[cfg(target_arch = "x86_64")]
142             Self::HypPci(pci) => pci.queue_used(queue),
143         }
144     }
145 
ack_interrupt(&mut self) -> bool146     fn ack_interrupt(&mut self) -> bool {
147         match self {
148             Self::Mmio(mmio) => mmio.ack_interrupt(),
149             Self::Pci(pci) => pci.ack_interrupt(),
150             #[cfg(target_arch = "x86_64")]
151             Self::HypPci(pci) => pci.ack_interrupt(),
152         }
153     }
154 
read_config_generation(&self) -> u32155     fn read_config_generation(&self) -> u32 {
156         match self {
157             Self::Mmio(mmio) => mmio.read_config_generation(),
158             Self::Pci(pci) => pci.read_config_generation(),
159             #[cfg(target_arch = "x86_64")]
160             Self::HypPci(pci) => pci.read_config_generation(),
161         }
162     }
163 
read_config_space<T: FromBytes>(&self, offset: usize) -> Result<T>164     fn read_config_space<T: FromBytes>(&self, offset: usize) -> Result<T> {
165         match self {
166             Self::Mmio(mmio) => mmio.read_config_space(offset),
167             Self::Pci(pci) => pci.read_config_space(offset),
168             #[cfg(target_arch = "x86_64")]
169             Self::HypPci(pci) => pci.read_config_space(offset),
170         }
171     }
172 
write_config_space<T: IntoBytes + Immutable>( &mut self, offset: usize, value: T, ) -> Result<()>173     fn write_config_space<T: IntoBytes + Immutable>(
174         &mut self,
175         offset: usize,
176         value: T,
177     ) -> Result<()> {
178         match self {
179             Self::Mmio(mmio) => mmio.write_config_space(offset, value),
180             Self::Pci(pci) => pci.write_config_space(offset, value),
181             #[cfg(target_arch = "x86_64")]
182             Self::HypPci(pci) => pci.write_config_space(offset, value),
183         }
184     }
185 }
186