Skip to main content

chipset/ioapic/
resolver.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resource resolver for the generic IO-APIC chipset device.
5
6use super::IoApicDevice;
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::ioapic::GenericIoApicDeviceHandle;
12use chipset_resources::ioapic::IOAPIC_NUM_ENTRIES;
13use chipset_resources::ioapic::IoApicRoutingHandleKind;
14use thiserror::Error;
15use vm_resource::AsyncResolveResource;
16use vm_resource::ResolveError;
17use vm_resource::ResourceResolver;
18use vm_resource::declare_static_async_resolver;
19use vm_resource::kind::ChipsetDeviceHandleKind;
20
21/// A resolver for generic IO-APIC devices.
22pub struct GenericIoApicResolver;
23
24declare_static_async_resolver! {
25    GenericIoApicResolver,
26    (ChipsetDeviceHandleKind, GenericIoApicDeviceHandle),
27}
28
29/// Errors that can occur when resolving a generic IO-APIC device.
30#[derive(Debug, Error)]
31#[expect(missing_docs)]
32pub enum ResolveGenericIoApicError {
33    #[error("failed to resolve ioapic routing")]
34    ResolveRouting(#[source] ResolveError),
35}
36
37#[async_trait]
38impl AsyncResolveResource<ChipsetDeviceHandleKind, GenericIoApicDeviceHandle>
39    for GenericIoApicResolver
40{
41    type Output = ResolvedChipsetDevice;
42    type Error = ResolveGenericIoApicError;
43
44    async fn resolve(
45        &self,
46        resolver: &ResourceResolver,
47        resource: GenericIoApicDeviceHandle,
48        input: ResolveChipsetDeviceHandleParams<'_>,
49    ) -> Result<Self::Output, Self::Error> {
50        let routing = resolver
51            .resolve::<IoApicRoutingHandleKind, _>(resource.routing, ())
52            .await
53            .map_err(ResolveGenericIoApicError::ResolveRouting)?;
54
55        input
56            .configure
57            .add_line_target(IRQ_LINE_SET, 0..=IOAPIC_NUM_ENTRIES as u32 - 1, 0);
58
59        Ok(IoApicDevice::new(IOAPIC_NUM_ENTRIES, routing.0).into())
60    }
61}