chipset_device_resources/
lib.rs1#![forbid(unsafe_code)]
7
8use async_trait::async_trait;
9use chipset_device::ChipsetDevice;
10use guestmem::GuestMemory;
11use inspect::InspectMut;
12use std::ops::RangeInclusive;
13use vm_resource::CanResolveTo;
14use vm_resource::kind::ChipsetDeviceHandleKind;
15use vmcore::device_state::ChangeDeviceState;
16use vmcore::line_interrupt::LineInterrupt;
17use vmcore::save_restore::ProtobufSaveRestore;
18use vmcore::vm_task::VmTaskDriverSource;
19use vmcore::vmtime::VmTimeSource;
20
21#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
23pub struct LineSetId(&'static str);
24
25impl LineSetId {
26 pub fn name(&self) -> &str {
28 self.0
29 }
30}
31
32pub const IRQ_LINE_SET: LineSetId = LineSetId("irq");
35pub const GPE0_LINE_SET: LineSetId = LineSetId("gpe0");
37pub const BSP_LINT_LINE_SET: LineSetId = LineSetId("bsp_lint");
39
40impl CanResolveTo<ResolvedChipsetDevice> for ChipsetDeviceHandleKind {
41 type Input<'a> = ResolveChipsetDeviceHandleParams<'a>;
42}
43
44pub struct ResolveChipsetDeviceHandleParams<'a> {
47 pub device_name: &'a str,
49 pub guest_memory: &'a GuestMemory,
51 pub encrypted_guest_memory: &'a GuestMemory,
56 pub vmtime: &'a VmTimeSource,
58 pub is_restoring: bool,
65 pub configure: &'a mut dyn ConfigureChipsetDevice,
67 pub task_driver_source: &'a VmTaskDriverSource,
69 pub register_mmio: &'a mut (dyn chipset_device::mmio::RegisterMmioIntercept + Send),
71 pub register_pio: &'a mut (dyn chipset_device::pio::RegisterPortIoIntercept + Send),
73}
74
75pub trait ConfigureChipsetDevice: Send {
77 fn new_line(&mut self, id: LineSetId, name: &str, vector: u32) -> LineInterrupt;
79
80 fn add_line_target(
82 &mut self,
83 id: LineSetId,
84 source_range: RangeInclusive<u32>,
85 target_start: u32,
86 );
87
88 fn omit_saved_state(&mut self);
90}
91
92#[async_trait]
93trait DynChipsetDevice: ChipsetDevice + ProtobufSaveRestore + InspectMut {
94 fn start(&mut self);
95 async fn stop(&mut self);
96 async fn reset(&mut self);
97}
98
99#[async_trait]
100impl<T: ChangeDeviceState + ChipsetDevice + ProtobufSaveRestore + InspectMut> DynChipsetDevice
101 for T
102{
103 fn start(&mut self) {
104 self.start()
105 }
106 async fn stop(&mut self) {
107 self.stop().await
108 }
109 async fn reset(&mut self) {
110 self.reset().await
111 }
112}
113
114pub struct ResolvedChipsetDevice(pub ErasedChipsetDevice);
116
117#[derive(InspectMut)]
119#[inspect(transparent(mut))]
120pub struct ErasedChipsetDevice(Box<dyn DynChipsetDevice>);
121
122impl<T: ChangeDeviceState + ChipsetDevice + ProtobufSaveRestore + InspectMut> From<T>
123 for ResolvedChipsetDevice
124{
125 fn from(value: T) -> Self {
126 Self(ErasedChipsetDevice(Box::new(value)))
127 }
128}
129
130impl ChangeDeviceState for ErasedChipsetDevice {
131 fn start(&mut self) {
132 self.0.start()
133 }
134
135 async fn stop(&mut self) {
136 self.0.stop().await
137 }
138
139 async fn reset(&mut self) {
140 self.0.reset().await
141 }
142}
143
144impl ChipsetDevice for ErasedChipsetDevice {
145 fn supports_pio(&mut self) -> Option<&mut dyn chipset_device::pio::PortIoIntercept> {
146 self.0.supports_pio()
147 }
148
149 fn supports_mmio(&mut self) -> Option<&mut dyn chipset_device::mmio::MmioIntercept> {
150 self.0.supports_mmio()
151 }
152
153 fn supports_pci(&mut self) -> Option<&mut dyn chipset_device::pci::PciConfigSpace> {
154 self.0.supports_pci()
155 }
156
157 fn supports_poll_device(&mut self) -> Option<&mut dyn chipset_device::poll_device::PollDevice> {
158 self.0.supports_poll_device()
159 }
160
161 fn supports_line_interrupt_target(
162 &mut self,
163 ) -> Option<&mut dyn chipset_device::interrupt::LineInterruptTarget> {
164 self.0.supports_line_interrupt_target()
165 }
166
167 fn supports_handle_eoi(&mut self) -> Option<&mut dyn chipset_device::interrupt::HandleEoi> {
168 self.0.supports_handle_eoi()
169 }
170
171 fn supports_acknowledge_pic_interrupt(
172 &mut self,
173 ) -> Option<&mut dyn chipset_device::interrupt::AcknowledgePicInterrupt> {
174 self.0.supports_acknowledge_pic_interrupt()
175 }
176}
177
178impl ProtobufSaveRestore for ErasedChipsetDevice {
179 fn save(
180 &mut self,
181 ) -> Result<vmcore::save_restore::SavedStateBlob, vmcore::save_restore::SaveError> {
182 self.0.save()
183 }
184
185 fn restore(
186 &mut self,
187 state: vmcore::save_restore::SavedStateBlob,
188 ) -> Result<(), vmcore::save_restore::RestoreError> {
189 self.0.restore(state)
190 }
191}