QEMU may want to disable guest's S3/S4 support and it wants to distinguish
between regular powerdown and S4 powerdown. To support that new fw_cfg
option was added that passes supported system states and what value should
guest use to enter each state. States are passed in 6 byte array. Each
byte represents one system state. If byte at offset X has its MSB set
it means that system state X is supported and to enter it guest should
use the value from lowest 7 bits. Patch also detects old QEMU and uses
values that work in backwards compatible way there.

Signed-off-by: Gleb Natapov <g...@redhat.com>
---
 src/acpi-dsdt.dsl  |   32 ---------
 src/acpi-dsdt.hex  |   42 +-----------
 src/acpi.c         |   15 ++++
 src/ssdt-pcihp.dsl |   36 ++++++++++
 src/ssdt-pcihp.hex |  185 +++++++++++++++++++++++++++++++++-------------------
 5 files changed, 172 insertions(+), 138 deletions(-)

diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl
index 4bdc268..37899fc 100644
--- a/src/acpi-dsdt.dsl
+++ b/src/acpi-dsdt.dsl
@@ -604,38 +604,6 @@ DefinitionBlock (
         }
     }
 
-
-/****************************************************************
- * Suspend
- ****************************************************************/
-
-    /*
-     * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes:
-     * must match piix4 emulation.
-     */
-    Name (\_S3, Package (0x04)
-    {
-        0x01,  /* PM1a_CNT.SLP_TYP */
-        0x01,  /* PM1b_CNT.SLP_TYP */
-        Zero,  /* reserved */
-        Zero   /* reserved */
-    })
-    Name (\_S4, Package (0x04)
-    {
-        Zero,  /* PM1a_CNT.SLP_TYP */
-        Zero,  /* PM1b_CNT.SLP_TYP */
-        Zero,  /* reserved */
-        Zero   /* reserved */
-    })
-    Name (\_S5, Package (0x04)
-    {
-        Zero,  /* PM1a_CNT.SLP_TYP */
-        Zero,  /* PM1b_CNT.SLP_TYP */
-        Zero,  /* reserved */
-        Zero   /* reserved */
-    })
-
-
 /****************************************************************
  * CPU hotplug
  ****************************************************************/
diff --git a/src/acpi-dsdt.hex b/src/acpi-dsdt.hex
index a4af597..8678fbf 100644
--- a/src/acpi-dsdt.hex
+++ b/src/acpi-dsdt.hex
@@ -3,12 +3,12 @@ static unsigned char AmlCode[] = {
 0x53,
 0x44,
 0x54,
-0x21,
-0x11,
+0xfd,
+0x10,
 0x0,
 0x0,
 0x1,
-0xe8,
+0x4a,
 0x42,
 0x58,
 0x50,
@@ -3925,42 +3925,6 @@ static unsigned char AmlCode[] = {
 0x52,
 0x51,
 0x30,
-0x8,
-0x5f,
-0x53,
-0x33,
-0x5f,
-0x12,
-0x6,
-0x4,
-0x1,
-0x1,
-0x0,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x34,
-0x5f,
-0x12,
-0x6,
-0x4,
-0x0,
-0x0,
-0x0,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x35,
-0x5f,
-0x12,
-0x6,
-0x4,
-0x0,
-0x0,
-0x0,
-0x0,
 0x10,
 0x49,
 0xe,
diff --git a/src/acpi.c b/src/acpi.c
index 30888b9..06ffe0a 100644
--- a/src/acpi.c
+++ b/src/acpi.c
@@ -492,6 +492,8 @@ extern void link_time_assertion(void);
 
 static void* build_pcihp(void)
 {
+    char *sys_states;
+    int sys_state_size;
     u32 rmvc_pcrm;
     int i;
 
@@ -523,6 +525,19 @@ static void* build_pcihp(void)
         }
     }
 
+    sys_states = romfile_loadfile("etc/system-states", &sys_state_size);
+    if (!sys_states || sys_state_size != 6)
+        sys_states = (char[]){128, 0, 0, 129, 128, 128};
+
+    if (!(sys_states[3] & 128))
+        ssdt[acpi_s3_name[0]] = 'X';
+    if (!(sys_states[4] & 128))
+        ssdt[acpi_s4_name[0]] = 'X';
+    else
+        ssdt[acpi_s4_pkg[0] + 1] = ssdt[acpi_s4_pkg[0] + 3] = sys_states[4] & 
127;
+    ((struct acpi_table_header*)ssdt)->checksum = 0;
+    ((struct acpi_table_header*)ssdt)->checksum -= checksum(ssdt, 
sizeof(ssdp_pcihp_aml));
+
     return ssdt;
 }
 
diff --git a/src/ssdt-pcihp.dsl b/src/ssdt-pcihp.dsl
index 4b435b8..12555e2 100644
--- a/src/ssdt-pcihp.dsl
+++ b/src/ssdt-pcihp.dsl
@@ -95,4 +95,40 @@ DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", 
"BXSSDTPCIHP", 0x1)
             gen_pci_hotplug(1f)
         }
     }
