Pull bugzilla-8630 into release branch
This commit is contained in:
commit
de9bde9adb
|
@ -51,6 +51,65 @@ ACPI_MODULE_NAME("tbutils")
|
|||
static acpi_physical_address
|
||||
acpi_tb_get_root_table_entry(u8 * table_entry,
|
||||
acpi_native_uint table_entry_size);
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_tb_check_xsdt
|
||||
*
|
||||
* PARAMETERS: address - Pointer to the XSDT
|
||||
*
|
||||
* RETURN: status
|
||||
* AE_OK - XSDT is okay
|
||||
* AE_NO_MEMORY - can't map XSDT
|
||||
* AE_INVALID_TABLE_LENGTH - invalid table length
|
||||
* AE_NULL_ENTRY - XSDT has NULL entry
|
||||
*
|
||||
* DESCRIPTION: validate XSDT
|
||||
******************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_tb_check_xsdt(acpi_physical_address address)
|
||||
{
|
||||
struct acpi_table_header *table;
|
||||
u32 length;
|
||||
u64 xsdt_entry_address;
|
||||
u8 *table_entry;
|
||||
u32 table_count;
|
||||
int i;
|
||||
|
||||
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
|
||||
if (!table)
|
||||
return AE_NO_MEMORY;
|
||||
|
||||
length = table->length;
|
||||
acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
|
||||
if (length < sizeof(struct acpi_table_header))
|
||||
return AE_INVALID_TABLE_LENGTH;
|
||||
|
||||
table = acpi_os_map_memory(address, length);
|
||||
if (!table)
|
||||
return AE_NO_MEMORY;
|
||||
|
||||
/* Calculate the number of tables described in XSDT */
|
||||
table_count =
|
||||
(u32) ((table->length -
|
||||
sizeof(struct acpi_table_header)) / sizeof(u64));
|
||||
table_entry =
|
||||
ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
|
||||
for (i = 0; i < table_count; i++) {
|
||||
ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry);
|
||||
if (!xsdt_entry_address) {
|
||||
/* XSDT has NULL entry */
|
||||
break;
|
||||
}
|
||||
table_entry += sizeof(u64);
|
||||
}
|
||||
acpi_os_unmap_memory(table, length);
|
||||
|
||||
if (i < table_count)
|
||||
return AE_NULL_ENTRY;
|
||||
else
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
|
@ -341,6 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
|
|||
u32 table_count;
|
||||
struct acpi_table_header *table;
|
||||
acpi_physical_address address;
|
||||
acpi_physical_address rsdt_address;
|
||||
u32 length;
|
||||
u8 *table_entry;
|
||||
acpi_status status;
|
||||
|
@ -369,6 +429,8 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
|
|||
*/
|
||||
address = (acpi_physical_address) rsdp->xsdt_physical_address;
|
||||
table_entry_size = sizeof(u64);
|
||||
rsdt_address = (acpi_physical_address)
|
||||
rsdp->rsdt_physical_address;
|
||||
} else {
|
||||
/* Root table is an RSDT (32-bit physical addresses) */
|
||||
|
||||
|
@ -382,6 +444,15 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
|
|||
*/
|
||||
acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
|
||||
|
||||
if (table_entry_size == sizeof(u64)) {
|
||||
if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) {
|
||||
/* XSDT has NULL entry, RSDT is used */
|
||||
address = rsdt_address;
|
||||
table_entry_size = sizeof(u32);
|
||||
ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry,"
|
||||
"using RSDT"));
|
||||
}
|
||||
}
|
||||
/* Map the RSDT/XSDT table header to get the full table length */
|
||||
|
||||
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
|
||||
|
|
Loading…
Reference in a new issue