diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index 8f2eb7cb8..7f0a12eba 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -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>, 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 = 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::(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::(0xb008)); // SLEEP_CONTROL_REG + #[cfg(target_arch = "x86_64")] facp.write(244, GenericAddress::io_port_address::(0x3c0)); // SLEEP_STATUS_REG + #[cfg(target_arch = "x86_64")] facp.write(256, GenericAddress::io_port_address::(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, diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 31fbf721c..5a4e053d4 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -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 } diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index b54518441..95f9b5cb4 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1201,17 +1201,20 @@ impl DeviceManager { self.bus_devices .push(Arc::clone(&shutdown_device) as Arc>); - 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>); - 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)) } diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index a2df724ba..1a0b89657 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -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(