acpi: Add customized acpi _PRx method

Without _PRx method, device couldn't put into D3cold. In order to
put vfio-pci device into D3cold in VM, this commit add _PRx method
for vfio-pci device. When guest call _PRx method, crosvm will trap
it and forward the _ON/_OFF request to host vfio-pci kernel driver
which manage physical device PM.

BUG=b:194390621
TEST=dump ssdt table in a guest with vfio-pci device

Change-Id: I5ec6ebc84f5328574b62b2d6e091ffe9605d1dd4
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3822009
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Victor Ding <victording@chromium.org>
This commit is contained in:
Xiong Zhang 2022-06-23 15:27:32 +08:00 committed by crosvm LUCI
parent 4cc3506fe4
commit 75dbd9763e
3 changed files with 59 additions and 0 deletions

View file

@ -45,6 +45,14 @@ impl Aml for DeviceVcfgRegister {
&4096_usize,
)
.to_aml_bytes(bytes);
aml::Field::new(
"VREG".into(),
aml::FieldAccessType::DWord,
aml::FieldLockRule::Lock,
aml::FieldUpdateRule::Preserve,
vec![aml::FieldEntry::Named(*b"PFPM", 32)],
)
.to_aml_bytes(bytes);
aml::OpRegion::new(
"SHAM".into(),
aml::OpRegionSpace::SystemMemory,
@ -58,3 +66,47 @@ impl Aml for DeviceVcfgRegister {
.to_aml_bytes(bytes);
}
}
pub struct PowerResourceMethod {}
impl Aml for PowerResourceMethod {
fn to_aml_bytes(&self, aml: &mut Vec<u8>) {
aml::PowerResource::new(
"PRIC".into(),
0u8,
0u16,
vec![
&aml::Name::new("_STA".into(), &aml::ONE),
&aml::Method::new(
"_ON_".into(),
0,
true,
vec![
&aml::Store::new(&aml::Name::new_field_name("PFPM"), &aml::ONE),
&aml::Store::new(&aml::Name::new_field_name("_STA"), &aml::ONE),
],
),
&aml::Method::new(
"_OFF".into(),
0,
true,
vec![
&aml::Store::new(&aml::Name::new_field_name("_STA"), &aml::ZERO),
&aml::Store::new(&aml::Name::new_field_name("PFPM"), &aml::ZERO),
],
),
],
)
.to_aml_bytes(aml);
aml::Name::new(
"_PR0".into(),
&aml::Package::new(vec![&aml::Name::new_field_name("PRIC")]),
)
.to_aml_bytes(aml);
aml::Name::new(
"_PR3".into(),
&aml::Package::new(vec![&aml::Name::new_field_name("PRIC")]),
)
.to_aml_bytes(aml);
}
}

View file

@ -42,6 +42,7 @@ pub use self::ac97::Ac97Dev;
#[cfg(all(unix, feature = "audio"))]
pub use self::ac97::Ac97Parameters;
pub use self::acpi::DeviceVcfgRegister;
pub use self::acpi::PowerResourceMethod;
#[cfg(unix)]
pub use self::coiommu::CoIommuDev;
#[cfg(unix)]

View file

@ -51,6 +51,7 @@ use vm_control::VmRequest;
use vm_control::VmResponse;
use crate::pci::acpi::DeviceVcfgRegister;
use crate::pci::acpi::PowerResourceMethod;
use crate::pci::acpi::SHM_OFFSET;
use crate::pci::msi::MsiConfig;
use crate::pci::msi::MsiStatus;
@ -2159,6 +2160,11 @@ impl PciDevice for VfioPciDevice {
.create_shm_mmap()
.map(|shm| (vcfg_offset + SHM_OFFSET, shm));
self.vcfg_shm_mmap = vcfg_register.create_shm_mmap();
// All vfio-pci devices should have virtual _PRx method, otherwise
// host couldn't know whether device has enter into suspend state,
// host would always think it is in active state, so its parent PCIe
// switch couldn't enter into suspend state.
PowerResourceMethod {}.to_aml_bytes(&mut amls);
}
}