vmm: cpu: Port CpuManager to Aml::append_aml_bytes()

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-11-04 17:12:59 +00:00
parent a7786b4e0c
commit 986e43f899

View File

@ -1253,7 +1253,7 @@ impl Cpu {
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
impl Aml for Cpu { impl Aml for Cpu {
fn to_aml_bytes(&self) -> Vec<u8> { fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
let mat_data: Vec<u8> = self.generate_mat(); let mat_data: Vec<u8> = self.generate_mat();
@ -1305,7 +1305,7 @@ impl Aml for Cpu {
), ),
], ],
) )
.to_aml_bytes() .append_aml_bytes(bytes)
} }
} }
@ -1316,13 +1316,13 @@ struct CpuNotify {
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
impl Aml for CpuNotify { impl Aml for CpuNotify {
fn to_aml_bytes(&self) -> Vec<u8> { fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
let object = aml::Path::new(&format!("C{:03}", self.cpu_id)); let object = aml::Path::new(&format!("C{:03}", self.cpu_id));
aml::If::new( aml::If::new(
&aml::Equal::new(&aml::Arg(0), &self.cpu_id), &aml::Equal::new(&aml::Arg(0), &self.cpu_id),
vec![&aml::Notify::new(&object, &aml::Arg(1))], vec![&aml::Notify::new(&object, &aml::Arg(1))],
) )
.to_aml_bytes() .append_aml_bytes(bytes)
} }
} }
@ -1333,33 +1333,30 @@ struct CpuMethods {
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
impl Aml for CpuMethods { impl Aml for CpuMethods {
fn to_aml_bytes(&self) -> Vec<u8> { fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
let mut bytes = Vec::new(); // CPU status method
bytes.extend_from_slice( aml::Method::new(
// CPU status method "CSTA".into(),
&aml::Method::new( 1,
"CSTA".into(), true,
1, vec![
true, // Take lock defined above
vec![ &aml::Acquire::new("\\_SB_.PRES.CPLK".into(), 0xffff),
// Take lock defined above // Write CPU number (in first argument) to I/O port via field
&aml::Acquire::new("\\_SB_.PRES.CPLK".into(), 0xffff), &aml::Store::new(&aml::Path::new("\\_SB_.PRES.CSEL"), &aml::Arg(0)),
// Write CPU number (in first argument) to I/O port via field &aml::Store::new(&aml::Local(0), &aml::ZERO),
&aml::Store::new(&aml::Path::new("\\_SB_.PRES.CSEL"), &aml::Arg(0)), // Check if CPEN bit is set, if so make the local variable 0xf (see _STA for details of meaning)
&aml::Store::new(&aml::Local(0), &aml::ZERO), &aml::If::new(
// Check if CPEN bit is set, if so make the local variable 0xf (see _STA for details of meaning) &aml::Equal::new(&aml::Path::new("\\_SB_.PRES.CPEN"), &aml::ONE),
&aml::If::new( vec![&aml::Store::new(&aml::Local(0), &0xfu8)],
&aml::Equal::new(&aml::Path::new("\\_SB_.PRES.CPEN"), &aml::ONE), ),
vec![&aml::Store::new(&aml::Local(0), &0xfu8)], // Release lock
), &aml::Release::new("\\_SB_.PRES.CPLK".into()),
// Release lock // Return 0 or 0xf
&aml::Release::new("\\_SB_.PRES.CPLK".into()), &aml::Return::new(&aml::Local(0)),
// Return 0 or 0xf ],
&aml::Return::new(&aml::Local(0)), )
], .append_aml_bytes(bytes);
)
.to_aml_bytes(),
);
let mut cpu_notifies = Vec::new(); let mut cpu_notifies = Vec::new();
for cpu_id in 0..self.max_vcpus { for cpu_id in 0..self.max_vcpus {
@ -1371,144 +1368,125 @@ impl Aml for CpuMethods {
cpu_notifies_refs.push(&cpu_notifies[usize::from(cpu_id)]); cpu_notifies_refs.push(&cpu_notifies[usize::from(cpu_id)]);
} }
bytes.extend_from_slice( aml::Method::new("CTFY".into(), 2, true, cpu_notifies_refs).append_aml_bytes(bytes);
&aml::Method::new("CTFY".into(), 2, true, cpu_notifies_refs).to_aml_bytes(),
);
bytes.extend_from_slice( aml::Method::new(
&aml::Method::new( "CEJ0".into(),
"CEJ0".into(), 1,
1, true,
true, vec![
vec![ &aml::Acquire::new("\\_SB_.PRES.CPLK".into(), 0xffff),
&aml::Acquire::new("\\_SB_.PRES.CPLK".into(), 0xffff), // Write CPU number (in first argument) to I/O port via field
// Write CPU number (in first argument) to I/O port via field &aml::Store::new(&aml::Path::new("\\_SB_.PRES.CSEL"), &aml::Arg(0)),
&aml::Store::new(&aml::Path::new("\\_SB_.PRES.CSEL"), &aml::Arg(0)), // Set CEJ0 bit
// Set CEJ0 bit &aml::Store::new(&aml::Path::new("\\_SB_.PRES.CEJ0"), &aml::ONE),
&aml::Store::new(&aml::Path::new("\\_SB_.PRES.CEJ0"), &aml::ONE), &aml::Release::new("\\_SB_.PRES.CPLK".into()),
&aml::Release::new("\\_SB_.PRES.CPLK".into()), ],
], )
) .append_aml_bytes(bytes);
.to_aml_bytes(),
);
bytes.extend_from_slice( aml::Method::new(
&aml::Method::new( "CSCN".into(),
"CSCN".into(), 0,
0, true,
true, vec![
vec![ // Take lock defined above
// Take lock defined above &aml::Acquire::new("\\_SB_.PRES.CPLK".into(), 0xffff),
&aml::Acquire::new("\\_SB_.PRES.CPLK".into(), 0xffff), &aml::Store::new(&aml::Local(0), &aml::ZERO),
&aml::Store::new(&aml::Local(0), &aml::ZERO), &aml::While::new(
&aml::While::new( &aml::LessThan::new(&aml::Local(0), &self.max_vcpus),
&aml::LessThan::new(&aml::Local(0), &self.max_vcpus), vec![
vec![ // Write CPU number (in first argument) to I/O port via field
// Write CPU number (in first argument) to I/O port via field &aml::Store::new(&aml::Path::new("\\_SB_.PRES.CSEL"), &aml::Local(0)),
&aml::Store::new(&aml::Path::new("\\_SB_.PRES.CSEL"), &aml::Local(0)), // Check if CINS bit is set
// Check if CINS bit is set &aml::If::new(
&aml::If::new( &aml::Equal::new(&aml::Path::new("\\_SB_.PRES.CINS"), &aml::ONE),
&aml::Equal::new(&aml::Path::new("\\_SB_.PRES.CINS"), &aml::ONE), // Notify device if it is
// Notify device if it is vec![
vec![ &aml::MethodCall::new(
&aml::MethodCall::new( "CTFY".into(),
"CTFY".into(), vec![&aml::Local(0), &aml::ONE],
vec![&aml::Local(0), &aml::ONE], ),
), // Reset CINS bit
// Reset CINS bit &aml::Store::new(&aml::Path::new("\\_SB_.PRES.CINS"), &aml::ONE),
&aml::Store::new( ],
&aml::Path::new("\\_SB_.PRES.CINS"), ),
&aml::ONE, // Check if CRMV bit is set
), &aml::If::new(
], &aml::Equal::new(&aml::Path::new("\\_SB_.PRES.CRMV"), &aml::ONE),
), // Notify device if it is (with the eject constant 0x3)
// Check if CRMV bit is set vec![
&aml::If::new( &aml::MethodCall::new("CTFY".into(), vec![&aml::Local(0), &3u8]),
&aml::Equal::new(&aml::Path::new("\\_SB_.PRES.CRMV"), &aml::ONE), // Reset CRMV bit
// Notify device if it is (with the eject constant 0x3) &aml::Store::new(&aml::Path::new("\\_SB_.PRES.CRMV"), &aml::ONE),
vec![ ],
&aml::MethodCall::new( ),
"CTFY".into(), &aml::Add::new(&aml::Local(0), &aml::Local(0), &aml::ONE),
vec![&aml::Local(0), &3u8], ],
), ),
// Reset CRMV bit // Release lock
&aml::Store::new( &aml::Release::new("\\_SB_.PRES.CPLK".into()),
&aml::Path::new("\\_SB_.PRES.CRMV"), ],
&aml::ONE, )
), .append_aml_bytes(bytes)
],
),
&aml::Add::new(&aml::Local(0), &aml::Local(0), &aml::ONE),
],
),
// Release lock
&aml::Release::new("\\_SB_.PRES.CPLK".into()),
],
)
.to_aml_bytes(),
);
bytes
} }
} }
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
impl Aml for CpuManager { impl Aml for CpuManager {
fn to_aml_bytes(&self) -> Vec<u8> { fn append_aml_bytes(&self, bytes: &mut Vec<u8>) {
let mut bytes = Vec::new();
// CPU hotplug controller // CPU hotplug controller
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
bytes.extend_from_slice( aml::Device::new(
&aml::Device::new( "_SB_.PRES".into(),
"_SB_.PRES".into(), vec![
vec![ &aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0A06")),
&aml::Name::new("_HID".into(), &aml::EisaName::new("PNP0A06")), &aml::Name::new("_UID".into(), &"CPU Hotplug Controller"),
&aml::Name::new("_UID".into(), &"CPU Hotplug Controller"), // Mutex to protect concurrent access as we write to choose CPU and then read back status
// Mutex to protect concurrent access as we write to choose CPU and then read back status &aml::Mutex::new("CPLK".into(), 0),
&aml::Mutex::new("CPLK".into(), 0), &aml::Name::new(
&aml::Name::new( "_CRS".into(),
"_CRS".into(), &aml::ResourceTemplate::new(vec![&aml::AddressSpace::new_memory(
&aml::ResourceTemplate::new(vec![&aml::AddressSpace::new_memory( aml::AddressSpaceCachable::NotCacheable,
aml::AddressSpaceCachable::NotCacheable, true,
true, self.acpi_address.0 as u64,
self.acpi_address.0 as u64, self.acpi_address.0 + CPU_MANAGER_ACPI_SIZE as u64 - 1,
self.acpi_address.0 + CPU_MANAGER_ACPI_SIZE as u64 - 1, )]),
)]), ),
), // OpRegion and Fields map MMIO range into individual field values
// OpRegion and Fields map MMIO range into individual field values &aml::OpRegion::new(
&aml::OpRegion::new( "PRST".into(),
"PRST".into(), aml::OpRegionSpace::SystemMemory,
aml::OpRegionSpace::SystemMemory, self.acpi_address.0 as usize,
self.acpi_address.0 as usize, CPU_MANAGER_ACPI_SIZE,
CPU_MANAGER_ACPI_SIZE, ),
), &aml::Field::new(
&aml::Field::new( "PRST".into(),
"PRST".into(), aml::FieldAccessType::Byte,
aml::FieldAccessType::Byte, aml::FieldUpdateRule::WriteAsZeroes,
aml::FieldUpdateRule::WriteAsZeroes, vec![
vec![ aml::FieldEntry::Reserved(32),
aml::FieldEntry::Reserved(32), aml::FieldEntry::Named(*b"CPEN", 1),
aml::FieldEntry::Named(*b"CPEN", 1), aml::FieldEntry::Named(*b"CINS", 1),
aml::FieldEntry::Named(*b"CINS", 1), aml::FieldEntry::Named(*b"CRMV", 1),
aml::FieldEntry::Named(*b"CRMV", 1), aml::FieldEntry::Named(*b"CEJ0", 1),
aml::FieldEntry::Named(*b"CEJ0", 1), aml::FieldEntry::Reserved(4),
aml::FieldEntry::Reserved(4), aml::FieldEntry::Named(*b"CCMD", 8),
aml::FieldEntry::Named(*b"CCMD", 8), ],
], ),
), &aml::Field::new(
&aml::Field::new( "PRST".into(),
"PRST".into(), aml::FieldAccessType::DWord,
aml::FieldAccessType::DWord, aml::FieldUpdateRule::Preserve,
aml::FieldUpdateRule::Preserve, vec![
vec![ aml::FieldEntry::Named(*b"CSEL", 32),
aml::FieldEntry::Named(*b"CSEL", 32), aml::FieldEntry::Reserved(32),
aml::FieldEntry::Reserved(32), aml::FieldEntry::Named(*b"CDAT", 32),
aml::FieldEntry::Named(*b"CDAT", 32), ],
], ),
), ],
], )
) .append_aml_bytes(bytes);
.to_aml_bytes(),
);
// CPU devices // CPU devices
let hid = aml::Name::new("_HID".into(), &"ACPI0010"); let hid = aml::Name::new("_HID".into(), &"ACPI0010");
@ -1534,10 +1512,7 @@ impl Aml for CpuManager {
cpu_data_inner.push(cpu_device); cpu_data_inner.push(cpu_device);
} }
bytes.extend_from_slice( aml::Device::new("_SB_.CPUS".into(), cpu_data_inner).append_aml_bytes(bytes)
&aml::Device::new("_SB_.CPUS".into(), cpu_data_inner).to_aml_bytes(),
);
bytes
} }
} }