1use crate::SerialPl011;
7use async_trait::async_trait;
8use chipset_device_resources::IRQ_LINE_SET;
9use chipset_device_resources::ResolveChipsetDeviceHandleParams;
10use chipset_device_resources::ResolvedChipsetDevice;
11use serial_core::resources::ResolveSerialBackendParams;
12use serial_pl011_resources::SerialPl011DeviceHandle;
13use thiserror::Error;
14use vm_resource::AsyncResolveResource;
15use vm_resource::ResolveError;
16use vm_resource::ResourceResolver;
17use vm_resource::declare_static_async_resolver;
18use vm_resource::kind::ChipsetDeviceHandleKind;
19
20pub struct SerialPl011Resolver;
22
23declare_static_async_resolver! {
24 SerialPl011Resolver,
25 (ChipsetDeviceHandleKind, SerialPl011DeviceHandle),
26}
27
28#[expect(missing_docs)]
30#[derive(Debug, Error)]
31pub enum ResolvePl011Error {
32 #[error("failed to resolve io backend")]
33 ResolveBackend(#[source] ResolveError),
34 #[error("failed to configure serial device")]
35 Configuration(#[source] super::ConfigurationError),
36}
37
38#[async_trait]
39impl AsyncResolveResource<ChipsetDeviceHandleKind, SerialPl011DeviceHandle>
40 for SerialPl011Resolver
41{
42 type Output = ResolvedChipsetDevice;
43 type Error = ResolvePl011Error;
44
45 async fn resolve(
46 &self,
47 resolver: &ResourceResolver,
48 resource: SerialPl011DeviceHandle,
49 input: ResolveChipsetDeviceHandleParams<'_>,
50 ) -> Result<Self::Output, Self::Error> {
51 let io = resolver
52 .resolve(
53 resource.io,
54 ResolveSerialBackendParams {
55 driver: Box::new(input.task_driver_source.simple()),
56 _async_trait_workaround: &(),
57 },
58 )
59 .await
60 .map_err(ResolvePl011Error::ResolveBackend)?;
61
62 let interrupt = input
63 .configure
64 .new_line(IRQ_LINE_SET, "interrupt", resource.irq);
65
66 let device = SerialPl011::new(
67 input.device_name.to_string(),
68 resource.base,
69 interrupt,
70 io.0.into_io(),
71 )
72 .map_err(ResolvePl011Error::Configuration)?;
73
74 Ok(device.into())
75 }
76}