mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-04 19:11:11 +00:00
acpi: Implement IORT for AArch64
This commit implements the IO Remapping Table (IORT) for AArch64. The IORT is one of the required ACPI table for AArch64, since it describes the GICv3ITS node. Signed-off-by: Henry Wang <Henry.Wang@arm.com>
This commit is contained in:
parent
213da7d862
commit
d882f8c928
@ -313,6 +313,48 @@ fn create_spcr_table(base_address: u64, gsi: u32) -> Sdt {
|
||||
spcr
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn create_iort_table() -> Sdt {
|
||||
const ACPI_IORT_NODE_ITS_GROUP: u8 = 0x00;
|
||||
const ACPI_IORT_NODE_PCI_ROOT_COMPLEX: u8 = 0x02;
|
||||
|
||||
// IORT
|
||||
let mut iort = Sdt::new(*b"IORT", 124, 2, *b"CLOUDH", *b"CHIORT ", 1);
|
||||
// Nodes: PCI Root Complex, ITS
|
||||
// Note: We currently do not support SMMU
|
||||
iort.write(36, (2u32).to_le());
|
||||
iort.write(40, (48u32).to_le());
|
||||
|
||||
// ITS group node
|
||||
iort.write(48, ACPI_IORT_NODE_ITS_GROUP as u8);
|
||||
// Length of the ITS group node in bytes
|
||||
iort.write(49, (24u16).to_le());
|
||||
// ITS counts
|
||||
iort.write(64, (1u32).to_le());
|
||||
|
||||
// Root Complex Node
|
||||
iort.write(72, ACPI_IORT_NODE_PCI_ROOT_COMPLEX as u8);
|
||||
// Length of the root complex node in bytes
|
||||
iort.write(73, (52u16).to_le());
|
||||
// Mapping counts
|
||||
iort.write(80, (1u32).to_le());
|
||||
// Offset from the start of the RC node to the start of its Array of ID mappings
|
||||
iort.write(84, (32u32).to_le());
|
||||
// Fully coherent device
|
||||
iort.write(88, (1u32).to_le());
|
||||
// CCA = CPM = DCAS = 1
|
||||
iort.write(95, 3u8);
|
||||
// Identity RID mapping covering the whole input RID range
|
||||
iort.write(108, (0xffff_u32).to_le());
|
||||
// id_mapping_array_output_reference should be
|
||||
// the ITS group node (the first node) if no SMMU
|
||||
iort.write(116, (48u32).to_le());
|
||||
|
||||
iort.update_checksum();
|
||||
|
||||
iort
|
||||
}
|
||||
|
||||
pub fn create_acpi_tables(
|
||||
guest_mem: &GuestMemoryMmap,
|
||||
device_manager: &Arc<Mutex<DeviceManager>>,
|
||||
@ -430,14 +472,25 @@ pub fn create_acpi_tables(
|
||||
prev_tbl_off = slit_offset;
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
let iort = create_iort_table();
|
||||
let iort_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(iort.as_slice(), iort_offset)
|
||||
.expect("Error writing IORT table");
|
||||
tables.push(iort_offset.0);
|
||||
prev_tbl_len = iort.len() as u64;
|
||||
prev_tbl_off = iort_offset;
|
||||
}
|
||||
|
||||
// XSDT
|
||||
let mut xsdt = Sdt::new(*b"XSDT", 36, 1, *b"CLOUDH", *b"CHXSDT ", 1);
|
||||
for table in tables {
|
||||
xsdt.append(table);
|
||||
}
|
||||
xsdt.update_checksum();
|
||||
|
||||
let xsdt_offset = prev_tbl_off.checked_add(prev_tbl_len as u64).unwrap();
|
||||
let xsdt_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(xsdt.as_slice(), xsdt_offset)
|
||||
.expect("Error writing XSDT table");
|
||||
|
Loading…
Reference in New Issue
Block a user