serial_pl011/
resolver.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resource resolver for a serial Pl011 UART chipset device.
5
6use 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
20/// The resource resolver for [`SerialPl011`].
21pub struct SerialPl011Resolver;
22
23declare_static_async_resolver! {
24    SerialPl011Resolver,
25    (ChipsetDeviceHandleKind, SerialPl011DeviceHandle),
26}
27
28/// An error resolving a [`SerialPl011DeviceHandle`].
29#[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}