mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-04 19:11:11 +00:00
vmm: acpi: Support compiling ACPI code on aarch64
This skeleton commit brings in the support for compiling aarch64 with the "acpi" feature ready to the ACPI enabling. It builds on the work to move the ACPI hotplug devices from I/O ports to MMIO and conditionalises any code that is x86_64 only (i.e. because it uses an I/O port.) Filling in the aarch64 specific details in tables such as the MADT it out of the scope. See: #2178 Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
7659055eec
commit
76e15a4240
@ -6,12 +6,10 @@ use crate::cpu::CpuManager;
|
||||
use crate::device_manager::DeviceManager;
|
||||
use crate::memory_manager::MemoryManager;
|
||||
use crate::vm::NumaNodes;
|
||||
use acpi_tables::{
|
||||
aml::Aml,
|
||||
rsdp::RSDP,
|
||||
sdt::{GenericAddress, SDT},
|
||||
};
|
||||
use arch::layout;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use acpi_tables::sdt::GenericAddress;
|
||||
use acpi_tables::{aml::Aml, rsdp::RSDP, sdt::SDT};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use vm_memory::GuestRegionMmap;
|
||||
@ -114,8 +112,16 @@ pub fn create_acpi_tables(
|
||||
memory_manager: &Arc<Mutex<MemoryManager>>,
|
||||
numa_nodes: &NumaNodes,
|
||||
) -> GuestAddress {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
// RSDP is at the EBDA
|
||||
let rsdp_offset = layout::RSDP_POINTER;
|
||||
let rsdp_offset = arch::layout::RSDP_POINTER;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
// TODO: For aarch64 place the ACPI tables in the last MiB of guest RAM
|
||||
let rsdp_offset = {
|
||||
use vm_memory::GuestMemory;
|
||||
guest_mem.last_addr().checked_sub(1 << 20).unwrap()
|
||||
};
|
||||
|
||||
let mut tables: Vec<u64> = Vec::new();
|
||||
|
||||
// DSDT
|
||||
@ -130,6 +136,7 @@ pub fn create_acpi_tables(
|
||||
let mut facp = SDT::new(*b"FACP", 276, 6, *b"CLOUDH", *b"CHFACP ", 1);
|
||||
|
||||
// PM_TMR_BLK I/O port
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
facp.write(76, 0xb008u32);
|
||||
|
||||
// HW_REDUCED_ACPI, RESET_REG_SUP, TMR_VAL_EXT
|
||||
@ -137,19 +144,24 @@ pub fn create_acpi_tables(
|
||||
facp.write(112, fadt_flags);
|
||||
|
||||
// RESET_REG
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
facp.write(116, GenericAddress::io_port_address::<u8>(0x3c0));
|
||||
// RESET_VALUE
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
facp.write(128, 1u8);
|
||||
|
||||
facp.write(131, 3u8); // FADT minor version
|
||||
facp.write(140, dsdt_offset.0); // X_DSDT
|
||||
|
||||
// X_PM_TMR_BLK
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
facp.write(208, GenericAddress::io_port_address::<u32>(0xb008));
|
||||
|
||||
// SLEEP_CONTROL_REG
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
facp.write(244, GenericAddress::io_port_address::<u8>(0x3c0));
|
||||
// SLEEP_STATUS_REG
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
facp.write(256, GenericAddress::io_port_address::<u8>(0x3c0));
|
||||
|
||||
facp.write(268, b"CLOUDHYP"); // Hypervisor Vendor Identity
|
||||
@ -177,7 +189,7 @@ pub fn create_acpi_tables(
|
||||
|
||||
// 32-bit PCI enhanced configuration mechanism
|
||||
mcfg.append(PCIRangeEntry {
|
||||
base_address: layout::PCI_MMCONFIG_START.0,
|
||||
base_address: arch::layout::PCI_MMCONFIG_START.0,
|
||||
segment: 0,
|
||||
start: 0,
|
||||
end: 0,
|
||||
|
@ -22,8 +22,6 @@ use crate::CPU_MANAGER_SNAPSHOT_ID;
|
||||
#[cfg(feature = "acpi")]
|
||||
use acpi_tables::{aml, aml::Aml, sdt::SDT};
|
||||
use anyhow::anyhow;
|
||||
#[cfg(feature = "acpi")]
|
||||
use arch::layout;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use arch::x86_64::SgxEpcSection;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@ -1031,40 +1029,48 @@ impl CpuManager {
|
||||
assert!(self.config.boot_vcpus <= self.config.max_vcpus);
|
||||
|
||||
let mut madt = SDT::new(*b"APIC", 44, 5, *b"CLOUDH", *b"CHMADT ", 1);
|
||||
madt.write(36, layout::APIC_START);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
madt.write(36, arch::layout::APIC_START);
|
||||
|
||||
for cpu in 0..self.config.max_vcpus {
|
||||
let lapic = LocalAPIC {
|
||||
r#type: 0,
|
||||
length: 8,
|
||||
processor_id: cpu,
|
||||
apic_id: cpu,
|
||||
flags: if cpu < self.config.boot_vcpus {
|
||||
1 << MADT_CPU_ENABLE_FLAG
|
||||
} else {
|
||||
0
|
||||
},
|
||||
};
|
||||
madt.append(lapic);
|
||||
for cpu in 0..self.config.max_vcpus {
|
||||
let lapic = LocalAPIC {
|
||||
r#type: 0,
|
||||
length: 8,
|
||||
processor_id: cpu,
|
||||
apic_id: cpu,
|
||||
flags: if cpu < self.config.boot_vcpus {
|
||||
1 << MADT_CPU_ENABLE_FLAG
|
||||
} else {
|
||||
0
|
||||
},
|
||||
};
|
||||
madt.append(lapic);
|
||||
}
|
||||
|
||||
madt.append(IOAPIC {
|
||||
r#type: 1,
|
||||
length: 12,
|
||||
ioapic_id: 0,
|
||||
apic_address: arch::layout::IOAPIC_START.0 as u32,
|
||||
gsi_base: 0,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
madt.append(InterruptSourceOverride {
|
||||
r#type: 2,
|
||||
length: 10,
|
||||
bus: 0,
|
||||
source: 4,
|
||||
gsi: 4,
|
||||
flags: 0,
|
||||
});
|
||||
}
|
||||
|
||||
madt.append(IOAPIC {
|
||||
r#type: 1,
|
||||
length: 12,
|
||||
ioapic_id: 0,
|
||||
apic_address: layout::IOAPIC_START.0 as u32,
|
||||
gsi_base: 0,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
madt.append(InterruptSourceOverride {
|
||||
r#type: 2,
|
||||
length: 10,
|
||||
bus: 0,
|
||||
source: 4,
|
||||
gsi: 4,
|
||||
flags: 0,
|
||||
});
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
madt.update_checksum();
|
||||
}
|
||||
|
||||
madt
|
||||
}
|
||||
|
@ -1201,17 +1201,20 @@ impl DeviceManager {
|
||||
self.bus_devices
|
||||
.push(Arc::clone(&shutdown_device) as Arc<Mutex<dyn BusDevice>>);
|
||||
|
||||
self.address_manager
|
||||
.allocator
|
||||
.lock()
|
||||
.unwrap()
|
||||
.allocate_io_addresses(Some(GuestAddress(0x3c0)), 0x8, None)
|
||||
.ok_or(DeviceManagerError::AllocateIOPort)?;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
self.address_manager
|
||||
.allocator
|
||||
.lock()
|
||||
.unwrap()
|
||||
.allocate_io_addresses(Some(GuestAddress(0x3c0)), 0x8, None)
|
||||
.ok_or(DeviceManagerError::AllocateIOPort)?;
|
||||
|
||||
self.address_manager
|
||||
.io_bus
|
||||
.insert(shutdown_device, 0x3c0, 0x4)
|
||||
.map_err(DeviceManagerError::BusError)?;
|
||||
self.address_manager
|
||||
.io_bus
|
||||
.insert(shutdown_device, 0x3c0, 0x4)
|
||||
.map_err(DeviceManagerError::BusError)?;
|
||||
}
|
||||
|
||||
let ged_irq = self
|
||||
.address_manager
|
||||
@ -1253,17 +1256,20 @@ impl DeviceManager {
|
||||
self.bus_devices
|
||||
.push(Arc::clone(&pm_timer_device) as Arc<Mutex<dyn BusDevice>>);
|
||||
|
||||
self.address_manager
|
||||
.allocator
|
||||
.lock()
|
||||
.unwrap()
|
||||
.allocate_io_addresses(Some(GuestAddress(0xb008)), 0x4, None)
|
||||
.ok_or(DeviceManagerError::AllocateIOPort)?;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
self.address_manager
|
||||
.allocator
|
||||
.lock()
|
||||
.unwrap()
|
||||
.allocate_io_addresses(Some(GuestAddress(0xb008)), 0x4, None)
|
||||
.ok_or(DeviceManagerError::AllocateIOPort)?;
|
||||
|
||||
self.address_manager
|
||||
.io_bus
|
||||
.insert(pm_timer_device, 0xb008, 0x4)
|
||||
.map_err(DeviceManagerError::BusError)?;
|
||||
self.address_manager
|
||||
.io_bus
|
||||
.insert(pm_timer_device, 0xb008, 0x4)
|
||||
.map_err(DeviceManagerError::BusError)?;
|
||||
}
|
||||
|
||||
Ok(Some(ged_device))
|
||||
}
|
||||
|
@ -1033,6 +1033,17 @@ impl Vm {
|
||||
|
||||
let pci_space = (pci_space_start.0, pci_space_size);
|
||||
|
||||
#[cfg(feature = "acpi")]
|
||||
{
|
||||
let _ = crate::acpi::create_acpi_tables(
|
||||
&mem,
|
||||
&self.device_manager,
|
||||
&self.cpu_manager,
|
||||
&self.memory_manager,
|
||||
&self.numa_nodes,
|
||||
);
|
||||
}
|
||||
|
||||
// Call `configure_system` and pass the GIC devices out, so that
|
||||
// we can register the GIC device to the device manager.
|
||||
let gic_device = arch::configure_system(
|
||||
|
Loading…
Reference in New Issue
Block a user