Skip to main content

guest_watchdog/
resolver.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resource resolver for the Hyper-V guest watchdog chipset device.
5
6use crate::GuestWatchdogServices;
7use async_trait::async_trait;
8use chipset_device_resources::ResolveChipsetDeviceHandleParams;
9use chipset_device_resources::ResolvedChipsetDevice;
10use chipset_resources::hyperv_guest_watchdog::HyperVGuestWatchdogDeviceHandle;
11use thiserror::Error;
12use vm_resource::AsyncResolveResource;
13use vm_resource::IntoResource;
14use vm_resource::PlatformResource;
15use vm_resource::ResolveError;
16use vm_resource::ResourceResolver;
17use vm_resource::declare_static_async_resolver;
18use vm_resource::kind::ChipsetDeviceHandleKind;
19use watchdog_core::resources::WatchdogPlatformHandleKind;
20
21/// Resolver for the Hyper-V guest watchdog device.
22pub struct HyperVGuestWatchdogResolver;
23
24declare_static_async_resolver! {
25    HyperVGuestWatchdogResolver,
26    (ChipsetDeviceHandleKind, HyperVGuestWatchdogDeviceHandle),
27}
28
29/// Errors that can occur while resolving a guest watchdog handle.
30#[derive(Debug, Error)]
31pub enum ResolveGuestWatchdogError {
32    /// Failed to resolve the watchdog platform capability.
33    #[error("failed to resolve watchdog platform capability")]
34    ResolvePlatform(#[source] ResolveError),
35}
36
37#[async_trait]
38impl AsyncResolveResource<ChipsetDeviceHandleKind, HyperVGuestWatchdogDeviceHandle>
39    for HyperVGuestWatchdogResolver
40{
41    type Output = ResolvedChipsetDevice;
42    type Error = ResolveGuestWatchdogError;
43
44    async fn resolve(
45        &self,
46        resolver: &ResourceResolver,
47        resource: HyperVGuestWatchdogDeviceHandle,
48        input: ResolveChipsetDeviceHandleParams<'_>,
49    ) -> Result<Self::Output, Self::Error> {
50        let mut pio_static_wdat_port = input.register_pio.new_io_region("wdat_port", 8);
51        pio_static_wdat_port.map(resource.port_base);
52
53        let watchdog_platform = resolver
54            .resolve::<WatchdogPlatformHandleKind, _>(PlatformResource.into_resource(), ())
55            .await
56            .map_err(ResolveGuestWatchdogError::ResolvePlatform)?
57            .into_inner();
58
59        let device = GuestWatchdogServices::new(
60            input.vmtime.access("guest-watchdog-time"),
61            watchdog_platform,
62            pio_static_wdat_port,
63            input.is_restoring,
64        )
65        .await;
66
67        Ok(device.into())
68    }
69}