Skip to content

Commit dd4d9d8

Browse files
committed
Introduce structs to manage device resources
Introduce data structures to manage device resources, so we could decouple resource allocator from resource consumers. Signed-off-by: Liu Jiang <[email protected]>
1 parent 21910a1 commit dd4d9d8

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ extern crate vm_memory;
77

88
use vm_memory::GuestAddress;
99

10+
pub mod resources;
11+
1012
/// IO Addresses.
1113
#[derive(Debug, Copy, Clone)]
1214
pub enum IoAddress {

src/resources.rs

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Copyright (C) 2019 Alibaba Cloud. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! Structs to manage device resources.
5+
6+
/// Type of Message Singaled Interrupt
7+
#[derive(Copy, Clone, PartialEq)]
8+
pub enum MsiIrqType {
9+
/// PCI MSI IRQ numbers.
10+
PciMsi,
11+
/// PCI MSIx IRQ numbers.
12+
PciMsix,
13+
/// Generic MSI IRQ numbers.
14+
GenericMsi,
15+
}
16+
17+
/// Enumeration for device resources.
18+
#[allow(missing_docs)]
19+
#[derive(Clone)]
20+
pub enum Resource {
21+
/// IO Port address range.
22+
PioAddressRange { base: u16, size: u16 },
23+
/// Memory Mapped IO address range.
24+
MmioAddressRange { base: u64, size: u64 },
25+
/// Legacy IRQ number.
26+
LegacyIrq(u32),
27+
/// Message Signaled Interrupt
28+
MsiIrq {
29+
ty: MsiIrqType,
30+
base: u32,
31+
size: u32,
32+
},
33+
/// Network Interface Card MAC address.
34+
MacAddresss(String),
35+
/// KVM memslot index.
36+
KvmMemSlot(u32),
37+
}
38+
39+
/// Newtype to store a set of device resources.
40+
#[derive(Default, Clone)]
41+
pub struct DeviceResources(Vec<Resource>);
42+
43+
impl DeviceResources {
44+
/// Create a container object to store device resources.
45+
pub fn new() -> Self {
46+
DeviceResources(Vec::new())
47+
}
48+
49+
/// Append a device resource to the container object.
50+
pub fn append(&mut self, entry: Resource) {
51+
self.0.push(entry);
52+
}
53+
54+
/// Get the IO port address resources.
55+
pub fn get_pio_address_ranges(&self) -> Vec<(u16, u16)> {
56+
let mut vec = Vec::new();
57+
for entry in self.0.iter().as_ref() {
58+
if let Resource::PioAddressRange { base, size } = entry {
59+
vec.push((*base, *size));
60+
}
61+
}
62+
vec
63+
}
64+
65+
/// Get the Memory Mapped IO address resources.
66+
pub fn get_mmio_address_ranges(&self) -> Vec<(u64, u64)> {
67+
let mut vec = Vec::new();
68+
for entry in self.0.iter().as_ref() {
69+
if let Resource::MmioAddressRange { base, size } = entry {
70+
vec.push((*base, *size));
71+
}
72+
}
73+
vec
74+
}
75+
76+
/// Get the first legacy interrupt number(IRQ).
77+
pub fn get_legacy_irq(&self) -> Option<u32> {
78+
for entry in self.0.iter().as_ref() {
79+
if let Resource::LegacyIrq(base) = entry {
80+
return Some(*base);
81+
}
82+
}
83+
None
84+
}
85+
86+
/// Get information about the first PCI MSI interrupt resource.
87+
pub fn get_pci_msi_irqs(&self) -> Option<(u32, u32)> {
88+
self.get_msi_irqs(MsiIrqType::PciMsi)
89+
}
90+
91+
/// Get information about the first PCI MSIx interrupt resource.
92+
pub fn get_pci_msix_irqs(&self) -> Option<(u32, u32)> {
93+
self.get_msi_irqs(MsiIrqType::PciMsix)
94+
}
95+
96+
/// Get information about the first Generic MSI interrupt resource.
97+
pub fn get_generic_msi_irqs(&self) -> Option<(u32, u32)> {
98+
self.get_msi_irqs(MsiIrqType::GenericMsi)
99+
}
100+
101+
fn get_msi_irqs(&self, ty: MsiIrqType) -> Option<(u32, u32)> {
102+
for entry in self.0.iter().as_ref() {
103+
if let Resource::MsiIrq {
104+
ty: msi_type,
105+
base,
106+
size,
107+
} = entry
108+
{
109+
if ty == *msi_type {
110+
return Some((*base, *size));
111+
}
112+
}
113+
}
114+
None
115+
}
116+
117+
/// Get the KVM memory slots to map memory into the guest.
118+
pub fn get_kvm_mem_slots(&self) -> Vec<u32> {
119+
let mut vec = Vec::new();
120+
for entry in self.0.iter().as_ref() {
121+
if let Resource::KvmMemSlot(index) = entry {
122+
vec.push(*index);
123+
}
124+
}
125+
vec
126+
}
127+
128+
/// Get the first resource information for NIC MAC address.
129+
pub fn get_mac_address(&self) -> Option<String> {
130+
for entry in self.0.iter().as_ref() {
131+
if let Resource::MacAddresss(addr) = entry {
132+
return Some(addr.clone());
133+
}
134+
}
135+
None
136+
}
137+
138+
/// Get immutable reference to all the resources.
139+
pub fn get_all_resources(&self) -> &[Resource] {
140+
&self.0
141+
}
142+
}

0 commit comments

Comments
 (0)