mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
arch: x86_64: Generate basic ACPI tables
Generate very basic ACPI tables for HW reduced ACPI. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
eea6f1dc9e
commit
ee83c2d44e
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -32,6 +32,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "arch"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"acpi_tables 0.1.0",
|
||||
"arch_gen 0.1.0",
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kvm-bindings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -9,6 +9,7 @@ kvm-bindings = "0.1.1"
|
||||
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls", branch = "master" }
|
||||
libc = "0.2.60"
|
||||
|
||||
acpi_tables = { path ="../acpi_tables" }
|
||||
arch_gen = { path = "../arch_gen" }
|
||||
|
||||
[dependencies.vm-memory]
|
||||
|
@ -13,6 +13,7 @@ extern crate byteorder;
|
||||
extern crate kvm_bindings;
|
||||
extern crate libc;
|
||||
|
||||
extern crate acpi_tables;
|
||||
extern crate arch_gen;
|
||||
extern crate kvm_ioctls;
|
||||
extern crate linux_loader;
|
||||
|
70
arch/src/x86_64/acpi.rs
Normal file
70
arch/src/x86_64/acpi.rs
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright © 2019 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
use acpi_tables::{rsdp::RSDP, sdt::SDT};
|
||||
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
||||
|
||||
use vm_memory::{Address, ByteValued, Bytes};
|
||||
|
||||
pub fn create_acpi_tables(guest_mem: &GuestMemoryMmap) -> GuestAddress {
|
||||
// RSDP is at the EBDA
|
||||
let rsdp_offset = super::EBDA_START;
|
||||
let mut tables: Vec<u64> = Vec::new();
|
||||
|
||||
// DSDT
|
||||
let mut dsdt = SDT::new(*b"DSDT", 36, 6, *b"CLOUDH", *b"CHDSDT ", 1);
|
||||
dsdt.update_checksum();
|
||||
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");
|
||||
|
||||
// FACP aka FADT
|
||||
// Revision 6 of the ACPI FADT table is 276 bytes long
|
||||
let mut facp = SDT::new(*b"FACP", 276, 6, *b"CLOUDH", *b"CHFACP ", 1);
|
||||
|
||||
let fadt_flags: u32 = 1 << 20; // HW_REDUCED_ACPI
|
||||
facp.write(112, fadt_flags);
|
||||
|
||||
// TODO: RESET_REG/RESET_VALUE @ offset 116/128
|
||||
|
||||
facp.write(131, 3u8); // FADT minor version
|
||||
facp.write(140, dsdt_offset.0); // X_DSDT
|
||||
|
||||
// TODO: SLEEP_CONTROL_REG/SLEEP_STATUS_REG @ offset 244/256
|
||||
|
||||
facp.write(268, b"CLOUDHYP"); // Hypervisor Vendor Identity
|
||||
|
||||
facp.update_checksum();
|
||||
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.push(facp_offset.0);
|
||||
|
||||
// XSDT
|
||||
let mut xsdt = SDT::new(
|
||||
*b"XSDT",
|
||||
36 + 8 * tables.len() as u32,
|
||||
1,
|
||||
*b"CLOUDH",
|
||||
*b"CHXSDT ",
|
||||
1,
|
||||
);
|
||||
xsdt.write(36, tables[0]);
|
||||
xsdt.update_checksum();
|
||||
|
||||
let xsdt_offset = facp_offset.checked_add(facp.len() as u64).unwrap();
|
||||
guest_mem
|
||||
.write_slice(xsdt.as_slice(), xsdt_offset)
|
||||
.expect("Error writing XSDT table");
|
||||
|
||||
// RSDP
|
||||
let rsdp = RSDP::new(*b"CLOUDH", xsdt_offset.0);
|
||||
guest_mem
|
||||
.write_slice(rsdp.as_slice(), rsdp_offset)
|
||||
.expect("Error writing RSDP");
|
||||
|
||||
rsdp_offset
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE-BSD-3-Clause file.
|
||||
|
||||
mod acpi;
|
||||
mod gdt;
|
||||
pub mod interrupts;
|
||||
pub mod layout;
|
||||
@ -181,6 +182,9 @@ pub fn configure_system(
|
||||
}
|
||||
}
|
||||
|
||||
let rsdp_addr = acpi::create_acpi_tables(guest_mem);
|
||||
params.0.acpi_rsdp_addr = rsdp_addr.0;
|
||||
|
||||
let zero_page_addr = layout::ZERO_PAGE_START;
|
||||
guest_mem
|
||||
.checked_offset(zero_page_addr, mem::size_of::<boot_params>())
|
||||
|
Loading…
Reference in New Issue
Block a user