summary refs log tree commit diff
diff options
context:
space:
mode:
authorChuanxiao Dong <chuanxiao.dong@intel.com>2020-02-22 09:32:30 +0800
committerCommit Bot <commit-bot@chromium.org>2020-02-28 12:46:19 +0000
commit93cb038258eb4b29bc42f273181986e0c5702bf6 (patch)
tree1b0bb867ad4ee2c73947c5a05b9e8be1895eba64
parent05d30607bc70b2c3f79337405a35bc4be43a1660 (diff)
downloadcrosvm-93cb038258eb4b29bc42f273181986e0c5702bf6.tar
crosvm-93cb038258eb4b29bc42f273181986e0c5702bf6.tar.gz
crosvm-93cb038258eb4b29bc42f273181986e0c5702bf6.tar.bz2
crosvm-93cb038258eb4b29bc42f273181986e0c5702bf6.tar.lz
crosvm-93cb038258eb4b29bc42f273181986e0c5702bf6.tar.xz
crosvm-93cb038258eb4b29bc42f273181986e0c5702bf6.tar.zst
crosvm-93cb038258eb4b29bc42f273181986e0c5702bf6.zip
acpi: add S1 capability in DSDT
S1 is a sleep state which is lighter than S3, but enough to put the devices
into the suspended state.

With this DSDT, the guest kernel is able to see the S1 capability and to
put the VM into virtual S1. During the virtual S1, guest kernel will call
each suspend callbacks of the devices driver to put the devices into the
suspend state, including the pass through device.

BUG=chromium:1018674
TEST=boot linux guest with ACPI enabled, and able to see "shallow" by
"cat /sys/power/mem_sleep", which means the S1

Change-Id: I232609f6f2474895fd9ec4046d88236c413e51af
Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2035353
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Tomasz Jeznach <tjeznach@chromium.org>
-rw-r--r--x86_64/src/acpi.rs37
1 files changed, 29 insertions, 8 deletions
diff --git a/x86_64/src/acpi.rs b/x86_64/src/acpi.rs
index 7030bd8..3600d16 100644
--- a/x86_64/src/acpi.rs
+++ b/x86_64/src/acpi.rs
@@ -65,6 +65,34 @@ const MADT_ENABLED: u32 = 1;
 // XSDT
 const XSDT_REVISION: u8 = 1;
 
+fn create_dsdt_table() -> SDT {
+    // The hex tables in this file are generated from the ASL below with:
+    // "iasl -tc <dsdt.asl>"
+    // Below is the tables represents by the pm_dsdt_data
+    // Name (_S1, Package (0x04)  // _S1_: S1 System State
+    // {
+    //     One,
+    //     One,
+    //     Zero,
+    //     Zero
+    // })
+    let pm_dsdt_data = [
+        0x08u8, 0x5F, 0x53, 0x31, 0x5f, 0x12, 0x06, 0x04, 0x01, 0x01, 0x00, 0x00,
+    ];
+
+    let mut dsdt = SDT::new(
+        *b"DSDT",
+        acpi_tables::HEADER_LEN,
+        DSDT_REVISION,
+        *b"CROSVM",
+        *b"CROSVMDT",
+        OEM_REVISION,
+    );
+    dsdt.append(pm_dsdt_data);
+
+    dsdt
+}
+
 /// Create ACPI tables and return the RSDP.
 /// The basic tables DSDT/FACP/MADT/XSDT are constructed in this function.
 /// # Arguments
@@ -80,14 +108,7 @@ pub fn create_acpi_tables(guest_mem: &GuestMemory, num_cpus: u8, sci_irq: u32) -
     let mut tables: Vec<u64> = Vec::new();
 
     // DSDT
-    let dsdt = SDT::new(
-        *b"DSDT",
-        acpi_tables::HEADER_LEN,
-        DSDT_REVISION,
-        *b"CROSVM",
-        *b"CROSVMDT",
-        OEM_REVISION,
-    );
+    let dsdt = create_dsdt_table();
     let dsdt_offset = rsdp_offset.checked_add(RSDP::len() as u64).unwrap();
     guest_mem
         .write_at_addr(dsdt.as_slice(), dsdt_offset)