Loading drivers/acpi/tables/tbutils.c +71 −0 Original line number Diff line number Diff line Loading @@ -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; } /******************************************************************************* * Loading Loading @@ -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; Loading Loading @@ -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) */ Loading @@ -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 Loading
drivers/acpi/tables/tbutils.c +71 −0 Original line number Diff line number Diff line Loading @@ -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; } /******************************************************************************* * Loading Loading @@ -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; Loading Loading @@ -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) */ Loading @@ -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