diff --git a/devices/src/acpi.rs b/devices/src/acpi.rs index c342817b4..1bee3c9eb 100644 --- a/devices/src/acpi.rs +++ b/devices/src/acpi.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use vm_device::interrupt::InterruptSourceGroup; +use vm_memory::GuestAddress; use vmm_sys_util::eventfd::EventFd; use BusDevice; use HotPlugNotificationFlags; @@ -60,14 +61,22 @@ pub struct AcpiGEDDevice { interrupt: Arc>, notification_type: HotPlugNotificationFlags, ged_irq: u32, + device_base: GuestAddress, } impl AcpiGEDDevice { - pub fn new(interrupt: Arc>, ged_irq: u32) -> AcpiGEDDevice { + pub const DEVICE_SIZE: u64 = 1; + + pub fn new( + interrupt: Arc>, + ged_irq: u32, + device_base: GuestAddress, + ) -> AcpiGEDDevice { AcpiGEDDevice { interrupt, notification_type: HotPlugNotificationFlags::NO_DEVICES_CHANGED, ged_irq, + device_base, } } @@ -82,9 +91,13 @@ impl AcpiGEDDevice { pub fn irq(&self) -> u32 { self.ged_irq } + + pub fn device_base(&self) -> GuestAddress { + self.device_base + } } -// I/O port reports what type of notification was made +// MMIO region 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]) { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index a7597ef9d..52f938d58 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -192,6 +192,9 @@ pub enum DeviceManagerError { /// Failed creating IOAPIC. CreateIoapic(ioapic::Error), + + /// Failed to allocate MMIO area + AllocateMMIO, } pub type DeviceManagerResult = result::Result; @@ -749,22 +752,28 @@ impl DeviceManager { .create_group(PIN_IRQ, ged_irq as InterruptIndex, 1 as InterruptIndex) .map_err(DeviceManagerError::CreateInterruptGroup)?; - let ged_device = Arc::new(Mutex::new(devices::AcpiGEDDevice::new( - interrupt_group, - ged_irq, - ))); - - address_manager + let ged_base = address_manager .allocator .lock() .unwrap() - .allocate_io_addresses(Some(GuestAddress(0xb000)), 0x1, None) - .ok_or(DeviceManagerError::AllocateIOPort)?; + .allocate_mmio_addresses(None, devices::AcpiGEDDevice::DEVICE_SIZE, None) + .ok_or(DeviceManagerError::AllocateMMIO)?; + + let ged_device = Arc::new(Mutex::new(devices::AcpiGEDDevice::new( + interrupt_group, + ged_irq, + ged_base, + ))); address_manager - .io_bus - .insert(ged_device.clone(), 0xb000, 0x1) + .mmio_bus + .insert( + ged_device.clone(), + ged_base.0, + devices::AcpiGEDDevice::DEVICE_SIZE, + ) .map_err(DeviceManagerError::BusError)?; + Ok(Some(ged_device)) } @@ -1651,7 +1660,7 @@ impl Drop for DeviceManager { } #[cfg(feature = "acpi")] -fn create_ged_device(ged_irq: u32) -> Vec { +fn create_ged_device(ged_base: u64, ged_irq: u32) -> Vec { aml::Device::new( "_SB_.GED_".into(), vec![ @@ -1663,7 +1672,12 @@ fn create_ged_device(ged_irq: u32) -> Vec { true, true, false, false, ged_irq, )]), ), - &aml::OpRegion::new("GDST".into(), aml::OpRegionSpace::SystemIO, 0xb000, 0x1), + &aml::OpRegion::new( + "GDST".into(), + aml::OpRegionSpace::SystemMemory, + ged_base as usize, + devices::AcpiGEDDevice::DEVICE_SIZE as usize, + ), &aml::Field::new( "GDST".into(), aml::FieldAccessType::Byte, @@ -1770,14 +1784,21 @@ impl Aml for DeviceManager { let s5_sleep_data = aml::Name::new("_S5_".into(), &aml::Package::new(vec![&5u8])).to_aml_bytes(); - let ged_data = create_ged_device( - self.ged_notification_device - .as_ref() - .unwrap() - .lock() - .unwrap() - .irq(), - ); + let ged_irq = self + .ged_notification_device + .as_ref() + .unwrap() + .lock() + .unwrap() + .irq(); + let ged_base = self + .ged_notification_device + .as_ref() + .unwrap() + .lock() + .unwrap() + .device_base(); + let ged_data = create_ged_device(ged_base.0, ged_irq); bytes.extend_from_slice(pci_dsdt_data.as_slice()); bytes.extend_from_slice(mbrd_dsdt_data.as_slice());