Skip to main content

chipset_legacy/piix4_pm/
resolver.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resolver for the PIIX4 power management device.
5
6use super::Piix4Pm;
7use async_trait::async_trait;
8use chipset::pm::resolver::ResolvePmError;
9use chipset::pm::resolver::register_gpe0_lines;
10use chipset::pm::resolver::resolve_pm_deps;
11use chipset_device_resources::IRQ_LINE_SET;
12use chipset_device_resources::ResolveChipsetDeviceHandleParams;
13use chipset_device_resources::ResolvedChipsetDevice;
14use chipset_resources::pm::Piix4PowerManagementDeviceHandle;
15use vm_resource::AsyncResolveResource;
16use vm_resource::ResourceResolver;
17use vm_resource::declare_static_async_resolver;
18use vm_resource::kind::ChipsetDeviceHandleKind;
19
20/// A resolver for the PIIX4 power management device.
21pub struct Piix4PowerManagementResolver;
22
23declare_static_async_resolver! {
24    Piix4PowerManagementResolver,
25    (ChipsetDeviceHandleKind, Piix4PowerManagementDeviceHandle),
26}
27
28#[async_trait]
29impl AsyncResolveResource<ChipsetDeviceHandleKind, Piix4PowerManagementDeviceHandle>
30    for Piix4PowerManagementResolver
31{
32    type Output = ResolvedChipsetDevice;
33    type Error = ResolvePmError;
34
35    async fn resolve(
36        &self,
37        resolver: &ResourceResolver,
38        resource: Piix4PowerManagementDeviceHandle,
39        input: ResolveChipsetDeviceHandleParams<'_>,
40    ) -> Result<Self::Output, Self::Error> {
41        // Hard-coded to IRQ line 9, as per PIIX4 spec.
42        let interrupt = input.configure.new_line(IRQ_LINE_SET, "acpi", 9);
43
44        // Resolve common PM dependencies through the shared resolver
45        // infrastructure, then construct the inner PowerManagementDevice.
46        let deps = resolve_pm_deps(resolver, resource.pm_timer_assist).await?;
47
48        let inner = chipset::pm::PowerManagementDevice::new(
49            deps.power_action,
50            interrupt,
51            input.register_pio,
52            input.vmtime.access("piix4-pm"),
53            None, // PIIX4 manages ACPI mode via PCI config space
54            deps.pm_timer_assist,
55        );
56
57        let pm = Piix4Pm::new(inner, input.register_pio);
58
59        register_gpe0_lines(input.configure, &pm);
60
61        Ok(pm.into())
62    }
63}