Skip to main content

chipset_legacy/piix4_pci_isa_bridge/
resolver.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resolver for the PIIX4 PCI-ISA bridge device.
5
6use super::PciIsaBridge;
7use async_trait::async_trait;
8use chipset_device_resources::ResolveChipsetDeviceHandleParams;
9use chipset_device_resources::ResolvedChipsetDevice;
10use chipset_resources::piix4_pci_isa_bridge::Piix4PciIsaBridgeDeviceHandle;
11use power_resources::PowerRequest;
12use power_resources::PowerRequestHandleKind;
13use thiserror::Error;
14use vm_resource::AsyncResolveResource;
15use vm_resource::IntoResource;
16use vm_resource::PlatformResource;
17use vm_resource::ResolveError;
18use vm_resource::ResourceResolver;
19use vm_resource::declare_static_async_resolver;
20use vm_resource::kind::ChipsetDeviceHandleKind;
21
22/// A resolver for the PIIX4 PCI-ISA bridge device.
23pub struct Piix4PciIsaBridgeResolver;
24
25declare_static_async_resolver! {
26    Piix4PciIsaBridgeResolver,
27    (ChipsetDeviceHandleKind, Piix4PciIsaBridgeDeviceHandle),
28}
29
30/// Errors that can occur when resolving the PIIX4 PCI-ISA bridge.
31#[derive(Debug, Error)]
32#[expect(missing_docs)]
33pub enum ResolvePiix4PciIsaBridgeError {
34    #[error("failed to resolve power request")]
35    ResolvePowerRequest(#[source] ResolveError),
36}
37
38#[async_trait]
39impl AsyncResolveResource<ChipsetDeviceHandleKind, Piix4PciIsaBridgeDeviceHandle>
40    for Piix4PciIsaBridgeResolver
41{
42    type Output = ResolvedChipsetDevice;
43    type Error = ResolvePiix4PciIsaBridgeError;
44
45    async fn resolve(
46        &self,
47        resolver: &ResourceResolver,
48        _resource: Piix4PciIsaBridgeDeviceHandle,
49        _input: ResolveChipsetDeviceHandleParams<'_>,
50    ) -> Result<Self::Output, Self::Error> {
51        let power_request = resolver
52            .resolve::<PowerRequestHandleKind, _>(PlatformResource.into_resource(), ())
53            .await
54            .map_err(ResolvePiix4PciIsaBridgeError::ResolvePowerRequest)?;
55
56        let reset = Box::new(move || {
57            power_request.power_request(PowerRequest::Reset);
58        });
59
60        let set_a20_signal = Box::new(move |active| {
61            tracelimit::info_ratelimited!(active, "setting stubbed A20 signal")
62        });
63
64        Ok(PciIsaBridge::new(reset, set_a20_signal).into())
65    }
66}