vmm_core/
vmotherboard_adapter.rs1use crate::partition_unit::Halt;
8use std::sync::Arc;
9use virt::VpIndex;
10use virt::io::CpuIo;
11use vmm_core_defs::HaltReason;
12use vmotherboard::Chipset;
13
14#[derive(Clone)]
18pub struct AdaptedChipset {
19 pub chipset: Arc<Chipset>,
20 fatal_policy: FatalErrorPolicy,
21}
22
23#[derive(Clone)]
24pub enum FatalErrorPolicy {
25 Panic(Arc<dyn Fn() + Send + Sync>),
27 DebugBreak(mesh::Sender<Box<dyn std::error::Error + Send + Sync>>),
30}
31
32impl AdaptedChipset {
33 pub fn new(chipset: Arc<Chipset>, fatal_policy: FatalErrorPolicy) -> Self {
35 Self {
36 chipset,
37 fatal_policy,
38 }
39 }
40}
41
42impl CpuIo for AdaptedChipset {
43 fn is_mmio(&self, address: u64) -> bool {
44 self.chipset.is_mmio(address)
45 }
46
47 fn acknowledge_pic_interrupt(&self) -> Option<u8> {
48 self.chipset.acknowledge_pic_interrupt()
49 }
50
51 fn handle_eoi(&self, irq: u32) {
52 self.chipset.handle_eoi(irq)
53 }
54
55 fn read_mmio(&self, vp: VpIndex, address: u64, data: &mut [u8]) -> impl Future<Output = ()> {
56 self.chipset.mmio_read(vp.index(), address, data)
57 }
58
59 fn write_mmio(&self, vp: VpIndex, address: u64, data: &[u8]) -> impl Future<Output = ()> {
60 self.chipset.mmio_write(vp.index(), address, data)
61 }
62
63 fn read_io(&self, vp: VpIndex, port: u16, data: &mut [u8]) -> impl Future<Output = ()> {
64 self.chipset.io_read(vp.index(), port, data)
65 }
66
67 fn write_io(&self, vp: VpIndex, port: u16, data: &[u8]) -> impl Future<Output = ()> {
68 self.chipset.io_write(vp.index(), port, data)
69 }
70
71 #[track_caller]
72 fn fatal_error(&self, error: Box<dyn std::error::Error + Send + Sync>) -> virt::VpHaltReason {
73 tracing::error!(
74 err = error.as_ref() as &dyn std::error::Error,
75 "fatal error"
76 );
77 match &self.fatal_policy {
78 FatalErrorPolicy::Panic(prep) => {
79 prep();
80 panic!("fatal error: {}", error)
81 }
82 FatalErrorPolicy::DebugBreak(channel) => {
83 channel.send(error);
84 virt::VpHaltReason::SingleStep
85 }
86 }
87 }
88}
89
90impl vmotherboard::PowerEventHandler for Halt {
91 fn on_power_event(&self, evt: vmotherboard::PowerEvent) {
92 let reason = match evt {
93 vmotherboard::PowerEvent::PowerOff => HaltReason::PowerOff,
94 vmotherboard::PowerEvent::Reset => HaltReason::Reset,
95 vmotherboard::PowerEvent::Hibernate => HaltReason::Hibernate,
96 };
97 self.halt(reason)
98 }
99}
100
101impl vmotherboard::DebugEventHandler for Halt {
102 fn on_debug_break(&self, vp: Option<u32>) {
103 self.halt(HaltReason::DebugBreak { vp })
104 }
105}