vmm: acpi: Make 'create_acpi_tables' more flexible
Now 'create_acpi_tables_internal()' can generate ACPI tables with different dsdt offset, so that it can be reused for generating ACPI tables for `fw_cfg`. Signed-off-by: Bo Chen <bchen@crusoe.ai> Signed-off-by: Alex Orozco <alexorozco@google.com>
This commit is contained in:
parent
e2d2b2f2f0
commit
cda1ea53a5
1 changed files with 54 additions and 53 deletions
107
vmm/src/acpi.rs
107
vmm/src/acpi.rs
|
|
@ -626,41 +626,32 @@ fn create_viot_table(iommu_bdf: &PciBdf, devices_bdf: &[PciBdf]) -> Sdt {
|
|||
viot
|
||||
}
|
||||
|
||||
pub fn create_acpi_tables(
|
||||
guest_mem: &GuestMemoryMmap,
|
||||
fn create_acpi_tables_internal(
|
||||
dsdt_offset: GuestAddress,
|
||||
device_manager: &Arc<Mutex<DeviceManager>>,
|
||||
cpu_manager: &Arc<Mutex<CpuManager>>,
|
||||
memory_manager: &Arc<Mutex<MemoryManager>>,
|
||||
numa_nodes: &NumaNodes,
|
||||
tpm_enabled: bool,
|
||||
) -> GuestAddress {
|
||||
trace_scoped!("create_acpi_tables");
|
||||
|
||||
let start_time = Instant::now();
|
||||
let rsdp_offset = arch::layout::RSDP_POINTER;
|
||||
) -> (Rsdp, Vec<u8>, Vec<u64>) {
|
||||
// Generated bytes for ACPI tables
|
||||
let mut tables_bytes: Vec<u8> = Vec::new();
|
||||
let mut tables: Vec<u64> = Vec::new();
|
||||
|
||||
// DSDT
|
||||
let dsdt = create_dsdt_table(device_manager, cpu_manager, memory_manager);
|
||||
let dsdt_offset = rsdp_offset.checked_add(Rsdp::len() as u64).unwrap();
|
||||
guest_mem
|
||||
.write_slice(dsdt.as_slice(), dsdt_offset)
|
||||
.expect("Error writing DSDT table");
|
||||
tables_bytes.extend_from_slice(dsdt.as_slice());
|
||||
|
||||
// FACP aka FADT
|
||||
let facp = create_facp_table(dsdt_offset, device_manager);
|
||||
let facp_offset = dsdt_offset.checked_add(dsdt.len() as u64).unwrap();
|
||||
guest_mem
|
||||
.write_slice(facp.as_slice(), facp_offset)
|
||||
.expect("Error writing FACP table");
|
||||
tables_bytes.extend_from_slice(facp.as_slice());
|
||||
tables.push(facp_offset.0);
|
||||
|
||||
// MADT
|
||||
let madt = cpu_manager.lock().unwrap().create_madt();
|
||||
let madt_offset = facp_offset.checked_add(facp.len() as u64).unwrap();
|
||||
guest_mem
|
||||
.write_slice(madt.as_slice(), madt_offset)
|
||||
.expect("Error writing MADT table");
|
||||
tables_bytes.extend_from_slice(madt.as_slice());
|
||||
tables.push(madt_offset.0);
|
||||
let mut prev_tbl_len = madt.len() as u64;
|
||||
let mut prev_tbl_off = madt_offset;
|
||||
|
|
@ -670,9 +661,7 @@ pub fn create_acpi_tables(
|
|||
{
|
||||
let pptt = cpu_manager.lock().unwrap().create_pptt();
|
||||
let pptt_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(pptt.as_slice(), pptt_offset)
|
||||
.expect("Error writing PPTT table");
|
||||
tables_bytes.extend_from_slice(pptt.as_slice());
|
||||
tables.push(pptt_offset.0);
|
||||
prev_tbl_len = pptt.len() as u64;
|
||||
prev_tbl_off = pptt_offset;
|
||||
|
|
@ -683,9 +672,7 @@ pub fn create_acpi_tables(
|
|||
{
|
||||
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_bytes.extend_from_slice(gtdt.as_slice());
|
||||
tables.push(gtdt_offset.0);
|
||||
prev_tbl_len = gtdt.len() as u64;
|
||||
prev_tbl_off = gtdt_offset;
|
||||
|
|
@ -694,9 +681,7 @@ pub fn create_acpi_tables(
|
|||
// MCFG
|
||||
let mcfg = create_mcfg_table(device_manager.lock().unwrap().pci_segments());
|
||||
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");
|
||||
tables_bytes.extend_from_slice(mcfg.as_slice());
|
||||
tables.push(mcfg_offset.0);
|
||||
prev_tbl_len = mcfg.len() as u64;
|
||||
prev_tbl_off = mcfg_offset;
|
||||
|
|
@ -728,9 +713,7 @@ pub fn create_acpi_tables(
|
|||
// SPCR
|
||||
let spcr = create_spcr_table(serial_device_addr, serial_device_irq);
|
||||
let spcr_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(spcr.as_slice(), spcr_offset)
|
||||
.expect("Error writing SPCR table");
|
||||
tables_bytes.extend_from_slice(spcr.as_slice());
|
||||
tables.push(spcr_offset.0);
|
||||
prev_tbl_len = spcr.len() as u64;
|
||||
prev_tbl_off = spcr_offset;
|
||||
|
|
@ -738,9 +721,7 @@ pub fn create_acpi_tables(
|
|||
// DBG2
|
||||
let dbg2 = create_dbg2_table(serial_device_addr);
|
||||
let dbg2_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(dbg2.as_slice(), dbg2_offset)
|
||||
.expect("Error writing DBG2 table");
|
||||
tables_bytes.extend_from_slice(dbg2.as_slice());
|
||||
tables.push(dbg2_offset.0);
|
||||
prev_tbl_len = dbg2.len() as u64;
|
||||
prev_tbl_off = dbg2_offset;
|
||||
|
|
@ -750,9 +731,7 @@ pub fn create_acpi_tables(
|
|||
// TPM2 Table
|
||||
let tpm2 = create_tpm2_table();
|
||||
let tpm2_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(tpm2.as_slice(), tpm2_offset)
|
||||
.expect("Error writing TPM2 table");
|
||||
tables_bytes.extend_from_slice(tpm2.as_slice());
|
||||
tables.push(tpm2_offset.0);
|
||||
|
||||
prev_tbl_len = tpm2.len() as u64;
|
||||
|
|
@ -770,17 +749,13 @@ pub fn create_acpi_tables(
|
|||
topology,
|
||||
);
|
||||
let srat_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(srat.as_slice(), srat_offset)
|
||||
.expect("Error writing SRAT table");
|
||||
tables_bytes.extend_from_slice(srat.as_slice());
|
||||
tables.push(srat_offset.0);
|
||||
|
||||
// SLIT
|
||||
let slit = create_slit_table(numa_nodes);
|
||||
let slit_offset = srat_offset.checked_add(srat.len() as u64).unwrap();
|
||||
guest_mem
|
||||
.write_slice(slit.as_slice(), slit_offset)
|
||||
.expect("Error writing SLIT table");
|
||||
tables_bytes.extend_from_slice(slit.as_slice());
|
||||
tables.push(slit_offset.0);
|
||||
|
||||
prev_tbl_len = slit.len() as u64;
|
||||
|
|
@ -791,9 +766,7 @@ pub fn create_acpi_tables(
|
|||
{
|
||||
let iort = create_iort_table(device_manager.lock().unwrap().pci_segments());
|
||||
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_bytes.extend_from_slice(iort.as_slice());
|
||||
tables.push(iort_offset.0);
|
||||
prev_tbl_len = iort.len() as u64;
|
||||
prev_tbl_off = iort_offset;
|
||||
|
|
@ -805,9 +778,7 @@ pub fn create_acpi_tables(
|
|||
let viot = create_viot_table(iommu_bdf, devices_bdf);
|
||||
|
||||
let viot_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
|
||||
guest_mem
|
||||
.write_slice(viot.as_slice(), viot_offset)
|
||||
.expect("Error writing VIOT table");
|
||||
tables_bytes.extend_from_slice(viot.as_slice());
|
||||
tables.push(viot_offset.0);
|
||||
prev_tbl_len = viot.len() as u64;
|
||||
prev_tbl_off = viot_offset;
|
||||
|
|
@ -815,26 +786,56 @@ pub fn create_acpi_tables(
|
|||
|
||||
// XSDT
|
||||
let mut xsdt = Sdt::new(*b"XSDT", 36, 1, *b"CLOUDH", *b"CHXSDT ", 1);
|
||||
for table in tables {
|
||||
xsdt.append(table);
|
||||
for table in &tables {
|
||||
xsdt.append(*table);
|
||||
}
|
||||
xsdt.update_checksum();
|
||||
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");
|
||||
tables_bytes.extend_from_slice(xsdt.as_slice());
|
||||
|
||||
// RSDP
|
||||
let rsdp = Rsdp::new(*b"CLOUDH", xsdt_offset.0);
|
||||
|
||||
(rsdp, tables_bytes, tables)
|
||||
}
|
||||
|
||||
pub fn create_acpi_tables(
|
||||
guest_mem: &GuestMemoryMmap,
|
||||
device_manager: &Arc<Mutex<DeviceManager>>,
|
||||
cpu_manager: &Arc<Mutex<CpuManager>>,
|
||||
memory_manager: &Arc<Mutex<MemoryManager>>,
|
||||
numa_nodes: &NumaNodes,
|
||||
tpm_enabled: bool,
|
||||
) -> GuestAddress {
|
||||
trace_scoped!("create_acpi_tables");
|
||||
|
||||
let start_time = Instant::now();
|
||||
let rsdp_offset = arch::layout::RSDP_POINTER;
|
||||
let dsdt_offset = rsdp_offset.checked_add(Rsdp::len() as u64).unwrap();
|
||||
|
||||
let (rsdp, tables_bytes, _tables_offset) = create_acpi_tables_internal(
|
||||
dsdt_offset,
|
||||
device_manager,
|
||||
cpu_manager,
|
||||
memory_manager,
|
||||
numa_nodes,
|
||||
tpm_enabled,
|
||||
);
|
||||
|
||||
guest_mem
|
||||
.write_slice(rsdp.as_bytes(), rsdp_offset)
|
||||
.expect("Error writing RSDP");
|
||||
|
||||
guest_mem
|
||||
.write_slice(tables_bytes.as_slice(), dsdt_offset)
|
||||
.expect("Error writing ACPI tables");
|
||||
|
||||
info!(
|
||||
"Generated ACPI tables: took {}µs size = {}",
|
||||
Instant::now().duration_since(start_time).as_micros(),
|
||||
xsdt_offset.0 + xsdt.len() as u64 - rsdp_offset.0
|
||||
Rsdp::len() + tables_bytes.len(),
|
||||
);
|
||||
|
||||
rsdp_offset
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue