Pull bugzilla-8630 into release branch
This commit is contained in:
@@ -51,6 +51,65 @@ ACPI_MODULE_NAME("tbutils")
|
|||||||
static acpi_physical_address
|
static acpi_physical_address
|
||||||
acpi_tb_get_root_table_entry(u8 * table_entry,
|
acpi_tb_get_root_table_entry(u8 * table_entry,
|
||||||
acpi_native_uint table_entry_size);
|
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;
|
u32 table_count;
|
||||||
struct acpi_table_header *table;
|
struct acpi_table_header *table;
|
||||||
acpi_physical_address address;
|
acpi_physical_address address;
|
||||||
|
acpi_physical_address rsdt_address;
|
||||||
u32 length;
|
u32 length;
|
||||||
u8 *table_entry;
|
u8 *table_entry;
|
||||||
acpi_status status;
|
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;
|
address = (acpi_physical_address) rsdp->xsdt_physical_address;
|
||||||
table_entry_size = sizeof(u64);
|
table_entry_size = sizeof(u64);
|
||||||
|
rsdt_address = (acpi_physical_address)
|
||||||
|
rsdp->rsdt_physical_address;
|
||||||
} else {
|
} else {
|
||||||
/* Root table is an RSDT (32-bit physical addresses) */
|
/* 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));
|
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 */
|
/* Map the RSDT/XSDT table header to get the full table length */
|
||||||
|
|
||||||
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
|
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
|
||||||
|
Reference in New Issue
Block a user