chipset/i8042/
resolver.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resolver for i8042 devices.
5
6use super::I8042Device;
7use async_trait::async_trait;
8use chipset_device_resources::IRQ_LINE_SET;
9use chipset_device_resources::ResolveChipsetDeviceHandleParams;
10use chipset_device_resources::ResolvedChipsetDevice;
11use chipset_resources::i8042::I8042DeviceHandle;
12use power_resources::PowerRequest;
13use power_resources::PowerRequestHandleKind;
14use thiserror::Error;
15use vm_resource::AsyncResolveResource;
16use vm_resource::IntoResource;
17use vm_resource::PlatformResource;
18use vm_resource::ResolveError;
19use vm_resource::ResourceResolver;
20use vm_resource::declare_static_async_resolver;
21use vm_resource::kind::ChipsetDeviceHandleKind;
22
23/// A resolver for i8042 devices.
24pub struct I8042Resolver;
25
26declare_static_async_resolver! {
27    I8042Resolver,
28    (ChipsetDeviceHandleKind, I8042DeviceHandle),
29}
30
31/// Errors that can occur when resolving an i8042 device.
32#[derive(Debug, Error)]
33#[expect(missing_docs)]
34pub enum ResolveI8042Error {
35    #[error("failed to resolve keyboard input")]
36    ResolveKeyboardInput(#[source] ResolveError),
37    #[error("failed to resolve power request")]
38    ResolvePowerRequest(#[source] ResolveError),
39}
40
41#[async_trait]
42impl AsyncResolveResource<ChipsetDeviceHandleKind, I8042DeviceHandle> for I8042Resolver {
43    type Output = ResolvedChipsetDevice;
44    type Error = ResolveI8042Error;
45
46    async fn resolve(
47        &self,
48        resolver: &ResourceResolver,
49        resource: I8042DeviceHandle,
50        input: ResolveChipsetDeviceHandleParams<'_>,
51    ) -> Result<Self::Output, Self::Error> {
52        // Hard-coded to IRQ line 1, as per x86 spec.
53        let keyboard_interrupt = input.configure.new_line(IRQ_LINE_SET, "keyboard", 1);
54
55        // Hard-coded to IRQ line 12, as per x86 convention.
56        let mouse_interrupt = input.configure.new_line(IRQ_LINE_SET, "aux", 12);
57
58        let keyboard_input = resolver
59            .resolve(resource.keyboard_input, input.device_name)
60            .await
61            .map_err(ResolveI8042Error::ResolveKeyboardInput)?;
62
63        let power_request = resolver
64            .resolve::<PowerRequestHandleKind, _>(PlatformResource.into_resource(), ())
65            .await
66            .map_err(ResolveI8042Error::ResolvePowerRequest)?;
67
68        let reset = Box::new(move || {
69            power_request.power_request(PowerRequest::Reset);
70        });
71
72        Ok(
73            I8042Device::new(reset, keyboard_interrupt, mouse_interrupt, keyboard_input.0)
74                .await
75                .into(),
76        )
77    }
78}