mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-02 11:35:46 +00:00
acpi: Implement MADT on AArch64
Added following structures in MADT table: - GICC: GIC CPU interface structure - GICD: GIC Distributor structure - GICR: GIC Redistributor Structure - GICITS: GIC Interrupt Translation Service Structure Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
parent
084fdd9d10
commit
cab103d172
@ -15,6 +15,22 @@ use std::sync::{Arc, Mutex};
|
|||||||
use vm_memory::GuestRegionMmap;
|
use vm_memory::GuestRegionMmap;
|
||||||
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryMmap, GuestMemoryRegion};
|
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryMmap, GuestMemoryRegion};
|
||||||
|
|
||||||
|
/* Values for Type in APIC sub-headers */
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub const ACPI_APIC_PROCESSOR: u8 = 0;
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub const ACPI_APIC_IO: u8 = 1;
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub const ACPI_APIC_XRUPT_OVERRIDE: u8 = 2;
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
pub const ACPI_APIC_GENERIC_CPU_INTERFACE: u8 = 11;
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
pub const ACPI_APIC_GENERIC_DISTRIBUTOR: u8 = 12;
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
pub const ACPI_APIC_GENERIC_REDISTRIBUTOR: u8 = 14;
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
pub const ACPI_APIC_GENERIC_TRANSLATOR: u8 = 15;
|
||||||
|
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct PciRangeEntry {
|
struct PciRangeEntry {
|
||||||
|
141
vmm/src/cpu.rs
141
vmm/src/cpu.rs
@ -153,6 +153,63 @@ struct Ioapic {
|
|||||||
pub gsi_base: u32,
|
pub gsi_base: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "aarch64", feature = "acpi"))]
|
||||||
|
#[repr(packed)]
|
||||||
|
struct GicC {
|
||||||
|
pub r#type: u8,
|
||||||
|
pub length: u8,
|
||||||
|
pub reserved0: u16,
|
||||||
|
pub cpu_interface_number: u32,
|
||||||
|
pub uid: u32,
|
||||||
|
pub flags: u32,
|
||||||
|
pub parking_version: u32,
|
||||||
|
pub performance_interrupt: u32,
|
||||||
|
pub parked_address: u64,
|
||||||
|
pub base_address: u64,
|
||||||
|
pub gicv_base_address: u64,
|
||||||
|
pub gich_base_address: u64,
|
||||||
|
pub vgic_interrupt: u32,
|
||||||
|
pub gicr_base_address: u64,
|
||||||
|
pub mpidr: u64,
|
||||||
|
pub proc_power_effi_class: u8,
|
||||||
|
pub reserved1: u8,
|
||||||
|
pub spe_overflow_interrupt: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "aarch64", feature = "acpi"))]
|
||||||
|
#[repr(packed)]
|
||||||
|
struct GicD {
|
||||||
|
pub r#type: u8,
|
||||||
|
pub length: u8,
|
||||||
|
pub reserved0: u16,
|
||||||
|
pub gic_id: u32,
|
||||||
|
pub base_address: u64,
|
||||||
|
pub global_irq_base: u32,
|
||||||
|
pub version: u8,
|
||||||
|
pub reserved1: [u8; 3],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "aarch64", feature = "acpi"))]
|
||||||
|
#[repr(packed)]
|
||||||
|
struct GicR {
|
||||||
|
pub r#type: u8,
|
||||||
|
pub length: u8,
|
||||||
|
pub reserved: u16,
|
||||||
|
pub base_address: u64,
|
||||||
|
pub range_length: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "aarch64", feature = "acpi"))]
|
||||||
|
#[repr(packed)]
|
||||||
|
struct GicIts {
|
||||||
|
pub r#type: u8,
|
||||||
|
pub length: u8,
|
||||||
|
pub reserved0: u16,
|
||||||
|
pub translation_id: u32,
|
||||||
|
pub base_address: u64,
|
||||||
|
pub reserved1: u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct InterruptSourceOverride {
|
struct InterruptSourceOverride {
|
||||||
@ -1069,6 +1126,7 @@ impl CpuManager {
|
|||||||
|
|
||||||
#[cfg(feature = "acpi")]
|
#[cfg(feature = "acpi")]
|
||||||
pub fn create_madt(&self) -> Sdt {
|
pub fn create_madt(&self) -> Sdt {
|
||||||
|
use crate::acpi;
|
||||||
// This is also checked in the commandline parsing.
|
// This is also checked in the commandline parsing.
|
||||||
assert!(self.config.boot_vcpus <= self.config.max_vcpus);
|
assert!(self.config.boot_vcpus <= self.config.max_vcpus);
|
||||||
|
|
||||||
@ -1079,7 +1137,7 @@ impl CpuManager {
|
|||||||
|
|
||||||
for cpu in 0..self.config.max_vcpus {
|
for cpu in 0..self.config.max_vcpus {
|
||||||
let lapic = LocalApic {
|
let lapic = LocalApic {
|
||||||
r#type: 0,
|
r#type: acpi::ACPI_APIC_PROCESSOR,
|
||||||
length: 8,
|
length: 8,
|
||||||
processor_id: cpu,
|
processor_id: cpu,
|
||||||
apic_id: cpu,
|
apic_id: cpu,
|
||||||
@ -1093,7 +1151,7 @@ impl CpuManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
madt.append(Ioapic {
|
madt.append(Ioapic {
|
||||||
r#type: 1,
|
r#type: acpi::ACPI_APIC_IO,
|
||||||
length: 12,
|
length: 12,
|
||||||
ioapic_id: 0,
|
ioapic_id: 0,
|
||||||
apic_address: arch::layout::IOAPIC_START.0 as u32,
|
apic_address: arch::layout::IOAPIC_START.0 as u32,
|
||||||
@ -1102,7 +1160,7 @@ impl CpuManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
madt.append(InterruptSourceOverride {
|
madt.append(InterruptSourceOverride {
|
||||||
r#type: 2,
|
r#type: acpi::ACPI_APIC_XRUPT_OVERRIDE,
|
||||||
length: 10,
|
length: 10,
|
||||||
bus: 0,
|
bus: 0,
|
||||||
source: 4,
|
source: 4,
|
||||||
@ -1113,6 +1171,83 @@ impl CpuManager {
|
|||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
{
|
{
|
||||||
|
/* Notes:
|
||||||
|
* Ignore Local Interrupt Controller Address at byte offset 36 of MADT table.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// See section 5.2.12.14 GIC CPU Interface (GICC) Structure in ACPI spec.
|
||||||
|
for cpu in 0..self.config.boot_vcpus {
|
||||||
|
let vcpu = &self.vcpus[cpu as usize];
|
||||||
|
let mpidr = vcpu.lock().unwrap().get_mpidr();
|
||||||
|
/* ARMv8 MPIDR format:
|
||||||
|
Bits [63:40] Must be zero
|
||||||
|
Bits [39:32] Aff3 : Match Aff3 of target processor MPIDR
|
||||||
|
Bits [31:24] Must be zero
|
||||||
|
Bits [23:16] Aff2 : Match Aff2 of target processor MPIDR
|
||||||
|
Bits [15:8] Aff1 : Match Aff1 of target processor MPIDR
|
||||||
|
Bits [7:0] Aff0 : Match Aff0 of target processor MPIDR
|
||||||
|
*/
|
||||||
|
let mpidr_mask = 0xff_00ff_ffff;
|
||||||
|
let gicc = GicC {
|
||||||
|
r#type: acpi::ACPI_APIC_GENERIC_CPU_INTERFACE,
|
||||||
|
length: 80,
|
||||||
|
reserved0: 0,
|
||||||
|
cpu_interface_number: cpu as u32,
|
||||||
|
uid: cpu as u32,
|
||||||
|
flags: 1,
|
||||||
|
parking_version: 0,
|
||||||
|
performance_interrupt: 0,
|
||||||
|
parked_address: 0,
|
||||||
|
base_address: 0,
|
||||||
|
gicv_base_address: 0,
|
||||||
|
gich_base_address: 0,
|
||||||
|
vgic_interrupt: 0,
|
||||||
|
gicr_base_address: 0,
|
||||||
|
mpidr: mpidr & mpidr_mask,
|
||||||
|
proc_power_effi_class: 0,
|
||||||
|
reserved1: 0,
|
||||||
|
spe_overflow_interrupt: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
madt.append(gicc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GIC Distributor structure. See section 5.2.12.15 in ACPI spec.
|
||||||
|
let gicd = GicD {
|
||||||
|
r#type: acpi::ACPI_APIC_GENERIC_DISTRIBUTOR,
|
||||||
|
length: 24,
|
||||||
|
reserved0: 0,
|
||||||
|
gic_id: 0,
|
||||||
|
base_address: arch::layout::MAPPED_IO_START - 0x0001_0000,
|
||||||
|
global_irq_base: 0,
|
||||||
|
version: 3,
|
||||||
|
reserved1: [0; 3],
|
||||||
|
};
|
||||||
|
madt.append(gicd);
|
||||||
|
|
||||||
|
// See 5.2.12.17 GIC Redistributor (GICR) Structure in ACPI spec.
|
||||||
|
let gicr_size: u32 = 0x0001_0000 * 2 * (self.config.boot_vcpus as u32);
|
||||||
|
let gicr_base: u64 = arch::layout::MAPPED_IO_START - 0x0001_0000 - gicr_size as u64;
|
||||||
|
let gicr = GicR {
|
||||||
|
r#type: acpi::ACPI_APIC_GENERIC_REDISTRIBUTOR,
|
||||||
|
length: 16,
|
||||||
|
reserved: 0,
|
||||||
|
base_address: gicr_base,
|
||||||
|
range_length: gicr_size,
|
||||||
|
};
|
||||||
|
madt.append(gicr);
|
||||||
|
|
||||||
|
// See 5.2.12.18 GIC Interrupt Translation Service (ITS) Structure in ACPI spec.
|
||||||
|
let gicits = GicIts {
|
||||||
|
r#type: acpi::ACPI_APIC_GENERIC_TRANSLATOR,
|
||||||
|
length: 20,
|
||||||
|
reserved0: 0,
|
||||||
|
translation_id: 0,
|
||||||
|
base_address: gicr_base - 2 * 0x0001_0000,
|
||||||
|
reserved1: 0,
|
||||||
|
};
|
||||||
|
madt.append(gicits);
|
||||||
|
|
||||||
madt.update_checksum();
|
madt.update_checksum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user