+
+    Scope(\) {
+/****************************************************************
+ * Suspend
+ ****************************************************************/
+
+    /*
+     * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes:
+     * must match piix4 emulation.
+     */
+
+        ACPI_EXTRACT_NAME_STRING acpi_s3_name
+        Name (_S3, Package (0x04)
+        {
+            One,  /* PM1a_CNT.SLP_TYP */
+            One,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* reserved */
+            Zero   /* reserved */
+        })
+        ACPI_EXTRACT_NAME_STRING acpi_s4_name
+        ACPI_EXTRACT_PKG_START acpi_s4_pkg
+        Name (_S4, Package (0x04)
+        {
+            0x2,  /* PM1a_CNT.SLP_TYP */
+            0x2,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* reserved */
+            Zero   /* reserved */
+        })
+        Name (_S5, Package (0x04)
+        {
+            Zero,  /* PM1a_CNT.SLP_TYP */
+            Zero,  /* PM1b_CNT.SLP_TYP */
+            Zero,  /* reserved */
+            Zero   /* reserved */
+        })
+    }
 }
diff --git a/src/ssdt-pcihp.hex b/src/ssdt-pcihp.hex
index b15ad5a..f3bb3c6 100644
--- a/src/ssdt-pcihp.hex
+++ b/src/ssdt-pcihp.hex
@@ -1,80 +1,20 @@
-static unsigned short aml_adr_dword[] = {
-0x3e,
-0x62,
-0x88,
-0xae,
-0xd4,
-0xfa,
-0x120,
-0x146,
-0x16c,
-0x192,
-0x1b8,
-0x1de,
-0x204,
-0x22a,
-0x250,
-0x276,
-0x29c,
-0x2c2,
-0x2e8,
-0x30e,
-0x334,
-0x35a,
-0x380,
-0x3a6,
-0x3cc,
-0x3f2,
-0x418,
-0x43e,
-0x464,
-0x48a,
-0x4b0
+static unsigned short acpi_s4_pkg[] = {
+0x65c
 };
-static unsigned short aml_ej0_name[] = {
-0x44,
-0x68,
-0x8e,
-0xb4,
-0xda,
-0x100,
-0x126,
-0x14c,
-0x172,
-0x198,
-0x1be,
-0x1e4,
-0x20a,
-0x230,
-0x256,
-0x27c,
-0x2a2,
-0x2c8,
-0x2ee,
-0x314,
-0x33a,
-0x360,
-0x386,
-0x3ac,
-0x3d2,
-0x3f8,
-0x41e,
-0x444,
-0x46a,
-0x490,
-0x4b6
+static unsigned short acpi_s3_name[] = {
+0x649
 };
 static unsigned char ssdp_pcihp_aml[] = {
 0x53,
 0x53,
 0x44,
 0x54,
-0x44,
+0x6e,
 0x6,
 0x0,
 0x0,
 0x1,
-0x94,
+0x7e,
 0x42,
 0x58,
 0x50,
@@ -1668,5 +1608,116 @@ static unsigned char ssdp_pcihp_aml[] = {
 0x31,
 0x46,
 0x5f,
-0x69
+0x69,
+0x10,
+0x29,
+0x5c,
+0x0,
+0x8,
+0x5f,
+0x53,
+0x33,
+0x5f,
+0x12,
+0x6,
+0x4,
+0x1,
+0x1,
+0x0,
+0x0,
+0x8,
+0x5f,
+0x53,
+0x34,
+0x5f,
+0x12,
+0x8,
+0x4,
+0xa,
+0x2,
+0xa,
+0x2,
+0x0,
+0x0,
+0x8,
+0x5f,
+0x53,
+0x35,
+0x5f,
+0x12,
+0x6,
+0x4,
+0x0,
+0x0,
+0x0,
+0x0
+};
+static unsigned short aml_adr_dword[] = {
+0x3e,
+0x62,
+0x88,
+0xae,
+0xd4,
+0xfa,
+0x120,
+0x146,
+0x16c,
+0x192,
+0x1b8,
+0x1de,
+0x204,
+0x22a,
+0x250,
+0x276,
+0x29c,
+0x2c2,
+0x2e8,
+0x30e,
+0x334,
+0x35a,
+0x380,
+0x3a6,
+0x3cc,
+0x3f2,
+0x418,
+0x43e,
+0x464,
+0x48a,
+0x4b0
+};
+static unsigned short acpi_s4_name[] = {
+0x655
+};
+static unsigned short aml_ej0_name[] = {
+0x44,
+0x68,
+0x8e,
+0xb4,
+0xda,
+0x100,
+0x126,
+0x14c,
+0x172,
+0x198,
+0x1be,
+0x1e4,
+0x20a,
+0x230,
+0x256,
+0x27c,
+0x2a2,
+0x2c8,
+0x2ee,
+0x314,
+0x33a,
+0x360,
+0x386,
+0x3ac,
+0x3d2,
+0x3f8,
+0x41e,
+0x444,
+0x46a,
+0x490,
+0x4b6
 };
-- 
1.7.7.3


Reply via email to