ACPICA: Clear reserved fields for incoming ACPI 1.0 FADTs

Fixed a problem with the internal FADT conversion where ACPI 1.0
FADTs that contained invalid non-zero values in reserved fields
could cause later failures because these fields have meaning in
later revisions of the FADT. For incoming ACPI 1.0 FADTs, these
fields are now always zeroed. (Preferred_PM_Profile, PSTATE_CNT,
CST_CNT, IAPC_BOOT_FLAGS.)

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Bob Moore 2007-05-02 15:51:37 -04:00 committed by Len Brown
parent e0b91050f2
commit 55f8f3cc4f

View File

@ -211,14 +211,17 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags)
* DESCRIPTION: Get a local copy of the FADT and convert it to a common format. * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
* Performs validation on some important FADT fields. * Performs validation on some important FADT fields.
* *
* NOTE: We create a local copy of the FADT regardless of the version.
*
******************************************************************************/ ******************************************************************************/
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
{ {
/* /*
* Check if the FADT is larger than what we know about (ACPI 2.0 version). * Check if the FADT is larger than the largest table that we expect
* Truncate the table, but make some noise. * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue
* a warning.
*/ */
if (length > sizeof(struct acpi_table_fadt)) { if (length > sizeof(struct acpi_table_fadt)) {
ACPI_WARNING((AE_INFO, ACPI_WARNING((AE_INFO,
@ -227,10 +230,12 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
sizeof(struct acpi_table_fadt))); sizeof(struct acpi_table_fadt)));
} }
/* Copy the entire FADT locally. Zero first for tb_convert_fadt */ /* Clear the entire local FADT */
ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt));
/* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */
ACPI_MEMCPY(&acpi_gbl_FADT, table, ACPI_MEMCPY(&acpi_gbl_FADT, table,
ACPI_MIN(length, sizeof(struct acpi_table_fadt))); ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
@ -251,7 +256,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
* RETURN: None * RETURN: None
* *
* DESCRIPTION: Converts all versions of the FADT to a common internal format. * DESCRIPTION: Converts all versions of the FADT to a common internal format.
* -> Expand all 32-bit addresses to 64-bit. * Expand all 32-bit addresses to 64-bit.
* *
* NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt),
* and must contain a copy of the actual FADT. * and must contain a copy of the actual FADT.
@ -292,8 +297,23 @@ static void acpi_tb_convert_fadt(void)
} }
/* /*
* Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
* structures as necessary. * should be zero are indeed zero. This will workaround BIOSs that
* inadvertently place values in these fields.
*
* The ACPI 1.0 reserved fields that will be zeroed are the bytes located at
* offset 45, 55, 95, and the word located at offset 109, 110.
*/
if (acpi_gbl_FADT.header.revision < 3) {
acpi_gbl_FADT.preferred_profile = 0;
acpi_gbl_FADT.pstate_control = 0;
acpi_gbl_FADT.cst_control = 0;
acpi_gbl_FADT.boot_flags = 0;
}
/*
* Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X"
* generic address structures as necessary.
*/ */
for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
target = target =
@ -349,18 +369,6 @@ static void acpi_tb_convert_fadt(void)
acpi_gbl_FADT.xpm1a_event_block.space_id; acpi_gbl_FADT.xpm1a_event_block.space_id;
} }
/*
* For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero)
* are indeed zero. This will workaround BIOSs that inadvertently placed
* values in these fields.
*/
if (acpi_gbl_FADT.header.revision < 3) {
acpi_gbl_FADT.preferred_profile = 0;
acpi_gbl_FADT.pstate_control = 0;
acpi_gbl_FADT.cst_control = 0;
acpi_gbl_FADT.boot_flags = 0;
}
} }
/****************************************************************************** /******************************************************************************