From 97cbb7d196845ec9a6c0e3cc33ec20503f8c4e73 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 3 Feb 2009 14:41:03 +0800 Subject: ACPICA: Remove extraneous parameter in table manager Removed the Flags parameter from several internal functions since it was not being used. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/tbfadt.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/acpi/acpica/tbfadt.c') diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 3636e4f8fb7..4b683ccd4a9 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -172,7 +172,6 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, * FUNCTION: acpi_tb_parse_fadt * * PARAMETERS: table_index - Index for the FADT - * Flags - Flags * * RETURN: None * @@ -181,7 +180,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, * ******************************************************************************/ -void acpi_tb_parse_fadt(u32 table_index, u8 flags) +void acpi_tb_parse_fadt(u32 table_index) { u32 length; struct acpi_table_header *table; @@ -219,10 +218,10 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags) /* Obtain the DSDT and FACS tables via their addresses within the FADT */ acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, - flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); + ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, - flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); + ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); } /******************************************************************************* -- cgit v1.2.3 From 531c633d2be8e79087335a46d3c017ca5837e588 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 18 Feb 2009 14:06:12 +0800 Subject: ACPICA: Split out PM1 status registers from the FADT Add new globals for the PM1 status registers (A/B), similar to the way the PM1 enable registers are handled. Instead of overloading the FADT Event Register blocks. This makes the code clearer and less prone to error. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/tbfadt.c | 246 +++++++++++++++++++++++-------------------- 1 file changed, 133 insertions(+), 113 deletions(-) (limited to 'drivers/acpi/acpica/tbfadt.c') diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 4b683ccd4a9..a8191efd9aa 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -57,6 +57,8 @@ static void acpi_tb_convert_fadt(void); static void acpi_tb_validate_fadt(void); +static void acpi_tb_setup_fadt_registers(void); + /* Table for conversion of FADT to common internal format and FADT validation */ typedef struct acpi_fadt_info { @@ -132,6 +134,35 @@ static struct acpi_fadt_info fadt_info_table[] = { #define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) +/* Table used to split Event Blocks into separate status/enable registers */ + +typedef struct acpi_fadt_pm_info { + struct acpi_generic_address *target; + u8 source; + u8 register_num; + +} acpi_fadt_pm_info; + +static struct acpi_fadt_pm_info fadt_pm_info_table[] = { + {&acpi_gbl_xpm1a_status, + ACPI_FADT_OFFSET(xpm1a_event_block), + 0}, + + {&acpi_gbl_xpm1a_enable, + ACPI_FADT_OFFSET(xpm1a_event_block), + 1}, + + {&acpi_gbl_xpm1b_status, + ACPI_FADT_OFFSET(xpm1b_event_block), + 0}, + + {&acpi_gbl_xpm1b_enable, + ACPI_FADT_OFFSET(xpm1b_event_block), + 1} +}; + +#define ACPI_FADT_PM_INFO_ENTRIES (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info)) + /******************************************************************************* * * FUNCTION: acpi_tb_init_generic_address @@ -207,7 +238,7 @@ void acpi_tb_parse_fadt(u32 table_index) */ (void)acpi_tb_verify_checksum(table, length); - /* Obtain a local copy of the FADT in common ACPI 2.0+ format */ + /* Create a local copy of the FADT in common ACPI 2.0+ format */ acpi_tb_create_local_fadt(table, length); @@ -265,11 +296,17 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) ACPI_MEMCPY(&acpi_gbl_FADT, table, ACPI_MIN(length, sizeof(struct acpi_table_fadt))); - /* - * 1) Convert the local copy of the FADT to the common internal format - * 2) Validate some of the important values within the FADT - */ + /* Convert the local copy of the FADT to the common internal format */ + acpi_tb_convert_fadt(); + + /* Validate FADT values now, before we make any changes */ + + acpi_tb_validate_fadt(); + + /* Initialize the global ACPI register structures */ + + acpi_tb_setup_fadt_registers(); } /******************************************************************************* @@ -303,8 +340,6 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) static void acpi_tb_convert_fadt(void) { - u8 pm1_register_bit_width; - u8 pm1_register_byte_width; struct acpi_generic_address *target64; u32 i; @@ -379,112 +414,6 @@ static void acpi_tb_convert_fadt(void) address32)); } } - - /* Validate FADT values now, before we make any changes */ - - acpi_tb_validate_fadt(); - - /* - * Optionally check all register lengths against the default values and - * update them if they are incorrect. - */ - if (acpi_gbl_use_default_register_widths) { - for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { - target64 = - ACPI_ADD_PTR(struct acpi_generic_address, - &acpi_gbl_FADT, - fadt_info_table[i].address64); - - /* - * If a valid register (Address != 0) and the (default_length > 0) - * (Not a GPE register), then check the width against the default. - */ - if ((target64->address) && - (fadt_info_table[i].default_length > 0) && - (fadt_info_table[i].default_length != - target64->bit_width)) { - ACPI_WARNING((AE_INFO, - "Invalid length for %s: %d, using default %d", - fadt_info_table[i].name, - target64->bit_width, - fadt_info_table[i]. - default_length)); - - /* Incorrect size, set width to the default */ - - target64->bit_width = - fadt_info_table[i].default_length; - } - } - } - - /* - * Get the length of the individual PM1 registers (enable and status). - * Each register is defined to be (event block length / 2). - */ - pm1_register_bit_width = - (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width); - pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width); - - /* - * Adjust the lengths of the PM1 Event Blocks so that they can be used to - * access the PM1 status register(s). Use (width / 2) - */ - acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width; - acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width; - - /* - * Calculate separate GAS structs for the PM1 Enable registers. - * These addresses do not appear (directly) in the FADT, so it is - * useful to calculate them once, here. - * - * The PM event blocks are split into two register blocks, first is the - * PM Status Register block, followed immediately by the PM Enable - * Register block. Each is of length (xpm1x_event_block.bit_width/2). - * - * On various systems the v2 fields (and particularly the bit widths) - * cannot be relied upon, though. Hence resort to using the v1 length - * here (and warn about the inconsistency). - */ - if (acpi_gbl_FADT.xpm1a_event_block.bit_width - != acpi_gbl_FADT.pm1_event_length * 8) - printk(KERN_WARNING "FADT: " - "X_PM1a_EVT_BLK.bit_width (%u) does not match" - " PM1_EVT_LEN (%u)\n", - acpi_gbl_FADT.xpm1a_event_block.bit_width, - acpi_gbl_FADT.pm1_event_length); - - /* The PM1A register block is required */ - - acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, - acpi_gbl_FADT.xpm1a_event_block.space_id, - pm1_register_byte_width, - (acpi_gbl_FADT.xpm1a_event_block.address + - pm1_register_byte_width)); - /* Don't forget to copy space_id of the GAS */ - acpi_gbl_xpm1a_enable.space_id = - acpi_gbl_FADT.xpm1a_event_block.space_id; - - /* The PM1B register block is optional, ignore if not present */ - - if (acpi_gbl_FADT.xpm1b_event_block.address) { - if (acpi_gbl_FADT.xpm1b_event_block.bit_width - != acpi_gbl_FADT.pm1_event_length * 8) - printk(KERN_WARNING "FADT: " - "X_PM1b_EVT_BLK.bit_width (%u) does not match" - " PM1_EVT_LEN (%u)\n", - acpi_gbl_FADT.xpm1b_event_block.bit_width, - acpi_gbl_FADT.pm1_event_length); - acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, - acpi_gbl_FADT.xpm1b_event_block.space_id, - pm1_register_byte_width, - (acpi_gbl_FADT.xpm1b_event_block. - address + pm1_register_byte_width)); - /* Don't forget to copy space_id of the GAS */ - acpi_gbl_xpm1b_enable.space_id = - acpi_gbl_FADT.xpm1b_event_block.space_id; - - } } /****************************************************************************** @@ -607,3 +536,94 @@ static void acpi_tb_validate_fadt(void) } } } + +/****************************************************************************** + * + * FUNCTION: acpi_tb_setup_fadt_registers + * + * PARAMETERS: None, uses acpi_gbl_FADT. + * + * RETURN: None + * + * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally, + * force FADT register definitions to their default lengths. + * + ******************************************************************************/ + +static void acpi_tb_setup_fadt_registers(void) +{ + struct acpi_generic_address *target64; + struct acpi_generic_address *source64; + u8 pm1_register_byte_width; + u32 i; + + /* + * Optionally check all register lengths against the default values and + * update them if they are incorrect. + */ + if (acpi_gbl_use_default_register_widths) { + for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { + target64 = + ACPI_ADD_PTR(struct acpi_generic_address, + &acpi_gbl_FADT, + fadt_info_table[i].address64); + + /* + * If a valid register (Address != 0) and the (default_length > 0) + * (Not a GPE register), then check the width against the default. + */ + if ((target64->address) && + (fadt_info_table[i].default_length > 0) && + (fadt_info_table[i].default_length != + target64->bit_width)) { + ACPI_WARNING((AE_INFO, + "Invalid length for %s: %d, using default %d", + fadt_info_table[i].name, + target64->bit_width, + fadt_info_table[i]. + default_length)); + + /* Incorrect size, set width to the default */ + + target64->bit_width = + fadt_info_table[i].default_length; + } + } + } + + /* + * Get the length of the individual PM1 registers (enable and status). + * Each register is defined to be (event block length / 2). Extra divide + * by 8 converts bits to bytes. + */ + pm1_register_byte_width = + (u8)ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width); + + /* + * Calculate separate GAS structs for the PM1x (A/B) Status and Enable + * registers. These addresses do not appear (directly) in the FADT, so it + * is useful to pre-calculate them from the PM1 Event Block definitions. + * + * The PM event blocks are split into two register blocks, first is the + * PM Status Register block, followed immediately by the PM Enable + * Register block. Each is of length (pm1_event_length/2) + * + * Note: The PM1A event block is required by the ACPI specification. + * However, the PM1B event block is optional and is rarely, if ever, + * used. + */ + + for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) { + source64 = + ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, + fadt_pm_info_table[i].source); + + acpi_tb_init_generic_address(fadt_pm_info_table[i].target, + source64->space_id, + pm1_register_byte_width, + source64->address + + (fadt_pm_info_table[i]. + register_num * + pm1_register_byte_width)); + } +} -- cgit v1.2.3 From 5e053e77f233342b56fda419d347fd2c958b9849 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Wed, 4 Mar 2009 14:31:25 +0800 Subject: ACPICA: Check for non-zero address before being converted to GAS Reported-by: FreeBSD community Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/tbfadt.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/acpi/acpica/tbfadt.c') diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index a8191efd9aa..43fe886b41a 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -618,12 +618,14 @@ static void acpi_tb_setup_fadt_registers(void) ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, fadt_pm_info_table[i].source); - acpi_tb_init_generic_address(fadt_pm_info_table[i].target, - source64->space_id, - pm1_register_byte_width, - source64->address + - (fadt_pm_info_table[i]. - register_num * - pm1_register_byte_width)); + if (source64->address) { + acpi_tb_init_generic_address(fadt_pm_info_table[i]. + target, source64->space_id, + pm1_register_byte_width, + source64->address + + (fadt_pm_info_table[i]. + register_num * + pm1_register_byte_width)); + } } } -- cgit v1.2.3 From ec41f193eadb6301f3c052b5e0dbc0b5636982e8 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 18 Feb 2009 15:03:30 +0800 Subject: ACPICA: Formatting update - no functional changes Split some long lines. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/tbfadt.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'drivers/acpi/acpica/tbfadt.c') diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 43fe886b41a..af8fbe12d8b 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -132,7 +132,8 @@ static struct acpi_fadt_info fadt_info_table[] = { ACPI_FADT_SEPARATE_LENGTH} }; -#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) +#define ACPI_FADT_INFO_ENTRIES \ + (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) /* Table used to split Event Blocks into separate status/enable registers */ @@ -161,7 +162,8 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = { 1} }; -#define ACPI_FADT_PM_INFO_ENTRIES (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info)) +#define ACPI_FADT_PM_INFO_ENTRIES \ + (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info)) /******************************************************************************* * @@ -416,7 +418,7 @@ static void acpi_tb_convert_fadt(void) } } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: acpi_tb_validate_fadt * @@ -503,7 +505,8 @@ static void acpi_tb_validate_fadt(void) */ if (!address64->address || !length) { ACPI_ERROR((AE_INFO, - "Required field %s has zero address and/or length: %8.8X%8.8X/%X", + "Required field %s has zero address and/or length:" + " %8.8X%8.8X/%X", name, ACPI_FORMAT_UINT64(address64-> address), @@ -512,12 +515,14 @@ static void acpi_tb_validate_fadt(void) } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { /* * Field is optional (PM2Control, GPE0, GPE1) AND has its own - * length field. If present, both the address and length must be valid. + * length field. If present, both the address and length must + * be valid. */ - if ((address64->address && !length) - || (!address64->address && length)) { + if ((address64->address && !length) || + (!address64->address && length)) { ACPI_WARNING((AE_INFO, - "Optional field %s has zero address or length: %8.8X%8.8X/%X", + "Optional field %s has zero address or length: " + "%8.8X%8.8X/%X", name, ACPI_FORMAT_UINT64(address64-> address), @@ -525,8 +530,10 @@ static void acpi_tb_validate_fadt(void) } } - /* If both 32- and 64-bit addresses are valid (non-zero), they must match */ - + /* + * If both 32- and 64-bit addresses are valid (non-zero), + * they must match + */ if (address64->address && *address32 && (address64->address != (u64) * address32)) { ACPI_ERROR((AE_INFO, @@ -537,7 +544,7 @@ static void acpi_tb_validate_fadt(void) } } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: acpi_tb_setup_fadt_registers * @@ -596,8 +603,8 @@ static void acpi_tb_setup_fadt_registers(void) * Each register is defined to be (event block length / 2). Extra divide * by 8 converts bits to bytes. */ - pm1_register_byte_width = - (u8)ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width); + pm1_register_byte_width = (u8) + ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width); /* * Calculate separate GAS structs for the PM1x (A/B) Status and Enable -- cgit v1.2.3 From aab61b676a024d3527f6201e2b31285a96f7a1d2 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 6 Mar 2009 10:09:00 +0800 Subject: ACPICA: FADT: Fix extraneous length mismatch warning Incorrect register length mismatch between the 32 and 64 bit registers in some cases. Code was was checking the wrong pointer for non-zero, should be looking at the address within the GAS structure. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/tbfadt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/acpi/acpica/tbfadt.c') diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index af8fbe12d8b..ff89cfee0e7 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -491,7 +491,8 @@ static void acpi_tb_validate_fadt(void) * For each extended field, check for length mismatch between the * legacy length field and the corresponding 64-bit X length field. */ - if (address64 && (address64->bit_width != ACPI_MUL_8(length))) { + if (address64->address && + (address64->bit_width != ACPI_MUL_8(length))) { ACPI_WARNING((AE_INFO, "32/64X length mismatch in %s: %d/%d", name, ACPI_MUL_8(length), -- cgit v1.2.3 From 31fbc073a35a017e34840deb9e865a701e986002 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 19 Mar 2009 10:12:13 +0800 Subject: ACPICA: FADT: Favor 32-bit register addresses for compatibility Use the 32-bit register addresses whenever they are non-zero. This means that the 32-bit addresses are favored over the 64-bit (GAS) addresses. The 64-bit addresses are only used if the 32-bit addresses are zero. This change provides compatibility with all versions of Windows. The worst case that this solves is when both the 32-bit and 64-bit addresses are non-zero, but only the 32-bit addresses are actually valid. This appears to happen in some BIOSes because in this case, Windows uses the 32-bit addresses. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/tbfadt.c | 86 ++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 35 deletions(-) (limited to 'drivers/acpi/acpica/tbfadt.c') diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index ff89cfee0e7..f87bfb259ef 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -320,29 +320,35 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) * RETURN: None * * DESCRIPTION: Converts all versions of the FADT to a common internal format. - * Expand all 32-bit addresses to 64-bit. + * Expand 32-bit addresses to 64-bit as necessary. * * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), * and must contain a copy of the actual FADT. * - * ACPICA will use the "X" fields of the FADT for all addresses. + * Notes on 64-bit register addresses: * - * "X" fields are optional extensions to the original V1.0 fields. Even if - * they are present in the structure, they can be optionally not used by - * setting them to zero. Therefore, we must selectively expand V1.0 fields - * if the corresponding X field is zero. + * After this FADT conversion, later ACPICA code will only use the 64-bit "X" + * fields of the FADT for all ACPI register addresses. * - * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding - * "X" fields. + * The 64-bit "X" fields are optional extensions to the original 32-bit FADT + * V1.0 fields. Even if they are present in the FADT, they are optional and + * are unused if the BIOS sets them to zero. Therefore, we must copy/expand + * 32-bit V1.0 fields if the corresponding X field is zero. * - * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by - * expanding the corresponding ACPI 1.0 field. + * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the + * corresponding "X" fields in the internal FADT. + * + * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded + * to the corresponding 64-bit X fields. For compatibility with other ACPI + * implementations, we ignore the 64-bit field if the 32-bit field is valid, + * regardless of whether the host OS is 32-bit or 64-bit. * ******************************************************************************/ static void acpi_tb_convert_fadt(void) { - struct acpi_generic_address *target64; + struct acpi_generic_address *address64; + u32 address32; u32 i; /* Update the local FADT table header length */ @@ -391,29 +397,51 @@ static void acpi_tb_convert_fadt(void) * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" * generic address structures as necessary. Later code will always use * the 64-bit address structures. + * + * March 2009: + * We now always use the 32-bit address if it is valid (non-null). This + * is not in accordance with the ACPI specification which states that + * the 64-bit address supersedes the 32-bit version, but we do this for + * compatibility with other ACPI implementations. Most notably, in the + * case where both the 32 and 64 versions are non-null, we use the 32-bit + * version. This is the only address that is guaranteed to have been + * tested by the BIOS manufacturer. */ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { - target64 = - ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, - fadt_info_table[i].address64); + address32 = *ACPI_ADD_PTR(u32, + &acpi_gbl_FADT, + fadt_info_table[i].address32); - /* Expand only if the 64-bit X target is null */ + address64 = ACPI_ADD_PTR(struct acpi_generic_address, + &acpi_gbl_FADT, + fadt_info_table[i].address64); - if (!target64->address) { + /* + * If both 32- and 64-bit addresses are valid (non-zero), + * they must match. + */ + if (address64->address && address32 && + (address64->address != (u64) address32)) { + ACPI_ERROR((AE_INFO, + "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32", + fadt_info_table[i].name, address32, + ACPI_FORMAT_UINT64(address64->address))); + } - /* The space_id is always I/O for the 32-bit legacy address fields */ + /* Always use 32-bit address if it is valid (non-null) */ - acpi_tb_init_generic_address(target64, + if (address32) { + /* + * Copy the 32-bit address to the 64-bit GAS structure. The + * Space ID is always I/O for 32-bit legacy address fields + */ + acpi_tb_init_generic_address(address64, ACPI_ADR_SPACE_SYSTEM_IO, *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, fadt_info_table [i].length), - (u64) * ACPI_ADD_PTR(u32, - &acpi_gbl_FADT, - fadt_info_table - [i]. - address32)); + address32); } } } @@ -530,18 +558,6 @@ static void acpi_tb_validate_fadt(void) length)); } } - - /* - * If both 32- and 64-bit addresses are valid (non-zero), - * they must match - */ - if (address64->address && *address32 && - (address64->address != (u64) * address32)) { - ACPI_ERROR((AE_INFO, - "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X", - name, *address32, - ACPI_FORMAT_UINT64(address64->address))); - } } } -- cgit v1.2.3 From f65563063375b05898a94ab71b52612cbe3a789b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 19 Mar 2009 10:13:40 +0800 Subject: ACPICA: FADT: Favor 32-bit FACS and DSDT addresses If both the 32-bit and 64-bit addresses are non-null, use the 32-bit address. Provides Windows compatibility. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/tbfadt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/acpi/acpica/tbfadt.c') diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index f87bfb259ef..71e655d14cb 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -483,18 +483,22 @@ static void acpi_tb_validate_fadt(void) (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) { ACPI_WARNING((AE_INFO, "32/64X FACS address mismatch in FADT - " - "two FACS tables! %8.8X/%8.8X%8.8X", + "%8.8X/%8.8X%8.8X, using 32", acpi_gbl_FADT.facs, ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs))); + + acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; } if (acpi_gbl_FADT.dsdt && (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) { ACPI_WARNING((AE_INFO, "32/64X DSDT address mismatch in FADT - " - "two DSDT tables! %8.8X/%8.8X%8.8X", + "%8.8X/%8.8X%8.8X, using 32", acpi_gbl_FADT.dsdt, ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt))); + + acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; } /* Examine all of the 64-bit extended address fields (X fields) */ -- cgit v1.2.3