chipset_arc_mutex_device/
services.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Chipset-facing traits required to wire-up a Arc + Mutex backed
5//! [`ChipsetDevice`](chipset_device::ChipsetDevice).
6
7use chipset_device::mmio::RegisterMmioIntercept;
8use chipset_device::pio::RegisterPortIoIntercept;
9
10/// Compile-time type metadata bundle specified by concrete [`ChipsetServices`]
11/// implementations.
12///
13/// If an implementation doesn't support a particular service, the service's
14/// corresponding type should be set to [`Unimplemented`].
15///
16/// Rather than having `ChipsetServices` directly encode all these type (and
17/// make the type signatures for the `supports_XXX` methods absolutely
18/// _nightmarish_), we split them all out into their own trait, which can be
19/// references via a single type parameter.
20pub trait ChipsetServicesMeta {
21    // DEVNOTE: ideally, these would all have a default `= Unimplemented`, but
22    // associated type defaults are still unstable...
23    //
24    /// Concrete type that impls `RegisterMmioIntercept`
25    type RegisterMmioIntercept: RegisterMmioIntercept;
26    /// Concrete type that impls `RegisterPortIoIntercept`
27    type RegisterPortIoIntercept: RegisterPortIoIntercept;
28}
29
30/// The intermediary that allows a device to wire itself up to various VM
31/// chipset services.
32pub trait ChipsetServices {
33    /// A bundle of associated types used by the concrete implementation.
34    type M: ChipsetServicesMeta;
35
36    /// Support for MMIO intercepts.
37    #[inline(always)]
38    fn supports_mmio(&mut self) -> Option<&mut dyn MmioInterceptServices<M = Self::M>> {
39        None
40    }
41
42    /// Support for Port IO intercepts.
43    #[inline(always)]
44    fn supports_pio(&mut self) -> Option<&mut dyn PortIoInterceptServices<M = Self::M>> {
45        None
46    }
47
48    /// Support for PCI configuration space.
49    #[inline(always)]
50    fn supports_pci(&mut self) -> Option<&mut dyn PciConfigSpaceServices<M = Self::M>> {
51        None
52    }
53
54    /// Support for poll.
55    #[inline(always)]
56    fn supports_poll_device(&mut self) -> Option<&mut dyn PollDeviceServices<M = Self::M>> {
57        None
58    }
59}
60
61/// Implemented by chipsets that can support [`MmioIntercept`] devices.
62///
63/// [`MmioIntercept`]: chipset_device::mmio::MmioIntercept
64pub trait MmioInterceptServices: ChipsetServices {
65    /// Obtain an instance of [`RegisterMmioIntercept`]
66    fn register_mmio(&self) -> <Self::M as ChipsetServicesMeta>::RegisterMmioIntercept;
67
68    /// Return `true` if any [`MmioInterceptServices`] method has been invoked.
69    fn is_being_used(&self) -> bool;
70}
71
72/// Implemented by chipsets that can support [`PciConfigSpace`] devices.
73///
74/// [`PciConfigSpace`]: chipset_device::pci::PciConfigSpace
75pub trait PciConfigSpaceServices: ChipsetServices {
76    /// Register the device at the specified (bus, device, function)
77    fn register_static_pci(&mut self, bus: u8, device: u8, function: u8);
78
79    /// Return `true` if any [`PciConfigSpaceServices`] method has been invoked.
80    fn is_being_used(&self) -> bool;
81}
82
83/// Implemented by chipsets that can support [`PortIoIntercept`] devices.
84///
85/// [`PortIoIntercept`]: chipset_device::pio::PortIoIntercept
86pub trait PortIoInterceptServices: ChipsetServices {
87    /// Obtain an instance of [`RegisterPortIoIntercept`]
88    fn register_pio(&self) -> <Self::M as ChipsetServicesMeta>::RegisterPortIoIntercept;
89
90    /// Return `true` if any [`PortIoInterceptServices`] method has been invoked.
91    fn is_being_used(&self) -> bool;
92}
93
94/// Implemented by chipsets that can support [`PollDevice`] devices.
95///
96/// [`PollDevice`]: chipset_device::poll_device::PollDevice
97pub trait PollDeviceServices: ChipsetServices {
98    /// Register for asynchronous polling.
99    fn register_poll(&mut self);
100
101    /// Return `true` if [`Self::register_poll`] has been invoked.
102    fn is_being_used(&self) -> bool;
103}
104
105/// A placeholder type to represent a bit of unimplemented functionality.
106pub enum Unimplemented {}
107
108impl RegisterMmioIntercept for Unimplemented {
109    fn new_io_region(
110        &mut self,
111        _: &str,
112        _: u64,
113    ) -> Box<dyn chipset_device::mmio::ControlMmioIntercept> {
114        unreachable!()
115    }
116}
117
118impl RegisterPortIoIntercept for Unimplemented {
119    fn new_io_region(
120        &mut self,
121        _: &str,
122        _: u16,
123    ) -> Box<dyn chipset_device::pio::ControlPortIoIntercept> {
124        unreachable!()
125    }
126}