1#![forbid(unsafe_code)]
7
8use local_clock::InspectableLocalClock;
9use vm_resource::CanResolveTo;
10use vm_resource::ResourceKind;
11
12pub const LEGACY_CHIPSET_PCI_BUS_NAME: &str = "i440bx";
14
15pub enum CmosRtcTimeSourceHandleKind {}
17
18impl ResourceKind for CmosRtcTimeSourceHandleKind {
19 const NAME: &'static str = "cmos_rtc_time_source";
20}
21
22pub struct ResolvedCmosRtcTimeSource(pub Box<dyn InspectableLocalClock>);
24
25impl CanResolveTo<ResolvedCmosRtcTimeSource> for CmosRtcTimeSourceHandleKind {
26 type Input<'a> = ();
27}
28
29pub mod ipmi_kcs {
30 use super::CmosRtcTimeSourceHandleKind;
33 use ipmi_protocol::SelRecord;
34 use mesh::MeshPayload;
35 use vm_resource::CanResolveTo;
36 use vm_resource::Resource;
37 use vm_resource::ResourceId;
38 use vm_resource::ResourceKind;
39 use vm_resource::kind::ChipsetDeviceHandleKind;
40
41 pub const IPMI_KCS_DATA_PORT: u16 = 0xca2;
43 pub const IPMI_KCS_STATUS_COMMAND_PORT: u16 = IPMI_KCS_DATA_PORT + 1;
45 pub const IPMI_KCS_MMIO_BASE_ADDRESS_AARCH64: u64 = 0xeffe_7000;
47 pub const IPMI_KCS_MMIO_REGISTER_SPACING_AARCH64: u64 = 4;
49 pub const IPMI_KCS_MMIO_DATA_ADDRESS_AARCH64: u64 = IPMI_KCS_MMIO_BASE_ADDRESS_AARCH64;
51 pub const IPMI_KCS_MMIO_STATUS_COMMAND_ADDRESS_AARCH64: u64 =
53 IPMI_KCS_MMIO_BASE_ADDRESS_AARCH64 + IPMI_KCS_MMIO_REGISTER_SPACING_AARCH64;
54 pub const IPMI_KCS_MMIO_REGION_SIZE_AARCH64: u64 = 0x1000;
56
57 pub trait SelEventSink: Send {
59 fn try_send(&mut self, record_id: u16, record: SelRecord) -> bool;
61 }
62
63 pub enum IpmiSelEventSinkHandleKind {}
65
66 impl ResourceKind for IpmiSelEventSinkHandleKind {
67 const NAME: &'static str = "ipmi_sel_event_sink";
68 }
69
70 pub struct ResolvedIpmiSelEventSink(pub Box<dyn SelEventSink>);
72
73 impl CanResolveTo<ResolvedIpmiSelEventSink> for IpmiSelEventSinkHandleKind {
74 type Input<'a> = ();
75 }
76
77 #[derive(MeshPayload)]
79 pub struct IpmiKcsDeviceHandleX64 {
80 pub event_sink: Resource<IpmiSelEventSinkHandleKind>,
82 pub time_source: Resource<CmosRtcTimeSourceHandleKind>,
87 }
88
89 impl ResourceId<ChipsetDeviceHandleKind> for IpmiKcsDeviceHandleX64 {
90 const ID: &'static str = "ipmi-kcs-x64";
91 }
92
93 #[derive(MeshPayload)]
95 pub struct IpmiKcsDeviceHandleAArch64 {
96 pub event_sink: Resource<IpmiSelEventSinkHandleKind>,
98 pub time_source: Resource<CmosRtcTimeSourceHandleKind>,
103 }
104
105 impl ResourceId<ChipsetDeviceHandleKind> for IpmiKcsDeviceHandleAArch64 {
106 const ID: &'static str = "ipmi-kcs-aarch64";
107 }
108}
109
110pub mod cmos_rtc_time_source {
111 use super::CmosRtcTimeSourceHandleKind;
114 use super::ResolvedCmosRtcTimeSource;
115 use local_clock::LocalClockDelta;
116 use local_clock::SystemTimeClock;
117 use mesh::MeshPayload;
118 use vm_resource::ResolveResource;
119 use vm_resource::ResourceId;
120 use vm_resource::declare_static_resolver;
121
122 #[derive(MeshPayload)]
125 pub struct SystemTimeClockHandle {
126 pub delta_milliseconds: i64,
128 }
129
130 impl ResourceId<CmosRtcTimeSourceHandleKind> for SystemTimeClockHandle {
131 const ID: &'static str = "system_time_clock";
132 }
133
134 pub struct SystemTimeClockResolver;
136
137 declare_static_resolver! {
138 SystemTimeClockResolver,
139 (CmosRtcTimeSourceHandleKind, SystemTimeClockHandle),
140 }
141
142 impl ResolveResource<CmosRtcTimeSourceHandleKind, SystemTimeClockHandle>
143 for SystemTimeClockResolver
144 {
145 type Output = ResolvedCmosRtcTimeSource;
146 type Error = std::convert::Infallible;
147
148 fn resolve(
149 &self,
150 resource: SystemTimeClockHandle,
151 (): (),
152 ) -> Result<Self::Output, Self::Error> {
153 Ok(ResolvedCmosRtcTimeSource(Box::new(SystemTimeClock::new(
154 LocalClockDelta::from_millis(resource.delta_milliseconds),
155 ))))
156 }
157 }
158}
159
160pub mod i8042 {
161 use mesh::MeshPayload;
164 use vm_resource::Resource;
165 use vm_resource::ResourceId;
166 use vm_resource::kind::ChipsetDeviceHandleKind;
167 use vm_resource::kind::KeyboardInputHandleKind;
168
169 #[derive(MeshPayload)]
171 pub struct I8042DeviceHandle {
172 pub keyboard_input: Resource<KeyboardInputHandleKind>,
174 }
175
176 impl ResourceId<ChipsetDeviceHandleKind> for I8042DeviceHandle {
177 const ID: &'static str = "i8042";
178 }
179}
180
181pub mod isa_dma {
182 use mesh::MeshPayload;
185 use vm_resource::ResourceId;
186 use vm_resource::kind::IsaDmaControllerHandleKind;
187
188 #[derive(MeshPayload)]
190 pub struct GenericIsaDmaDeviceHandle;
191
192 impl ResourceId<IsaDmaControllerHandleKind> for GenericIsaDmaDeviceHandle {
193 const ID: &'static str = "genericIsaDma";
194 }
195}
196
197pub mod pic {
198 use mesh::MeshPayload;
201 use vm_resource::ResourceId;
202 use vm_resource::kind::ChipsetDeviceHandleKind;
203
204 #[derive(MeshPayload)]
206 pub struct PicDeviceHandle;
207
208 impl ResourceId<ChipsetDeviceHandleKind> for PicDeviceHandle {
209 const ID: &'static str = "pic";
210 }
211}
212
213pub mod pit {
214 use mesh::MeshPayload;
217 use vm_resource::ResourceId;
218 use vm_resource::kind::ChipsetDeviceHandleKind;
219
220 #[derive(MeshPayload)]
222 pub struct PitDeviceHandle;
223
224 impl ResourceId<ChipsetDeviceHandleKind> for PitDeviceHandle {
225 const ID: &'static str = "pit";
226 }
227}
228
229pub mod battery {
230 #[cfg(feature = "arbitrary")]
233 use arbitrary::Arbitrary;
234 use inspect::Inspect;
235 use mesh::MeshPayload;
236 use vm_resource::ResourceId;
237 use vm_resource::kind::ChipsetDeviceHandleKind;
238 #[derive(MeshPayload)]
240 pub struct BatteryDeviceHandleX64 {
241 pub battery_status_recv: mesh::Receiver<HostBatteryUpdate>,
243 }
244
245 impl ResourceId<ChipsetDeviceHandleKind> for BatteryDeviceHandleX64 {
246 const ID: &'static str = "batteryX64";
247 }
248
249 #[derive(MeshPayload)]
251 pub struct BatteryDeviceHandleAArch64 {
252 pub battery_status_recv: mesh::Receiver<HostBatteryUpdate>,
254 }
255
256 impl ResourceId<ChipsetDeviceHandleKind> for BatteryDeviceHandleAArch64 {
257 const ID: &'static str = "batteryAArch64";
258 }
259
260 #[derive(Debug, Clone, Copy, Inspect, PartialEq, Eq, MeshPayload, Default)]
262 #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
263 pub struct HostBatteryUpdate {
264 pub battery_present: bool,
266 pub charging: bool,
268 pub discharging: bool,
270 pub rate: u32,
272 pub remaining_capacity: u32,
274 pub max_capacity: u32,
276 pub ac_online: bool,
278 }
279
280 impl HostBatteryUpdate {
281 pub fn default_present() -> Self {
283 Self {
284 battery_present: true,
285 charging: true,
286 discharging: false,
287 rate: 1,
288 remaining_capacity: 950,
289 max_capacity: 1000,
290 ac_online: true,
291 }
292 }
293 }
294}
295
296pub mod piix4_pci_isa_bridge {
297 use mesh::MeshPayload;
300 use vm_resource::ResourceId;
301 use vm_resource::kind::ChipsetDeviceHandleKind;
302
303 #[derive(MeshPayload)]
305 pub struct Piix4PciIsaBridgeDeviceHandle;
306
307 pub const PIIX4_PCI_ISA_BRIDGE_BDF: (u8, u8, u8) = (0, 7, 0);
309
310 impl ResourceId<ChipsetDeviceHandleKind> for Piix4PciIsaBridgeDeviceHandle {
311 const ID: &'static str = "piix4PciIsaBridge";
312 }
313}
314
315pub mod ioapic {
316 use mesh::MeshPayload;
319 use std::fmt;
320 use std::fmt::Debug;
321 use vm_resource::CanResolveTo;
322 use vm_resource::Resource;
323 use vm_resource::ResourceId;
324 use vm_resource::ResourceKind;
325 use vm_resource::kind::ChipsetDeviceHandleKind;
326
327 pub const IOAPIC_NUM_ENTRIES: u8 = 24;
329
330 pub trait IoApicRouting: Send + Sync {
332 fn assert(&self, irq: u8);
334 fn set_route(&self, irq: u8, request: Option<(u64, u32)>);
337 }
338
339 impl Debug for dyn IoApicRouting {
340 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341 f.pad("IoApicRouting")
342 }
343 }
344
345 pub enum IoApicRoutingHandleKind {}
347
348 impl ResourceKind for IoApicRoutingHandleKind {
349 const NAME: &'static str = "ioapic_routing";
350 }
351
352 pub struct ResolvedIoApicRouting(pub Box<dyn IoApicRouting>);
357
358 impl CanResolveTo<ResolvedIoApicRouting> for IoApicRoutingHandleKind {
359 type Input<'a> = ();
360 }
361
362 #[derive(MeshPayload)]
364 pub struct GenericIoApicDeviceHandle {
365 pub routing: Resource<IoApicRoutingHandleKind>,
367 }
368
369 impl ResourceId<ChipsetDeviceHandleKind> for GenericIoApicDeviceHandle {
370 const ID: &'static str = "generic-ioapic";
371 }
372}
373
374pub mod piix4_uhci {
375 use mesh::MeshPayload;
378 use vm_resource::ResourceId;
379 use vm_resource::kind::ChipsetDeviceHandleKind;
380
381 #[derive(MeshPayload)]
383 pub struct Piix4PciUsbUhciStubDeviceHandle;
384
385 pub const PIIX4_PCI_USB_UHCI_STUB_BDF: (u8, u8, u8) = (0, 7, 2);
387
388 impl ResourceId<ChipsetDeviceHandleKind> for Piix4PciUsbUhciStubDeviceHandle {
389 const ID: &'static str = "piix4PciUsbUhciStub";
390 }
391}
392
393pub mod hyperv_guest_watchdog {
394 use mesh::MeshPayload;
397 use vm_resource::ResourceId;
398 use vm_resource::kind::ChipsetDeviceHandleKind;
399
400 pub const DEFAULT_WDAT_PORT_BASE: u16 = 0x30;
402
403 #[derive(MeshPayload)]
405 pub struct HyperVGuestWatchdogDeviceHandle {
406 pub port_base: u16,
408 }
409
410 impl ResourceId<ChipsetDeviceHandleKind> for HyperVGuestWatchdogDeviceHandle {
411 const ID: &'static str = "hyperv_guest_watchdog";
412 }
413}
414
415pub mod pm {
416 use mesh::MeshPayload;
419 use vm_resource::CanResolveTo;
420 use vm_resource::Resource;
421 use vm_resource::ResourceId;
422 use vm_resource::ResourceKind;
423 use vm_resource::kind::ChipsetDeviceHandleKind;
424
425 pub trait PmTimerAssist: Send + Sync {
427 fn set(&self, port: Option<u16>);
429 }
430
431 pub struct ResolvedPmTimerAssist(pub Box<dyn PmTimerAssist>);
433
434 pub enum PmTimerAssistHandleKind {}
436
437 impl ResourceKind for PmTimerAssistHandleKind {
438 const NAME: &'static str = "pm_timer_assist";
439 }
440
441 impl CanResolveTo<ResolvedPmTimerAssist> for PmTimerAssistHandleKind {
442 type Input<'a> = ();
443 }
444
445 #[derive(MeshPayload)]
447 pub struct HyperVPowerManagementDeviceHandle {
448 pub acpi_irq: u32,
450 pub pio_base: u16,
452 pub pm_timer_assist: Option<Resource<PmTimerAssistHandleKind>>,
454 }
455
456 impl ResourceId<ChipsetDeviceHandleKind> for HyperVPowerManagementDeviceHandle {
457 const ID: &'static str = "hyperv_power_management";
458 }
459
460 #[derive(MeshPayload)]
462 pub struct Piix4PowerManagementDeviceHandle {
463 pub pm_timer_assist: Option<Resource<PmTimerAssistHandleKind>>,
465 }
466
467 pub const PIIX4_PM_BDF: (u8, u8, u8) = (0, 7, 3);
469
470 pub const DEFAULT_PM_PIO_BASE: u16 = 0x400;
474
475 pub const DEFAULT_ACPI_IRQ: u32 = 9;
477
478 impl ResourceId<ChipsetDeviceHandleKind> for Piix4PowerManagementDeviceHandle {
479 const ID: &'static str = "piix4_power_management";
480 }
481}
482
483pub mod i440bx_host_pci_bridge {
484 use memory_range::MemoryRange;
487 use mesh::MeshPayload;
488 use vm_resource::CanResolveTo;
489 use vm_resource::Resource;
490 use vm_resource::ResourceId;
491 use vm_resource::ResourceKind;
492 use vm_resource::kind::ChipsetDeviceHandleKind;
493
494 #[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
496 pub enum GpaState {
497 #[default]
499 Writable,
500 WriteProtected,
502 WriteOnly,
504 Mmio,
506 }
507
508 pub trait AdjustGpaRange: Send {
513 fn adjust_gpa_range(&mut self, range: MemoryRange, state: GpaState);
515 }
516
517 pub struct ResolvedAdjustGpaRange(pub Box<dyn AdjustGpaRange>);
519
520 pub enum AdjustGpaRangeHandleKind {}
522
523 impl ResourceKind for AdjustGpaRangeHandleKind {
524 const NAME: &'static str = "i440bx_adjust_gpa_range";
525 }
526
527 impl CanResolveTo<ResolvedAdjustGpaRange> for AdjustGpaRangeHandleKind {
528 type Input<'a> = ();
529 }
530
531 #[derive(MeshPayload)]
533 pub struct I440BxHostPciBridgeDeviceHandle {
534 pub adjust_gpa_range: Resource<AdjustGpaRangeHandleKind>,
536 }
537
538 pub const I440BX_HOST_PCI_BRIDGE_BDF: (u8, u8, u8) = (0, 0, 0);
540
541 impl ResourceId<ChipsetDeviceHandleKind> for I440BxHostPciBridgeDeviceHandle {
542 const ID: &'static str = "i440bx-host-pci-bridge";
543 }
544}