From patchwork Mon May 14 12:35:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gleb Natapov X-Patchwork-Id: 158992 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 0DB46B702E for ; Mon, 14 May 2012 22:35:44 +1000 (EST) Received: from localhost ([::1]:41934 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1STuV3-00054B-Sz for incoming@patchwork.ozlabs.org; Mon, 14 May 2012 08:35:41 -0400 Received: from eggs.gnu.org ([208.118.235.92]:42113) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1STuUv-000543-3N for qemu-devel@nongnu.org; Mon, 14 May 2012 08:35:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1STuUq-0004h3-UY for qemu-devel@nongnu.org; Mon, 14 May 2012 08:35:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:1025) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1STuUq-0004gl-LW for qemu-devel@nongnu.org; Mon, 14 May 2012 08:35:28 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q4ECZRLU022383 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 14 May 2012 08:35:27 -0400 Received: from dhcp-1-237.tlv.redhat.com (dhcp-4-26.tlv.redhat.com [10.35.4.26]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q4ECZQWp030523; Mon, 14 May 2012 08:35:26 -0400 Received: by dhcp-1-237.tlv.redhat.com (Postfix, from userid 13519) id ED6C218D477; Mon, 14 May 2012 15:35:25 +0300 (IDT) From: Gleb Natapov To: seabios@seabios.org Date: Mon, 14 May 2012 15:35:23 +0300 Message-Id: <1336998923-30144-2-git-send-email-gleb@redhat.com> In-Reply-To: <1336998923-30144-1-git-send-email-gleb@redhat.com> References: <1336998923-30144-1-git-send-email-gleb@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 2/2] Get system state configuration from QEMU and patcth DSDT with it. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- src/acpi-dsdt.dsl | 7 +++++-- src/acpi-dsdt.hex | 21 ++++++++++++++++----- src/acpi.c | 12 +++++++++++- src/paravirt.c | 16 ++++++++++++++++ src/paravirt.h | 2 ++ 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl index 4bdc268..cd4ce52 100644 --- a/src/acpi-dsdt.dsl +++ b/src/acpi-dsdt.dsl @@ -613,6 +613,7 @@ DefinitionBlock ( * 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) { 0x01, /* PM1a_CNT.SLP_TYP */ @@ -620,10 +621,12 @@ DefinitionBlock ( Zero, /* reserved */ Zero /* reserved */ }) + ACPI_EXTRACT_NAME_STRING acpi_s4_name + ACPI_EXTRACT_PKG_START acpi_s4_pkg Name (\_S4, Package (0x04) { - Zero, /* PM1a_CNT.SLP_TYP */ - Zero, /* PM1b_CNT.SLP_TYP */ + 0x2, /* PM1a_CNT.SLP_TYP */ + 0x2, /* PM1b_CNT.SLP_TYP */ Zero, /* reserved */ Zero /* reserved */ }) diff --git a/src/acpi-dsdt.hex b/src/acpi-dsdt.hex index a4af597..8a50f55 100644 --- a/src/acpi-dsdt.hex +++ b/src/acpi-dsdt.hex @@ -1,14 +1,20 @@ +static unsigned short acpi_s3_name[] = { +0xf57 +}; +static unsigned short acpi_s4_name[] = { +0xf63 +}; static unsigned char AmlCode[] = { 0x44, 0x53, 0x44, 0x54, -0x21, +0x23, 0x11, 0x0, 0x0, 0x1, -0xe8, +0xcc, 0x42, 0x58, 0x50, @@ -3943,10 +3949,12 @@ static unsigned char AmlCode[] = { 0x34, 0x5f, 0x12, -0x6, +0x8, 0x4, -0x0, -0x0, +0xa, +0x2, +0xa, +0x2, 0x0, 0x0, 0x8, @@ -4385,3 +4393,6 @@ static unsigned char AmlCode[] = { 0xa4, 0x1 }; +static unsigned short acpi_s4_pkg[] = { +0xf6a +}; diff --git a/src/acpi.c b/src/acpi.c index 30888b9..1e7d466 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -734,13 +734,23 @@ acpi_bios_init(void) } if (fadt && !fadt->dsdt) { /* default DSDT */ - void *dsdt = malloc_high(sizeof(AmlCode)); + char *dsdt = malloc_high(sizeof(AmlCode)); + char sys_states[6]; if (!dsdt) { warn_noalloc(); return; } memcpy(dsdt, AmlCode, sizeof(AmlCode)); fill_dsdt(fadt, dsdt); + qemu_cfg_system_states(sys_states); + if (!(sys_states[3] & 128)) + dsdt[acpi_s3_name[0]] = 'X'; + if (!(sys_states[4] & 128)) + dsdt[acpi_s4_name[0]] = 'X'; + else + dsdt[acpi_s4_pkg[0] + 1] = dsdt[acpi_s4_pkg[0] + 3] = sys_states[4] & 127; + ((struct acpi_table_header*)dsdt)->checksum = 0; + ((struct acpi_table_header*)dsdt)->checksum -= checksum(dsdt, sizeof(AmlCode)); } // Build final rsdt table diff --git a/src/paravirt.c b/src/paravirt.c index 9cf77de..201bbc3 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -92,6 +92,22 @@ int qemu_cfg_irq0_override(void) return v; } +int qemu_cfg_system_states(char *states) +{ + char s[6] = {128, 0, 0, 129, 128, 128}; + + if (qemu_cfg_present) { + qemu_cfg_read_entry(states, QEMU_CFG_SYSTEM_STATES, 6); + if (states[0]) + return 1; + } + + /* use defaults matching old QEMU */ + memcpy(states, s, sizeof(s)); + + return 0; +} + u16 qemu_cfg_acpi_additional_tables(void) { u16 cnt; diff --git a/src/paravirt.h b/src/paravirt.h index f39e226..b69646c 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -40,6 +40,7 @@ static inline int kvm_para_available(void) #define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1) #define QEMU_CFG_IRQ0_OVERRIDE (QEMU_CFG_ARCH_LOCAL + 2) #define QEMU_CFG_E820_TABLE (QEMU_CFG_ARCH_LOCAL + 3) +#define QEMU_CFG_SYSTEM_STATES (QEMU_CFG_ARCH_LOCAL + 5) extern int qemu_cfg_present; @@ -109,4 +110,5 @@ u64 romfile_loadint(const char *name, u64 defval); u32 qemu_cfg_e820_entries(void); void* qemu_cfg_e820_load_next(void *addr); +int qemu_cfg_system_states(char *states); #endif