From patchwork Fri Apr 7 14:41:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 9669647 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0598A602A0 for ; Fri, 7 Apr 2017 14:48:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EBCAF2621D for ; Fri, 7 Apr 2017 14:48:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E055528616; Fri, 7 Apr 2017 14:48:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 288082621D for ; Fri, 7 Apr 2017 14:48:24 +0000 (UTC) Received: from localhost ([::1]:51287 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwVBW-00029W-N4 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 07 Apr 2017 10:48:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36053) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwV5F-0005iI-SO for qemu-devel@nongnu.org; Fri, 07 Apr 2017 10:41:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cwV5B-0007CA-Op for qemu-devel@nongnu.org; Fri, 07 Apr 2017 10:41:53 -0400 Received: from mail-wm0-x22c.google.com ([2a00:1450:400c:c09::22c]:35405) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cwV5B-0007Bx-Eb for qemu-devel@nongnu.org; Fri, 07 Apr 2017 10:41:49 -0400 Received: by mail-wm0-x22c.google.com with SMTP id w64so365373wma.0 for ; Fri, 07 Apr 2017 07:41:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=coYNLmUrUAqgKUVDK2Zi5PeFbmzx3Hj2g440VsVoAIE=; b=IOugTb1AXKf5xB9Ph8FuX2oeztQ3ByAJWs6IFZvCNBgPj57APHY7tI2AE3pztM5Mnt 35tvQRgBmdXnHZXaxMOrA8BimpxPlUzRvULKxvDD8Ey1zNCXyhWfy31HJiBDBTNsdJES KHuRFSsElOq+xu0AYvqasNDNUL31mOlfZj/xs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=coYNLmUrUAqgKUVDK2Zi5PeFbmzx3Hj2g440VsVoAIE=; b=rWXPTF9URFube65+3nTmEBA9gXJfeW99cnyuaGD02TsU//e6w4esQfbaLyIqan+6Bm BopjeZPe/zsMFoJNqI/RqZaZrID48GXOKuv6N5c7PtRNk04gywFXyW4xwxerWIaXeiQI VUXwb7Uh3n7dPUzz2ASIj3FPgSgjnMo0ijCKnD1Jo3fpgIZ1GyXdw358oY+vgMCVvQfo 3vpvsQR96NNgRXf54AOs7R2khWcVCgrrZX5009G5pNCorBD5kxPY750e/V2NQDvLizp+ 4M+pXoklpXyAxS9d8jFSv8E4OSxlDWatwDJEXUndJa/LhHvRpBGP0G9lwp898oyi/7F1 t3yg== X-Gm-Message-State: AFeK/H3wJ2aJVFc0bCTW/H8+hX+9vtypRyrgLoDz1eHwLbYh0ynthuJF UcU+Pn2LSvZUdlnh X-Received: by 10.28.74.147 with SMTP id n19mr24924097wmi.86.1491576108203; Fri, 07 Apr 2017 07:41:48 -0700 (PDT) Received: from localhost.localdomain ([196.81.139.226]) by smtp.gmail.com with ESMTPSA id n6sm6256331wrb.62.2017.04.07.07.41.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Apr 2017 07:41:47 -0700 (PDT) From: Ard Biesheuvel To: qemu-devel@nongnu.org, peter.maydell@linaro.org, lersek@redhat.com Date: Fri, 7 Apr 2017 15:41:38 +0100 Message-Id: <20170407144138.12871-1-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.9.3 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::22c Subject: [Qemu-devel] [PATCH v2] hw/arm/virt: generate 64-bit addressable ACPI objects X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: phil@philjordan.eu, Ard Biesheuvel , mst@redhat.com, drjones@redhat.com, zhaoshenglong@huawei.com, imammedo@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Our current ACPI table generation code limits the placement of ACPI tables to 32-bit addressable memory, in order to be able to emit the root pointer (RSDP) and root table (RSDT) using table types from the ACPI 1.0 days. Since ARM was not supported by ACPI before version 5.0, it makes sense to lift this restriction. This is not crucial for mach-virt, which is guaranteed to have some memory available below the 4 GB mark, but it is a nice to have for QEMU machines that do not have any 32-bit addressable memory, which is not uncommon for real world 64-bit ARM systems. Since we already emit a version of the RSDP root pointer that has a secondary 64-bit wide address field for the 64-bit root table (XSDT), all we need to do is replace the RSDT generation with the generation of an XSDT table, and use a different slot in the FADT table to refer to the DSDT. Signed-off-by: Ard Biesheuvel Reviewed-by: Andrew Jones Acked-by: Laszlo Ersek Reviewed-by: Igor Mammedov --- v2: - move new build_xsdt() function to hw/acpi/aml-build.c - tweak commit log text - add Drew's and Laszlo's acks hw/acpi/aml-build.c | 27 ++++++++++++++++++++ hw/arm/virt-acpi-build.c | 26 +++++++++---------- include/hw/acpi/acpi-defs.h | 11 ++++++++ include/hw/acpi/aml-build.h | 3 +++ 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index c6f2032decb1..4ddfb68b247f 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -1599,6 +1599,33 @@ build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets, (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id); } +/* Build xsdt table */ +void +build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets, + const char *oem_id, const char *oem_table_id) +{ + int i; + unsigned xsdt_entries_offset; + AcpiXsdtDescriptorRev2 *xsdt; + const unsigned table_data_len = (sizeof(uint64_t) * table_offsets->len); + const unsigned xsdt_entry_size = sizeof(xsdt->table_offset_entry[0]); + const size_t xsdt_len = sizeof(*xsdt) + table_data_len; + + xsdt = acpi_data_push(table_data, xsdt_len); + xsdt_entries_offset = (char *)xsdt->table_offset_entry - table_data->data; + for (i = 0; i < table_offsets->len; ++i) { + uint64_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i); + uint64_t xsdt_entry_offset = xsdt_entries_offset + xsdt_entry_size * i; + + /* xsdt->table_offset_entry to be filled by Guest linker */ + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, xsdt_entry_offset, xsdt_entry_size, + ACPI_BUILD_TABLE_FILE, ref_tbl_offset); + } + build_header(linker, table_data, + (void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id); +} + void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base, uint64_t len, int node, MemoryAffinityFlags flags) { diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index b173bd109b91..2177f60544ce 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -391,12 +391,12 @@ static void acpi_dsdt_add_power_button(Aml *scope) /* RSDP */ static GArray * -build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) +build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset) { AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); - unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address); - unsigned rsdt_pa_offset = - (char *)&rsdp->rsdt_physical_address - rsdp_table->data; + unsigned xsdt_pa_size = sizeof(rsdp->xsdt_physical_address); + unsigned xsdt_pa_offset = + (char *)&rsdp->xsdt_physical_address - rsdp_table->data; bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16, true /* fseg memory */); @@ -408,8 +408,8 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) /* Address to be filled by Guest linker */ bios_linker_loader_add_pointer(linker, - ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size, - ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset); + ACPI_BUILD_RSDP_FILE, xsdt_pa_offset, xsdt_pa_size, + ACPI_BUILD_TABLE_FILE, xsdt_tbl_offset); /* Checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, @@ -686,7 +686,7 @@ static void build_fadt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms, unsigned dsdt_tbl_offset) { AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt)); - unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data; + unsigned xdsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data; uint16_t bootflags; switch (vms->psci_conduit) { @@ -712,7 +712,7 @@ static void build_fadt(GArray *table_data, BIOSLinker *linker, /* DSDT address to be filled by Guest linker */ bios_linker_loader_add_pointer(linker, - ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt), + ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->Xdsdt), ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset); build_header(linker, table_data, @@ -777,7 +777,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) { VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); GArray *table_offsets; - unsigned dsdt, rsdt; + unsigned dsdt, xsdt; GArray *tables_blob = tables->table_data; table_offsets = g_array_new(false, true /* clear */, @@ -817,12 +817,12 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) build_iort(tables_blob, tables->linker); } - /* RSDT is pointed to by RSDP */ - rsdt = tables_blob->len; - build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL); + /* XSDT is pointed to by RSDP */ + xsdt = tables_blob->len; + build_xsdt(tables_blob, tables->linker, table_offsets, NULL, NULL); /* RSDP is in FSEG memory, so allocate it separately */ - build_rsdp(tables->rsdp, tables->linker, rsdt); + build_rsdp(tables->rsdp, tables->linker, xsdt); /* Cleanup memory that's no longer used. */ g_array_free(table_offsets, true); diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index 4cc3630e613e..bf37acf4c4c6 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -238,6 +238,17 @@ struct AcpiRsdtDescriptorRev1 typedef struct AcpiRsdtDescriptorRev1 AcpiRsdtDescriptorRev1; /* + * ACPI 2.0 eXtended System Description Table (XSDT) + */ +struct AcpiXsdtDescriptorRev2 +{ + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ + uint64_t table_offset_entry[0]; /* Array of pointers to other */ + /* ACPI tables */ +} QEMU_PACKED; +typedef struct AcpiXsdtDescriptorRev2 AcpiXsdtDescriptorRev2; + +/* * ACPI 1.0 Firmware ACPI Control Structure (FACS) */ struct AcpiFacsDescriptorRev1 diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 00c21f160c19..eb07c2d43c99 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -381,6 +381,9 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre); void build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets, const char *oem_id, const char *oem_table_id); +void +build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets, + const char *oem_id, const char *oem_table_id); int build_append_named_dword(GArray *array, const char *name_format, ...)