acpi: Enable DSDT for CpuManager on AArch64

Simplified definition block of CPU's on AArch64. It is not complete yet.
Guest boots. But more is to do in future:
- Fix the error in ACPI definition blocks (seen in boot messages)
- Implement CPU hot-plug controller

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
Michael Zhao 2021-02-19 14:29:45 +08:00 committed by Sebastien Boeuf
parent 5f27d649a6
commit e1ef141112

View File

@ -132,7 +132,7 @@ pub enum Error {
} }
pub type Result<T> = result::Result<T, Error>; pub type Result<T> = result::Result<T, Error>;
#[cfg(feature = "acpi")] #[cfg(all(target_arch = "x86_64", feature = "acpi"))]
#[repr(packed)] #[repr(packed)]
struct LocalApic { struct LocalApic {
pub r#type: u8, pub r#type: u8,
@ -394,6 +394,7 @@ pub struct CpuManager {
seccomp_action: SeccompAction, seccomp_action: SeccompAction,
vmmops: Arc<Box<dyn VmmOps>>, vmmops: Arc<Box<dyn VmmOps>>,
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
acpi_address: GuestAddress, acpi_address: GuestAddress,
} }
@ -1260,12 +1261,13 @@ struct Cpu {
cpu_id: u8, cpu_id: u8,
} }
#[cfg(feature = "acpi")] #[cfg(all(target_arch = "x86_64", feature = "acpi"))]
const MADT_CPU_ENABLE_FLAG: usize = 0; const MADT_CPU_ENABLE_FLAG: usize = 0;
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
impl Aml for Cpu { impl Cpu {
fn to_aml_bytes(&self) -> Vec<u8> { #[cfg(target_arch = "x86_64")]
fn generate_mat(&self) -> Vec<u8> {
let lapic = LocalApic { let lapic = LocalApic {
r#type: 0, r#type: 0,
length: 8, length: 8,
@ -1278,11 +1280,22 @@ impl Aml for Cpu {
mat_data.resize(std::mem::size_of_val(&lapic), 0); mat_data.resize(std::mem::size_of_val(&lapic), 0);
unsafe { *(mat_data.as_mut_ptr() as *mut LocalApic) = lapic }; unsafe { *(mat_data.as_mut_ptr() as *mut LocalApic) = lapic };
mat_data
}
}
#[cfg(feature = "acpi")]
impl Aml for Cpu {
fn to_aml_bytes(&self) -> Vec<u8> {
#[cfg(target_arch = "x86_64")]
let mat_data: Vec<u8> = self.generate_mat();
aml::Device::new( aml::Device::new(
format!("C{:03}", self.cpu_id).as_str().into(), format!("C{:03}", self.cpu_id).as_str().into(),
vec![ vec![
&aml::Name::new("_HID".into(), &"ACPI0007"), &aml::Name::new("_HID".into(), &"ACPI0007"),
&aml::Name::new("_UID".into(), &self.cpu_id), &aml::Name::new("_UID".into(), &self.cpu_id),
// Currently, AArch64 cannot support following fields.
/* /*
_STA return value: _STA return value:
Bit [0] Set if the device is present. Bit [0] Set if the device is present.
@ -1292,6 +1305,7 @@ impl Aml for Cpu {
Bit [4] Set if the battery is present. Bit [4] Set if the battery is present.
Bits [31:5] Reserved (must be cleared). Bits [31:5] Reserved (must be cleared).
*/ */
#[cfg(target_arch = "x86_64")]
&aml::Method::new( &aml::Method::new(
"_STA".into(), "_STA".into(),
0, 0,
@ -1305,8 +1319,10 @@ impl Aml for Cpu {
// The Linux kernel expects every CPU device to have a _MAT entry // The Linux kernel expects every CPU device to have a _MAT entry
// containing the LAPIC for this processor with the enabled bit set // containing the LAPIC for this processor with the enabled bit set
// even it if is disabled in the MADT (non-boot CPU) // even it if is disabled in the MADT (non-boot CPU)
#[cfg(target_arch = "x86_64")]
&aml::Name::new("_MAT".into(), &aml::Buffer::new(mat_data)), &aml::Name::new("_MAT".into(), &aml::Buffer::new(mat_data)),
// Trigger CPU ejection // Trigger CPU ejection
#[cfg(target_arch = "x86_64")]
&aml::Method::new( &aml::Method::new(
"_EJ0".into(), "_EJ0".into(),
1, 1,
@ -1467,6 +1483,7 @@ impl Aml for CpuManager {
fn to_aml_bytes(&self) -> Vec<u8> { fn to_aml_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
// CPU hotplug controller // CPU hotplug controller
#[cfg(target_arch = "x86_64")]
bytes.extend_from_slice( bytes.extend_from_slice(
&aml::Device::new( &aml::Device::new(
"_SB_.PRES".into(), "_SB_.PRES".into(),