*****************************************************************************/
/*
- * Copyright (C) 2000 - 2007, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/* Local prototypes */
static acpi_physical_address
-acpi_tb_get_root_table_entry(u8 * table_entry,
- acpi_native_uint table_entry_size);
+acpi_tb_get_root_table_entry(u8 *table_entry, u32 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;
+}
/*******************************************************************************
*
/* FACS only has signature and length fields of common table header */
- ACPI_INFO((AE_INFO, "%4.4s @ 0x%p/0x%04X",
- header->signature, ACPI_CAST_PTR(void, address),
+ ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X",
+ header->signature, (unsigned long)address,
header->length));
} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
/* RSDP has no common fields */
- ACPI_INFO((AE_INFO, "RSDP @ 0x%p/0x%04X (v%3.3d %6.6s)",
- ACPI_CAST_PTR(void, address),
+ ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)",
+ (unsigned long)address,
(ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
revision >
0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
/* Standard ACPI table with full common header */
ACPI_INFO((AE_INFO,
- "%4.4s @ 0x%p/0x%04X (v%3.3d %6.6s %8.8s 0x%08X %4.4s 0x%08X)",
- header->signature, ACPI_CAST_PTR(void, address),
+ "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)",
+ header->signature, (unsigned long)address,
header->length, header->revision, header->oem_id,
header->oem_table_id, header->oem_revision,
header->asl_compiler_id,
if (checksum) {
ACPI_WARNING((AE_INFO,
- "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X",
+ "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X",
table->signature, table->checksum,
(u8) (table->checksum - checksum)));
*
******************************************************************************/
-u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
+u8 acpi_tb_checksum(u8 *buffer, u32 length)
{
u8 sum = 0;
u8 *end = buffer + length;
void
acpi_tb_install_table(acpi_physical_address address,
- u8 flags, char *signature, acpi_native_uint table_index)
+ u8 flags, char *signature, u32 table_index)
{
struct acpi_table_header *table;
******************************************************************************/
static acpi_physical_address
-acpi_tb_get_root_table_entry(u8 * table_entry,
- acpi_native_uint table_entry_size)
+acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
{
u64 address64;
acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
{
struct acpi_table_rsdp *rsdp;
- acpi_native_uint table_entry_size;
- acpi_native_uint i;
+ u32 table_entry_size;
+ u32 i;
u32 table_count;
struct acpi_table_header *table;
acpi_physical_address address;
+ acpi_physical_address uninitialized_var(rsdt_address);
u32 length;
u8 *table_entry;
acpi_status status;
*/
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) */
*/
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));