diff --git a/devices/src/acpi.rs b/devices/src/acpi.rs index 3165b504b..745c8a0e7 100644 --- a/devices/src/acpi.rs +++ b/devices/src/acpi.rs @@ -5,6 +5,8 @@ use vmm_sys_util::eventfd::EventFd; use BusDevice; +use HotPlugNotificationType; +use Interrupt; /// A device for handling ACPI shutdown and reboot pub struct AcpiShutdownDevice { @@ -50,3 +52,37 @@ impl BusDevice for AcpiShutdownDevice { } } } + +/// A device for handling ACPI GED event generation +pub struct AcpiGEDDevice { + interrupt: Box, + notification_type: HotPlugNotificationType, +} + +impl AcpiGEDDevice { + pub fn new(interrupt: Box) -> AcpiGEDDevice { + AcpiGEDDevice { + interrupt, + notification_type: HotPlugNotificationType::NoDevicesChanged, + } + } + + pub fn notify( + &mut self, + notification_type: HotPlugNotificationType, + ) -> Result<(), std::io::Error> { + self.notification_type = notification_type; + self.interrupt.deliver() + } +} + +// I/O port reports what type of notification was made +impl BusDevice for AcpiGEDDevice { + // Spec has all fields as zero + fn read(&mut self, _base: u64, _offset: u64, data: &mut [u8]) { + data[0] = self.notification_type as u8; + self.notification_type = HotPlugNotificationType::NoDevicesChanged; + } + + fn write(&mut self, _base: u64, _offset: u64, _data: &[u8]) {} +} diff --git a/devices/src/lib.rs b/devices/src/lib.rs index c6e86da99..e377a2d95 100644 --- a/devices/src/lib.rs +++ b/devices/src/lib.rs @@ -26,7 +26,7 @@ pub mod ioapic; pub mod legacy; #[cfg(feature = "acpi")] -pub use self::acpi::AcpiShutdownDevice; +pub use self::acpi::{AcpiGEDDevice, AcpiShutdownDevice}; pub use self::bus::{Bus, BusDevice, Error as BusError}; pub type DeviceEventT = u16; @@ -70,3 +70,9 @@ pub enum Error { pub trait Interrupt: Send + Sync { fn deliver(&self) -> result::Result<(), std::io::Error>; } + +#[derive(Clone, Copy)] +pub enum HotPlugNotificationType { + NoDevicesChanged, + CPUDevicesChanged, +}