mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-01 11:05:46 +00:00
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:
parent
4ebeeb1310
commit
28ab6cea0e
@ -8,9 +8,12 @@ use std::sync::{Arc, Barrier};
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use vm_device::interrupt::InterruptSourceGroup;
|
use vm_device::interrupt::InterruptSourceGroup;
|
||||||
use vm_device::BusDevice;
|
use vm_device::BusDevice;
|
||||||
|
use vm_memory::GuestAddress;
|
||||||
use vmm_sys_util::eventfd::EventFd;
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
use AcpiNotificationFlags;
|
use AcpiNotificationFlags;
|
||||||
|
|
||||||
|
pub const GED_DEVICE_ACPI_SIZE: usize = 0x1;
|
||||||
|
|
||||||
/// A device for handling ACPI shutdown and reboot
|
/// A device for handling ACPI shutdown and reboot
|
||||||
pub struct AcpiShutdownDevice {
|
pub struct AcpiShutdownDevice {
|
||||||
exit_evt: EventFd,
|
exit_evt: EventFd,
|
||||||
@ -63,14 +66,20 @@ pub struct AcpiGEDDevice {
|
|||||||
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
|
interrupt: Arc<Box<dyn InterruptSourceGroup>>,
|
||||||
notification_type: AcpiNotificationFlags,
|
notification_type: AcpiNotificationFlags,
|
||||||
ged_irq: u32,
|
ged_irq: u32,
|
||||||
|
address: GuestAddress,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AcpiGEDDevice {
|
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 {
|
AcpiGEDDevice {
|
||||||
interrupt,
|
interrupt,
|
||||||
notification_type: AcpiNotificationFlags::NO_DEVICES_CHANGED,
|
notification_type: AcpiNotificationFlags::NO_DEVICES_CHANGED,
|
||||||
ged_irq,
|
ged_irq,
|
||||||
|
address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +123,12 @@ impl Aml for AcpiGEDDevice {
|
|||||||
self.ged_irq,
|
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(
|
&aml::Field::new(
|
||||||
"GDST".into(),
|
"GDST".into(),
|
||||||
aml::FieldAccessType::Byte,
|
aml::FieldAccessType::Byte,
|
||||||
|
@ -26,7 +26,7 @@ extern crate serde_derive;
|
|||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
|
||||||
#[cfg(feature = "acpi")]
|
#[cfg(feature = "acpi")]
|
||||||
mod acpi;
|
pub mod acpi;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub mod gic;
|
pub mod gic;
|
||||||
pub mod interrupt_controller;
|
pub mod interrupt_controller;
|
||||||
|
@ -244,6 +244,9 @@ pub enum DeviceManagerError {
|
|||||||
/// Failed to allocate IO port
|
/// Failed to allocate IO port
|
||||||
AllocateIOPort,
|
AllocateIOPort,
|
||||||
|
|
||||||
|
/// Failed to allocate MMIO address
|
||||||
|
AllocateMMIOAddress,
|
||||||
|
|
||||||
// Failed to make hotplug notification
|
// Failed to make hotplug notification
|
||||||
HotPlugNotification(io::Error),
|
HotPlugNotification(io::Error),
|
||||||
|
|
||||||
@ -1210,32 +1213,33 @@ impl DeviceManager {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate_irq()
|
.allocate_irq()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let interrupt_group = interrupt_manager
|
let interrupt_group = interrupt_manager
|
||||||
.create_group(LegacyIrqGroupConfig {
|
.create_group(LegacyIrqGroupConfig {
|
||||||
irq: ged_irq as InterruptIndex,
|
irq: ged_irq as InterruptIndex,
|
||||||
})
|
})
|
||||||
.map_err(DeviceManagerError::CreateInterruptGroup)?;
|
.map_err(DeviceManagerError::CreateInterruptGroup)?;
|
||||||
|
let ged_address = self
|
||||||
let ged_device = Arc::new(Mutex::new(devices::AcpiGEDDevice::new(
|
.address_manager
|
||||||
interrupt_group,
|
|
||||||
ged_irq,
|
|
||||||
)));
|
|
||||||
|
|
||||||
self.bus_devices
|
|
||||||
.push(Arc::clone(&ged_device) as Arc<Mutex<dyn BusDevice>>);
|
|
||||||
|
|
||||||
self.address_manager
|
|
||||||
.allocator
|
.allocator
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate_io_addresses(Some(GuestAddress(0xb000)), 0x1, None)
|
.allocate_mmio_addresses(None, devices::acpi::GED_DEVICE_ACPI_SIZE as u64, None)
|
||||||
.ok_or(DeviceManagerError::AllocateIOPort)?;
|
.ok_or(DeviceManagerError::AllocateMMIOAddress)?;
|
||||||
|
let ged_device = Arc::new(Mutex::new(devices::AcpiGEDDevice::new(
|
||||||
|
interrupt_group,
|
||||||
|
ged_irq,
|
||||||
|
ged_address,
|
||||||
|
)));
|
||||||
self.address_manager
|
self.address_manager
|
||||||
.io_bus
|
.mmio_bus
|
||||||
.insert(ged_device.clone(), 0xb000, 0x1)
|
.insert(
|
||||||
|
ged_device.clone(),
|
||||||
|
ged_address.0,
|
||||||
|
devices::acpi::GED_DEVICE_ACPI_SIZE as u64,
|
||||||
|
)
|
||||||
.map_err(DeviceManagerError::BusError)?;
|
.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()));
|
let pm_timer_device = Arc::new(Mutex::new(devices::AcpiPMTimerDevice::new()));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user