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 gleb@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 };