1use crate::kvp::KvpIc;
7use crate::shutdown::ShutdownIc;
8use crate::timesync::TimesyncIc;
9use anyhow::Context as _;
10use async_trait::async_trait;
11use hyperv_ic_resources::kvp::KvpIcHandle;
12use hyperv_ic_resources::shutdown::ShutdownIcHandle;
13use hyperv_ic_resources::timesync::TimesyncIcHandle;
14use std::convert::Infallible;
15use vm_resource::AsyncResolveResource;
16use vm_resource::IntoResource;
17use vm_resource::PlatformResource;
18use vm_resource::ResolveResource;
19use vm_resource::ResourceResolver;
20use vm_resource::declare_static_async_resolver;
21use vm_resource::declare_static_resolver;
22use vm_resource::kind::VmbusDeviceHandleKind;
23use vmbus_channel::resources::ResolveVmbusDeviceHandleParams;
24use vmbus_channel::resources::ResolvedVmbusDevice;
25use vmbus_channel::simple::SimpleDeviceWrapper;
26use vmcore::reference_time::ReferenceTimeSourceKind;
27
28pub struct ShutdownIcResolver;
30
31declare_static_resolver! {
32 ShutdownIcResolver,
33 (VmbusDeviceHandleKind, ShutdownIcHandle),
34}
35
36impl ResolveResource<VmbusDeviceHandleKind, ShutdownIcHandle> for ShutdownIcResolver {
37 type Output = ResolvedVmbusDevice;
38 type Error = Infallible;
39
40 fn resolve(
41 &self,
42 resource: ShutdownIcHandle,
43 input: ResolveVmbusDeviceHandleParams<'_>,
44 ) -> Result<Self::Output, Self::Error> {
45 Ok(
46 SimpleDeviceWrapper::new(input.driver_source.simple(), ShutdownIc::new(resource.recv))
47 .into(),
48 )
49 }
50}
51
52pub struct KvpIcResolver;
54
55declare_static_resolver! {
56 KvpIcResolver,
57 (VmbusDeviceHandleKind, KvpIcHandle),
58}
59
60impl ResolveResource<VmbusDeviceHandleKind, KvpIcHandle> for KvpIcResolver {
61 type Output = ResolvedVmbusDevice;
62 type Error = Infallible;
63
64 fn resolve(
65 &self,
66 resource: KvpIcHandle,
67 input: ResolveVmbusDeviceHandleParams<'_>,
68 ) -> Result<Self::Output, Self::Error> {
69 Ok(
70 SimpleDeviceWrapper::new(input.driver_source.simple(), KvpIc::new(resource.recv))
71 .into(),
72 )
73 }
74}
75
76pub struct TimesyncIcResolver;
78
79declare_static_async_resolver! {
80 TimesyncIcResolver,
81 (VmbusDeviceHandleKind, TimesyncIcHandle),
82}
83
84#[async_trait]
85impl AsyncResolveResource<VmbusDeviceHandleKind, TimesyncIcHandle> for TimesyncIcResolver {
86 type Output = ResolvedVmbusDevice;
87 type Error = anyhow::Error;
88
89 async fn resolve(
90 &self,
91 resolver: &ResourceResolver,
92 TimesyncIcHandle: TimesyncIcHandle,
93 input: ResolveVmbusDeviceHandleParams<'_>,
94 ) -> Result<Self::Output, Self::Error> {
95 let ref_time = resolver
96 .resolve::<ReferenceTimeSourceKind, _>(PlatformResource.into_resource(), ())
97 .await
98 .context("failed to resolve reference time")?;
99
100 Ok(SimpleDeviceWrapper::new(
101 input.driver_source.simple(),
102 TimesyncIc::new(&input.driver_source.simple(), ref_time),
103 )
104 .into())
105 }
106}