From 65082bfcb486ef06f93b7603a9045cdf0c0022e8 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 3 Aug 2017 14:26:50 +0800 Subject: ACPICA: CLib: Add short multiply/shift support ACPICA commit 01b8f5a2350b9cc329cd8402ac8faec36fc501f5 In order to build ACPICA EFI tools with EDK-II on Windows, 64-bit multiply/shift supports are also required to be implemented. Otherwise, MSVC complains: acpidump.lib(utstrtoul64.obj) : error LNK2001: unresolved external symbol __allmul acpidump.lib(uthex.obj) : error LNK2001: unresolved external symbol __aullshr Note: 1. This patch also splits _EDK2_EFI from _GNU_EFI as they might have different math64 supports. 2. Support of gcc math64 is not included in this patch. 3. Support of EDK2 arch independent math64 is done via linking to base_lib. This patch fixes this issue. Reported by Shao Ming, fixed by Lv Zheng. For Linux kernel, this patch is a functional no-op. Link: https://github.com/acpica/acpica/commit/01b8f5a2 Tested-by: "Shao, Ming" Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- tools/power/acpi/tools/acpidump/apfiles.c | 2 +- tools/power/acpi/tools/acpidump/apmain.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c index 31b5a7f74015..d686e11936c4 100644 --- a/tools/power/acpi/tools/acpidump/apfiles.c +++ b/tools/power/acpi/tools/acpidump/apfiles.c @@ -61,7 +61,7 @@ static int ap_is_existing_file(char *pathname); static int ap_is_existing_file(char *pathname) { -#ifndef _GNU_EFI +#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) struct stat stat_info; if (!stat(pathname, &stat_info)) { diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index dd82afa897bd..943b6b614683 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c @@ -300,7 +300,7 @@ static int ap_do_options(int argc, char **argv) * ******************************************************************************/ -#ifndef _GNU_EFI +#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) #else int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[]) -- cgit v1.2.3 From 03c5b6b0da3f8ce8a4ba463daeb26b151d36f10e Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Thu, 3 Aug 2017 14:26:56 +0800 Subject: ACPICA: acpidump: Add DSDT/FACS instance support for Linux and EFI ACPICA commit 343fc31840d40c06001f3b170ee5bcdfd3c7f3e0 ACPI spec allows to configure different 32-bit/64-bit table addresses for DSDT and FACS. And for FACS, it's meaningful to dump both of them as they are used to support different suspend protocols. While: 1. on Linux, only 1 instance is supported for DSDT/FACS; and 2. on EFI, the code in osl_get_table() is buggy with special table instances, causing endless file dump for such tables (reported by Shao Ming in link #2). This patch adds DSDT/FACS instance support for Linux/EFI acpidump. Fixed by Lv Zheng. Link: https://github.com/acpica/acpica/commit/343fc318 Link: https://bugs.acpica.org/show_bug.cgi?id=1407 [#1] Link: https://github.com/acpica/acpica/issues/285 [#2] Reported-by: Shao Ming Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- .../acpi/os_specific/service_layers/oslinuxtbl.c | 105 ++++++++++++++------- 1 file changed, 73 insertions(+), 32 deletions(-) (limited to 'tools') diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c index 82a2ff896a95..52a39ecf5ca1 100644 --- a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c +++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c @@ -759,7 +759,7 @@ static acpi_status osl_list_bios_tables(void) /* Skip NULL entries in RSDT/XSDT */ - if (!table_address) { + if (table_address == 0) { continue; } @@ -808,7 +808,8 @@ osl_get_bios_table(char *signature, u8 number_of_tables; u8 item_size; u32 current_instance = 0; - acpi_physical_address table_address = 0; + acpi_physical_address table_address; + acpi_physical_address first_table_address = 0; u32 table_length = 0; acpi_status status = AE_OK; u32 i; @@ -820,9 +821,10 @@ osl_get_bios_table(char *signature, ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT) || ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT) || ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) { - if (instance > 0) { - return (AE_LIMIT); - } + +find_next_instance: + + table_address = 0; /* * Get the appropriate address, either 32-bit or 64-bit. Be very @@ -830,41 +832,66 @@ osl_get_bios_table(char *signature, * Note: The 64-bit addresses have priority. */ if (ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT)) { - if ((gbl_fadt->header.length >= MIN_FADT_FOR_XDSDT) && - gbl_fadt->Xdsdt) { - table_address = - (acpi_physical_address)gbl_fadt->Xdsdt; - } else - if ((gbl_fadt->header.length >= MIN_FADT_FOR_DSDT) - && gbl_fadt->dsdt) { - table_address = - (acpi_physical_address)gbl_fadt->dsdt; + if (current_instance < 2) { + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_XDSDT) && gbl_fadt->Xdsdt + && current_instance == 0) { + table_address = + (acpi_physical_address)gbl_fadt-> + Xdsdt; + } else + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_DSDT) + && gbl_fadt->dsdt != + first_table_address) { + table_address = + (acpi_physical_address)gbl_fadt-> + dsdt; + } } } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) { - if ((gbl_fadt->header.length >= MIN_FADT_FOR_XFACS) && - gbl_fadt->Xfacs) { - table_address = - (acpi_physical_address)gbl_fadt->Xfacs; - } else - if ((gbl_fadt->header.length >= MIN_FADT_FOR_FACS) - && gbl_fadt->facs) { - table_address = - (acpi_physical_address)gbl_fadt->facs; + if (current_instance < 2) { + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_XFACS) && gbl_fadt->Xfacs + && current_instance == 0) { + table_address = + (acpi_physical_address)gbl_fadt-> + Xfacs; + } else + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_FACS) + && gbl_fadt->facs != + first_table_address) { + table_address = + (acpi_physical_address)gbl_fadt-> + facs; + } } } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT)) { if (!gbl_revision) { return (AE_BAD_SIGNATURE); } - table_address = - (acpi_physical_address)gbl_rsdp. - xsdt_physical_address; + if (current_instance == 0) { + table_address = + (acpi_physical_address)gbl_rsdp. + xsdt_physical_address; + } } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT)) { - table_address = - (acpi_physical_address)gbl_rsdp. - rsdt_physical_address; + if (current_instance == 0) { + table_address = + (acpi_physical_address)gbl_rsdp. + rsdt_physical_address; + } } else { - table_address = (acpi_physical_address)gbl_rsdp_address; - signature = ACPI_SIG_RSDP; + if (current_instance == 0) { + table_address = + (acpi_physical_address)gbl_rsdp_address; + signature = ACPI_SIG_RSDP; + } + } + + if (table_address == 0) { + goto exit_find_table; } /* Now we can get the requested special table */ @@ -875,6 +902,18 @@ osl_get_bios_table(char *signature, } table_length = ap_get_table_length(mapped_table); + if (first_table_address == 0) { + first_table_address = table_address; + } + + /* Match table instance */ + + if (current_instance != instance) { + osl_unmap_table(mapped_table); + mapped_table = NULL; + current_instance++; + goto find_next_instance; + } } else { /* Case for a normal ACPI table */ if (osl_can_use_xsdt()) { @@ -913,7 +952,7 @@ osl_get_bios_table(char *signature, /* Skip NULL entries in RSDT/XSDT */ - if (!table_address) { + if (table_address == 0) { continue; } @@ -946,6 +985,8 @@ osl_get_bios_table(char *signature, } } +exit_find_table: + if (!mapped_table) { return (AE_LIMIT); } -- cgit v1.2.3