vmm: acpi: Move ACPI GED device to MMIO bus

Currently the GED control is in a fixed I/O port address but instead use
an MMIO address that has been chosen by the allocator.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-01-20 15:32:10 +00:00 committed by Sebastien Boeuf
parent 4ebeeb1310
commit 28ab6cea0e
3 changed files with 37 additions and 19 deletions

View File

@ -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<Box<dyn InterruptSourceGroup>>,
notification_type: AcpiNotificationFlags,
ged_irq: u32,
address: GuestAddress,
}
impl AcpiGEDDevice {
pub fn new(interrupt: Arc<Box<dyn InterruptSourceGroup>>, ged_irq: u32) -> AcpiGEDDevice {
pub fn new(
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
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,

View File

@ -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;

View File

@ -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<Mutex<dyn BusDevice>>);
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<Mutex<dyn BusDevice>>);
let pm_timer_device = Arc::new(Mutex::new(devices::AcpiPMTimerDevice::new()));