From patchwork Wed Oct 7 13:21:43 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gleb Natapov X-Patchwork-Id: 35290 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 22077B7B83 for ; Thu, 8 Oct 2009 01:05:46 +1100 (EST) Received: from localhost ([127.0.0.1]:45840 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MvX9D-0000i1-K2 for incoming@patchwork.ozlabs.org; Wed, 07 Oct 2009 10:05:43 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MvWSr-0003TM-CO for qemu-devel@nongnu.org; Wed, 07 Oct 2009 09:21:57 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MvWSk-0003QW-Hv for qemu-devel@nongnu.org; Wed, 07 Oct 2009 09:21:55 -0400 Received: from [199.232.76.173] (port=40293 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MvWSk-0003QG-2C for qemu-devel@nongnu.org; Wed, 07 Oct 2009 09:21:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:1025) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MvWSj-00034b-L6 for qemu-devel@nongnu.org; Wed, 07 Oct 2009 09:21:49 -0400 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n97DLl0q005682; Wed, 7 Oct 2009 09:21:47 -0400 Received: from dhcp-1-237.tlv.redhat.com (dhcp-1-237.tlv.redhat.com [10.35.1.237]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n97DLjrX021491; Wed, 7 Oct 2009 09:21:46 -0400 Received: by dhcp-1-237.tlv.redhat.com (Postfix, from userid 13519) id D1E261336CB; Wed, 7 Oct 2009 15:21:44 +0200 (IST) From: Gleb Natapov To: kevin@koconnor.net Date: Wed, 7 Oct 2009 15:21:43 +0200 Message-Id: <1254921704-18810-1-git-send-email-gleb@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 1/2] Cleanup acpi table creation. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Makes dynamic number of acpi table possible. Signed-off-by: Gleb Natapov --- src/acpi.c | 82 +++++++++++++++++++++++++++++++++-------------------------- 1 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index d0c9201..b9d449f 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -43,7 +43,7 @@ struct acpi_table_header /* ACPI common table header */ struct rsdt_descriptor_rev1 { ACPI_TABLE_HEADER_DEF /* ACPI common table header */ - u32 table_offset_entry[3]; /* Array of pointers to other */ + u32 table_offset_entry[0]; /* Array of pointers to other */ /* ACPI tables */ } PACKED; @@ -224,8 +224,7 @@ static inline u32 cpu_to_le32(u32 x) } static void -build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev - , struct rsdt_descriptor_rev1 *rsdt) +build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev) { h->signature = sig; h->length = cpu_to_le32(len); @@ -237,21 +236,10 @@ build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev h->oem_revision = cpu_to_le32(1); h->asl_compiler_revision = cpu_to_le32(1); h->checksum -= checksum(h, len); - - // Add to rsdt table - if (!rsdt) - return; - if (rsdt->length >= sizeof(*rsdt)) { - dprintf(1, "No more room for rsdt entry!\n"); - return; - } - u32 *p = (void*)rsdt + rsdt->length; - *p = (u32)h; - rsdt->length += sizeof(*p); } -static void -build_fadt(struct rsdt_descriptor_rev1 *rsdt, int bdf) +static void* +build_fadt(int bdf) { struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt)); struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs)); @@ -259,7 +247,7 @@ build_fadt(struct rsdt_descriptor_rev1 *rsdt, int bdf) if (!fadt || !facs || !dsdt) { dprintf(1, "Not enough memory for fadt!\n"); - return; + return NULL; } /* FACS */ @@ -292,11 +280,13 @@ build_fadt(struct rsdt_descriptor_rev1 *rsdt, int bdf) /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */ fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6)); - build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1, rsdt); + build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1); + + return fadt; } -static void -build_madt(struct rsdt_descriptor_rev1 *rsdt) +static void* +build_madt(void) { int smp_cpus = CountCPUs; int madt_size = (sizeof(struct multiple_apic_table) @@ -306,7 +296,7 @@ build_madt(struct rsdt_descriptor_rev1 *rsdt) struct multiple_apic_table *madt = malloc_high(madt_size); if (!madt) { dprintf(1, "Not enough memory for madt!\n"); - return; + return NULL; } memset(madt, 0, madt_size); madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR); @@ -351,13 +341,13 @@ build_madt(struct rsdt_descriptor_rev1 *rsdt) intsrcovr++; } - build_header((void*)madt, APIC_SIGNATURE, (void*)intsrcovr - (void*)madt - , 1, rsdt); + build_header((void*)madt, APIC_SIGNATURE, (void*)intsrcovr - (void*)madt, 1); + return madt; } #define SSDT_SIGNATURE 0x54445353 // SSDT -static void -build_ssdt(struct rsdt_descriptor_rev1 *rsdt) +static void* +build_ssdt(void) { int smp_cpus = CountCPUs; int acpi_cpus = smp_cpus > 0xff ? 0xff : smp_cpus; @@ -369,7 +359,7 @@ build_ssdt(struct rsdt_descriptor_rev1 *rsdt) u8 *ssdt = malloc_high(length); if (! ssdt) { dprintf(1, "No space for ssdt!\n"); - return; + return NULL; } u8 *ssdt_ptr = ssdt; @@ -410,11 +400,14 @@ build_ssdt(struct rsdt_descriptor_rev1 *rsdt) *(ssdt_ptr++) = 6; // Processor block length } - build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1, rsdt); + build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1); + + return ssdt; } struct rsdp_descriptor *RsdpAddr; +#define MAX_ACPI_TABLES 20 void acpi_bios_init(void) { @@ -432,20 +425,37 @@ acpi_bios_init(void) // Create initial rsdt table struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp)); - struct rsdt_descriptor_rev1 *rsdt = malloc_high(sizeof(*rsdt)); - if (!rsdp || !rsdt) { - dprintf(1, "Not enough memory for acpi rsdp/rsdt table!\n"); + if (!rsdp) { + dprintf(1, "Not enough memory for acpi rsdp table!\n"); return; } - memset(rsdt, 0, sizeof(*rsdt)); - rsdt->length = offsetof(struct rsdt_descriptor_rev1, table_offset_entry[0]); + + u32 tables[MAX_ACPI_TABLES], tbl_idx = 0; + +#define ACPI_INIT_TABLE(X) \ + do { \ + tables[tbl_idx] = (u32)(X); \ + if (tables[tbl_idx]) \ + tbl_idx++; \ + } while(0) // Add tables - build_fadt(rsdt, bdf); - build_ssdt(rsdt); - build_madt(rsdt); + ACPI_INIT_TABLE(build_fadt(bdf)); + ACPI_INIT_TABLE(build_ssdt()); + ACPI_INIT_TABLE(build_madt()); + + struct rsdt_descriptor_rev1 *rsdt; + size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx; + rsdt = malloc_high(rsdt_len); + + if (!rsdt) { + dprintf(1, "Not enough memory for acpi rsdt table!\n"); + return; + } + memset(rsdt, 0, rsdt_len); + memcpy(rsdt->table_offset_entry, tables, sizeof(u32) * tbl_idx); - build_header((void*)rsdt, RSDT_SIGNATURE, rsdt->length, 1, NULL); + build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1); // Build rsdp pointer table memset(rsdp, 0, sizeof(*rsdp));