vmm_core/
vmotherboard_adapter.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Glue code to adapt OpenVMM-specific platform APIs to the types/traits
5//! required by `vmotherboard`.
6
7use crate::partition_unit::Halt;
8use crate::synic::SynicPorts;
9use hvdef::Vtl;
10use std::sync::Arc;
11use virt::VpIndex;
12use virt::io::CpuIo;
13use vmm_core_defs::HaltReason;
14use vmotherboard::Chipset;
15
16#[expect(missing_docs)]
17#[derive(Clone)]
18pub struct ChipsetPlusSynic {
19    pub synic_ports: Arc<SynicPorts>,
20    pub chipset: Arc<Chipset>,
21}
22
23impl ChipsetPlusSynic {
24    #[expect(missing_docs)]
25    pub fn new(synic_ports: Arc<SynicPorts>, chipset: Arc<Chipset>) -> Self {
26        Self {
27            synic_ports,
28            chipset,
29        }
30    }
31}
32
33impl CpuIo for ChipsetPlusSynic {
34    fn is_mmio(&self, address: u64) -> bool {
35        self.chipset.is_mmio(address)
36    }
37
38    fn acknowledge_pic_interrupt(&self) -> Option<u8> {
39        self.chipset.acknowledge_pic_interrupt()
40    }
41
42    fn handle_eoi(&self, irq: u32) {
43        self.chipset.handle_eoi(irq)
44    }
45
46    fn signal_synic_event(&self, vtl: Vtl, connection_id: u32, flag: u16) -> hvdef::HvResult<()> {
47        self.synic_ports.on_signal_event(vtl, connection_id, flag)
48    }
49
50    fn post_synic_message(
51        &self,
52        vtl: Vtl,
53        connection_id: u32,
54        secure: bool,
55        message: &[u8],
56    ) -> hvdef::HvResult<()> {
57        self.synic_ports
58            .on_post_message(vtl, connection_id, secure, message)
59    }
60
61    fn read_mmio(
62        &self,
63        vp: VpIndex,
64        address: u64,
65        data: &mut [u8],
66    ) -> impl std::future::Future<Output = ()> {
67        self.chipset.mmio_read(vp.index(), address, data)
68    }
69
70    fn write_mmio(
71        &self,
72        vp: VpIndex,
73        address: u64,
74        data: &[u8],
75    ) -> impl std::future::Future<Output = ()> {
76        self.chipset.mmio_write(vp.index(), address, data)
77    }
78
79    fn read_io(
80        &self,
81        vp: VpIndex,
82        port: u16,
83        data: &mut [u8],
84    ) -> impl std::future::Future<Output = ()> {
85        self.chipset.io_read(vp.index(), port, data)
86    }
87
88    fn write_io(
89        &self,
90        vp: VpIndex,
91        port: u16,
92        data: &[u8],
93    ) -> impl std::future::Future<Output = ()> {
94        self.chipset.io_write(vp.index(), port, data)
95    }
96}
97
98impl vmotherboard::PowerEventHandler for Halt {
99    fn on_power_event(&self, evt: vmotherboard::PowerEvent) {
100        let reason = match evt {
101            vmotherboard::PowerEvent::PowerOff => HaltReason::PowerOff,
102            vmotherboard::PowerEvent::Reset => HaltReason::Reset,
103            vmotherboard::PowerEvent::Hibernate => HaltReason::Hibernate,
104        };
105        self.halt(reason)
106    }
107}
108
109impl vmotherboard::DebugEventHandler for Halt {
110    fn on_debug_break(&self, vp: Option<u32>) {
111        self.halt(HaltReason::DebugBreak { vp })
112    }
113}