mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-04 19:11:11 +00:00
acpi: Implement GTDT on AArch64
This commit implements an AArch64-specific ACPI table: Generic Timer Description Table (GTDT). The GTDT provides OSPM with information about a system’s Generic Timers configuration. The Generic Timer (GT) is a standard timer interface implemented on ARM processor-based systems. Signed-off-by: Henry Wang <Henry.Wang@arm.com>
This commit is contained in:
parent
7bfb51489b
commit
9c5528490e
@ -248,6 +248,40 @@ fn create_slit_table(numa_nodes: &NumaNodes) -> Sdt {
|
||||
slit
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn create_gtdt_table() -> Sdt {
|
||||
const ARCH_TIMER_NS_EL2_IRQ: u32 = 10;
|
||||
const ARCH_TIMER_VIRT_IRQ: u32 = 11;
|
||||
const ARCH_TIMER_S_EL1_IRQ: u32 = 13;
|
||||
const ARCH_TIMER_NS_EL1_IRQ: u32 = 14;
|
||||
const ACPI_GTDT_INTERRUPT_MODE_LEVEL: u32 = 0;
|
||||
const ACPI_GTDT_CAP_ALWAYS_ON: u32 = 1 << 2;
|
||||
|
||||
let irqflags: u32 = ACPI_GTDT_INTERRUPT_MODE_LEVEL;
|
||||
// GTDT
|
||||
let mut gtdt = Sdt::new(*b"GTDT", 104, 2, *b"CLOUDH", *b"CHGTDT ", 1);
|
||||
// Secure EL1 Timer GSIV
|
||||
gtdt.write(48, (ARCH_TIMER_S_EL1_IRQ + 16) as u32);
|
||||
// Secure EL1 Timer Flags
|
||||
gtdt.write(52, irqflags);
|
||||
// Non-Secure EL1 Timer GSIV
|
||||
gtdt.write(56, (ARCH_TIMER_NS_EL1_IRQ + 16) as u32);
|
||||
// Non-Secure EL1 Timer Flags
|
||||
gtdt.write(60, (irqflags | ACPI_GTDT_CAP_ALWAYS_ON) as u32);
|
||||
// Virtual EL1 Timer GSIV
|
||||
gtdt.write(64, (ARCH_TIMER_VIRT_IRQ + 16) as u32);
|
||||
// Virtual EL1 Timer Flags
|
||||
gtdt.write(68, irqflags);
|
||||
// EL2 Timer GSIV
|
||||
gtdt.write(72, (ARCH_TIMER_NS_EL2_IRQ + 16) as u32);
|
||||
// EL2 Timer Flags
|
||||
gtdt.write(76, irqflags);
|
||||
|
||||
gtdt.update_checksum();
|
||||
|
||||
gtdt
|
||||
}
|
||||
|
||||
pub fn create_acpi_tables(
|
||||
guest_mem: &GuestMemoryMmap,
|
||||
device_manager: &Arc<Mutex<DeviceManager>>,
|
||||
@ -255,6 +289,8 @@ pub fn create_acpi_tables(
|
||||
memory_manager: &Arc<Mutex<MemoryManager>>,
|
||||
numa_nodes: &NumaNodes,
|
||||
) -> GuestAddress {
|
||||
let mut prev_tbl_len: u64;
|
||||
let mut prev_tbl_off: GuestAddress;
|
||||
let rsdp_offset = arch::layout::RSDP_POINTER;
|
||||
let mut tables: Vec<u64> = Vec::new();
|
||||
|
||||
@ -280,10 +316,25 @@ pub fn create_acpi_tables(
|
||||
.write_slice(madt.as_slice(), madt_offset)
|
||||
.expect("Error writing MADT table");
|
||||
tables.push(madt_offset.0);
|
||||
prev_tbl_len = madt.len() as u64;
|
||||
prev_tbl_off = madt_offset;
|
||||
|
||||
// GTDT
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
let gtdt = create_gtdt_table();
|
||||
let gtdt_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(gtdt.as_slice(), gtdt_offset)
|
||||
.expect("Error writing GTDT table");
|
||||
tables.push(gtdt_offset.0);
|
||||
prev_tbl_len = gtdt.len() as u64;
|
||||
prev_tbl_off = gtdt_offset;
|
||||
}
|
||||
|
||||
// MCFG
|
||||
let mcfg = create_mcfg_table();
|
||||
let mcfg_offset = madt_offset.checked_add(madt.len() as u64).unwrap();
|
||||
let mcfg_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(mcfg.as_slice(), mcfg_offset)
|
||||
.expect("Error writing MCFG table");
|
||||
|
Loading…
Reference in New Issue
Block a user