diff --git a/devices/src/acpi.rs b/devices/src/acpi.rs index cc640bb1e..395e9b25b 100644 --- a/devices/src/acpi.rs +++ b/devices/src/acpi.rs @@ -8,9 +8,12 @@ use std::sync::{Arc, Barrier}; use std::time::Instant; use vm_device::interrupt::InterruptSourceGroup; use vm_device::BusDevice; +use vm_memory::GuestAddress; use vmm_sys_util::eventfd::EventFd; use AcpiNotificationFlags; +pub const GED_DEVICE_ACPI_SIZE: usize = 0x1; + /// A device for handling ACPI shutdown and reboot pub struct AcpiShutdownDevice { exit_evt: EventFd, @@ -63,14 +66,20 @@ pub struct AcpiGEDDevice { interrupt: Arc>, notification_type: AcpiNotificationFlags, ged_irq: u32, + address: GuestAddress, } impl AcpiGEDDevice { - pub fn new(interrupt: Arc>, ged_irq: u32) -> AcpiGEDDevice { + pub fn new( + interrupt: Arc>, + ged_irq: u32, + address: GuestAddress, + ) -> AcpiGEDDevice { AcpiGEDDevice { interrupt, notification_type: AcpiNotificationFlags::NO_DEVICES_CHANGED, ged_irq, + address, } } @@ -114,7 +123,12 @@ impl Aml for AcpiGEDDevice { self.ged_irq, )]), ), - &aml::OpRegion::new("GDST".into(), aml::OpRegionSpace::SystemIO, 0xb000, 0x1), + &aml::OpRegion::new( + "GDST".into(), + aml::OpRegionSpace::SystemMemory, + self.address.0 as usize, + GED_DEVICE_ACPI_SIZE, + ), &aml::Field::new( "GDST".into(), aml::FieldAccessType::Byte, diff --git a/devices/src/lib.rs b/devices/src/lib.rs index 4d2f260a0..0f42f367a 100644 --- a/devices/src/lib.rs +++ b/devices/src/lib.rs @@ -26,7 +26,7 @@ extern crate serde_derive; extern crate serde_json; #[cfg(feature = "acpi")] -mod acpi; +pub mod acpi; #[cfg(target_arch = "aarch64")] pub mod gic; pub mod interrupt_controller; diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 664038f0f..8fc481951 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -244,6 +244,9 @@ pub enum DeviceManagerError { /// Failed to allocate IO port AllocateIOPort, + /// Failed to allocate MMIO address + AllocateMMIOAddress, + // Failed to make hotplug notification HotPlugNotification(io::Error), @@ -1210,32 +1213,33 @@ impl DeviceManager { .unwrap() .allocate_irq() .unwrap(); - let interrupt_group = interrupt_manager .create_group(LegacyIrqGroupConfig { irq: ged_irq as InterruptIndex, }) .map_err(DeviceManagerError::CreateInterruptGroup)?; - - let ged_device = Arc::new(Mutex::new(devices::AcpiGEDDevice::new( - interrupt_group, - ged_irq, - ))); - - self.bus_devices - .push(Arc::clone(&ged_device) as Arc>); - - self.address_manager + let ged_address = self + .address_manager .allocator .lock() .unwrap() - .allocate_io_addresses(Some(GuestAddress(0xb000)), 0x1, None) - .ok_or(DeviceManagerError::AllocateIOPort)?; - + .allocate_mmio_addresses(None, devices::acpi::GED_DEVICE_ACPI_SIZE as u64, None) + .ok_or(DeviceManagerError::AllocateMMIOAddress)?; + let ged_device = Arc::new(Mutex::new(devices::AcpiGEDDevice::new( + interrupt_group, + ged_irq, + ged_address, + ))); self.address_manager - .io_bus - .insert(ged_device.clone(), 0xb000, 0x1) + .mmio_bus + .insert( + ged_device.clone(), + ged_address.0, + devices::acpi::GED_DEVICE_ACPI_SIZE as u64, + ) .map_err(DeviceManagerError::BusError)?; + self.bus_devices + .push(Arc::clone(&ged_device) as Arc>); let pm_timer_device = Arc::new(Mutex::new(devices::AcpiPMTimerDevice::new()));