vmm: acpi: Generate IORT table according to spec revision E.b
The current IORT table implementation is based on IORT Spec revision E.b [1], as evidenced by: * The PCI root complex node revision being set to `3` * The code being updated in late 2021 [2] when revision E.b was the latest version This patch ensures the IORT table is properly generated according to this specification revision, fixing three issues: 1. The IORT table revision should be `3` rather than `2` (see Table 2 in the spec [1]) 2. The GIC ITS group node revision should be `1` rather than `0` (see Table 12 in the spec [1]) 3. The "Memory access properties" and "ATS Attribute" fields of the PCI root complex node was set incorrectly - specifically the MAF (Memory Access Flags) including CPM and DACS bits (see Tables 14, 15, and 17 in the spec [1]) [1] https://developer.arm.com/documentation/den0049/eb/?lang=en [2] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/3356 Signed-off-by: Bo Chen <bchen@crusoe.ai>
This commit is contained in:
parent
079d94ecae
commit
c87ca39219
1 changed files with 6 additions and 2 deletions
|
|
@ -515,6 +515,8 @@ fn create_dbg2_table(base_address: u64) -> Sdt {
|
|||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
// Generate IORT table based on Spec Revision E.b:
|
||||
// https://developer.arm.com/documentation/den0049/eb/?lang=en
|
||||
fn create_iort_table(pci_segments: &[PciSegment]) -> Sdt {
|
||||
const ACPI_IORT_NODE_ITS_GROUP: u8 = 0x00;
|
||||
const ACPI_IORT_NODE_PCI_ROOT_COMPLEX: u8 = 0x02;
|
||||
|
|
@ -528,7 +530,7 @@ fn create_iort_table(pci_segments: &[PciSegment]) -> Sdt {
|
|||
let iort_table_size: u32 = (ACPI_IORT_NODE_ROOT_COMPLEX_OFFSET
|
||||
+ ACPI_IORT_NODE_ROOT_COMPLEX_SIZE * pci_segments.len())
|
||||
as u32;
|
||||
let mut iort = Sdt::new(*b"IORT", iort_table_size, 2, *b"CLOUDH", *b"CHIORT ", 1);
|
||||
let mut iort = Sdt::new(*b"IORT", iort_table_size, 3, *b"CLOUDH", *b"CHIORT ", 1);
|
||||
iort.write(36, ((1 + pci_segments.len()) as u32).to_le());
|
||||
iort.write(40, (48u32).to_le());
|
||||
|
||||
|
|
@ -536,6 +538,8 @@ fn create_iort_table(pci_segments: &[PciSegment]) -> Sdt {
|
|||
iort.write(48, ACPI_IORT_NODE_ITS_GROUP);
|
||||
// Length of the ITS group node in bytes
|
||||
iort.write(49, (24u16).to_le());
|
||||
// Revision
|
||||
iort.write(51, (1u8).to_le());
|
||||
// ITS counts
|
||||
iort.write(64, (1u32).to_le());
|
||||
|
||||
|
|
@ -560,7 +564,7 @@ fn create_iort_table(pci_segments: &[PciSegment]) -> Sdt {
|
|||
// Fully coherent device
|
||||
iort.write(node_offset + 16, (1u32).to_le());
|
||||
// CCA = CPM = DCAS = 1
|
||||
iort.write(node_offset + 24, 3u8);
|
||||
iort.write(node_offset + 23, 3u8);
|
||||
// PCI segment number
|
||||
iort.write(node_offset + 28, (segment.id as u32).to_le());
|
||||
// Memory address size limit
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue